<?php declare(strict_types=1);
/**
* @copyright 2020 Crehler Sp. z o. o. <https://crehler.com>
*
* @author Jakub MedyĆski <jme@crehler.com>
* @support Crehler <support@crehler.com>
* @created 10 sie 2020
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Crehler\Arrangements\Service;
use Crehler\Arrangements\Entity\Arrangement\Aggregate\ArrangementMedia\Aggregate\ArrangementMediaDot\ArrangementMediaDotCollection;
use Crehler\Arrangements\Entity\Arrangement\Aggregate\ArrangementMedia\Aggregate\ArrangementMediaDot\ArrangementMediaDotEntity;
use Crehler\Arrangements\Entity\Arrangement\Aggregate\ArrangementMedia\ArrangementMediaEntity;
use Crehler\Arrangements\Entity\Arrangement\Aggregate\ArrangementProduct\ArrangementProductEntity;
use Crehler\Arrangements\Entity\Arrangement\ArrangementEntity;
use Crehler\Tools\Enum\LoaderFlags;
use Crehler\Tools\Product\ProductLoaderInterface;
use Monolog\Logger;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
class ArrangementService
{
public function __construct(
private readonly EntityRepository $arrangementRepository,
private readonly ProductLoaderInterface $productLoader,
private readonly Logger $logger
)
{
}
public function getArrangementById(string $arrangementId, SalesChannelContext $salesChannelContext, Request $request): ?ArrangementEntity
{
$criteria = new Criteria([$arrangementId]);
$criteria->addAssociation('arrangementProducts');
$criteria->addAssociation('media')
->addAssociation('cover.arrangementMediaDots.arrangementProduct')
->addAssociation('cover.arrangementMediaDots.arrangementProduct');
$criteria->getAssociation('media')
->addAssociation('arrangementMediaDots.arrangementProduct')
->addAssociation('arrangementMediaDots.arrangementProduct')
->addSorting(new FieldSorting('position'));
/** @var ArrangementEntity $arrangement */
$arrangement = $this->arrangementRepository->search($criteria, $salesChannelContext->getContext())->first();
$this->filterDotCollection($arrangement->getCover()->getArrangementMediaDots(), $salesChannelContext);
/** @var ArrangementMediaEntity $media */
foreach ($arrangement->getMedia() as $media) {
$this->filterDotCollection($media->getArrangementMediaDots(), $salesChannelContext);
}
/** @var ArrangementProductEntity $arrangementProduct */
foreach ($arrangement->getArrangementProducts() as $arrangementProduct) {
$salesChannelProduct = $this->productLoader->load(
$arrangementProduct->getProductId(),
$salesChannelContext,
LoaderFlags::SkipPageLoading,
LoaderFlags::SkipSeoCategory,
LoaderFlags::IgnoreHideCloseoutProductsWhenOutOfStock)
->first();
if ($salesChannelProduct === null) {
$this->logger->warning("Remove " . $arrangementProduct->getProductId() . " from arrangement " . $arrangement->getId());
$arrangement->getArrangementProducts()->remove($arrangementProduct->getId());
continue;
}
$arrangementProduct->setProduct($salesChannelProduct);
}
return $arrangement;
}
private function filterDotCollection(ArrangementMediaDotCollection $arrangementMediaDotCollection, SalesChannelContext $salesChannelContext): void
{
/** @var ArrangementMediaDotEntity $arrangementMediaDot */
foreach ($arrangementMediaDotCollection as $arrangementMediaDot) {
$productId = $arrangementMediaDot->getArrangementProduct()->getProductId();
$salesChannelProduct = $this->productLoader->load(
$productId,
$salesChannelContext,
LoaderFlags::SkipPageLoading,
LoaderFlags::SkipSeoCategory,
LoaderFlags::IgnoreHideCloseoutProductsWhenOutOfStock)
->first();
if ($salesChannelProduct === null) {
$arrangementMediaDotCollection->remove($arrangementMediaDot->getId());
$this->logger->warning("Remove " . $productId . " from arrangement media dot " . $arrangementMediaDot->getId());
continue;
}
$arrangementMediaDot->getArrangementProduct()->setProduct($salesChannelProduct);
}
}
}