[BUGFIX] Ensure workspace preview works with Site Handling 02/58502/3
authorBenni Mack <benni@typo3.org>
Sun, 30 Sep 2018 15:23:02 +0000 (17:23 +0200)
committerBenni Mack <benni@typo3.org>
Sun, 30 Sep 2018 17:26:57 +0000 (19:26 +0200)
While introducing Page URL handling, the workspace functionality
still built the URL with `/index.php` although the Router should
take care of that now.

As drive-by fix, the BackendUtility preview URL hook now works again
due to some refactoring back in TYPO3 9.2.

Another drive-by fix allows to register the middleware at the
right place to render the workspace preview in general.

Resolves: #86480
Releases: master
Change-Id: Icfa5a5eee304c27db39cf25903b9a14452c81168
Reviewed-on: https://review.typo3.org/58502
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/workspaces/Classes/Controller/PreviewController.php
typo3/sysext/workspaces/Classes/Controller/Remote/ActionHandler.php
typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php
typo3/sysext/workspaces/Classes/Preview/PreviewUriBuilder.php
typo3/sysext/workspaces/Configuration/RequestMiddlewares.php

index bc8af0d..bf5f6a6 100644 (file)
@@ -2661,7 +2661,8 @@ class BackendUtility
             }
         }
 
-        if ($alternativeUrl) {
+        // If there is an alternative URL or the URL has been modified by a hook, use that one.
+        if ($alternativeUrl || $viewScript !== '/index.php?id=') {
             $previewUrl = $viewScript;
         } else {
             $permissionClause = $GLOBALS['BE_USER']->getPagePermsClause(Permission::PAGE_SHOW);
index 2c8dca6..e2ea0e6 100644 (file)
@@ -21,7 +21,10 @@ use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Exception\SiteNotFoundException;
 use TYPO3\CMS\Core\Http\HtmlResponse;
+use TYPO3\CMS\Core\Site\Entity\Site;
+use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\View\StandaloneView;
 use TYPO3\CMS\Workspaces\Service\StagesService;
@@ -137,8 +140,34 @@ class PreviewController
             BackendUtility::setUpdateSignal('updatePageTree');
         }
 
-        // Base URL for frontend preview links
-        $previewBaseUrl = BackendUtility::getViewDomain($this->pageId) . '/index.php?' . $queryString;
+        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
+        try {
+            /** @var Site $site */
+            $site = $siteFinder->getSiteByPageId($this->pageId);
+            if (isset($queryParameters['L'])) {
+                $queryParameters['_language'] = $site->getLanguageById((int)$queryParameters['L']);
+                unset($queryParameters['L']);
+            }
+            if (!WorkspaceService::isNewPage($this->pageId)) {
+                $parameters = $queryParameters;
+                $parameters['ADMCMD_noBeUser'] = 1;
+                $parameters['ADMCMD_prev'] = 'IGNORE';
+                $liveUrl = (string)$site->getRouter()->generateUri($this->pageId, $parameters);
+            }
+
+            $parameters = $queryParameters;
+            $parameters['ADMCMD_view'] = 1;
+            $parameters['ADMCMD_editIcons'] = 1;
+            $parameters['ADMCMD_prev'] = 'IGNORE';
+            $wsUrl = (string)$site->getRouter()->generateUri($this->pageId, $parameters);
+        } catch (SiteNotFoundException $e) {
+            // Base URL for frontend preview links
+            $previewBaseUrl = BackendUtility::getViewDomain($this->pageId) . '/index.php?' . $queryString;
+            if (!WorkspaceService::isNewPage($this->pageId)) {
+                $liveUrl = $previewBaseUrl . '&ADMCMD_noBeUser=1&ADMCMD_prev=IGNORE';
+            }
+            $wsUrl = $previewBaseUrl . '&ADMCMD_prev=IGNORE&ADMCMD_view=1&ADMCMD_editIcons=1';
+        }
 
         // Build the "list view" link to the review controller
         $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
@@ -146,11 +175,6 @@ class PreviewController
             'tx_workspaces_web_workspacesworkspaces' => ['action' => 'singleIndex']
         ], UriBuilder::ABSOLUTE_URL);
 
-        if (!WorkspaceService::isNewPage($this->pageId)) {
-            $liveUrl = $previewBaseUrl . '&ADMCMD_noBeUser=1&ADMCMD_prev=IGNORE';
-        }
-        $wsUrl = $previewBaseUrl . '&ADMCMD_prev=IGNORE&ADMCMD_view=1&ADMCMD_editIcons=1';
-
         // Evaluate available preview modes
         $splitPreviewModes = GeneralUtility::trimExplode(
             ',',
index 5a8d62a..e145383 100644 (file)
@@ -61,7 +61,7 @@ class ActionHandler
      */
     public function generateWorkspacePreviewLink($uid)
     {
-        return GeneralUtility::makeInstance(PreviewUriBuilder::class)->buildUriForPage((int)$uid);
+        return GeneralUtility::makeInstance(PreviewUriBuilder::class)->buildUriForPage((int)$uid, 0);
     }
 
     /**
index 3d800ae..1f1779d 100644 (file)
@@ -612,7 +612,7 @@ class DataHandlerHook
                 $tempEmailMessage = $emailConfig['message'];
             }
             if (strpos($tempEmailMessage, '###PREVIEW_LINK###') !== false) {
-                $markers['###PREVIEW_LINK###'] = $previewUriBuilder->buildUriForPage((int)$elementUid);
+                $markers['###PREVIEW_LINK###'] = $previewUriBuilder->buildUriForPage((int)$elementUid, 0);
             }
             unset($tempEmailMessage);
 
index 3be9cae..9473f7d 100644 (file)
@@ -22,6 +22,9 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
+use TYPO3\CMS\Core\Exception\SiteNotFoundException;
+use TYPO3\CMS\Core\Site\Entity\Site;
+use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Versioning\VersionState;
 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
@@ -50,21 +53,36 @@ class PreviewUriBuilder
      * Generates a workspace preview link.
      *
      * @param int $uid The ID of the record to be linked
+     * @param int $languageId the language to link to
      * @return string the full domain including the protocol http:// or https://, but without the trailing '/'
      */
-    public function buildUriForPage(int $uid): string
+    public function buildUriForPage(int $uid, int $languageId = 0): string
     {
         $previewKeyword = $this->compilePreviewKeyword(
-            $this->getBackendUser()->user['uid'],
+            (int)$this->getBackendUser()->user['uid'],
             $this->getPreviewLinkLifetime() * 3600,
             $this->workspaceService->getCurrentWorkspace()
         );
 
-        $linkParams = [
-            'ADMCMD_prev' => $previewKeyword,
-            'id' => $uid
-        ];
-        return BackendUtility::getViewDomain($uid) . '/index.php?' . GeneralUtility::implodeArrayForUrl('', $linkParams);
+        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
+        try {
+            /** @var Site $site */
+            $site = $siteFinder->getSiteByPageId($uid);
+            try {
+                $language = $site->getLanguageById($languageId);
+            } catch (\InvalidArgumentException $e) {
+                $language = $site->getDefaultLanguage();
+            }
+            $uri = $site->getRouter()->generateUri($uid, ['ADMCMD_prev' => $previewKeyword, '_language' => $language], '');
+            return (string)$uri;
+        } catch (SiteNotFoundException $e) {
+            $linkParams = [
+                'ADMCMD_prev' => $previewKeyword,
+                'id' => $uid,
+                'L' => $languageId
+            ];
+            return BackendUtility::getViewDomain($uid) . '/index.php?' . GeneralUtility::implodeArrayForUrl('', $linkParams);
+        }
     }
 
     /**
@@ -75,12 +93,11 @@ class PreviewUriBuilder
      */
     public function buildUrisForAllLanguagesOfPage(int $pageId): array
     {
-        $previewUrl = $this->buildUriForPage($pageId);
         $previewLanguages = $this->getAvailableLanguages($pageId);
         $previewLinks = [];
 
         foreach ($previewLanguages as $languageUid => $language) {
-            $previewLinks[$language] = $previewUrl . '&L=' . $languageUid;
+            $previewLinks[$language] = $this->buildUriForPage($pageId, $languageUid);
         }
 
         return $previewLinks;
@@ -101,7 +118,7 @@ class PreviewUriBuilder
         }
         $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
         // the actual uid will be appended directly in BackendUtility Hook
-        $viewScript = $uriBuilder->buildUriFromRoute('workspace_previewcontrols', ['id' => '']);
+        $viewScript = $uriBuilder->buildUriFromRoute('workspace_previewcontrols', ['id' => $uid]);
         if ($addDomain === true) {
             $viewScript = $uriBuilder->buildUriFromRoute('workspace_previewcontrols', ['id' => $uid]);
             return BackendUtility::getViewDomain($uid) . 'index.php?redirect_url=' . urlencode($viewScript);
index 37b37c8..eeb3a84 100644 (file)
@@ -7,14 +7,13 @@ return [
         'typo3/cms-workspaces/preview' => [
             'target' => \TYPO3\CMS\Workspaces\Middleware\WorkspacePreview::class,
             'after' => [
-                'typo3/cms-core/normalized-params-attribute',
                 // TSFE is needed to store information about the preview
                 'typo3/cms-frontend/tsfe',
                 // A preview user will override an existing logged-in backend user
                 'typo3/cms-frontend/backend-user-authentication',
-                // Ensure, when a preview text is added, that the content length headers are added later-on
-                'typo3/cms-frontend/content-length-headers',
-                'typo3/cms-frontend/output-compression'
+            ],
+            'before' => [
+                'typo3/cms-frontend/page-resolver',
             ]
         ],
     ]