vendor/ibexa/product-catalog/src/bundle/EventSubscriber/ProductFormSubscriber.php line 97

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4.  * @license For full copyright and license information view LICENSE file distributed with this source code.
  5.  */
  6. declare(strict_types=1);
  7. namespace Ibexa\Bundle\ProductCatalog\EventSubscriber;
  8. use Exception;
  9. use Ibexa\Bundle\ProductCatalog\Form\Data\AbstractProductData;
  10. use Ibexa\Bundle\ProductCatalog\Form\Data\ProductCreateData;
  11. use Ibexa\Bundle\ProductCatalog\Form\Data\ProductUpdateData;
  12. use Ibexa\Bundle\ProductCatalog\Form\Event\ProductFormEvents;
  13. use Ibexa\ContentForms\Event\FormActionEvent;
  14. use Ibexa\Contracts\AdminUi\Notification\TranslatableNotificationHandlerInterface;
  15. use Ibexa\Contracts\Core\Repository\Repository;
  16. use Ibexa\Contracts\ProductCatalog\Local\LocalProductServiceInterface;
  17. use Ibexa\Contracts\ProductCatalog\Values\ContentAwareProductInterface;
  18. use Ibexa\Contracts\ProductCatalog\Values\ProductInterface;
  19. use Ibexa\ProductCatalog\FieldType\ProductSpecification\Value as ProductSpecificationValue;
  20. use Ibexa\ProductCatalog\Tab\Product\TranslationsTab;
  21. use JMS\TranslationBundle\Annotation\Desc;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\HttpFoundation\RedirectResponse;
  24. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  25. final class ProductFormSubscriber implements EventSubscriberInterface
  26. {
  27.     private Repository $repository;
  28.     private LocalProductServiceInterface $localProductService;
  29.     private UrlGeneratorInterface $urlGenerator;
  30.     private TranslatableNotificationHandlerInterface $notificationHandler;
  31.     public function __construct(
  32.         Repository $repository,
  33.         LocalProductServiceInterface $localProductService,
  34.         UrlGeneratorInterface $urlGenerator,
  35.         TranslatableNotificationHandlerInterface $notificationHandler
  36.     ) {
  37.         $this->repository $repository;
  38.         $this->localProductService $localProductService;
  39.         $this->urlGenerator $urlGenerator;
  40.         $this->notificationHandler $notificationHandler;
  41.     }
  42.     public static function getSubscribedEvents(): array
  43.     {
  44.         return [
  45.             ProductFormEvents::PRODUCT_CREATE => ['onProductCreate', -255],
  46.             ProductFormEvents::PRODUCT_UPDATE => ['onProductUpdate', -255],
  47.         ];
  48.     }
  49.     public function onProductCreate(FormActionEvent $event): void
  50.     {
  51.         $form $event->getForm();
  52.         $data $event->getData();
  53.         if (!$data instanceof ProductCreateData) {
  54.             return;
  55.         }
  56.         $languageCode $form->getConfig()->getOption('languageCode');
  57.         $createStruct $this->localProductService->newProductCreateStruct(
  58.             $data->getProductType(),
  59.             $languageCode
  60.         );
  61.         $this->mapDataToStruct($createStruct$data$languageCode);
  62.         $this->repository->beginTransaction();
  63.         try {
  64.             $product $this->localProductService->createProduct($createStruct);
  65.             $this->repository->commit();
  66.         } catch (Exception $e) {
  67.             $this->repository->rollback();
  68.             throw $e;
  69.         }
  70.         $this->notificationHandler->success(
  71.             /** @Desc("Product '%name%' created.") */
  72.             'product.create.success',
  73.             ['%name%' => $product->getName()],
  74.             'ibexa_product_catalog'
  75.         );
  76.         $event->setResponse($this->createRedirectToProductView($product));
  77.     }
  78.     public function onProductUpdate(FormActionEvent $event): void
  79.     {
  80.         $form $event->getForm();
  81.         $data $event->getData();
  82.         if (!$data instanceof ProductUpdateData) {
  83.             return;
  84.         }
  85.         $languageCode $form->getConfig()->getOption('languageCode');
  86.         $mainLanguageCode $form->getConfig()->getOption('mainLanguageCode');
  87.         $isTranslation $languageCode !== $mainLanguageCode;
  88.         $updateStruct $this->localProductService->newProductUpdateStruct($data->getProduct());
  89.         $updateStruct->getContentUpdateStruct()->initialLanguageCode $languageCode;
  90.         $this->mapDataToStruct($updateStruct$data$languageCode$isTranslation);
  91.         $this->repository->beginTransaction();
  92.         try {
  93.             $product $this->localProductService->updateProduct($updateStruct);
  94.             $this->repository->commit();
  95.         } catch (Exception $e) {
  96.             $this->repository->rollback();
  97.             throw $e;
  98.         }
  99.         $this->notificationHandler->success(
  100.             /** @Desc("Product '%name%' updated.") */
  101.             'product.update.success',
  102.             ['%name%' => $product->getName()],
  103.             'ibexa_product_catalog'
  104.         );
  105.         $response $this->createRedirectToProductView(
  106.             $product,
  107.             $isTranslation TranslationsTab::URI_FRAGMENT null
  108.         );
  109.         $event->setResponse($response);
  110.     }
  111.     private function createRedirectToProductView(ProductInterface $product, ?string $fragment null): RedirectResponse
  112.     {
  113.         $parameters = [
  114.             'productCode' => $product->getCode(),
  115.             '_fragment' => $fragment,
  116.         ];
  117.         if ($product instanceof ContentAwareProductInterface) {
  118.             $parameters['updatedContentId'] = $product->getContent()->id;
  119.         }
  120.         $redirectionUrl $this->urlGenerator->generate(
  121.             'ibexa.product_catalog.product.view',
  122.             $parameters,
  123.         );
  124.         return new RedirectResponse($redirectionUrl);
  125.     }
  126.     /**
  127.      * @param \Ibexa\Contracts\ProductCatalog\Local\Values\Product\ProductCreateStruct|\Ibexa\Contracts\ProductCatalog\Local\Values\Product\ProductUpdateStruct  $struct
  128.      * @param \Ibexa\Bundle\ProductCatalog\Form\Data\AbstractProductData $data
  129.      */
  130.     private function mapDataToStruct(
  131.         $struct,
  132.         AbstractProductData $data,
  133.         string $languageCode,
  134.         bool $isTranslation false
  135.     ): void {
  136.         $struct->setCode($data->getCode());
  137.         foreach ($data->getFieldsData() as $fieldDefIdentifier => $fieldData) {
  138.             if ($fieldData->value instanceof ProductSpecificationValue) {
  139.                 continue;
  140.             }
  141.             if ($isTranslation && !$fieldData->fieldDefinition->isTranslatable) {
  142.                 continue;
  143.             }
  144.             $struct->setField($fieldDefIdentifier$fieldData->value$languageCode);
  145.         }
  146.         if (!$isTranslation) {
  147.             foreach ($data->getAttributes() as $attributeData) {
  148.                 $struct->setAttribute(
  149.                     $attributeData->getAttributeDefinition()->getIdentifier(),
  150.                     $attributeData->getValue()
  151.                 );
  152.             }
  153.         }
  154.     }
  155. }