custom/plugins/PickwareErpStarter/vendor/pickware/dal-bundle/src/EntityPreWriteValidationEventDispatcher.php line 59

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (c) Pickware GmbH. All rights reserved.
  4.  * This file is part of software that is released under a proprietary license.
  5.  * You must not copy, modify, distribute, make publicly available, or execute
  6.  * its contents or parts thereof without express permission by the copyright
  7.  * holder, unless otherwise permitted by law.
  8.  */
  9. declare(strict_types=1);
  10. namespace Pickware\DalBundle;
  11. use Psr\EventDispatcher\EventDispatcherInterface;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. /**
  15.  * Shopware dispatches only one "pre_write_validation" event for each call to the DAL (like entity create, update or
  16.  * delete). The same event is dispatched for every entity that is written at once, so subscribers listening on this
  17.  * event then need to be instantiated in the container even if they do not need information about the entity in
  18.  * question. Only after their instantiation they can decide whether to act or not.
  19.  *
  20.  * This dispatcher and the new event being only scoped on individual entities solves this problem by allowing subscribers
  21.  * to specify the concerned entities before their instantiation. This means that the symfony DI container will not
  22.  * instantiate a subscriber if the subscriber will not act on the event.
  23.  *
  24.  * During plugin updates, the "plugin" entity is updated and thus a "pre_write_validation" event is dispatched. When
  25.  * listening on the old event, subscribers were instantiated even if they did not act on the "plugin" entity. As during
  26.  * a plugin update the code is updated before the container refreshes, the container might try to instantiate a
  27.  * subscriber with invalid constructor parameters. This leads to a (from the admin irrecoverable) container crash. With
  28.  * the new event, the subscriber is not instantiated and thus the container does not crash.
  29.  *
  30.  * This also prevents subscribers from requesting change-sets for every entity and uncovers missing change-set requests.
  31.  *
  32.  * See:
  33.  * - https://github.com/pickware/shopware-plugins/issues/3500
  34.  * - https://github.com/pickware/shopware-plugins/issues/2764
  35.  */
  36. class EntityPreWriteValidationEventDispatcher implements EventSubscriberInterface
  37. {
  38.     private EventDispatcherInterface $eventDispatcher;
  39.     public function __construct(EventDispatcherInterface $eventDispatcher)
  40.     {
  41.         $this->eventDispatcher $eventDispatcher;
  42.     }
  43.     public static function getSubscribedEvents(): array
  44.     {
  45.         return [PreWriteValidationEvent::class => 'onPreWriteValidation'];
  46.     }
  47.     public static function getEventName(string $entityName): string
  48.     {
  49.         return sprintf('pickware_dal_bundle.%s.pre_write_validation'$entityName);
  50.     }
  51.     public function onPreWriteValidation(PreWriteValidationEvent $event): void
  52.     {
  53.         $writeCommandsByEntityNames = [];
  54.         $definitionClassNamesByEntityNames = [];
  55.         foreach ($event->getCommands() as $command) {
  56.             $entityName $command->getDefinition()->getEntityName();
  57.             $writeCommandsByEntityNames[$entityName] ??= [];
  58.             $writeCommandsByEntityNames[$entityName][] = $command;
  59.             $definitionClassNamesByEntityNames[$entityName] = $command->getDefinition()->getClass();
  60.         }
  61.         foreach ($writeCommandsByEntityNames as $entityName => $writeCommands) {
  62.             /** @var EntityPreWriteValidationEvent $entityPreWriteValidationEvent */
  63.             $entityPreWriteValidationEvent $this->eventDispatcher->dispatch(
  64.                 new EntityPreWriteValidationEvent(
  65.                     $event->getWriteContext(),
  66.                     $writeCommands,
  67.                     $definitionClassNamesByEntityNames[$entityName],
  68.                 ),
  69.                 self::getEventName($entityName),
  70.             );
  71.             foreach ($entityPreWriteValidationEvent->getViolations() as $violation) {
  72.                 $event->getExceptions()->add($violation);
  73.             }
  74.         }
  75.     }
  76. }