[TASK] Remove workspaceFrontendPreviewEnabled
[Packages/TYPO3.CMS.git] / typo3 / sysext / workspaces / Classes / Controller / PreviewController.php
1 <?php
2 namespace TYPO3\CMS\Workspaces\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Backend\View\BackendTemplateView;
19 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
20 use TYPO3\CMS\Core\Messaging\FlashMessage;
21 use TYPO3\CMS\Core\Messaging\FlashMessageService;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Core\Utility\PathUtility;
24 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
25 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
26 use TYPO3\CMS\Workspaces\Service\StagesService;
27 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
28
29 /**
30 * Implements the preview controller of the workspace module.
31 */
32 class PreviewController extends AbstractController
33 {
34 /**
35 * @var StagesService
36 */
37 protected $stageService;
38
39 /**
40 * @var WorkspaceService
41 */
42 protected $workspaceService;
43
44 /**
45 * Set up the doc header properly here
46 *
47 * @param ViewInterface $view
48 */
49 protected function initializeView(ViewInterface $view)
50 {
51 if ($view instanceof BackendTemplateView) {
52 /** @var BackendTemplateView $view */
53 parent::initializeView($view);
54 $view->getModuleTemplate()->getDocHeaderComponent()->disable();
55 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
56 }
57 }
58
59 /**
60 * Initializes the controller before invoking an action method.
61 *
62 * @return void
63 */
64 protected function initializeAction()
65 {
66 parent::initializeAction();
67 $this->stageService = GeneralUtility::makeInstance(StagesService::class);
68 $this->workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
69 $this->pageRenderer->addJsFile('EXT:backend/Resources/Public/JavaScript/ExtDirect.StateProvider.js');
70 $this->pageRenderer->loadExtJS(false, false);
71 // Load JavaScript:
72 $this->pageRenderer->addExtDirectCode([
73 'TYPO3.Workspaces',
74 'TYPO3.ExtDirectStateProvider'
75 ]);
76 $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
77 $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
78 $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit'));
79 $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history'));
80 // @todo this part should be done with inlineLocallanglabels
81 $this->pageRenderer->addJsInlineCode('workspace-inline-code', $this->generateJavascript());
82 }
83
84 /**
85 * Basically makes sure that the workspace preview is rendered.
86 * The preview itself consists of three frames, so there are
87 * only the frames-urls we've to generate here
88 *
89 * @param int $previewWS
90 * @return void
91 */
92 public function indexAction($previewWS = null)
93 {
94 $backendUser = $this->getBackendUser();
95
96 // Get all the GET parameters to pass them on to the frames
97 $queryParameters = GeneralUtility::_GET();
98
99 // Remove the GET parameters related to the workspaces module and the page id
100 unset($queryParameters['tx_workspaces_web_workspacesworkspaces']);
101 unset($queryParameters['M']);
102 unset($queryParameters['id']);
103
104 // Assemble a query string from the retrieved parameters
105 $queryString = GeneralUtility::implodeArrayForUrl('', $queryParameters);
106
107 // fetch the next and previous stage
108 $workspaceItemsArray = $this->workspaceService->selectVersionsInWorkspace($this->stageService->getWorkspaceId(), ($filter = 1), ($stage = -99), $this->pageId, ($recursionLevel = 0), ($selectionType = 'tables_modify'));
109 list(, $nextStage) = $this->stageService->getNextStageForElementCollection($workspaceItemsArray);
110 list(, $previousStage) = $this->stageService->getPreviousStageForElementCollection($workspaceItemsArray);
111 /** @var $wsService WorkspaceService */
112 $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
113 $wsList = $wsService->getAvailableWorkspaces();
114 $activeWorkspace = $backendUser->workspace;
115 if (!is_null($previewWS)) {
116 if (in_array($previewWS, array_keys($wsList)) && $activeWorkspace != $previewWS) {
117 $activeWorkspace = $previewWS;
118 $backendUser->setWorkspace($activeWorkspace);
119 BackendUtility::setUpdateSignal('updatePageTree');
120 }
121 }
122 /** @var $uriBuilder UriBuilder */
123 $uriBuilder = $this->objectManager->get(UriBuilder::class);
124 $wsSettingsPath = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
125 $wsSettingsUri = $uriBuilder->uriFor('singleIndex', [], ReviewController::class, 'workspaces', 'web_workspacesworkspaces');
126 $wsSettingsParams = '&tx_workspaces_web_workspacesworkspaces[controller]=Review';
127 $wsSettingsUrl = $wsSettingsPath . $wsSettingsUri . $wsSettingsParams;
128 $viewDomain = BackendUtility::getViewDomain($this->pageId);
129 $wsBaseUrl = $viewDomain . '/index.php?id=' . $this->pageId . $queryString;
130 // @todo - handle new pages here
131 // branchpoints are not handled anymore because this feature is not supposed anymore
132 if (WorkspaceService::isNewPage($this->pageId)) {
133 $wsNewPageUri = $uriBuilder->uriFor('newPage', [], self::class, 'workspaces', 'web_workspacesworkspaces');
134 $wsNewPageParams = '&tx_workspaces_web_workspacesworkspaces[controller]=Preview';
135 $liveUrl = $wsSettingsPath . $wsNewPageUri . $wsNewPageParams . '&ADMCMD_prev=IGNORE';
136 } else {
137 $liveUrl = $wsBaseUrl . '&ADMCMD_noBeUser=1&ADMCMD_prev=IGNORE';
138 }
139 $wsUrl = $wsBaseUrl . '&ADMCMD_prev=IGNORE&ADMCMD_view=1&ADMCMD_editIcons=1&ADMCMD_previewWS=' . $backendUser->workspace;
140 $backendDomain = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
141 $splitPreviewTsConfig = BackendUtility::getModTSconfig($this->pageId, 'workspaces.splitPreviewModes');
142 $splitPreviewModes = GeneralUtility::trimExplode(',', $splitPreviewTsConfig['value']);
143 $allPreviewModes = ['slider', 'vbox', 'hbox'];
144 if (!array_intersect($splitPreviewModes, $allPreviewModes)) {
145 $splitPreviewModes = $allPreviewModes;
146 }
147
148 $wsList = $wsService->getAvailableWorkspaces();
149 $activeWorkspace = $backendUser->workspace;
150
151 $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Preview');
152 $this->pageRenderer->addInlineSetting('Workspaces', 'SplitPreviewModes', $splitPreviewModes);
153 $this->pageRenderer->addInlineSetting('Workspaces', 'token', FormProtectionFactory::get('backend')->generateToken('extDirect'));
154
155 $cssFile = 'EXT:workspaces/Resources/Public/Css/preview.css';
156 $cssFile = GeneralUtility::getFileAbsFileName($cssFile);
157 $this->pageRenderer->addCssFile(PathUtility::getAbsoluteWebPath($cssFile));
158
159 $backendUser->setAndSaveSessionData('workspaces.backend_domain', GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'));
160
161 $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3-topbar@2x.png');
162 list($logoWidth, $logoHeight) = @getimagesize($logoPath);
163
164 // High-resolution?
165 $logoWidth = $logoWidth/2;
166 $logoHeight = $logoHeight/2;
167
168 $this->view->assignMultiple([
169 'logoUrl' => PathUtility::getAbsoluteWebPath($logoPath),
170 'logoLink' => TYPO3_URL_GENERAL,
171 'logoWidth' => $logoWidth,
172 'logoHeight' => $logoHeight,
173 'liveUrl' => $liveUrl,
174 'wsUrl' => $wsUrl,
175 'wsSettingsUrl' => $wsSettingsUrl,
176 'backendDomain' => $backendDomain,
177 'activeWorkspace' => $wsList[$activeWorkspace],
178 'splitPreviewModes' => $splitPreviewModes,
179 'firstPreviewMode' => current($splitPreviewModes),
180 'enablePreviousStageButton' => !$this->isInvalidStage($previousStage),
181 'enableNextStageButton' => !$this->isInvalidStage($nextStage),
182 'enableDiscardStageButton' => !$this->isInvalidStage($nextStage) || !$this->isInvalidStage($previousStage),
183 'nextStage' => $nextStage['title'],
184 'nextStageId' => $nextStage['uid'],
185 'prevStage' => $previousStage['title'],
186 'prevStageId' => $previousStage['uid'],
187 ]);
188 foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
189 $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
190 }
191 }
192
193 /**
194 * Evaluate the activate state based on given $stageArray.
195 *
196 * @param array $stageArray
197 * @return bool
198 */
199 protected function isInvalidStage($stageArray)
200 {
201 return !(is_array($stageArray) && !empty($stageArray));
202 }
203
204 /**
205 * @return void
206 */
207 public function newPageAction()
208 {
209 /** @var FlashMessage $flashMessage */
210 $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:info.newpage.detail'), $this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:info.newpage'), FlashMessage::INFO);
211 /** @var $flashMessageService FlashMessageService */
212 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
213 /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
214 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
215 $defaultFlashMessageQueue->enqueue($flashMessage);
216 }
217
218 /**
219 * Generates the JavaScript code for the backend,
220 * and since we're loading a backend module outside of the actual backend
221 * this copies parts of the index.php?M=main module
222 *
223 * @return string
224 */
225 protected function generateJavascript()
226 {
227 $backendUser = $this->getBackendUser();
228 $lang = $this->getLanguageService();
229 // If another page module was specified, replace the default Page module with the new one
230 $newPageModule = trim($backendUser->getTSConfigVal('options.overridePageModule'));
231 $pageModule = BackendUtility::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout';
232 if (!$backendUser->check('modules', $pageModule)) {
233 $pageModule = '';
234 }
235 $t3Configuration = [
236 'siteUrl' => GeneralUtility::getIndpEnv('TYPO3_SITE_URL'),
237 'username' => htmlspecialchars($backendUser->user['username']),
238 'uniqueID' => GeneralUtility::shortMD5(uniqid('', true)),
239 'pageModule' => $pageModule,
240 'inWorkspace' => $backendUser->workspace !== 0,
241 'topBarHeight' => isset($GLOBALS['TBE_STYLES']['dims']['topFrameH']) ? (int)$GLOBALS['TBE_STYLES']['dims']['topFrameH'] : 30,
242 'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup'] : false,
243 'debugInWindow' => $backendUser->uc['debugInWindow'] ? 1 : 0,
244 'ContextHelpWindows' => [
245 'width' => 600,
246 'height' => 400
247 ]
248 ];
249
250 return '
251 TYPO3.configuration = ' . json_encode($t3Configuration) . ';
252
253 /**
254 * TypoSetup object.
255 */
256 function typoSetup() { //
257 this.username = TYPO3.configuration.username;
258 this.uniqueID = TYPO3.configuration.uniqueID;
259 }
260 var TS = new typoSetup();
261 //backwards compatibility
262 ';
263 }
264
265 /**
266 * @return \TYPO3\CMS\Lang\LanguageService
267 */
268 protected function getLanguageService()
269 {
270 return $GLOBALS['LANG'];
271 }
272
273 /**
274 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
275 */
276 protected function getBackendUser()
277 {
278 return $GLOBALS['BE_USER'];
279 }
280 }