‪TYPO3CMS  ‪main
PreviewController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
25 use TYPO3\CMS\Backend\Utility\BackendUtility;
37 
43 #[AsController]
45 {
46  public function ‪__construct(
47  protected readonly ‪StagesService $stageService,
48  protected readonly ‪WorkspaceService $workspaceService,
49  protected readonly ‪PageRenderer $pageRenderer,
50  protected readonly ‪UriBuilder $uriBuilder,
51  protected readonly ‪SiteFinder $siteFinder,
52  protected readonly ‪ModuleTemplateFactory $moduleTemplateFactory
53  ) {}
54 
60  public function ‪handleRequest(ServerRequestInterface $request): ResponseInterface
61  {
62  $queryParameters = $request->getQueryParams();
63  $previewWS = $queryParameters['previewWS'] ?? null;
64  $pageUid = (int)$queryParameters['id'];
65  $backendUser = $this->‪getBackendUser();
66 
67  // Initialize module template here, so custom css / js is loaded afterwards (making overrides possible)
68  $view = $this->moduleTemplateFactory->create($request);
69  $view->getDocHeaderComponent()->disable();
70 
71  $this->pageRenderer->loadJavaScriptModule('@typo3/workspaces/preview.js');
72  $this->pageRenderer->addInlineSetting('Workspaces', 'States', $backendUser->uc['moduleData']['Workspaces']['States'] ?? []);
73  $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_edit'));
74  $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_history'));
75  // Needed for FormEngine manipulation (date picker)
76  $dateFormat = ['dd-MM-yyyy', 'HH:mm dd-MM-yyyy'];
77  $this->pageRenderer->addInlineSetting('DateTimePicker', 'DateFormat', $dateFormat);
78  // @todo Most likely the inline configuration can be removed. Seems to be unused in the JavaScript module
79  $this->pageRenderer->addInlineSetting('TYPO3', 'configuration', [
80  'username' => htmlspecialchars($backendUser->user['username']),
81  'showRefreshLoginPopup' => (bool)(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup'] ?? false),
82  ]);
83  $this->pageRenderer->addCssFile('EXT:workspaces/Resources/Public/Css/preview.css');
84  $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/wizard.xlf');
85  $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
86  // Evaluate available preview modes
87  $splitPreviewModes = ‪GeneralUtility::trimExplode(
88  ',',
89  BackendUtility::getPagesTSconfig($pageUid)['workspaces.']['splitPreviewModes'] ?? '',
90  true
91  );
92  $allPreviewModes = ['slider', 'vbox', 'hbox'];
93  if (!array_intersect($splitPreviewModes, $allPreviewModes)) {
94  $splitPreviewModes = $allPreviewModes;
95  }
96  $this->pageRenderer->addInlineSetting('Workspaces', 'SplitPreviewModes', $splitPreviewModes);
97  $this->pageRenderer->addInlineSetting('Workspaces', 'id', $pageUid);
98 
99  // Fetch next and previous stage
100  $workspaceItemsArray = $this->workspaceService->selectVersionsInWorkspace(
101  $this->stageService->getWorkspaceId(),
102  -99,
103  $pageUid,
104  0,
105  'tables_modify'
106  );
107  [, $nextStage] = $this->stageService->getNextStageForElementCollection($workspaceItemsArray);
108  [, $previousStage] = $this->stageService->getPreviousStageForElementCollection($workspaceItemsArray);
109  $availableWorkspaces = $this->workspaceService->getAvailableWorkspaces();
110  $activeWorkspace = $backendUser->workspace;
111  if ($previewWS !== null && array_key_exists($previewWS, $availableWorkspaces) && $activeWorkspace != $previewWS) {
112  $activeWorkspace = $previewWS;
113  $backendUser->setWorkspace($activeWorkspace);
114  BackendUtility::setUpdateSignal('updatePageTree');
115  }
116 
117  try {
118  $liveUrl = false;
119  $site = $this->siteFinder->getSiteByPageId($pageUid);
120  // Remove GET parameters related to the workspaces module
121  unset($queryParameters['route'], $queryParameters['token'], $queryParameters['previewWS']);
122  if (isset($queryParameters['L'])) {
123  $queryParameters['_language'] = $site->getLanguageById((int)$queryParameters['L']);
124  unset($queryParameters['L']);
125  }
126  $parameters = $queryParameters;
127  if (!$this->workspaceService->isNewPage($pageUid)) {
128  $parameters['ADMCMD_prev'] = 'LIVE';
129  $liveUrl = $this->‪generateUrl($site, $pageUid, $parameters);
130  }
131  $parameters = $queryParameters;
132  $parameters['ADMCMD_prev'] = 'IGNORE';
133  $wsUrl = $this->‪generateUrl($site, $pageUid, $parameters);
135  throw new ‪UnableToLinkToPageException(sprintf('The link to the page with ID "%d" could not be generated: %s', $pageUid, $e->getMessage()), 1559794913, $e);
136  }
137 
138  $view->assignMultiple([
140  'liveUrl' => $liveUrl,
141  'wsUrl' => $wsUrl,
142  'activeWorkspace' => $availableWorkspaces[$activeWorkspace],
143  'splitPreviewModes' => $splitPreviewModes,
144  'firstPreviewMode' => current($splitPreviewModes),
145  'enablePreviousStageButton' => $this->‪isValidStage($previousStage),
146  'enableNextStageButton' => $this->‪isValidStage($nextStage),
147  'enableDiscardStageButton' => $this->‪isValidStage($nextStage) || $this->‪isValidStage($previousStage),
148  'nextStage' => $nextStage['title'] ?? '',
149  'nextStageId' => $nextStage['uid'] ?? 0,
150  'prevStage' => $previousStage['title'] ?? '',
151  'prevStageId' => $previousStage['uid'] ?? 0,
152  ]);
153  return $view->renderResponse('Preview/Index');
154  }
155 
159  protected function ‪isValidStage($stageArray): bool
160  {
161  return is_array($stageArray) && !empty($stageArray);
162  }
163 
165  {
166  return ‪$GLOBALS['BE_USER'];
167  }
168 
169  protected function ‪generateUrl(‪Site $site, int $pageUid, array $parameters): string
170  {
171  return (string)$site->‪getRouter()->generateUri($pageUid, $parameters);
172  }
173 }
‪TYPO3\CMS\Workspaces\Controller\PreviewController\getBackendUser
‪getBackendUser()
Definition: PreviewController.php:164
‪TYPO3\CMS\Core\Information\Typo3Information
Definition: Typo3Information.php:28
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:33
‪TYPO3\CMS\Workspaces\Controller\PreviewController\__construct
‪__construct(protected readonly StagesService $stageService, protected readonly WorkspaceService $workspaceService, protected readonly PageRenderer $pageRenderer, protected readonly UriBuilder $uriBuilder, protected readonly SiteFinder $siteFinder, protected readonly ModuleTemplateFactory $moduleTemplateFactory)
Definition: PreviewController.php:46
‪TYPO3\CMS\Workspaces\Controller\PreviewController
Definition: PreviewController.php:45
‪TYPO3\CMS\Core\Exception\SiteNotFoundException
Definition: SiteNotFoundException.php:25
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:44
‪TYPO3\CMS\Core\Information\Typo3Information\URL_COMMUNITY
‪const URL_COMMUNITY
Definition: Typo3Information.php:29
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException
Definition: InvalidRouteArgumentsException.php:25
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Workspaces\Service\WorkspaceService
Definition: WorkspaceService.php:38
‪TYPO3\CMS\Workspaces\Service\StagesService
Definition: StagesService.php:33
‪TYPO3\CMS\Workspaces\Controller\PreviewController\isValidStage
‪isValidStage($stageArray)
Definition: PreviewController.php:159
‪TYPO3\CMS\Workspaces\Controller\PreviewController\generateUrl
‪generateUrl(Site $site, int $pageUid, array $parameters)
Definition: PreviewController.php:169
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Attribute\AsController
Definition: AsController.php:25
‪TYPO3\CMS\Workspaces\Controller\PreviewController\handleRequest
‪handleRequest(ServerRequestInterface $request)
Definition: PreviewController.php:60
‪TYPO3\CMS\Workspaces\Controller
Definition: AjaxController.php:18
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Site\Entity\Site\getRouter
‪getRouter(Context $context=null)
Definition: Site.php:346
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822