82b5a16a5524d52bb5df623fcfeca36dcd531444
[Packages/TYPO3.CMS.git] / typo3 / sysext / workspaces / Classes / Controller / ReviewController.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\Core\Authentication\BackendUserAuthentication;
19 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
20 use TYPO3\CMS\Core\Imaging\Icon;
21 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
24 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
25
26 /**
27 * Review controller.
28 */
29 class ReviewController extends AbstractController
30 {
31 /**
32 * Set up the doc header properly here
33 *
34 * @param ViewInterface $view
35 */
36 protected function initializeView(ViewInterface $view)
37 {
38 parent::initializeView($view);
39 $this->registerButtons();
40 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
41 }
42
43 /**
44 * Registers the DocHeader buttons
45 */
46 protected function registerButtons()
47 {
48 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
49 $currentRequest = $this->request;
50 $moduleName = $currentRequest->getPluginName();
51 $getVars = $this->request->getArguments();
52 $extensionName = $currentRequest->getControllerExtensionName();
53 if (count($getVars) === 0) {
54 $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
55 $getVars = ['id', 'M', $modulePrefix];
56 }
57 $shortcutButton = $buttonBar->makeShortcutButton()
58 ->setModuleName($moduleName)
59 ->setGetVariables($getVars);
60 $buttonBar->addButton($shortcutButton);
61 }
62
63 /**
64 * Renders the review module user dependent with all workspaces.
65 * The module will show all records of one workspace.
66 *
67 * @return void
68 */
69 public function indexAction()
70 {
71 $backendUser = $this->getBackendUser();
72 $moduleTemplate = $this->view->getModuleTemplate();
73
74 /** @var WorkspaceService $wsService */
75 $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
76 if (GeneralUtility::_GP('id')) {
77 $pageRecord = BackendUtility::getRecord('pages', GeneralUtility::_GP('id'));
78 if ($pageRecord) {
79 $moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageRecord);
80 $this->view->assign('pageTitle', BackendUtility::getRecordTitle('pages', $pageRecord));
81 }
82 }
83 $wsList = $wsService->getAvailableWorkspaces();
84 $activeWorkspace = $backendUser->workspace;
85 $performWorkspaceSwitch = false;
86 // Only admins see multiple tabs, we decided to use it this
87 // way for usability reasons. Regular users might be confused
88 // by switching workspaces with the tabs in a module.
89 if (!$backendUser->isAdmin()) {
90 $wsCur = [$activeWorkspace => true];
91 $wsList = array_intersect_key($wsList, $wsCur);
92 } else {
93 if ((string)GeneralUtility::_GP('workspace') !== '') {
94 $switchWs = (int)GeneralUtility::_GP('workspace');
95 if (in_array($switchWs, array_keys($wsList)) && $activeWorkspace != $switchWs) {
96 $activeWorkspace = $switchWs;
97 $backendUser->setWorkspace($activeWorkspace);
98 $performWorkspaceSwitch = true;
99 BackendUtility::setUpdateSignal('updatePageTree');
100 } elseif ($switchWs == WorkspaceService::SELECT_ALL_WORKSPACES) {
101 $this->redirect('fullIndex');
102 }
103 }
104 }
105 $this->pageRenderer->addInlineSetting('Workspaces', 'isLiveWorkspace', (int)$backendUser->workspace === 0);
106 $this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, $activeWorkspace));
107 $this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', $activeWorkspace);
108 $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit'));
109 $workspaceIsAccessible = !($backendUser->workspace === 0 && !$backendUser->isAdmin());
110 $this->view->assignMultiple([
111 'showGrid' => $workspaceIsAccessible,
112 'showLegend' => $workspaceIsAccessible,
113 'pageUid' => (int)GeneralUtility::_GP('id'),
114 'performWorkspaceSwitch' => $performWorkspaceSwitch,
115 'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
116 'activeWorkspaceUid' => $activeWorkspace,
117 'activeWorkspaceTitle' => WorkspaceService::getWorkspaceTitle($activeWorkspace),
118 'showPreviewLink' => $wsService->canCreatePreviewLink(GeneralUtility::_GP('id'), $activeWorkspace)
119 ]);
120
121 if ($wsService->canCreatePreviewLink(GeneralUtility::_GP('id'), $activeWorkspace)) {
122 $buttonBar = $moduleTemplate->getDocHeaderComponent()->getButtonBar();
123 $iconFactory = $moduleTemplate->getIconFactory();
124 $showButton = $buttonBar->makeLinkButton()
125 ->setHref('#')
126 ->setClasses('t3js-preview-link')
127 ->setTitle($this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:tooltip.generatePagePreview'))
128 ->setIcon($iconFactory->getIcon('module-workspaces-action-preview-link', Icon::SIZE_SMALL));
129 $buttonBar->addButton($showButton);
130 }
131 $backendUser->setAndSaveSessionData('tx_workspace_activeWorkspace', $activeWorkspace);
132 }
133
134 /**
135 * Renders the review module user dependent.
136 * The module will show all records of all workspaces.
137 *
138 * @return void
139 */
140 public function fullIndexAction()
141 {
142 $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
143 $wsList = $wsService->getAvailableWorkspaces();
144
145 $activeWorkspace = $this->getBackendUser()->workspace;
146 if (!$this->getBackendUser()->isAdmin()) {
147 $wsCur = [$activeWorkspace => true];
148 $wsList = array_intersect_key($wsList, $wsCur);
149 }
150
151 $this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, WorkspaceService::SELECT_ALL_WORKSPACES));
152 $this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', WorkspaceService::SELECT_ALL_WORKSPACES);
153 $this->view->assignMultiple([
154 'pageUid' => (int)GeneralUtility::_GP('id'),
155 'showGrid' => true,
156 'showLegend' => true,
157 'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
158 'activeWorkspaceUid' => WorkspaceService::SELECT_ALL_WORKSPACES,
159 'showPreviewLink', false
160 ]);
161 $this->getBackendUser()->setAndSaveSessionData('tx_workspace_activeWorkspace', WorkspaceService::SELECT_ALL_WORKSPACES);
162 // set flag for javascript
163 $this->pageRenderer->addInlineSetting('Workspaces', 'allView', '1');
164 }
165
166 /**
167 * Renders the review module for a single page. This is used within the
168 * workspace-preview frame.
169 *
170 * @return void
171 */
172 public function singleIndexAction()
173 {
174 $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
175 $wsList = $wsService->getAvailableWorkspaces();
176 $activeWorkspace = $this->getBackendUser()->workspace;
177 $wsCur = [$activeWorkspace => true];
178 $wsList = array_intersect_key($wsList, $wsCur);
179 $backendDomain = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
180 $this->view->assignMultiple([
181 'pageUid' => (int)GeneralUtility::_GP('id'),
182 'showGrid' => true,
183 'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace, false),
184 'activeWorkspaceUid' => $activeWorkspace,
185 'backendDomain' => $backendDomain
186 ]);
187 // Setting the document.domain early before JavScript
188 // libraries are loaded, try to access top frame reference
189 // and possibly run into some CORS issue
190 $this->pageRenderer->setMetaCharsetTag(
191 $this->pageRenderer->getMetaCharsetTag() . LF
192 . GeneralUtility::wrapJS('document.domain = ' . GeneralUtility::quoteJSvalue($backendDomain) . ';')
193 );
194 $this->pageRenderer->addInlineSetting('Workspaces', 'singleView', '1');
195 }
196
197 /**
198 * Initializes the controller before invoking an action method.
199 *
200 * @return void
201 */
202 protected function initializeAction()
203 {
204 parent::initializeAction();
205 $backendRelPath = ExtensionManagementUtility::extRelPath('backend');
206 $this->pageRenderer->addJsFile($backendRelPath . 'Resources/Public/JavaScript/ExtDirect.StateProvider.js');
207 $this->pageRenderer->loadExtJS(false, false);
208 $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
209 $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
210 // Load JavaScript:
211 $this->pageRenderer->addExtDirectCode([
212 'TYPO3.Workspaces'
213 ]);
214
215 foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
216 $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
217 }
218 $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
219 $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit'));
220 $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history'));
221 $this->pageRenderer->addInlineSetting('Workspaces', 'token', FormProtectionFactory::get('backend')->generateToken('extDirect'));
222 $this->pageRenderer->addInlineSetting('Workspaces', 'id', (int)GeneralUtility::_GP('id'));
223 }
224
225 /**
226 * Prepares available workspace tabs.
227 *
228 * @param array $workspaceList
229 * @param int $activeWorkspace
230 * @param bool $showAllWorkspaceTab
231 * @return array
232 */
233 protected function prepareWorkspaceTabs(array $workspaceList, $activeWorkspace, $showAllWorkspaceTab = true)
234 {
235 $tabs = [];
236
237 if ($activeWorkspace !== WorkspaceService::SELECT_ALL_WORKSPACES) {
238 $tabs[] = [
239 'title' => $workspaceList[$activeWorkspace],
240 'itemId' => 'workspace-' . $activeWorkspace,
241 'workspaceId' => $activeWorkspace,
242 'triggerUrl' => $this->getModuleUri($activeWorkspace),
243 ];
244 }
245
246 if ($showAllWorkspaceTab) {
247 $tabs[] = [
248 'title' => 'All workspaces',
249 'itemId' => 'workspace-' . WorkspaceService::SELECT_ALL_WORKSPACES,
250 'workspaceId' => WorkspaceService::SELECT_ALL_WORKSPACES,
251 'triggerUrl' => $this->getModuleUri(WorkspaceService::SELECT_ALL_WORKSPACES),
252 ];
253 }
254
255 foreach ($workspaceList as $workspaceId => $workspaceTitle) {
256 if ($workspaceId === $activeWorkspace) {
257 continue;
258 }
259 $tabs[] = [
260 'title' => $workspaceTitle,
261 'itemId' => 'workspace-' . $workspaceId,
262 'workspaceId' => $workspaceId,
263 'triggerUrl' => $this->getModuleUri($workspaceId),
264 ];
265 }
266
267 return $tabs;
268 }
269
270 /**
271 * Gets the module URI.
272 *
273 * @param int $workspaceId
274 * @return string
275 */
276 protected function getModuleUri($workspaceId)
277 {
278 $parameters = [
279 'id' => (int)$this->pageId,
280 'workspace' => (int)$workspaceId,
281 ];
282 // The "all workspaces" tab is handled in fullIndexAction
283 // which is required as additional GET parameter in the URI then
284 if ($workspaceId === WorkspaceService::SELECT_ALL_WORKSPACES) {
285 $this->uriBuilder->reset()->uriFor('fullIndex');
286 $parameters = array_merge($parameters, $this->uriBuilder->getArguments());
287 }
288 return BackendUtility::getModuleUrl('web_WorkspacesWorkspaces', $parameters);
289 }
290
291 /**
292 * @return \TYPO3\CMS\Lang\LanguageService
293 */
294 protected function getLanguageService()
295 {
296 return $GLOBALS['LANG'];
297 }
298
299 /**
300 * @return BackendUserAuthentication
301 */
302 protected function getBackendUser()
303 {
304 return $GLOBALS['BE_USER'];
305 }
306 }