diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml
index 967c64fbb7..2902742338 100644
--- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml
+++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml
@@ -110,6 +110,8 @@ services:
$authorizationChecker: '@security.authorization_checker'
$locationProvider: '@ezpublish.content_preview.location_provider'
$controllerChecker: '@ezpublish.view.custom_location_controller_checker'
+ $debugMode: '%kernel.debug%'
+ $logger: '@logger'
tags:
- { name: controller.service_arguments }
diff --git a/eZ/Publish/Core/MVC/Symfony/Controller/Content/PreviewController.php b/eZ/Publish/Core/MVC/Symfony/Controller/Content/PreviewController.php
index 6ec36517f2..d37c06faf0 100644
--- a/eZ/Publish/Core/MVC/Symfony/Controller/Content/PreviewController.php
+++ b/eZ/Publish/Core/MVC/Symfony/Controller/Content/PreviewController.php
@@ -8,11 +8,13 @@
use Exception;
use eZ\Publish\API\Repository\ContentService;
+use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException;
use eZ\Publish\API\Repository\Exceptions\NotImplementedException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\API\Repository\Values\Content\Location;
+use eZ\Publish\Core\Base\Exceptions\BadStateException;
use eZ\Publish\Core\Helper\ContentPreviewHelper;
use eZ\Publish\Core\Helper\PreviewLocationProvider;
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
@@ -21,13 +23,19 @@
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
use eZ\Publish\Core\MVC\Symfony\View\CustomLocationControllerChecker;
use eZ\Publish\Core\MVC\Symfony\View\ViewManagerInterface;
+use Psr\Log\LoggerAwareTrait;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class PreviewController
{
+ use LoggerAwareTrait;
+
public const PREVIEW_PARAMETER_NAME = 'isPreview';
public const CONTENT_VIEW_ROUTE = '_ez_content_view';
@@ -52,6 +60,9 @@ class PreviewController
/** @var \eZ\Publish\Core\MVC\Symfony\View\CustomLocationControllerChecker */
private $controllerChecker;
+ /** @var bool */
+ private $debugMode;
+
public function __construct(
ContentService $contentService,
LocationService $locationService,
@@ -59,7 +70,9 @@ public function __construct(
ContentPreviewHelper $previewHelper,
AuthorizationCheckerInterface $authorizationChecker,
PreviewLocationProvider $locationProvider,
- CustomLocationControllerChecker $controllerChecker
+ CustomLocationControllerChecker $controllerChecker,
+ bool $debugMode,
+ ?LoggerInterface $logger = null
) {
$this->contentService = $contentService;
$this->locationService = $locationService;
@@ -68,12 +81,14 @@ public function __construct(
$this->authorizationChecker = $authorizationChecker;
$this->locationProvider = $locationProvider;
$this->controllerChecker = $controllerChecker;
+ $this->debugMode = $debugMode;
+ $this->logger = $logger ?? new NullLogger();
}
/**
* @throws \eZ\Publish\API\Repository\Exceptions\NotImplementedException If Content is missing location as this is not supported in current version
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
- * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
+ * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
*/
public function previewContentAction(
Request $request,
@@ -82,7 +97,7 @@ public function previewContentAction(
$language,
$siteAccessName = null,
?int $locationId = null
- ) {
+ ): Response {
$this->previewHelper->setPreviewActive(true);
try {
@@ -117,19 +132,21 @@ public function previewContentAction(
HttpKernelInterface::SUB_REQUEST,
false
);
- } catch (\Exception $e) {
- if ($location->isDraft() && $this->controllerChecker->usesCustomController($content, $location)) {
- // @todo This should probably be an exception that embeds the original one
- $message = <<
Location View is deprecated, as it causes issues with preview, such as an empty location id when previewing the first version of a content.
-EOF; - - throw new Exception($message, 0, $e); - } else { - throw $e; + } catch (APINotFoundException $e) { + $message = 'Location not found or not available in requested language'; + $this->logger->warning( + 'Location not found or not available in requested language when loading the preview page', + ['exception' => $e] + ); + if ($this->debugMode) { + throw new BadStateException($message, 1, $e); } + + return new Response($message); + } catch (Exception $e) { + return $this->buildResponseForGenericPreviewError($location, $content, $e); } + $response->setPrivate(); $this->previewHelper->restoreConfigScope(); @@ -186,4 +203,39 @@ protected function getForwardRequest(Location $location, Content $content, SiteA $forwardRequestParameters ); } + + /** + * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException + */ + private function buildResponseForGenericPreviewError(Location $location, Content $content, Exception $e): Response + { + $message = ''; + try { + if ($location->isDraft() && $this->controllerChecker->usesCustomController($content, $location)) { + $message = <<Location View is deprecated, as it causes issues with preview, such as an empty location id when previewing the first version of a content.
+EOF; + } + } catch (Exception $innerException) { + $message = 'An exception occurred when handling page preview exception'; + $this->logger->warning( + 'Unable to check if location uses a custom controller when loading the preview page', + ['exception' => $innerException] + ); + } + + $this->logger->warning('Unable to load the preview page', ['exception' => $e]); + + $message .= <<See logs for more information
+EOF; + + if ($this->debugMode) { + throw new BadStateException($message, 1, $e); + } + + return new Response($message); + } } diff --git a/eZ/Publish/Core/MVC/Symfony/Controller/Tests/Controller/Content/PreviewControllerTest.php b/eZ/Publish/Core/MVC/Symfony/Controller/Tests/Controller/Content/PreviewControllerTest.php index 64f8f7e5d8..0e37a3456d 100644 --- a/eZ/Publish/Core/MVC/Symfony/Controller/Tests/Controller/Content/PreviewControllerTest.php +++ b/eZ/Publish/Core/MVC/Symfony/Controller/Tests/Controller/Content/PreviewControllerTest.php @@ -70,7 +70,9 @@ protected function getPreviewController(): PreviewController $this->previewHelper, $this->authorizationChecker, $this->locationProvider, - $this->controllerChecker + $this->controllerChecker, + false, + null ); }