vendor/ezsystems/repository-forms/lib/Form/Processor/ContentFormProcessor.php line 188

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\ContentService;
  10. use eZ\Publish\API\Repository\LocationService;
  11. use eZ\Publish\API\Repository\Values\Content\Content;
  12. use eZ\Publish\API\Repository\Values\Content\ContentStruct;
  13. use eZ\Publish\API\Repository\Values\Content\Location;
  14. use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
  15. use EzSystems\RepositoryForms\Data\Content\ContentCreateData;
  16. use EzSystems\RepositoryForms\Data\Content\ContentUpdateData;
  17. use EzSystems\RepositoryForms\Data\NewnessCheckable;
  18. use EzSystems\RepositoryForms\Event\FormActionEvent;
  19. use EzSystems\RepositoryForms\Event\RepositoryFormEvents;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\HttpFoundation\RedirectResponse;
  22. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  23. use Symfony\Component\Routing\RouterInterface;
  24. /**
  25.  * Listens for and processes RepositoryForm events: publish, remove draft, save draft...
  26.  */
  27. class ContentFormProcessor implements EventSubscriberInterface
  28. {
  29.     /** @var \eZ\Publish\API\Repository\ContentService */
  30.     private $contentService;
  31.     /** @var \eZ\Publish\API\Repository\LocationService */
  32.     private $locationService;
  33.     /** @var \Symfony\Component\Routing\RouterInterface */
  34.     private $router;
  35.     /**
  36.      * @param \eZ\Publish\API\Repository\ContentService $contentService
  37.      * @param \eZ\Publish\API\Repository\LocationService $locationService
  38.      * @param \Symfony\Component\Routing\RouterInterface $router
  39.      * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
  40.      */
  41.     public function __construct(
  42.         ContentService $contentService,
  43.         LocationService $locationService,
  44.         RouterInterface $router
  45.     ) {
  46.         $this->contentService $contentService;
  47.         $this->locationService $locationService;
  48.         $this->router $router;
  49.     }
  50.     /**
  51.      * @return array
  52.      */
  53.     public static function getSubscribedEvents(): array
  54.     {
  55.         return [
  56.             RepositoryFormEvents::CONTENT_PUBLISH => ['processPublish'10],
  57.             RepositoryFormEvents::CONTENT_CANCEL => ['processCancel'10],
  58.             RepositoryFormEvents::CONTENT_SAVE_DRAFT => ['processSaveDraft'10],
  59.             RepositoryFormEvents::CONTENT_CREATE_DRAFT => ['processCreateDraft'10],
  60.         ];
  61.     }
  62.     /**
  63.      * @param \EzSystems\RepositoryForms\Event\FormActionEvent $event
  64.      *
  65.      * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
  66.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
  67.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException
  68.      * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
  69.      * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
  70.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  71.      * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException
  72.      */
  73.     public function processSaveDraft(FormActionEvent $event)
  74.     {
  75.         /** @var \EzSystems\RepositoryForms\Data\Content\ContentCreateData|\EzSystems\RepositoryForms\Data\Content\ContentUpdateData $data */
  76.         $data $event->getData();
  77.         $form $event->getForm();
  78.         $formConfig $form->getConfig();
  79.         $languageCode $formConfig->getOption('languageCode');
  80.         $draft $this->saveDraft($data$languageCode);
  81.         $referrerLocation $event->getOption('referrerLocation');
  82.         $contentLocation $this->resolveLocation($draft$referrerLocation$data);
  83.         $event->setPayload('content'$draft);
  84.         $event->setPayload('is_new'$draft->contentInfo->isDraft());
  85.         $defaultUrl $this->router->generate('ez_content_draft_edit', [
  86.             'contentId' => $draft->id,
  87.             'versionNo' => $draft->getVersionInfo()->versionNo,
  88.             'language' => $languageCode,
  89.             'locationId' => null !== $contentLocation $contentLocation->id null,
  90.         ]);
  91.         $event->setResponse(new RedirectResponse($formConfig->getAction() ?: $defaultUrl));
  92.     }
  93.     /**
  94.      * @param \EzSystems\RepositoryForms\Event\FormActionEvent $event
  95.      *
  96.      * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
  97.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
  98.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException
  99.      * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
  100.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  101.      * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException
  102.      */
  103.     public function processPublish(FormActionEvent $event)
  104.     {
  105.         /** @var \EzSystems\RepositoryForms\Data\Content\ContentCreateData|\EzSystems\RepositoryForms\Data\Content\ContentUpdateData $data */
  106.         $data $event->getData();
  107.         $form $event->getForm();
  108.         $draft $this->saveDraft($data$form->getConfig()->getOption('languageCode'));
  109.         $versionInfo $draft->versionInfo;
  110.         $content $this->contentService->publishVersion($versionInfo, [$versionInfo->initialLanguageCode]);
  111.         $event->setPayload('content'$content);
  112.         $event->setPayload('is_new'$draft->contentInfo->isDraft());
  113.         $redirectUrl $form['redirectUrlAfterPublish']->getData() ?: $this->router->generate(
  114.             '_ezpublishLocation', [
  115.                 'locationId' => $content->contentInfo->mainLocationId,
  116.             ]
  117.         );
  118.         $event->setResponse(new RedirectResponse($redirectUrl));
  119.     }
  120.     /**
  121.      * @param \EzSystems\RepositoryForms\Event\FormActionEvent $event
  122.      *
  123.      * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
  124.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  125.      */
  126.     public function processCancel(FormActionEvent $event)
  127.     {
  128.         /** @var \EzSystems\RepositoryForms\Data\Content\ContentCreateData|\EzSystems\RepositoryForms\Data\Content\ContentUpdateData $data */
  129.         $data $event->getData();
  130.         if ($data->isNew()) {
  131.             $response = new RedirectResponse($this->router->generate(
  132.                 '_ezpublishLocation',
  133.                 ['locationId' => $data->getLocationStructs()[0]->parentLocationId]
  134.             ));
  135.             $event->setResponse($response);
  136.             return;
  137.         }
  138.         $content $data->contentDraft;
  139.         $contentInfo $content->contentInfo;
  140.         $versionInfo $data->contentDraft->getVersionInfo();
  141.         $event->setPayload('content'$content);
  142.         // if there is only one version you have to remove whole content instead of a version itself
  143.         if (=== count($this->contentService->loadVersions($contentInfo))) {
  144.             $parentLocation $this->locationService->loadParentLocationsForDraftContent($versionInfo)[0];
  145.             $redirectionLocationId $parentLocation->id;
  146.             $this->contentService->deleteContent($contentInfo);
  147.         } else {
  148.             $redirectionLocationId $contentInfo->mainLocationId;
  149.             $this->contentService->deleteVersion($versionInfo);
  150.         }
  151.         $url $this->router->generate(
  152.             '_ezpublishLocation',
  153.             ['locationId' => $redirectionLocationId],
  154.             UrlGeneratorInterface::ABSOLUTE_URL
  155.         );
  156.         $event->setResponse(new RedirectResponse($url));
  157.     }
  158.     /**
  159.      * @param \EzSystems\RepositoryForms\Event\FormActionEvent $event
  160.      *
  161.      * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
  162.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  163.      */
  164.     public function processCreateDraft(FormActionEvent $event)
  165.     {
  166.         /** @var $createContentDraft \EzSystems\RepositoryForms\Data\Content\CreateContentDraftData */
  167.         $createContentDraft $event->getData();
  168.         $contentInfo $this->contentService->loadContentInfo($createContentDraft->contentId);
  169.         $versionInfo $this->contentService->loadVersionInfo($contentInfo$createContentDraft->fromVersionNo);
  170.         $contentDraft $this->contentService->createContentDraft($contentInfo$versionInfo);
  171.         $referrerLocation $event->getOption('referrerLocation');
  172.         $event->setPayload('content'$contentDraft);
  173.         $event->setPayload('is_new'$contentDraft->contentInfo->isDraft());
  174.         $contentEditUrl $this->router->generate('ez_content_draft_edit', [
  175.             'contentId' => $contentDraft->id,
  176.             'versionNo' => $contentDraft->getVersionInfo()->versionNo,
  177.             'language' => $contentDraft->contentInfo->mainLanguageCode,
  178.             'locationId' => null !== $referrerLocation $referrerLocation->id null,
  179.         ]);
  180.         $event->setResponse(new RedirectResponse($contentEditUrl));
  181.     }
  182.     /**
  183.      * Saves content draft corresponding to $data.
  184.      * Depending on the nature of $data (create or update data), the draft will either be created or simply updated.
  185.      *
  186.      * @param ContentStruct|\EzSystems\RepositoryForms\Data\Content\ContentCreateData|\EzSystems\RepositoryForms\Data\Content\ContentUpdateData $data
  187.      * @param $languageCode
  188.      *
  189.      * @return \eZ\Publish\API\Repository\Values\Content\Content
  190.      *
  191.      * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
  192.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
  193.      * @throws \eZ\Publish\API\Repository\Exceptions\ContentValidationException
  194.      * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
  195.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  196.      * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException
  197.      */
  198.     private function saveDraft(ContentStruct $data$languageCode)
  199.     {
  200.         $mainLanguageCode $this->resolveMainLanguageCode($data);
  201.         foreach ($data->fieldsData as $fieldDefIdentifier => $fieldData) {
  202.             if ($mainLanguageCode != $languageCode && !$fieldData->fieldDefinition->isTranslatable) {
  203.                 continue;
  204.             }
  205.             $data->setField($fieldDefIdentifier$fieldData->value$languageCode);
  206.         }
  207.         if ($data->isNew()) {
  208.             $contentDraft $this->contentService->createContent($data$data->getLocationStructs());
  209.         } else {
  210.             $contentDraft $this->contentService->updateContent($data->contentDraft->getVersionInfo(), $data);
  211.         }
  212.         return $contentDraft;
  213.     }
  214.     /**
  215.      * @param \EzSystems\RepositoryForms\Data\Content\ContentUpdateData|\EzSystems\RepositoryForms\Data\Content\ContentCreateData $data
  216.      *
  217.      * @return string
  218.      *
  219.      * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException
  220.      */
  221.     private function resolveMainLanguageCode($data): string
  222.     {
  223.         if (!$data instanceof ContentUpdateData && !$data instanceof ContentCreateData) {
  224.             throw new InvalidArgumentException(
  225.                 '$data',
  226.                 'expected type of ContentUpdateData or ContentCreateData'
  227.             );
  228.         }
  229.         return $data->isNew()
  230.             ? $data->mainLanguageCode
  231.             $data->contentDraft->getVersionInfo()->getContentInfo()->mainLanguageCode;
  232.     }
  233.     /**
  234.      * @param \eZ\Publish\API\Repository\Values\Content\Content $content
  235.      * @param \eZ\Publish\API\Repository\Values\Content\Location|null $referrerLocation
  236.      * @param \EzSystems\RepositoryForms\Data\NewnessCheckable $data
  237.      *
  238.      * @return \eZ\Publish\API\Repository\Values\Content\Location|null
  239.      *
  240.      * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
  241.      * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
  242.      */
  243.     private function resolveLocation(Content $content, ?Location $referrerLocationNewnessCheckable $data): ?Location
  244.     {
  245.         if ($data->isNew() || (!$content->contentInfo->published && null === $content->contentInfo->mainLocationId)) {
  246.             return null// no location exists until new content is published
  247.         }
  248.         return $referrerLocation ?? $this->locationService->loadLocation($content->contentInfo->mainLocationId);
  249.     }
  250. }