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

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