custom/plugins/SwagCustomizedProducts/src/Storefront/Page/Product/ProductPageSubscriber.php line 126

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /*
  3.  * (c) shopware AG <info@shopware.com>
  4.  * For the full copyright and license information, please view the LICENSE
  5.  * file that was distributed with this source code.
  6.  */
  7. namespace Swag\CustomizedProducts\Storefront\Page\Product;
  8. use Shopware\Core\Content\Product\ProductEntity;
  9. use Shopware\Core\Framework\Context;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\Uuid\Uuid;
  13. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  14. use Swag\CustomizedProducts\Core\Content\Product\ProductWrittenSubscriber;
  15. use Swag\CustomizedProducts\Migration\Migration1565933910TemplateProduct;
  16. use Swag\CustomizedProducts\Storefront\Page\Product\Extensions\EditConfigurationExtension;
  17. use Swag\CustomizedProducts\Storefront\Page\Product\Extensions\ShareConfigurationExtension;
  18. use Swag\CustomizedProducts\Template\Aggregate\TemplateConfiguration\Aggregate\TemplateConfigurationShareEntity;
  19. use Swag\CustomizedProducts\Template\Aggregate\TemplateConfiguration\Service\TemplateConfigurationService;
  20. use Swag\CustomizedProducts\Template\Aggregate\TemplateConfiguration\TemplateConfigurationEntity;
  21. use Swag\CustomizedProducts\Template\SalesChannel\Price\PriceService;
  22. use Swag\CustomizedProducts\Template\TemplateEntity;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\HttpFoundation\Session\Session;
  25. use Symfony\Contracts\Translation\TranslatorInterface;
  26. class ProductPageSubscriber implements EventSubscriberInterface
  27. {
  28.     public const EDIT_CONFIGURATION_PARAMETER 'swagCustomizedProductsConfigurationEdit';
  29.     public const SHARE_CONFIGURATION_PARAMETER 'swagCustomizedProductsConfigurationShare';
  30.     /**
  31.      * @var EntityRepositoryInterface
  32.      */
  33.     private $productRepository;
  34.     /**
  35.      * @var PriceService
  36.      */
  37.     private $priceService;
  38.     /**
  39.      * @var EntityRepositoryInterface
  40.      */
  41.     private $configurationRepository;
  42.     /**
  43.      * @var EntityRepositoryInterface
  44.      */
  45.     private $configurationShareRepository;
  46.     /**
  47.      * @var Session
  48.      */
  49.     private $session;
  50.     /**
  51.      * @var TranslatorInterface
  52.      */
  53.     private $translator;
  54.     /**
  55.      * @var TemplateConfigurationService
  56.      */
  57.     private $configurationService;
  58.     public function __construct(
  59.         EntityRepositoryInterface $productRepository,
  60.         PriceService $priceService,
  61.         EntityRepositoryInterface $configurationRepository,
  62.         EntityRepositoryInterface $configurationShareRepository,
  63.         Session $session,
  64.         TranslatorInterface $translator,
  65.         TemplateConfigurationService $configurationService
  66.     ) {
  67.         $this->productRepository $productRepository;
  68.         $this->priceService $priceService;
  69.         $this->configurationRepository $configurationRepository;
  70.         $this->configurationShareRepository $configurationShareRepository;
  71.         $this->session $session;
  72.         $this->translator $translator;
  73.         $this->configurationService $configurationService;
  74.     }
  75.     public static function getSubscribedEvents(): array
  76.     {
  77.         return [
  78.             ProductPageLoadedEvent::class => [
  79.                 ['removeCustomizedProductsTemplateFromNoneInheritedVariant'400],
  80.                 ['enrichOptionPriceAbleDisplayPrices'300],
  81.                 ['addEditConfigurationExtension'200],
  82.                 ['addShareConfigurationExtension'100],
  83.             ],
  84.         ];
  85.     }
  86.     public function removeCustomizedProductsTemplateFromNoneInheritedVariant(ProductPageLoadedEvent $event): void
  87.     {
  88.         $product $event->getPage()->getProduct();
  89.         $parentId $product->getParentId();
  90.         if ($parentId === null) {
  91.             return;
  92.         }
  93.         $customFields $product->getCustomFields();
  94.         if ($customFields === null
  95.             || !\array_key_exists(ProductWrittenSubscriber::SWAG_CUSTOMIZED_PRODUCTS_TEMPLATE_INHERITED_CUSTOM_FIELD$customFields)
  96.         ) {
  97.             return;
  98.         }
  99.         if ($customFields[ProductWrittenSubscriber::SWAG_CUSTOMIZED_PRODUCTS_TEMPLATE_INHERITED_CUSTOM_FIELD]) {
  100.             return;
  101.         }
  102.         if ($this->variantHasOwnTemplateAssigned($product->getId(), $event->getContext())) {
  103.             return;
  104.         }
  105.         $product->removeExtension(Migration1565933910TemplateProduct::PRODUCT_TEMPLATE_INHERITANCE_COLUMN);
  106.     }
  107.     public function enrichOptionPriceAbleDisplayPrices(ProductPageLoadedEvent $event): void
  108.     {
  109.         /** @var TemplateEntity|null $customizedProductsTemplate */
  110.         $customizedProductsTemplate $event->getPage()->getProduct()->getExtension('swagCustomizedProductsTemplate');
  111.         if ($customizedProductsTemplate === null) {
  112.             return;
  113.         }
  114.         $this->priceService->calculateCurrencyPrices($customizedProductsTemplate$event->getSalesChannelContext());
  115.     }
  116.     public function addEditConfigurationExtension(ProductPageLoadedEvent $event): void
  117.     {
  118.         $query $event->getRequest()->query;
  119.         if (!$query->has(self::EDIT_CONFIGURATION_PARAMETER)) {
  120.             return;
  121.         }
  122.         $configurationId $query->getAlnum(self::EDIT_CONFIGURATION_PARAMETER);
  123.         if (!Uuid::isValid($configurationId)) {
  124.             return;
  125.         }
  126.         $context $event->getContext();
  127.         $configuration $this->getConfiguration($configurationId$context);
  128.         if ($configuration === null) {
  129.             $this->session->getFlashBag()->add(
  130.                 'info',
  131.                 $this->translator->trans('customizedProducts.configurationEdit.notRestorable')
  132.             );
  133.             return;
  134.         }
  135.         if (!$this->configurationService->isConfigurationFullyRestorable($configuration$context)) {
  136.             $this->session->getFlashBag()->add(
  137.                 'info',
  138.                 $this->translator->trans('customizedProducts.configurationEdit.notFullyRestorable')
  139.             );
  140.         }
  141.         $editConfigurationExtension = (new EditConfigurationExtension())->assign([
  142.             'oldHash' => $configuration->getHash(),
  143.             'configuration' => $configuration->getConfiguration(),
  144.         ]);
  145.         $event->getPage()->addExtension(self::EDIT_CONFIGURATION_PARAMETER$editConfigurationExtension);
  146.     }
  147.     public function addShareConfigurationExtension(ProductPageLoadedEvent $event): void
  148.     {
  149.         $context $event->getContext();
  150.         $query $event->getRequest()->query;
  151.         if (!$query->has(self::SHARE_CONFIGURATION_PARAMETER)) {
  152.             return;
  153.         }
  154.         $shareId $query->getAlnum(self::SHARE_CONFIGURATION_PARAMETER);
  155.         if (!Uuid::isValid($shareId)) {
  156.             return;
  157.         }
  158.         $configurationShare $this->getShare($shareId$context);
  159.         if ($configurationShare === null) {
  160.             $this->session->getFlashBag()->add(
  161.                 'info',
  162.                 $this->translator->trans('customizedProducts.configurationShare.unavailable')
  163.             );
  164.             return;
  165.         }
  166.         $shareConfigurationExtension = (new ShareConfigurationExtension())->assign([
  167.             'configuration' => $configurationShare->getTemplateConfiguration()->getConfiguration(),
  168.         ]);
  169.         $event->getPage()->addExtension(self::SHARE_CONFIGURATION_PARAMETER$shareConfigurationExtension);
  170.         if ($configurationShare->isOneTime()) {
  171.             $this->configurationShareRepository->delete([['id' => $configurationShare->getId()]], $context);
  172.         }
  173.     }
  174.     private function variantHasOwnTemplateAssigned(string $idContext $context): bool
  175.     {
  176.         $considerInheritance $context->considerInheritance();
  177.         $criteria = new Criteria([$id]);
  178.         $criteria->addAssociation(Migration1565933910TemplateProduct::PRODUCT_TEMPLATE_INHERITANCE_COLUMN);
  179.         $criteria->setLimit(1);
  180.         $context->setConsiderInheritance(false);
  181.         /** @var ProductEntity|null $product */
  182.         $product $this->productRepository->search($criteria$context)->first();
  183.         $context->setConsiderInheritance($considerInheritance);
  184.         if ($product === null) {
  185.             return false;
  186.         }
  187.         return $product->hasExtension(Migration1565933910TemplateProduct::PRODUCT_TEMPLATE_INHERITANCE_COLUMN);
  188.     }
  189.     private function getConfiguration(string $configurationIdContext $context): ?TemplateConfigurationEntity
  190.     {
  191.         $criteria = new Criteria([$configurationId]);
  192.         return $this->configurationRepository->search($criteria$context)->first();
  193.     }
  194.     private function getShare(string $shareIdContext $context): ?TemplateConfigurationShareEntity
  195.     {
  196.         $criteria = new Criteria([$shareId]);
  197.         $criteria->addAssociation('templateConfiguration');
  198.         return $this->configurationShareRepository->search($criteria$context)->first();
  199.     }
  200. }