vendor/ibexa/workflow/src/lib/Event/Subscriber/FormProcessor.php line 57

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\Workflow\Event\Subscriber;
  8. use Ibexa\ContentForms\Event\ContentFormEvents;
  9. use Ibexa\ContentForms\Event\FormActionEvent;
  10. use Ibexa\Contracts\Core\Repository\ContentService;
  11. use Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException;
  12. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  13. use Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct;
  14. use Ibexa\Contracts\Workflow\Registry\WorkflowRegistryInterface;
  15. use Ibexa\Contracts\Workflow\Service\WorkflowServiceInterface;
  16. use Ibexa\Workflow\Exception\NotFoundException;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. use Symfony\Component\HttpFoundation\RedirectResponse;
  19. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  20. class FormProcessor implements EventSubscriberInterface
  21. {
  22.     /** @var \Ibexa\Contracts\Core\Repository\ContentService */
  23.     private $contentService;
  24.     /** @var \Ibexa\Contracts\Workflow\Service\WorkflowServiceInterface */
  25.     private $workflowService;
  26.     /** @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface */
  27.     private $urlGenerator;
  28.     /** @var \Ibexa\Contracts\Workflow\Registry\WorkflowRegistryInterface */
  29.     private $workflowRegistry;
  30.     public function __construct(
  31.         ContentService $contentService,
  32.         WorkflowServiceInterface $workflowService,
  33.         WorkflowRegistryInterface $workflowRegistry,
  34.         UrlGeneratorInterface $urlGenerator
  35.     ) {
  36.         $this->contentService $contentService;
  37.         $this->workflowService $workflowService;
  38.         $this->urlGenerator $urlGenerator;
  39.         $this->workflowRegistry $workflowRegistry;
  40.     }
  41.     public static function getSubscribedEvents(): array
  42.     {
  43.         return [
  44.             ContentFormEvents::CONTENT_EDIT => ['onContentEdit'100],
  45.         ];
  46.     }
  47.     public function onContentEdit(FormActionEvent $event): void
  48.     {
  49.         $action $event->getClickedButton();
  50.         if ($action !== 'apply') {
  51.             return;
  52.         }
  53.         /** @var \Ibexa\ContentForms\Data\Content\ContentCreateData|\Ibexa\ContentForms\Data\Content\ContentUpdateData $data */
  54.         $data $event->getData();
  55.         $form $event->getForm();
  56.         $languageCode $form->getConfig()->getOption('languageCode');
  57.         $draft $this->saveDraft($event->getData(), $languageCode, []);
  58.         $workflowData $form->get('workflow')->getData();
  59.         $workflowName $workflowData['name'];
  60.         $transitionName $workflowData['transition'];
  61.         try {
  62.             $workflowMetadata $this->workflowService->loadWorkflowMetadataForContent($draft$workflowName);
  63.         } catch (NotFoundException $e) {
  64.             $workflowMetadata $this->workflowService->start($draft$workflowName);
  65.         }
  66.         if (!$this->workflowService->can($workflowMetadata$transitionName)) {
  67.             // @todo error on transition not possible
  68.             // @todo show notification
  69.             return;
  70.         }
  71.         /** @var string $comment */
  72.         $comment $form->get('workflow')->get('comment')->getData() ?? '';
  73.         $reviewerId $form->get('workflow')->get('reviewer')->getData() ?? null;
  74.         $workflow $this->workflowRegistry->getWorkflow($workflowName);
  75.         try {
  76.             $workflow->apply($workflowMetadata->content$transitionName, [
  77.                 'message' => $comment,
  78.                 'reviewerId' => $reviewerId,
  79.             ]);
  80.             $redirectionUrl $this->getRedirectionUrl($event$draft);
  81.         } catch (ContentFieldValidationException $e) {
  82.             $redirectionUrl $this->urlGenerator->generate(
  83.                 'ibexa.content.draft.edit',
  84.                 [
  85.                     'contentId' => $draft->id,
  86.                     'versionNo' => $draft->versionInfo->versionNo,
  87.                     'language' => $languageCode,
  88.                     'validate' => true,
  89.                 ]
  90.             );
  91.         }
  92.         $event->setResponse(new RedirectResponse($redirectionUrl));
  93.     }
  94.     /**
  95.      * Saves content draft corresponding to $data.
  96.      * Depending on the nature of $data (create or update data), the draft will either be created or simply updated.
  97.      *
  98.      * @param \Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct|\Ibexa\ContentForms\Data\Content\ContentCreateData|\Ibexa\ContentForms\Data\Content\ContentUpdateData $data
  99.      * @param string $languageCode
  100.      *
  101.      * @return \Ibexa\Contracts\Core\Repository\Values\Content\Content
  102.      *
  103.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
  104.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
  105.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
  106.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
  107.      * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
  108.      */
  109.     private function saveDraft(ContentStruct $datastring $languageCode, ?array $fieldIdentifiersToValidate null): Content
  110.     {
  111.         $mainLanguageCode $data->isNew()
  112.             ? $data->mainLanguageCode
  113.             $data->contentDraft->getVersionInfo()->getContentInfo()->mainLanguageCode;
  114.         foreach ($data->fieldsData as $fieldDefIdentifier => $fieldData) {
  115.             if ($mainLanguageCode !== $languageCode && !$fieldData->fieldDefinition->isTranslatable) {
  116.                 continue;
  117.             }
  118.             $data->setField($fieldDefIdentifier$fieldData->value$languageCode);
  119.         }
  120.         if ($data->isNew()) {
  121.             $contentDraft $this->contentService->createContent($data$data->getLocationStructs(), $fieldIdentifiersToValidate);
  122.         } else {
  123.             $contentDraft $this->contentService->updateContent($data->contentDraft->getVersionInfo(), $data$fieldIdentifiersToValidate);
  124.         }
  125.         return $contentDraft;
  126.     }
  127.     /**
  128.      * @param \Ibexa\Contracts\AdminUi\Event\FormActionEvent $event
  129.      * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $draft
  130.      *
  131.      * @return string
  132.      */
  133.     private function getRedirectionUrl(FormActionEvent $eventContent $draft): string
  134.     {
  135.         $referrerLocation $event->getOption('referrerLocation');
  136.         $contentInfo $draft->contentInfo;
  137.         if ($contentInfo->isPublished()) {
  138.             $redirectionUrl $this->urlGenerator->generate(
  139.                 'ibexa.content.view',
  140.                 [
  141.                     'contentId' => $referrerLocation $referrerLocation->contentId $contentInfo->id,
  142.                     'locationId' => $referrerLocation $referrerLocation->id $contentInfo->mainLocationId,
  143.                 ]
  144.             );
  145.         } else {
  146.             $redirectionUrl $this->urlGenerator->generate('ibexa.dashboard');
  147.         }
  148.         return $redirectionUrl;
  149.     }
  150. }
  151. class_alias(FormProcessor::class, 'EzSystems\EzPlatformWorkflow\Event\Subscriber\FormProcessor');