vendor/ezsystems/repository-forms/lib/Form/Processor/ContentTypeFormProcessor.php line 73

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