- <?php declare(strict_types=1);
- namespace Shopware\Core\Content\Cms\Subscriber;
- use Doctrine\DBAL\Connection;
- use Shopware\Core\Content\Category\CategoryDefinition;
- use Shopware\Core\Content\Cms\CmsException;
- use Shopware\Core\Content\Cms\CmsPageDefinition;
- use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
- use Shopware\Core\Content\Product\ProductDefinition;
- use Shopware\Core\Defaults;
- use Shopware\Core\Framework\DataAbstractionLayer\Event\BeforeDeleteEvent;
- use Shopware\Core\Framework\Log\Package;
- use Shopware\Core\Framework\Uuid\Uuid;
- use Shopware\Core\System\SystemConfig\Event\BeforeSystemConfigChangedEvent;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- /**
-  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
-  */
- #[Package('content')]
- class CmsPageDefaultChangeSubscriber implements EventSubscriberInterface
- {
-     /**
-      * @var array<string>
-      */
-     public static array $defaultCmsPageConfigKeys = [
-         ProductDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_PRODUCT,
-         CategoryDefinition::CONFIG_KEY_DEFAULT_CMS_PAGE_CATEGORY,
-     ];
-     private Connection $connection;
-     /**
-      * @internal
-      */
-     public function __construct(
-         Connection $connection
-     ) {
-         $this->connection = $connection;
-     }
-     public static function getSubscribedEvents(): array
-     {
-         return [
-             BeforeSystemConfigChangedEvent::class => 'validateChangeOfDefaultCmsPage',
-             BeforeDeleteEvent::class => 'beforeDeletion',
-         ];
-     }
-     /**
-      * @throws CmsException
-      * @throws \JsonException
-      */
-     public function beforeDeletion(BeforeDeleteEvent $event): void
-     {
-         $cmsPageIds = $event->getIds(CmsPageDefinition::ENTITY_NAME);
-         // no cms page is affected by this deletion event
-         if (empty($cmsPageIds)) {
-             return;
-         }
-         $defaultPages = $this->cmsPageIsDefault($cmsPageIds);
-         // count !== 0 indicates that there are some cms pages which would be deleted but are currently a default
-         if (\count($defaultPages) !== 0) {
-             throw CmsException::deletionOfDefault($defaultPages);
-         }
-     }
-     /**
-      * @throws CmsException
-      * @throws PageNotFoundException
-      */
-     public function validateChangeOfDefaultCmsPage(BeforeSystemConfigChangedEvent $event): void
-     {
-         $newDefaultCmsPageId = $event->getValue();
-         $systemConfigKey = $event->getKey();
-         $salesChannelId = $event->getSalesChannelId();
-         if (!\in_array($systemConfigKey, self::$defaultCmsPageConfigKeys, true)) {
-             return;
-         }
-         // prevent deleting the overall default (salesChannelId === null)
-         // a sales channel specific default can still be deleted (salesChannelId !== null)
-         if ($newDefaultCmsPageId === null && $salesChannelId === null) {
-             $oldCmsPageId = $this->getCurrentOverallDefaultCmsPageId($systemConfigKey);
-             throw CmsException::overallDefaultSystemConfigDeletion($oldCmsPageId);
-         }
-         if (!\is_string($newDefaultCmsPageId) && $newDefaultCmsPageId !== null) {
-             throw new PageNotFoundException('invalid page');
-         }
-         // prevent changing the default to an invalid cms page id
-         if (\is_string($newDefaultCmsPageId) && !$this->cmsPageExists($newDefaultCmsPageId)) {
-             throw new PageNotFoundException($newDefaultCmsPageId);
-         }
-     }
-     private function getCurrentOverallDefaultCmsPageId(string $systemConfigKey): string
-     {
-         $result = $this->connection->fetchOne(
-             'SELECT configuration_value FROM system_config WHERE configuration_key = :configKey AND sales_channel_id is NULL;',
-             [
-                 'configKey' => $systemConfigKey,
-             ]
-         );
-         $config = json_decode($result, true);
-         return $config['_value'];
-     }
-     /**
-      * @param array<string> $cmsPageIds
-      *
-      * @return array<string>
-      */
-     private function cmsPageIsDefault(array $cmsPageIds): array
-     {
-         $configurations = $this->connection->fetchAllAssociative(
-             'SELECT DISTINCT configuration_value FROM system_config WHERE configuration_key IN (:configKeys);',
-             [
-                 'configKeys' => self::$defaultCmsPageConfigKeys,
-             ],
-             [
-                 'configKeys' => Connection::PARAM_STR_ARRAY,
-             ]
-         );
-         $defaultIds = [];
-         foreach ($configurations as $configuration) {
-             $configValue = $configuration['configuration_value'];
-             $config = json_decode($configValue, true);
-             $defaultIds[] = $config['_value'];
-         }
-         // returns from all provided cms pages the ones which are default
-         return array_intersect($cmsPageIds, $defaultIds);
-     }
-     private function cmsPageExists(string $cmsPageId): bool
-     {
-         $count = $this->connection->fetchOne(
-             'SELECT count(*) FROM cms_page WHERE id = :cmsPageId AND version_id = :versionId LIMIT 1;',
-             [
-                 'cmsPageId' => Uuid::fromHexToBytes($cmsPageId),
-                 'versionId' => Uuid::fromHexToBytes(Defaults::LIVE_VERSION),
-             ]
-         );
-         return $count === '1';
-     }
- }
-