vendor/ibexa/admin-ui/src/lib/Form/Processor/ContentType/ContentTypeFormProcessor.php line 160

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. namespace Ibexa\AdminUi\Form\Processor\ContentType;
  7. use Ibexa\ContentForms\Event\FormActionEvent;
  8. use Ibexa\Contracts\AdminUi\Event\FormEvents;
  9. use Ibexa\Contracts\Core\Repository\ContentTypeService;
  10. use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentTypeDraft;
  11. use Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition;
  12. use Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinitionCreateStruct;
  13. use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
  14. use Ibexa\Core\Helper\FieldsGroups\FieldsGroupsList;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\Routing\RouterInterface;
  18. class ContentTypeFormProcessor implements EventSubscriberInterface
  19. {
  20.     /**
  21.      * @var \Ibexa\Contracts\Core\Repository\ContentTypeService
  22.      */
  23.     private $contentTypeService;
  24.     /**
  25.      * @var \Symfony\Component\Routing\RouterInterface
  26.      */
  27.     private $router;
  28.     /**
  29.      * @var array
  30.      */
  31.     private $options;
  32.     /**
  33.      * @var \Ibexa\Core\Helper\FieldsGroups\FieldsGroupsList
  34.      */
  35.     private $groupsList;
  36.     public function __construct(
  37.         ContentTypeService $contentTypeService,
  38.         RouterInterface $router,
  39.         array $options = []
  40.     ) {
  41.         $this->contentTypeService $contentTypeService;
  42.         $this->router $router;
  43.         $this->setOptions($options);
  44.     }
  45.     public function setGroupsList(FieldsGroupsList $groupsList)
  46.     {
  47.         $this->groupsList $groupsList;
  48.     }
  49.     public function setOptions(array $options = [])
  50.     {
  51.         $this->options $options + ['redirectRouteAfterPublish' => null];
  52.     }
  53.     public static function getSubscribedEvents()
  54.     {
  55.         return [
  56.             FormEvents::CONTENT_TYPE_UPDATE => 'processDefaultAction',
  57.             FormEvents::CONTENT_TYPE_ADD_FIELD_DEFINITION => 'processAddFieldDefinition',
  58.             FormEvents::CONTENT_TYPE_REMOVE_FIELD_DEFINITION => 'processRemoveFieldDefinition',
  59.             FormEvents::CONTENT_TYPE_PUBLISH => 'processPublishContentType',
  60.             FormEvents::CONTENT_TYPE_REMOVE_DRAFT => 'processRemoveContentTypeDraft',
  61.         ];
  62.     }
  63.     public function processDefaultAction(FormActionEvent $event)
  64.     {
  65.         // Don't update anything if we just want to cancel the draft.
  66.         if ($event->getClickedButton() === 'removeDraft') {
  67.             return;
  68.         }
  69.         // Always update FieldDefinitions and ContentTypeDraft
  70.         /** @var \Ibexa\AdminUi\Form\Data\ContentTypeData $contentTypeData */
  71.         $contentTypeData $event->getData();
  72.         $contentTypeDraft $contentTypeData->contentTypeDraft;
  73.         foreach ($contentTypeData->getFlatFieldDefinitionsData() as $fieldDefData) {
  74.             $this->contentTypeService->updateFieldDefinition($contentTypeDraft$fieldDefData->fieldDefinition$fieldDefData);
  75.         }
  76.         // Update enabled FieldDefinitions and remove disabled.
  77.         foreach ($contentTypeData->getFlatMetaFieldDefinitionsData() as $fieldDefData) {
  78.             if ($fieldDefData->enabled) {
  79.                 $this->contentTypeService->updateFieldDefinition(
  80.                     $contentTypeDraft,
  81.                     $fieldDefData->fieldDefinition,
  82.                     $fieldDefData
  83.                 );
  84.             } else {
  85.                 $this->contentTypeService->removeFieldDefinition($contentTypeDraft$fieldDefData->fieldDefinition);
  86.             }
  87.         }
  88.         $contentTypeData->sortFieldDefinitions();
  89.         $this->contentTypeService->updateContentTypeDraft($contentTypeDraft$contentTypeData);
  90.     }
  91.     public function processAddFieldDefinition(FormActionEvent $event)
  92.     {
  93.         // Reload the draft, to make sure we include any changes made in the current form submit
  94.         $contentTypeDraft $this->contentTypeService->loadContentTypeDraft($event->getData()->contentTypeDraft->id);
  95.         $fieldTypeIdentifier $event->getForm()->get('fieldTypeSelection')->getData();
  96.         $targetLanguageCode $event->getForm()->getConfig()->getOption('languageCode');
  97.         if ($contentTypeDraft->mainLanguageCode !== $targetLanguageCode) {
  98.             throw new InvalidArgumentException(
  99.                 'languageCode',
  100.                 'Field definitions can only be added to the main language translation'
  101.             );
  102.         }
  103.         $maxFieldPos 0;
  104.         foreach ($contentTypeDraft->fieldDefinitions as $existingFieldDef) {
  105.             if ($existingFieldDef->position $maxFieldPos) {
  106.                 $maxFieldPos $existingFieldDef->position;
  107.             }
  108.         }
  109.         $fieldDefCreateStruct = new FieldDefinitionCreateStruct([
  110.             'fieldTypeIdentifier' => $fieldTypeIdentifier,
  111.             'identifier' => $this->resolveNewFieldDefinitionIdentifier(
  112.                 $contentTypeDraft,
  113.                 $maxFieldPos,
  114.                 $fieldTypeIdentifier
  115.             ),
  116.             'names' => [$event->getOption('languageCode') => 'New FieldDefinition'],
  117.             'position' => $maxFieldPos 1,
  118.         ]);
  119.         if (isset($this->groupsList)) {
  120.             $fieldDefCreateStruct->fieldGroup $this->groupsList->getDefaultGroup();
  121.         }
  122.         $this->contentTypeService->addFieldDefinition($contentTypeDraft$fieldDefCreateStruct);
  123.     }
  124.     public function processRemoveFieldDefinition(FormActionEvent $event)
  125.     {
  126.         /** @var \Ibexa\Contracts\Core\Repository\Values\ContentType\ContentTypeDraft $contentTypeDraft */
  127.         $contentTypeDraft $event->getData()->contentTypeDraft;
  128.         // Accessing FieldDefinition user selection through the form and not the data,
  129.         // as "selected" is not a property of FieldDefinitionData.
  130.         /** @var \Symfony\Component\Form\FormInterface $fieldDefForm */
  131.         foreach ($event->getForm()->get('fieldDefinitionsData') as $fieldDefForm) {
  132.             if ($fieldDefForm->get('selected')->getData() === true) {
  133.                 $this->contentTypeService->removeFieldDefinition($contentTypeDraft$fieldDefForm->getData()->fieldDefinition);
  134.             }
  135.         }
  136.     }
  137.     public function processPublishContentType(FormActionEvent $event)
  138.     {
  139.         $contentTypeDraft $event->getData()->contentTypeDraft;
  140.         $this->contentTypeService->publishContentTypeDraft($contentTypeDraft);
  141.         if (isset($this->options['redirectRouteAfterPublish'])) {
  142.             $event->setResponse(
  143.                 new RedirectResponse($this->router->generate($this->options['redirectRouteAfterPublish']))
  144.             );
  145.         }
  146.     }
  147.     public function processRemoveContentTypeDraft(FormActionEvent $event)
  148.     {
  149.         $contentTypeDraft $event->getData()->contentTypeDraft;
  150.         $this->contentTypeService->deleteContentType($contentTypeDraft);
  151.         if (isset($this->options['redirectRouteAfterPublish'])) {
  152.             $event->setResponse(
  153.                 new RedirectResponse($this->router->generate($this->options['redirectRouteAfterPublish']))
  154.             );
  155.         }
  156.     }
  157.     /**
  158.      * Resolves unique field definition identifier.
  159.      *
  160.      * @param \Ibexa\Contracts\Core\Repository\Values\ContentType\ContentTypeDraft $contentTypeDraft
  161.      * @param int $startIndex
  162.      * @param string $fieldTypeIdentifier
  163.      *
  164.      * @return string
  165.      */
  166.     private function resolveNewFieldDefinitionIdentifier(
  167.         ContentTypeDraft $contentTypeDraft,
  168.         int $startIndex,
  169.         string $fieldTypeIdentifier
  170.     ): string {
  171.         $fieldDefinitionIdentifiers $contentTypeDraft
  172.             ->getFieldDefinitions()
  173.             ->map(static function (FieldDefinition $fieldDefinition): string {
  174.                 return $fieldDefinition->identifier;
  175.             });
  176.         do {
  177.             $fieldDefinitionIdentifier sprintf('new_%s_%d'$fieldTypeIdentifier, ++$startIndex);
  178.         } while (in_array($fieldDefinitionIdentifier$fieldDefinitionIdentifierstrue));
  179.         return $fieldDefinitionIdentifier;
  180.     }
  181. }
  182. class_alias(ContentTypeFormProcessor::class, 'EzSystems\EzPlatformAdminUi\Form\Processor\ContentType\ContentTypeFormProcessor');