vendor/ibexa/taxonomy/src/lib/Event/Subscriber/ContentTypeEventsSubscriber.php line 43

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\Taxonomy\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\Events\ContentType\BeforeRemoveFieldDefinitionEvent;
  9. use Ibexa\Contracts\Core\Repository\Events\ContentType\BeforeUpdateFieldDefinitionEvent;
  10. use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentTypeDraft;
  11. use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
  12. use Ibexa\Taxonomy\Service\TaxonomyConfiguration;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. /**
  15.  * Throws validation errors when Taxonomy fieldtypes are removed from content type.
  16.  *
  17.  * This prevents system from becoming corrupted due to broken Taxonomy content type.
  18.  *
  19.  * @internal
  20.  */
  21. final class ContentTypeEventsSubscriber implements EventSubscriberInterface
  22. {
  23.     private TaxonomyConfiguration $taxonomyConfiguration;
  24.     public function __construct(
  25.         TaxonomyConfiguration $taxonomyConfiguration
  26.     ) {
  27.         $this->taxonomyConfiguration $taxonomyConfiguration;
  28.     }
  29.     public static function getSubscribedEvents(): array
  30.     {
  31.         return [
  32.             BeforeRemoveFieldDefinitionEvent::class => 'onRemoveFieldDefinition',
  33.             BeforeUpdateFieldDefinitionEvent::class => 'onUpdateFieldDefinition',
  34.         ];
  35.     }
  36.     public function onRemoveFieldDefinition(BeforeRemoveFieldDefinitionEvent $event): void
  37.     {
  38.         $taxonomy $this->getTaxonomy($event->getContentTypeDraft());
  39.         if (null === $taxonomy) {
  40.             return;
  41.         }
  42.         $fieldMappings $this->taxonomyConfiguration->getFieldMappings($taxonomy);
  43.         $fieldDefinition $event->getFieldDefinition();
  44.         if (!in_array($fieldDefinition->identifier$fieldMappingstrue)) {
  45.             return;
  46.         }
  47.         throw new InvalidArgumentException(
  48.             '$fieldDefinition',
  49.             'Cannot remove field definitions used by Taxonomy content type',
  50.         );
  51.     }
  52.     public function onUpdateFieldDefinition(BeforeUpdateFieldDefinitionEvent $event): void
  53.     {
  54.         $taxonomy $this->getTaxonomy($event->getContentTypeDraft());
  55.         if (null === $taxonomy) {
  56.             return;
  57.         }
  58.         $fieldMappings $this->taxonomyConfiguration->getFieldMappings($taxonomy);
  59.         $fieldDefinition $event->getFieldDefinition();
  60.         if (!in_array($fieldDefinition->identifier$fieldMappingstrue)) {
  61.             return;
  62.         }
  63.         $fieldDefinitionUpdateStruct $event->getFieldDefinitionUpdateStruct();
  64.         if (
  65.             null !== $fieldDefinitionUpdateStruct->identifier
  66.             && $fieldDefinitionUpdateStruct->identifier !== $fieldDefinition->identifier
  67.         ) {
  68.             throw new InvalidArgumentException(
  69.                 '$fieldDefinition',
  70.                 'Cannot change field definition identifier used by Taxonomy content type',
  71.             );
  72.         }
  73.         // additional validation for identifier and parent
  74.         if (
  75.             $fieldDefinition->identifier === $fieldMappings['identifier']
  76.             || $fieldDefinition->identifier === $fieldMappings['parent']
  77.         ) {
  78.             if (
  79.                 null !== $fieldDefinitionUpdateStruct->isRequired
  80.                 && $fieldDefinition->isRequired !== $fieldDefinitionUpdateStruct->isRequired
  81.             ) {
  82.                 throw new InvalidArgumentException(
  83.                     '$fieldDefinition',
  84.                     'Cannot change isRequired flag on field definition used by Taxonomy content type',
  85.                 );
  86.             }
  87.             if (
  88.                 null !== $fieldDefinitionUpdateStruct->isTranslatable
  89.                 && $fieldDefinition->isTranslatable !== $fieldDefinitionUpdateStruct->isTranslatable
  90.             ) {
  91.                 throw new InvalidArgumentException(
  92.                     '$fieldDefinition',
  93.                     'Cannot change isTranslatable flag on field definition used by Taxonomy content type',
  94.                 );
  95.             }
  96.         }
  97.     }
  98.     private function getTaxonomy(ContentTypeDraft $contentTypeDraft): ?string
  99.     {
  100.         if (!$this->taxonomyConfiguration->isContentTypeAssociatedWithTaxonomy($contentTypeDraft)) {
  101.             return null;
  102.         }
  103.         return $this->taxonomyConfiguration->getTaxonomyForContentType($contentTypeDraft);
  104.     }
  105. }