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

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