src/Core/Content/Rule/DataAbstractionLayer/RulePayloadSubscriber.php line 40

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Rule\DataAbstractionLayer;
  3. use Shopware\Core\Content\Rule\RuleEntity;
  4. use Shopware\Core\Content\Rule\RuleEvents;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  6. use Shopware\Core\Framework\Log\Package;
  7. use Shopware\Core\Framework\Rule\Container\Container;
  8. use Shopware\Core\Framework\Rule\Container\FilterRule;
  9. use Shopware\Core\Framework\Rule\Rule;
  10. use Shopware\Core\Framework\Rule\ScriptRule;
  11. use Shopware\Core\Framework\Script\Debugging\ScriptTraces;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. /**
  14.  * @internal
  15.  */
  16. #[Package('business-ops')]
  17. class RulePayloadSubscriber implements EventSubscriberInterface
  18. {
  19.     /**
  20.      * @internal
  21.      */
  22.     public function __construct(
  23.         private readonly RulePayloadUpdater $updater,
  24.         private readonly ScriptTraces $traces,
  25.         private readonly string $cacheDir,
  26.         private readonly bool $debug
  27.     ) {
  28.     }
  29.     public static function getSubscribedEvents(): array
  30.     {
  31.         return [
  32.             RuleEvents::RULE_LOADED_EVENT => 'unserialize',
  33.         ];
  34.     }
  35.     public function unserialize(EntityLoadedEvent $event): void
  36.     {
  37.         $this->indexIfNeeded($event);
  38.         /** @var RuleEntity $entity */
  39.         foreach ($event->getEntities() as $entity) {
  40.             $payload $entity->getPayload();
  41.             if ($payload === null || !\is_string($payload)) {
  42.                 continue;
  43.             }
  44.             $payload unserialize($payload);
  45.             $this->enrichConditions([$payload]);
  46.             $entity->setPayload($payload);
  47.         }
  48.     }
  49.     private function indexIfNeeded(EntityLoadedEvent $event): void
  50.     {
  51.         $rules = [];
  52.         /** @var RuleEntity $rule */
  53.         foreach ($event->getEntities() as $rule) {
  54.             if ($rule->getPayload() === null && !$rule->isInvalid()) {
  55.                 $rules[$rule->getId()] = $rule;
  56.             }
  57.         }
  58.         if (!\count($rules)) {
  59.             return;
  60.         }
  61.         $updated $this->updater->update(array_keys($rules));
  62.         foreach ($updated as $id => $entity) {
  63.             $rules[$id]->assign($entity);
  64.         }
  65.     }
  66.     /**
  67.      * @param list<Rule> $conditions
  68.      */
  69.     private function enrichConditions(array $conditions): void
  70.     {
  71.         foreach ($conditions as $condition) {
  72.             if ($condition instanceof ScriptRule) {
  73.                 $condition->assign([
  74.                     'traces' => $this->traces,
  75.                     'cacheDir' => $this->cacheDir,
  76.                     'debug' => $this->debug,
  77.                 ]);
  78.                 continue;
  79.             }
  80.             if ($condition instanceof Container || $condition instanceof FilterRule) {
  81.                 $this->enrichConditions($condition->getRules());
  82.             }
  83.         }
  84.     }
  85. }