vendor/ibexa/personalization/src/lib/Event/Subscriber/ContentEventSubscriber.php line 83

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4.  * @license For full copyright and license information view LICENSE file distributed with this source code.
  5.  */
  6. declare(strict_types=1);
  7. namespace Ibexa\Personalization\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Limitation\Target;
  9. use Ibexa\Contracts\Core\Repository\ContentService as CoreContentService;
  10. use Ibexa\Contracts\Core\Repository\Events\Content\BeforeDeleteContentEvent;
  11. use Ibexa\Contracts\Core\Repository\Events\Content\BeforeDeleteTranslationEvent;
  12. use Ibexa\Contracts\Core\Repository\Events\Content\CopyContentEvent;
  13. use Ibexa\Contracts\Core\Repository\Events\Content\HideContentEvent;
  14. use Ibexa\Contracts\Core\Repository\Events\Content\PublishVersionEvent;
  15. use Ibexa\Contracts\Core\Repository\Events\Content\RevealContentEvent;
  16. use Ibexa\Contracts\Core\Repository\Events\Content\UpdateContentMetadataEvent;
  17. use Ibexa\Contracts\Core\Repository\LocationService;
  18. use Ibexa\Contracts\Core\Repository\PermissionResolver;
  19. use Ibexa\Contracts\Core\Repository\Repository;
  20. use Ibexa\Contracts\Core\Repository\SearchService;
  21. use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
  22. use Ibexa\Core\Base\Exceptions\UnauthorizedException;
  23. use Ibexa\Core\Query\QueryFactoryInterface;
  24. use Ibexa\Personalization\Config\ItemType\IncludedItemTypeResolverInterface;
  25. use Ibexa\Personalization\Event\PersonalizationEvent;
  26. use Ibexa\Personalization\Service\Content\ContentServiceInterface;
  27. use Ibexa\Personalization\Service\Setting\SettingServiceInterface;
  28. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  29. final class ContentEventSubscriber extends AbstractRepositoryEventSubscriber implements EventSubscriberInterface
  30. {
  31.     private PermissionResolver $permissionResolver;
  32.     private SettingServiceInterface $settingService;
  33.     public function __construct(
  34.         CoreContentService $coreContentService,
  35.         ContentServiceInterface $contentService,
  36.         IncludedItemTypeResolverInterface $includedItemTypeResolver,
  37.         LocationService $locationService,
  38.         Repository $repository,
  39.         PermissionResolver $permissionResolver,
  40.         SettingServiceInterface $settingService,
  41.         QueryFactoryInterface $queryFactory,
  42.         SearchService $searchService
  43.     ) {
  44.         parent::__construct(
  45.             $coreContentService,
  46.             $contentService,
  47.             $includedItemTypeResolver,
  48.             $locationService,
  49.             $repository,
  50.             $queryFactory,
  51.             $searchService
  52.         );
  53.         $this->permissionResolver $permissionResolver;
  54.         $this->settingService $settingService;
  55.     }
  56.     public static function getSubscribedEvents(): array
  57.     {
  58.         return [
  59.             BeforeDeleteContentEvent::class => ['onBeforeDeleteContent'PersonalizationEvent::DEFAULT_PRIORITY],
  60.             BeforeDeleteTranslationEvent::class => ['onBeforeDeleteTranslation'PersonalizationEvent::DEFAULT_PRIORITY],
  61.             HideContentEvent::class => ['onHideContent'PersonalizationEvent::DEFAULT_PRIORITY],
  62.             RevealContentEvent::class => ['onRevealContent'PersonalizationEvent::DEFAULT_PRIORITY],
  63.             UpdateContentMetadataEvent::class => ['onUpdateContentMetadata'PersonalizationEvent::DEFAULT_PRIORITY],
  64.             CopyContentEvent::class => ['onCopyContent'PersonalizationEvent::DEFAULT_PRIORITY],
  65.             PublishVersionEvent::class => ['onPublishVersion'PersonalizationEvent::DEFAULT_PRIORITY],
  66.         ];
  67.     }
  68.     /**
  69.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
  70.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
  71.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  72.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  73.      */
  74.     public function onBeforeDeleteContent(BeforeDeleteContentEvent $event): void
  75.     {
  76.         if (!$this->settingService->isInstallationKeyFound()) {
  77.             return;
  78.         }
  79.         $contentInfo $event->getContentInfo();
  80.         if (!$this->canDelete($contentInfo)) {
  81.             throw new UnauthorizedException('content''remove', ['contentId' => $contentInfo->getId()]);
  82.         }
  83.         $this->deleteContentWithChildrenFromAllLocations($contentInfo);
  84.         $relations $this->getContentRelations($contentInfo);
  85.         if (empty($relations)) {
  86.             return;
  87.         }
  88.         $this->contentService->updateContentItems($relations);
  89.     }
  90.     /**
  91.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  92.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
  93.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
  94.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  95.      */
  96.     public function onBeforeDeleteTranslation(BeforeDeleteTranslationEvent $event): void
  97.     {
  98.         if (!$this->settingService->isInstallationKeyFound()) {
  99.             return;
  100.         }
  101.         $contentInfo $event->getContentInfo();
  102.         $languageCodes = [$event->getLanguageCode()];
  103.         if (!$this->canDelete($contentInfo$languageCodes)) {
  104.             throw new UnauthorizedException('content''remove', ['contentId' => $contentInfo->getId()]);
  105.         }
  106.         $content $this->coreContentService->loadContentByContentInfo($event->getContentInfo());
  107.         if (!$this->includedItemTypeResolver->isContentIncluded($content)) {
  108.             return;
  109.         }
  110.         $this->contentService->deleteContent($content$languageCodes);
  111.     }
  112.     public function onHideContent(HideContentEvent $event): void
  113.     {
  114.         if (!$this->settingService->isInstallationKeyFound()) {
  115.             return;
  116.         }
  117.         $this->deleteContentWithChildrenFromAllLocations($event->getContentInfo());
  118.         $relations $this->getContentRelations($event->getContentInfo());
  119.         if (empty($relations)) {
  120.             return;
  121.         }
  122.         $this->contentService->updateContentItems($relations);
  123.     }
  124.     public function onRevealContent(RevealContentEvent $event): void
  125.     {
  126.         if (!$this->settingService->isInstallationKeyFound()) {
  127.             return;
  128.         }
  129.         $this->updateContentWithChildrenFromAllLocationsAndRelations(
  130.             $event->getContentInfo()
  131.         );
  132.     }
  133.     public function onUpdateContentMetadata(UpdateContentMetadataEvent $event): void
  134.     {
  135.         if (!$this->settingService->isInstallationKeyFound()) {
  136.             return;
  137.         }
  138.         $content $event->getContent();
  139.         if (!$this->includedItemTypeResolver->isContentIncluded($content)) {
  140.             return;
  141.         }
  142.         $this->contentService->updateContent($event->getContent());
  143.     }
  144.     public function onCopyContent(CopyContentEvent $event): void
  145.     {
  146.         if (!$this->settingService->isInstallationKeyFound()) {
  147.             return;
  148.         }
  149.         $content $event->getContent();
  150.         if (!$this->includedItemTypeResolver->isContentIncluded($content)) {
  151.             return;
  152.         }
  153.         $this->contentService->updateContent($content);
  154.     }
  155.     public function onPublishVersion(PublishVersionEvent $event): void
  156.     {
  157.         if (!$this->settingService->isInstallationKeyFound()) {
  158.             return;
  159.         }
  160.         $content $event->getContent();
  161.         if (!$this->includedItemTypeResolver->isContentIncluded($content)) {
  162.             return;
  163.         }
  164.         $this->contentService->updateContent($content$event->getTranslations());
  165.     }
  166.     /**
  167.      * @param array<string>|null $languageCodes
  168.      *
  169.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
  170.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
  171.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  172.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  173.      */
  174.     private function canDelete(
  175.         ContentInfo $contentInfo,
  176.         ?array $languageCodes null
  177.     ): bool {
  178.         if (empty($languageCodes)) {
  179.             $versionInfo $this->coreContentService->loadVersionInfo($contentInfo);
  180.             $languageCodes $this->getTranslationsToDelete($versionInfo->getLanguages());
  181.         }
  182.         $target = (new Target\Version())->deleteTranslations($languageCodes);
  183.         return $this->permissionResolver->canUser('content''remove'$contentInfo, [$target]);
  184.     }
  185.     /**
  186.      * @param iterable<\Ibexa\Contracts\Core\Repository\Values\Content\Language> $languages
  187.      *
  188.      * @return array<string>
  189.      */
  190.     private function getTranslationsToDelete(iterable $languages): array
  191.     {
  192.         $translations = [];
  193.         foreach ($languages as $language) {
  194.             $translations[] = $language->getLanguageCode();
  195.         }
  196.         return $translations;
  197.     }
  198. }
  199. class_alias(ContentEventSubscriber::class, 'EzSystems\EzRecommendationClient\Event\Subscriber\ContentEventSubscriber');