vendor/shopware/core/Content/Category/Validation/EntryPointValidator.php line 49

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Category\Validation;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\Content\Category\CategoryDefinition;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\InsertCommand;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\UpdateCommand;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteCommand;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PostWriteValidationEvent;
  9. use Shopware\Core\Framework\Log\Package;
  10. use Shopware\Core\Framework\Validation\WriteConstraintViolationException;
  11. use Shopware\Core\System\SalesChannel\SalesChannelDefinition;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Validator\ConstraintViolation;
  14. use Symfony\Component\Validator\ConstraintViolationList;
  15. use Symfony\Component\Validator\ConstraintViolationListInterface;
  16. /**
  17.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  18.  */
  19. #[Package('content')]
  20. class EntryPointValidator implements EventSubscriberInterface
  21. {
  22.     private const ERROR_CODE 'CONTENT__INVALID_CATEGORY_TYPE_AS_ENTRY_POINT';
  23.     private const ALLOWED_TYPE_CHANGE = [
  24.         CategoryDefinition::TYPE_PAGE,
  25.         CategoryDefinition::TYPE_FOLDER,
  26.     ];
  27.     private Connection $connection;
  28.     /**
  29.      * @internal
  30.      */
  31.     public function __construct(Connection $connection)
  32.     {
  33.         $this->connection $connection;
  34.     }
  35.     public static function getSubscribedEvents(): array
  36.     {
  37.         return [
  38.             PostWriteValidationEvent::class => 'postValidate',
  39.         ];
  40.     }
  41.     public function postValidate(PostWriteValidationEvent $event): void
  42.     {
  43.         $violationList = new ConstraintViolationList();
  44.         foreach ($event->getCommands() as $command) {
  45.             if (!($command instanceof InsertCommand || $command instanceof UpdateCommand)) {
  46.                 continue;
  47.             }
  48.             if ($command->getDefinition()->getClass() !== CategoryDefinition::class) {
  49.                 continue;
  50.             }
  51.             if (!isset($command->getPayload()['type'])) {
  52.                 continue;
  53.             }
  54.             $violationList->addAll($this->checkTypeChange($command$event));
  55.         }
  56.         if ($violationList->count() > 0) {
  57.             $event->getExceptions()->add(new WriteConstraintViolationException($violationList));
  58.             return;
  59.         }
  60.     }
  61.     private function checkTypeChange(WriteCommand $commandPostWriteValidationEvent $event): ConstraintViolationListInterface
  62.     {
  63.         $violationList = new ConstraintViolationList();
  64.         $payload $command->getPayload();
  65.         if (\in_array($payload['type'], self::ALLOWED_TYPE_CHANGEtrue)) {
  66.             return $violationList;
  67.         }
  68.         if ($this->isCategoryEntryPoint($command->getPrimaryKey()['id'], $event)) {
  69.             return $violationList;
  70.         }
  71.         $messageTemplate 'The type can not be assigned while category is entry point.';
  72.         $parameters = ['{{ value }}' => $payload['type']];
  73.         $violationList->add(new ConstraintViolation(
  74.             str_replace(array_keys($parameters), $parameters$messageTemplate),
  75.             $messageTemplate,
  76.             $parameters,
  77.             null,
  78.             sprintf('%s/type'$command->getPath()),
  79.             $payload['type'],
  80.             null,
  81.             self::ERROR_CODE
  82.         ));
  83.         return $violationList;
  84.     }
  85.     private function isCategoryEntryPoint(string $categoryIdPostWriteValidationEvent $event): bool
  86.     {
  87.         foreach ($event->getCommands() as $salesChannelCommand) {
  88.             if ($salesChannelCommand->getDefinition()->getClass() !== SalesChannelDefinition::class) {
  89.                 continue;
  90.             }
  91.             $payload $salesChannelCommand->getPayload();
  92.             if ((isset($payload['navigation_category_id']) && $payload['navigation_category_id'] === $categoryId)
  93.                 || (isset($payload['footer_category_id']) && $payload['footer_category_id'] === $categoryId)
  94.                 || (isset($payload['service_category_id']) && $payload['service_category_id'] === $categoryId)
  95.             ) {
  96.                 return false;
  97.             }
  98.         }
  99.         $result $this->connection->createQueryBuilder()
  100.             ->select('id')
  101.             ->from(SalesChannelDefinition::ENTITY_NAME)
  102.             ->where('navigation_category_id = :navigation_id')
  103.             ->orWhere('footer_category_id = :footer_id')
  104.             ->orWhere('service_category_id = :service_id')
  105.             ->setParameter('navigation_id'$categoryId)
  106.             ->setParameter('footer_id'$categoryId)
  107.             ->setParameter('service_id'$categoryId)
  108.             ->setMaxResults(1)
  109.             ->executeQuery();
  110.         return !$result->fetchOne();
  111.     }
  112. }