Completed
Push — master ( 8a2bff...51fbd3 )
by
unknown
15:59
created

ReviewController   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 380
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 186
dl 0
loc 380
rs 9.28
c 1
b 0
f 0
wmc 39

16 Methods

Rating   Name   Duplication   Size   Complexity  
A fullIndexAction() 0 23 2
A singleIndexAction() 0 14 1
A initializeView() 0 5 1
A registerButtons() 0 15 2
A initializeAction() 0 45 3
A canCreatePreviewLink() 0 11 4
A getLanguageService() 0 3 1
A getLanguageSelection() 0 8 2
A assignExtensionSettings() 0 12 1
A getPageRenderer() 0 3 1
B indexAction() 0 60 9
B prepareWorkspaceTabs() 0 39 7
A getBackendUser() 0 3 1
A getAdditionalColumnService() 0 3 1
A getModuleUri() 0 14 2
A getAdditionalResourceService() 0 3 1
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Workspaces\Controller;
17
18
use TYPO3\CMS\Backend\Routing\UriBuilder;
19
use TYPO3\CMS\Backend\Utility\BackendUtility;
20
use TYPO3\CMS\Backend\View\BackendTemplateView;
21
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
22
use TYPO3\CMS\Core\Imaging\Icon;
23
use TYPO3\CMS\Core\Imaging\IconFactory;
24
use TYPO3\CMS\Core\Localization\LanguageService;
25
use TYPO3\CMS\Core\Page\PageRenderer;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Core\Versioning\VersionState;
28
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
29
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
30
use TYPO3\CMS\Workspaces\Service\AdditionalColumnService;
31
use TYPO3\CMS\Workspaces\Service\AdditionalResourceService;
32
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
33
34
/**
35
 * @internal This is a specific Backend Controller implementation and is not considered part of the Public TYPO3 API.
36
 */
37
class ReviewController extends ActionController
38
{
39
    /**
40
     * @var string
41
     */
42
    protected $defaultViewObjectName = BackendTemplateView::class;
43
44
    /**
45
     * @var BackendTemplateView
46
     */
47
    protected $view;
48
49
    /**
50
     * @var PageRenderer
51
     */
52
    protected $pageRenderer;
53
54
    /**
55
     * @var int
56
     */
57
    protected $pageId;
58
59
    /**
60
     * Set up the doc header properly here
61
     *
62
     * @param ViewInterface $view
63
     */
64
    protected function initializeView(ViewInterface $view)
65
    {
66
        parent::initializeView($view);
67
        $this->registerButtons();
68
        $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
69
    }
70
71
    /**
72
     * Registers the DocHeader buttons
73
     */
74
    protected function registerButtons()
75
    {
76
        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
77
        $currentRequest = $this->request;
78
        $moduleName = $currentRequest->getPluginName();
79
        $getVars = $this->request->getArguments();
80
        $extensionName = $currentRequest->getControllerExtensionName();
81
        if (count($getVars) === 0) {
82
            $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
83
            $getVars = ['id', 'route', $modulePrefix];
84
        }
85
        $shortcutButton = $buttonBar->makeShortcutButton()
86
            ->setModuleName($moduleName)
87
            ->setGetVariables($getVars);
88
        $buttonBar->addButton($shortcutButton);
89
    }
90
91
    /**
92
     * Initializes the controller before invoking an action method.
93
     */
94
    protected function initializeAction()
95
    {
96
        $this->pageRenderer = $this->getPageRenderer();
97
        // @todo Evaluate how the (int) typecast can be used with Extbase validators/filters
98
        $this->pageId = (int)GeneralUtility::_GP('id');
99
        $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
100
        $lang = $this->getLanguageService();
101
        $icons = [
102
            'language' => $iconFactory->getIcon('flags-multiple', Icon::SIZE_SMALL)->render(),
103
            'integrity' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
104
            'success' => $iconFactory->getIcon('status-dialog-ok', Icon::SIZE_SMALL)->render(),
105
            'info' => $iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
106
            'warning' => $iconFactory->getIcon('status-dialog-warning', Icon::SIZE_SMALL)->render(),
107
            'error' => $iconFactory->getIcon('status-dialog-error', Icon::SIZE_SMALL)->render()
108
        ];
109
        $this->pageRenderer->addInlineSetting('Workspaces', 'icons', $icons);
110
        $this->pageRenderer->addInlineSetting('Workspaces', 'id', $this->pageId);
111
        $this->pageRenderer->addInlineSetting('Workspaces', 'depth', $this->pageId === 0 ? 999 : 1);
112
        $this->pageRenderer->addInlineSetting('Workspaces', 'language', $this->getLanguageSelection());
113
        $this->pageRenderer->addInlineLanguageLabelArray([
114
            'title' => $lang->getLL('title'),
115
            'path' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.path'),
116
            'table' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.table'),
117
            'depth' => $lang->sL('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:Depth'),
118
            'depth_0' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
119
            'depth_1' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
120
            'depth_2' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
121
            'depth_3' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
122
            'depth_4' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
123
            'depth_infi' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
124
        ]);
125
        $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
126
        $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
127
        $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
128
129
        foreach ($this->getAdditionalResourceService()->getLocalizationResources() as $localizationResource) {
130
            $this->pageRenderer->addInlineLanguageLabelFile($localizationResource);
131
        }
132
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
133
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
134
        $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
135
        $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
136
        $this->pageRenderer->addInlineSetting('Workspaces', 'id', (int)GeneralUtility::_GP('id'));
137
138
        $this->assignExtensionSettings();
139
    }
140
141
    /**
142
     * Renders the review module user dependent with all workspaces.
143
     * The module will show all records of one workspace.
144
     */
145
    public function indexAction()
146
    {
147
        $backendUser = $this->getBackendUser();
148
        $moduleTemplate = $this->view->getModuleTemplate();
149
150
        if (GeneralUtility::_GP('id')) {
151
            $pageRecord = BackendUtility::getRecord('pages', GeneralUtility::_GP('id'));
152
            if ($pageRecord) {
153
                $moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageRecord);
154
                $this->view->assign('pageTitle', BackendUtility::getRecordTitle('pages', $pageRecord));
155
            }
156
        }
157
        $wsList = GeneralUtility::makeInstance(WorkspaceService::class)->getAvailableWorkspaces();
158
        $activeWorkspace = $backendUser->workspace;
159
        $performWorkspaceSwitch = false;
160
        // Only admins see multiple tabs, we decided to use it this
161
        // way for usability reasons. Regular users might be confused
162
        // by switching workspaces with the tabs in a module.
163
        if (!$backendUser->isAdmin()) {
164
            $wsCur = [$activeWorkspace => true];
165
            $wsList = array_intersect_key($wsList, $wsCur);
166
        } else {
167
            if ((string)GeneralUtility::_GP('workspace') !== '') {
168
                $switchWs = (int)GeneralUtility::_GP('workspace');
169
                if (array_key_exists($switchWs, $wsList) && $activeWorkspace != $switchWs) {
170
                    $activeWorkspace = $switchWs;
171
                    $backendUser->setWorkspace($activeWorkspace);
172
                    $performWorkspaceSwitch = true;
173
                    BackendUtility::setUpdateSignal('updatePageTree');
174
                } elseif ($switchWs == WorkspaceService::SELECT_ALL_WORKSPACES) {
175
                    $this->redirect('fullIndex');
176
                }
177
            }
178
        }
179
        $this->pageRenderer->addInlineSetting('Workspaces', 'isLiveWorkspace', (int)$backendUser->workspace === 0);
180
        $this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, $activeWorkspace));
181
        $this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', $activeWorkspace);
182
        $workspaceIsAccessible = $backendUser->workspace !== WorkspaceService::LIVE_WORKSPACE_ID;
183
        $this->view->assignMultiple([
184
            'showGrid' => $workspaceIsAccessible,
185
            'showLegend' => $workspaceIsAccessible,
186
            'pageUid' => (int)GeneralUtility::_GP('id'),
187
            'performWorkspaceSwitch' => $performWorkspaceSwitch,
188
            'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
189
            'activeWorkspaceUid' => $activeWorkspace,
190
            'activeWorkspaceTitle' => WorkspaceService::getWorkspaceTitle($activeWorkspace),
191
        ]);
192
193
        if ($this->canCreatePreviewLink((int)GeneralUtility::_GP('id'), (int)$activeWorkspace)) {
194
            $buttonBar = $moduleTemplate->getDocHeaderComponent()->getButtonBar();
195
            $iconFactory = $moduleTemplate->getIconFactory();
196
            $showButton = $buttonBar->makeLinkButton()
197
                ->setHref('#')
198
                ->setClasses('t3js-preview-link')
199
                ->setShowLabelText(true)
200
                ->setTitle($this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:tooltip.generatePagePreview'))
201
                ->setIcon($iconFactory->getIcon('actions-version-workspaces-preview-link', Icon::SIZE_SMALL));
202
            $buttonBar->addButton($showButton);
203
        }
204
        $backendUser->setAndSaveSessionData('tx_workspace_activeWorkspace', $activeWorkspace);
205
    }
206
207
    /**
208
     * Renders the review module user dependent.
209
     * The module will show all records of all workspaces.
210
     */
211
    public function fullIndexAction()
212
    {
213
        $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
214
        $wsList = $wsService->getAvailableWorkspaces();
215
216
        $activeWorkspace = $this->getBackendUser()->workspace;
217
        if (!$this->getBackendUser()->isAdmin()) {
218
            $wsCur = [$activeWorkspace => true];
219
            $wsList = array_intersect_key($wsList, $wsCur);
220
        }
221
222
        $this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, WorkspaceService::SELECT_ALL_WORKSPACES));
223
        $this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', WorkspaceService::SELECT_ALL_WORKSPACES);
224
        $this->view->assignMultiple([
225
            'pageUid' => (int)GeneralUtility::_GP('id'),
226
            'showGrid' => true,
227
            'showLegend' => true,
228
            'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
229
            'activeWorkspaceUid' => WorkspaceService::SELECT_ALL_WORKSPACES
230
        ]);
231
        $this->getBackendUser()->setAndSaveSessionData('tx_workspace_activeWorkspace', WorkspaceService::SELECT_ALL_WORKSPACES);
232
        // set flag for javascript
233
        $this->pageRenderer->addInlineSetting('Workspaces', 'allView', '1');
234
    }
235
236
    /**
237
     * Renders the review module for a single page. This is used within the
238
     * workspace-preview frame.
239
     */
240
    public function singleIndexAction()
241
    {
242
        $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
243
        $wsList = $wsService->getAvailableWorkspaces();
244
        $activeWorkspace = $this->getBackendUser()->workspace;
245
        $wsCur = [$activeWorkspace => true];
246
        $wsList = array_intersect_key($wsList, $wsCur);
247
        $this->view->assignMultiple([
248
            'pageUid' => (int)GeneralUtility::_GP('id'),
249
            'showGrid' => true,
250
            'workspaceList' => $this->prepareWorkspaceTabs($wsList, (int)$activeWorkspace, false),
251
            'activeWorkspaceUid' => $activeWorkspace,
252
        ]);
253
        $this->pageRenderer->addInlineSetting('Workspaces', 'singleView', '1');
254
    }
255
256
    /**
257
     * Prepares available workspace tabs.
258
     *
259
     * @param array $workspaceList
260
     * @param int $activeWorkspace
261
     * @param bool $showAllWorkspaceTab
262
     * @return array
263
     */
264
    protected function prepareWorkspaceTabs(array $workspaceList, int $activeWorkspace, bool $showAllWorkspaceTab = true)
265
    {
266
        $tabs = [];
267
268
        if ($activeWorkspace !== WorkspaceService::SELECT_ALL_WORKSPACES
269
            && $activeWorkspace !== WorkspaceService::LIVE_WORKSPACE_ID
270
        ) {
271
            $tabs[] = [
272
                'title' => $workspaceList[$activeWorkspace],
273
                'itemId' => 'workspace-' . $activeWorkspace,
274
                'workspaceId' => $activeWorkspace,
275
                'triggerUrl' => $this->getModuleUri($activeWorkspace),
276
            ];
277
        }
278
279
        if ($showAllWorkspaceTab) {
280
            $tabs[] = [
281
                'title' => 'All workspaces',
282
                'itemId' => 'workspace-' . WorkspaceService::SELECT_ALL_WORKSPACES,
283
                'workspaceId' => WorkspaceService::SELECT_ALL_WORKSPACES,
284
                'triggerUrl' => $this->getModuleUri(WorkspaceService::SELECT_ALL_WORKSPACES),
285
            ];
286
        }
287
288
        foreach ($workspaceList as $workspaceId => $workspaceTitle) {
289
            if ($workspaceId === $activeWorkspace
290
                || $workspaceId === WorkspaceService::LIVE_WORKSPACE_ID
291
            ) {
292
                continue;
293
            }
294
            $tabs[] = [
295
                'title' => $workspaceTitle,
296
                'itemId' => 'workspace-' . $workspaceId,
297
                'workspaceId' => $workspaceId,
298
                'triggerUrl' => $this->getModuleUri($workspaceId),
299
            ];
300
        }
301
302
        return $tabs;
303
    }
304
305
    /**
306
     * Gets the module URI.
307
     *
308
     * @param int $workspaceId
309
     * @return string
310
     */
311
    protected function getModuleUri(int $workspaceId): string
312
    {
313
        $parameters = [
314
            'id' => $this->pageId,
315
            'workspace' => $workspaceId,
316
        ];
317
        // The "all workspaces" tab is handled in fullIndexAction
318
        // which is required as additional GET parameter in the URI then
319
        if ($workspaceId === WorkspaceService::SELECT_ALL_WORKSPACES) {
320
            $this->uriBuilder->reset()->uriFor('fullIndex');
321
            $parameters = array_merge($parameters, $this->uriBuilder->getArguments());
322
        }
323
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
324
        return (string)$uriBuilder->buildUriFromRoute('web_WorkspacesWorkspaces', $parameters);
325
    }
326
327
    /**
328
     * Assigns additional Workspace settings to TYPO3.settings.Workspaces.extension
329
     */
330
    protected function assignExtensionSettings()
331
    {
332
        $extension = [
333
            'AdditionalColumn' => [
334
                'Definition' => [],
335
                'Handler' => [],
336
            ],
337
        ];
338
339
        $extension['AdditionalColumn']['Definition'] = $this->getAdditionalColumnService()->getDefinition();
340
        $extension['AdditionalColumn']['Handler'] = $this->getAdditionalColumnService()->getHandler();
341
        $this->pageRenderer->addInlineSetting('Workspaces', 'extension', $extension);
342
    }
343
344
    /**
345
     * Determine whether this page for the current
346
     *
347
     * @param int $pageUid
348
     * @param int $workspaceUid
349
     * @return bool
350
     */
351
    protected function canCreatePreviewLink(int $pageUid, int $workspaceUid): bool
352
    {
353
        if ($pageUid > 0 && $workspaceUid > 0) {
354
            $pageRecord = BackendUtility::getRecord('pages', $pageUid);
355
            BackendUtility::workspaceOL('pages', $pageRecord, $workspaceUid);
356
            if (VersionState::cast($pageRecord['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
357
                return false;
358
            }
359
            return true;
360
        }
361
        return false;
362
    }
363
364
    /**
365
     * Gets the selected language.
366
     *
367
     * @return string
368
     */
369
    protected function getLanguageSelection(): string
370
    {
371
        $language = 'all';
372
        $backendUser = $this->getBackendUser();
373
        if (isset($backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'])) {
374
            $language = $backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'];
375
        }
376
        return $language;
377
    }
378
379
    /**
380
     * @return AdditionalColumnService
381
     */
382
    protected function getAdditionalColumnService(): AdditionalColumnService
383
    {
384
        return $this->objectManager->get(AdditionalColumnService::class);
385
    }
386
387
    /**
388
     * @return AdditionalResourceService
389
     */
390
    protected function getAdditionalResourceService(): AdditionalResourceService
391
    {
392
        return $this->objectManager->get(AdditionalResourceService::class);
393
    }
394
395
    /**
396
     * @return PageRenderer
397
     */
398
    protected function getPageRenderer(): PageRenderer
399
    {
400
        return GeneralUtility::makeInstance(PageRenderer::class);
401
    }
402
403
    /**
404
     * @return LanguageService
405
     */
406
    protected function getLanguageService(): LanguageService
407
    {
408
        return $GLOBALS['LANG'];
409
    }
410
411
    /**
412
     * @return BackendUserAuthentication
413
     */
414
    protected function getBackendUser(): BackendUserAuthentication
415
    {
416
        return $GLOBALS['BE_USER'];
417
    }
418
}
419