vendor/ibexa/admin-ui/src/lib/Form/Processor/PreviewFormProcessor.php line 75

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\AdminUi\Form\Processor;
  8. use Exception;
  9. use Ibexa\AdminUi\Form\Event\ContentEditEvents;
  10. use Ibexa\ContentForms\Data\NewnessCheckable;
  11. use Ibexa\ContentForms\Event\FormActionEvent;
  12. use Ibexa\Contracts\AdminUi\Notification\TranslatableNotificationHandlerInterface;
  13. use Ibexa\Contracts\Core\Repository\ContentService;
  14. use Ibexa\Contracts\Core\Repository\LocationService;
  15. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  16. use Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct;
  17. use Ibexa\Contracts\Core\Repository\Values\Content\Location;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  21. /**
  22.  * Listens for and processes RepositoryForm events.
  23.  */
  24. class PreviewFormProcessor implements EventSubscriberInterface
  25. {
  26.     /** @var \Ibexa\Contracts\Core\Repository\ContentService */
  27.     private $contentService;
  28.     /** @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface */
  29.     private $urlGenerator;
  30.     /** @var \Ibexa\Contracts\AdminUi\Notification\TranslatableNotificationHandlerInterface */
  31.     private $notificationHandler;
  32.     /** @var \Ibexa\Contracts\Core\Repository\LocationService */
  33.     private $locationService;
  34.     /**
  35.      * @param \Ibexa\Contracts\Core\Repository\ContentService $contentService
  36.      * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $urlGenerator
  37.      * @param \Ibexa\Contracts\AdminUi\Notification\TranslatableNotificationHandlerInterface $notificationHandler
  38.      * @param \Ibexa\Contracts\Core\Repository\LocationService $locationService
  39.      */
  40.     public function __construct(
  41.         ContentService $contentService,
  42.         UrlGeneratorInterface $urlGenerator,
  43.         TranslatableNotificationHandlerInterface $notificationHandler,
  44.         LocationService $locationService
  45.     ) {
  46.         $this->contentService $contentService;
  47.         $this->urlGenerator $urlGenerator;
  48.         $this->notificationHandler $notificationHandler;
  49.         $this->locationService $locationService;
  50.     }
  51.     /**
  52.      * {@inheritdoc}
  53.      */
  54.     public static function getSubscribedEvents(): array
  55.     {
  56.         return [
  57.             ContentEditEvents::CONTENT_PREVIEW => ['processPreview'10],
  58.         ];
  59.     }
  60.     /**
  61.      * @param \Ibexa\ContentForms\Event\FormActionEvent $event
  62.      *
  63.      * @throws \InvalidArgumentException
  64.      */
  65.     public function processPreview(FormActionEvent $event): void
  66.     {
  67.         /** @var \Ibexa\ContentForms\Data\Content\ContentCreateData|\Ibexa\ContentForms\Data\Content\ContentUpdateData $data */
  68.         $data $event->getData();
  69.         $form $event->getForm();
  70.         $languageCode $form->getConfig()->getOption('languageCode');
  71.         $referrerLocation $event->getOption('referrerLocation');
  72.         try {
  73.             $contentDraft $this->saveDraft($data$languageCode, []);
  74.             $contentLocation $this->resolveLocation($contentDraft$referrerLocation$data);
  75.             $url $this->urlGenerator->generate('ibexa.content.preview', [
  76.                 'locationId' => null !== $contentLocation $contentLocation->id null,
  77.                 'contentId' => $contentDraft->id,
  78.                 'versionNo' => $contentDraft->getVersionInfo()->versionNo,
  79.                 'languageCode' => $languageCode,
  80.             ]);
  81.         } catch (Exception $e) {
  82.             $this->notificationHandler->error(
  83.                 /** @Desc("Cannot save content draft.") */
  84.                 'error.preview',
  85.                 [],
  86.                 'content_preview'
  87.             );
  88.             $url $this->getContentEditUrl($data$languageCode);
  89.         }
  90.         $event->setResponse(
  91.             new RedirectResponse($url)
  92.         );
  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\ContentForms\Data\Content\ContentCreateData|\Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct|\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): Content
  110.     {
  111.         $mainLanguageCode $this->resolveMainLanguageCode($data);
  112.         foreach ($data->fieldsData as $fieldDefIdentifier => $fieldData) {
  113.             if ($mainLanguageCode != $languageCode && !$fieldData->fieldDefinition->isTranslatable) {
  114.                 continue;
  115.             }
  116.             $data->setField($fieldDefIdentifier$fieldData->value$languageCode);
  117.         }
  118.         if ($data->isNew()) {
  119.             $contentDraft $this->contentService->createContent($data$data->getLocationStructs(), $fieldIdentifiersToValidate);
  120.         } else {
  121.             $contentDraft $this->contentService->updateContent($data->contentDraft->getVersionInfo(), $data$fieldIdentifiersToValidate);
  122.         }
  123.         return $contentDraft;
  124.     }
  125.     /**
  126.      * Returns content create or edit URL depending on $data type.
  127.      *
  128.      * @param \Ibexa\ContentForms\Data\Content\ContentCreateData|\Ibexa\ContentForms\Data\Content\ContentUpdateData $data
  129.      * @param string $languageCode
  130.      *
  131.      * @return string
  132.      *
  133.      * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
  134.      * @throws \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
  135.      * @throws \Symfony\Component\Routing\Exception\InvalidParameterException
  136.      */
  137.     private function getContentEditUrl($datastring $languageCode): string
  138.     {
  139.         return $data->isNew()
  140.             ? $this->urlGenerator->generate('ibexa.content.create.proxy', [
  141.                 'parentLocationId' => $data->getLocationStructs()[0]->parentLocationId,
  142.                 'contentTypeIdentifier' => $data->contentType->identifier,
  143.                 'languageCode' => $languageCode,
  144.             ])
  145.             : $this->urlGenerator->generate('ibexa.content.draft.edit', [
  146.                 'contentId' => $data->contentDraft->id,
  147.                 'versionNo' => $data->contentDraft->getVersionInfo()->versionNo,
  148.                 'language' => $languageCode,
  149.             ]);
  150.     }
  151.     /**
  152.      * @param \Ibexa\ContentForms\Data\Content\ContentCreateData|\Ibexa\ContentForms\Data\Content\ContentUpdateData|\Ibexa\AdminUi\Form\Data\NewnessChecker $data
  153.      *
  154.      * @return string
  155.      */
  156.     private function resolveMainLanguageCode($data): string
  157.     {
  158.         return $data->isNew()
  159.             ? $data->mainLanguageCode
  160.             $data->contentDraft->getVersionInfo()->getContentInfo()->mainLanguageCode;
  161.     }
  162.     /**
  163.      * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content
  164.      * @param \Ibexa\Contracts\Core\Repository\Values\Content\Location|null $referrerLocation
  165.      * @param \Ibexa\ContentForms\Data\NewnessCheckable $data
  166.      *
  167.      * @return \Ibexa\Contracts\Core\Repository\Values\Content\Location|null
  168.      */
  169.     private function resolveLocation(Content $content, ?Location $referrerLocationNewnessCheckable $data): ?Location
  170.     {
  171.         if ($data->isNew() || (!$content->contentInfo->published && null === $content->contentInfo->mainLocationId)) {
  172.             return null// no location exists until new content is published
  173.         }
  174.         return $referrerLocation ?? $this->locationService->loadLocation($content->contentInfo->mainLocationId);
  175.     }
  176. }
  177. class_alias(PreviewFormProcessor::class, 'EzSystems\EzPlatformAdminUi\Form\Processor\PreviewFormProcessor');