vendor/shopware/core/Content/Cms/Subscriber/CmsPageDefaultChangeSubscriber.php line 55

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Cms\Subscriber;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\Content\Category\CategoryDefinition;
  5. use Shopware\Core\Content\Cms\CmsException;
  6. use Shopware\Core\Content\Cms\CmsPageDefinition;
  7. use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
  8. use Shopware\Core\Content\Product\ProductDefinition;
  9. use Shopware\Core\Defaults;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Event\BeforeDeleteEvent;
  11. use Shopware\Core\Framework\Log\Package;
  12. use Shopware\Core\Framework\Uuid\Uuid;
  13. use Shopware\Core\System\SystemConfig\Event\BeforeSystemConfigChangedEvent;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. /**
  16.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  17.  */
  18. #[Package('content')]
  19. class CmsPageDefaultChangeSubscriber implements EventSubscriberInterface
  20. {
  21.     /**
  22.      * @var array<string>
  23.      */
  24.     public static array $defaultCmsPageConfigKeys = [
  25.         ProductDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_PRODUCT,
  26.         CategoryDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_CATEGORY,
  27.     ];
  28.     private Connection $connection;
  29.     /**
  30.      * @internal
  31.      */
  32.     public function __construct(
  33.         Connection $connection
  34.     ) {
  35.         $this->connection $connection;
  36.     }
  37.     public static function getSubscribedEvents(): array
  38.     {
  39.         return [
  40.             BeforeSystemConfigChangedEvent::class => 'validateChangeOfDefaultCmsPage',
  41.             BeforeDeleteEvent::class => 'beforeDeletion',
  42.         ];
  43.     }
  44.     /**
  45.      * @throws CmsException
  46.      * @throws \JsonException
  47.      */
  48.     public function beforeDeletion(BeforeDeleteEvent $event): void
  49.     {
  50.         $cmsPageIds $event->getIds(CmsPageDefinition::ENTITY_NAME);
  51.         // no cms page is affected by this deletion event
  52.         if (empty($cmsPageIds)) {
  53.             return;
  54.         }
  55.         $defaultPages $this->cmsPageIsDefault($cmsPageIds);
  56.         // count !== 0 indicates that there are some cms pages which would be deleted but are currently a default
  57.         if (\count($defaultPages) !== 0) {
  58.             throw CmsException::deletionOfDefault($defaultPages);
  59.         }
  60.     }
  61.     /**
  62.      * @throws CmsException
  63.      * @throws PageNotFoundException
  64.      */
  65.     public function validateChangeOfDefaultCmsPage(BeforeSystemConfigChangedEvent $event): void
  66.     {
  67.         $newDefaultCmsPageId $event->getValue();
  68.         $systemConfigKey $event->getKey();
  69.         $salesChannelId $event->getSalesChannelId();
  70.         if (!\in_array($systemConfigKeyself::$defaultCmsPageConfigKeystrue)) {
  71.             return;
  72.         }
  73.         // prevent deleting the overall default (salesChannelId === null)
  74.         // a sales channel specific default can still be deleted (salesChannelId !== null)
  75.         if ($newDefaultCmsPageId === null && $salesChannelId === null) {
  76.             $oldCmsPageId $this->getCurrentOverallDefaultCmsPageId($systemConfigKey);
  77.             throw CmsException::overallDefaultSystemConfigDeletion($oldCmsPageId);
  78.         }
  79.         if (!\is_string($newDefaultCmsPageId) && $newDefaultCmsPageId !== null) {
  80.             throw new PageNotFoundException('invalid page');
  81.         }
  82.         // prevent changing the default to an invalid cms page id
  83.         if (\is_string($newDefaultCmsPageId) && !$this->cmsPageExists($newDefaultCmsPageId)) {
  84.             throw new PageNotFoundException($newDefaultCmsPageId);
  85.         }
  86.     }
  87.     private function getCurrentOverallDefaultCmsPageId(string $systemConfigKey): string
  88.     {
  89.         $result $this->connection->fetchOne(
  90.             'SELECT configuration_value FROM system_config WHERE configuration_key = :configKey AND sales_channel_id is NULL;',
  91.             [
  92.                 'configKey' => $systemConfigKey,
  93.             ]
  94.         );
  95.         $config json_decode($resulttrue);
  96.         return $config['_value'];
  97.     }
  98.     /**
  99.      * @param array<string> $cmsPageIds
  100.      *
  101.      * @return array<string>
  102.      */
  103.     private function cmsPageIsDefault(array $cmsPageIds): array
  104.     {
  105.         $configurations $this->connection->fetchAllAssociative(
  106.             'SELECT DISTINCT configuration_value FROM system_config WHERE configuration_key IN (:configKeys);',
  107.             [
  108.                 'configKeys' => self::$defaultCmsPageConfigKeys,
  109.             ],
  110.             [
  111.                 'configKeys' => Connection::PARAM_STR_ARRAY,
  112.             ]
  113.         );
  114.         $defaultIds = [];
  115.         foreach ($configurations as $configuration) {
  116.             $configValue $configuration['configuration_value'];
  117.             $config json_decode($configValuetrue);
  118.             $defaultIds[] = $config['_value'];
  119.         }
  120.         // returns from all provided cms pages the ones which are default
  121.         return array_intersect($cmsPageIds$defaultIds);
  122.     }
  123.     private function cmsPageExists(string $cmsPageId): bool
  124.     {
  125.         $count $this->connection->fetchOne(
  126.             'SELECT count(*) FROM cms_page WHERE id = :cmsPageId AND version_id = :versionId LIMIT 1;',
  127.             [
  128.                 'cmsPageId' => Uuid::fromHexToBytes($cmsPageId),
  129.                 'versionId' => Uuid::fromHexToBytes(Defaults::LIVE_VERSION),
  130.             ]
  131.         );
  132.         return $count === '1';
  133.     }
  134. }