custom/plugins/CioProductExtension/src/Subscriber/ProductCloneCioExtensionSubscriber.php line 48

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace CioProductExtension\Subscriber;
  4. use CioProductExtension\Definition\CioProductExtensionEntity;
  5. use Shopware\Core\Content\Product\ProductDefinition;
  6. use Shopware\Core\Framework\Context;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\Uuid\Uuid;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. class ProductCloneCioExtensionSubscriber implements EventSubscriberInterface
  13. {
  14.     private EntityRepository $productRepository;
  15.     private EntityRepository $cioProductExtensionRepository;
  16.     public function __construct(
  17.         EntityRepository $productRepository,
  18.         EntityRepository $cioProductExtensionRepository
  19.     ) {
  20.         $this->productRepository $productRepository;
  21.         $this->cioProductExtensionRepository $cioProductExtensionRepository;
  22.     }
  23.     /**
  24.      * @return array<class-string, string>
  25.      */
  26.     public static function getSubscribedEvents(): array
  27.     {
  28.         return [
  29.             EntityWrittenContainerEvent::class => 'onEntityWrittenContainerEvent',
  30.         ];
  31.     }
  32.     /**
  33.      * CIO-AI-Driven
  34.      *
  35.      * Duplicates the cio_product_extension entity when a product is cloned in the administration,
  36.      * because the relation between product.cio_extension_id and cio_product_extension.id must be 1:1.
  37.      *
  38.      * Important: Guards against empty/invalid IDs to avoid loading all products accidentally.
  39.      */
  40.     public function onEntityWrittenContainerEvent(EntityWrittenContainerEvent $event): void
  41.     {
  42.         if (!$event->isCloned()) {
  43.             return;
  44.         }
  45.         $productWrittenEvent $event->getEventByEntityName(ProductDefinition::ENTITY_NAME);
  46.         if ($productWrittenEvent === null) {
  47.             return;
  48.         }
  49.         $productIds $this->filterValidIds($productWrittenEvent->getIds());
  50.         if ($productIds === []) {
  51.             return;
  52.         }
  53.         $context $event->getContext();
  54.         $products $this->productRepository->search(new Criteria($productIds), $context)->getEntities();
  55.         $newExtensionPayloads = [];
  56.         $productUpdatePayloads = [];
  57.         $oldExtensionIds = [];
  58.         foreach ($products as $product) {
  59.             $cioExtensionId $product->get('cioExtensionId');
  60.             if (!\is_string($cioExtensionId) || $cioExtensionId === '' || !Uuid::isValid($cioExtensionId)) {
  61.                 continue;
  62.             }
  63.             $oldExtensionIds[$cioExtensionId] = true;
  64.         }
  65.         if ($oldExtensionIds === []) {
  66.             return;
  67.         }
  68.         $oldExtensionsById $this->fetchExtensionsById(array_keys($oldExtensionIds), $context);
  69.         foreach ($products as $product) {
  70.             $productId $product->getUniqueIdentifier();
  71.             $oldExtensionId $product->get('cioExtensionId');
  72.             if (!\is_string($oldExtensionId) || $oldExtensionId === '' || !Uuid::isValid($oldExtensionId)) {
  73.                 continue;
  74.             }
  75.             $oldExtension $oldExtensionsById[$oldExtensionId] ?? null;
  76.             $newExtensionId Uuid::randomHex();
  77.             $newExtensionPayloads[] = [
  78.                 'id' => $newExtensionId,
  79.                 'meldebestand' => $oldExtension $oldExtension->getMeldebestand() : null,
  80.                 'reportFlag' => $oldExtension $oldExtension->getReportFlag() : null,
  81.             ];
  82.             $productUpdatePayloads[] = [
  83.                 'id' => $productId,
  84.                 'cioExtensionId' => $newExtensionId,
  85.             ];
  86.         }
  87.         if ($newExtensionPayloads !== []) {
  88.             $this->cioProductExtensionRepository->create($newExtensionPayloads$context);
  89.         }
  90.         if ($productUpdatePayloads !== []) {
  91.             $this->productRepository->update($productUpdatePayloads$context);
  92.         }
  93.     }
  94.     /**
  95.      * @param array<int, mixed> $ids
  96.      *
  97.      * @return list<string>
  98.      */
  99.     private function filterValidIds(array $ids): array
  100.     {
  101.         $validIds = [];
  102.         foreach ($ids as $id) {
  103.             if (!\is_string($id)) {
  104.                 continue;
  105.             }
  106.             if ($id === '' || !Uuid::isValid($id)) {
  107.                 continue;
  108.             }
  109.             $validIds[] = $id;
  110.         }
  111.         return array_values(array_unique($validIds));
  112.     }
  113.     /**
  114.      * @param list<string> $extensionIds
  115.      *
  116.      * @return array<string, CioProductExtensionEntity>
  117.      */
  118.     private function fetchExtensionsById(array $extensionIdsContext $context): array
  119.     {
  120.         if ($extensionIds === []) {
  121.             return [];
  122.         }
  123.         $extensions $this->cioProductExtensionRepository->search(new Criteria($extensionIds), $context)->getEntities();
  124.         $extensionsById = [];
  125.         foreach ($extensions as $extension) {
  126.             if (!$extension instanceof CioProductExtensionEntity) {
  127.                 continue;
  128.             }
  129.             $extensionsById[$extension->getUniqueIdentifier()] = $extension;
  130.         }
  131.         return $extensionsById;
  132.     }
  133. }