Passed
Push — master ( d5a28b...d12ca0 )
by
unknown
17:01
created

ReviewController::getPageRenderer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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 Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
use TYPO3\CMS\Backend\Routing\UriBuilder;
21
use TYPO3\CMS\Backend\Template\ModuleTemplate;
22
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
23
use TYPO3\CMS\Backend\Utility\BackendUtility;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Http\HtmlResponse;
26
use TYPO3\CMS\Core\Imaging\Icon;
27
use TYPO3\CMS\Core\Imaging\IconFactory;
28
use TYPO3\CMS\Core\Localization\LanguageService;
29
use TYPO3\CMS\Core\Page\PageRenderer;
30
use TYPO3\CMS\Core\Utility\GeneralUtility;
31
use TYPO3\CMS\Core\Versioning\VersionState;
32
use TYPO3\CMS\Fluid\View\StandaloneView;
33
use TYPO3\CMS\Workspaces\Service\WorkspaceService;
34
35
/**
36
 * @internal This is a specific Backend Controller implementation and is not considered part of the Public TYPO3 API.
37
 */
38
class ReviewController
39
{
40
    /**
41
     * @var ModuleTemplate
42
     */
43
    protected $moduleTemplate;
44
45
    /**
46
     * @var StandaloneView
47
     */
48
    protected $view;
49
50
    /**
51
     * @var int
52
     */
53
    protected $pageId;
54
55
    protected WorkspaceService $workspaceService;
56
    protected IconFactory $iconFactory;
57
    protected PageRenderer $pageRenderer;
58
    protected UriBuilder $uriBuilder;
59
    protected ModuleTemplateFactory $moduleTemplateFactory;
60
61
    public function __construct(
62
        WorkspaceService $workspaceService,
63
        IconFactory $iconFactory,
64
        PageRenderer $pageRenderer,
65
        UriBuilder $uriBuilder,
66
        ModuleTemplateFactory $moduleTemplateFactory
67
    ) {
68
        $this->workspaceService = $workspaceService;
69
        $this->iconFactory = $iconFactory;
70
        $this->pageRenderer = $pageRenderer;
71
        $this->uriBuilder = $uriBuilder;
72
        $this->moduleTemplateFactory = $moduleTemplateFactory;
73
    }
74
75
    /**
76
     * Initializes the controller before invoking an action method.
77
     */
78
    protected function initializeAction()
79
    {
80
        $icons = [
81
            'language' => $this->iconFactory->getIcon('flags-multiple', Icon::SIZE_SMALL)->render(),
82
            'integrity' => $this->iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
83
            'success' => $this->iconFactory->getIcon('status-dialog-ok', Icon::SIZE_SMALL)->render(),
84
            'info' => $this->iconFactory->getIcon('status-dialog-information', Icon::SIZE_SMALL)->render(),
85
            'warning' => $this->iconFactory->getIcon('status-dialog-warning', Icon::SIZE_SMALL)->render(),
86
            'error' => $this->iconFactory->getIcon('status-dialog-error', Icon::SIZE_SMALL)->render()
87
        ];
88
        $this->pageRenderer->addInlineSetting('Workspaces', 'icons', $icons);
89
        $this->pageRenderer->addInlineSetting('Workspaces', 'id', $this->pageId);
90
        $this->pageRenderer->addInlineSetting('Workspaces', 'depth', $this->pageId === 0 ? 999 : 1);
91
        $this->pageRenderer->addInlineSetting('Workspaces', 'language', $this->getLanguageSelection());
92
93
        $lang = $this->getLanguageService();
94
        $this->pageRenderer->addInlineLanguageLabelArray([
95
            'title' => $lang->getLL('title'),
96
            'path' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.path'),
97
            'table' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.table'),
98
            'depth' => $lang->sL('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:Depth'),
99
            'depth_0' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
100
            'depth_1' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
101
            'depth_2' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
102
            'depth_3' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
103
            'depth_4' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
104
            'depth_infi' => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
105
        ]);
106
        $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
107
        $states = $this->getBackendUser()->uc['moduleData']['Workspaces']['States'];
108
        $this->pageRenderer->addInlineSetting('Workspaces', 'States', $states);
109
110
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Backend');
111
        $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_edit'));
112
        $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_history'));
113
        $this->pageRenderer->addInlineSetting('Workspaces', 'id', $this->pageId);
114
    }
115
116
    /**
117
     * Renders the review module user dependent with all workspaces.
118
     * The module will show all records of one workspace.
119
     *
120
     * @param ServerRequestInterface $request
121
     * @return ResponseInterface
122
     */
123
    public function indexAction(ServerRequestInterface $request): ResponseInterface
124
    {
125
        $this->moduleTemplate = $this->moduleTemplateFactory->create($request);
126
        $queryParams = $request->getQueryParams();
127
        $this->pageId = (int)($queryParams['id'] ?? 0);
128
129
        $this->initializeAction();
130
131
        $this->view = GeneralUtility::makeInstance(StandaloneView::class);
132
        $this->view->setTemplate('Index');
133
        // This is only needed for translate VH to resolve 'label only' to default locallang.xlf files
134
        $this->view->getRequest()->setControllerExtensionName('Workspaces');
135
        $this->view->setTemplateRootPaths(['EXT:workspaces/Resources/Private/Templates/Review']);
136
        $this->view->setPartialRootPaths(['EXT:workspaces/Resources/Private/Partials']);
137
        $this->view->setLayoutRootPaths(['EXT:workspaces/Resources/Private/Layouts']);
138
139
        $backendUser = $this->getBackendUser();
140
        $pageTitle = '';
141
142
        if ($this->pageId) {
143
            $pageRecord = BackendUtility::getRecord('pages', $this->pageId);
144
            if ($pageRecord) {
145
                $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageRecord);
146
                $pageTitle = BackendUtility::getRecordTitle('pages', $pageRecord);
147
            }
148
        }
149
        $wsList = $this->workspaceService->getAvailableWorkspaces();
150
        $customWorkspaceExists = $this->customWorkspaceExists($wsList);
151
        $activeWorkspace = (int)$backendUser->workspace;
152
        $activeWorkspaceTitle = WorkspaceService::getWorkspaceTitle($activeWorkspace);
153
        $performWorkspaceSwitch = false;
154
        if ((int)($queryParams['workspace'] ?? 0) > 0) {
155
            $switchWs = (int)$queryParams['workspace'];
156
            if (array_key_exists($switchWs, $wsList) && $activeWorkspace !== $switchWs) {
157
                $activeWorkspace = $switchWs;
158
                $backendUser->setWorkspace($activeWorkspace);
159
                $performWorkspaceSwitch = true;
160
                BackendUtility::setUpdateSignal('updatePageTree');
161
            }
162
        }
163
        $this->pageRenderer->addInlineSetting('Workspaces', 'isLiveWorkspace', (int)$backendUser->workspace === 0);
164
        $this->pageRenderer->addInlineSetting('Workspaces', 'workspaceTabs', $this->prepareWorkspaceTabs($wsList, $activeWorkspace));
165
        $this->pageRenderer->addInlineSetting('Workspaces', 'activeWorkspaceId', $activeWorkspace);
166
        $workspaceIsAccessible = $backendUser->workspace !== WorkspaceService::LIVE_WORKSPACE_ID;
167
        $this->view->assignMultiple([
168
            'isAdmin' => $backendUser->isAdmin(),
169
            'customWorkspaceExists' => $customWorkspaceExists,
170
            'showGrid' => $workspaceIsAccessible,
171
            'showLegend' => $workspaceIsAccessible,
172
            'pageUid' => $this->pageId,
173
            'pageTitle' => $pageTitle,
174
            'performWorkspaceSwitch' => $performWorkspaceSwitch,
175
            'workspaceList' => $this->prepareWorkspaceTabs($wsList, $activeWorkspace),
176
            'activeWorkspaceUid' => $activeWorkspace,
177
            'activeWorkspaceTitle' => $activeWorkspaceTitle,
178
        ]);
179
180
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
181
        if ($this->canCreatePreviewLink($this->pageId, $activeWorkspace)) {
182
            $showButton = $buttonBar->makeLinkButton()
183
                ->setHref('#')
184
                ->setClasses('t3js-preview-link')
185
                ->setShowLabelText(true)
186
                ->setTitle($this->getLanguageService()->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:tooltip.generatePagePreview'))
187
                ->setIcon($this->iconFactory->getIcon('actions-version-workspaces-preview-link', Icon::SIZE_SMALL));
188
            $buttonBar->addButton($showButton);
189
        }
190
        $shortcutButton = $buttonBar->makeShortcutButton()
191
            ->setRouteIdentifier('web_WorkspacesWorkspaces')
192
            ->setDisplayName(sprintf('%s: %s [%d]', $activeWorkspaceTitle, $pageTitle, $this->pageId))
193
            ->setArguments(['id' => (int)$this->pageId]);
194
        $buttonBar->addButton($shortcutButton);
195
196
        $this->moduleTemplate->setContent($this->view->render());
197
        return new HtmlResponse($this->moduleTemplate->renderContent());
198
    }
199
200
    /**
201
     * Prepares available workspace tabs.
202
     *
203
     * @param array $workspaceList
204
     * @param int $activeWorkspace
205
     * @return array
206
     */
207
    protected function prepareWorkspaceTabs(array $workspaceList, int $activeWorkspace)
208
    {
209
        $tabs = [];
210
211
        if ($activeWorkspace !== WorkspaceService::LIVE_WORKSPACE_ID) {
212
            $tabs[] = [
213
                'title' => $workspaceList[$activeWorkspace],
214
                'itemId' => 'workspace-' . $activeWorkspace,
215
                'workspaceId' => $activeWorkspace,
216
                'triggerUrl' => $this->getModuleUri($activeWorkspace),
217
            ];
218
        }
219
220
        foreach ($workspaceList as $workspaceId => $workspaceTitle) {
221
            if ($workspaceId === $activeWorkspace
222
                || $workspaceId === WorkspaceService::LIVE_WORKSPACE_ID
223
            ) {
224
                continue;
225
            }
226
            $tabs[] = [
227
                'title' => $workspaceTitle,
228
                'itemId' => 'workspace-' . $workspaceId,
229
                'workspaceId' => $workspaceId,
230
                'triggerUrl' => $this->getModuleUri((int)$workspaceId),
231
            ];
232
        }
233
234
        return $tabs;
235
    }
236
237
    /**
238
     * Gets the module URI.
239
     *
240
     * @param int $workspaceId
241
     * @return string
242
     */
243
    protected function getModuleUri(int $workspaceId): string
244
    {
245
        $parameters = [
246
            'id' => $this->pageId,
247
            'workspace' => $workspaceId,
248
        ];
249
        return (string)$this->uriBuilder->buildUriFromRoute('web_WorkspacesWorkspaces', $parameters);
250
    }
251
252
    /**
253
     * Determine whether this page for the current
254
     *
255
     * @param int $pageUid
256
     * @param int $workspaceUid
257
     * @return bool
258
     */
259
    protected function canCreatePreviewLink(int $pageUid, int $workspaceUid): bool
260
    {
261
        if ($pageUid > 0 && $workspaceUid > 0) {
262
            $pageRecord = BackendUtility::getRecord('pages', $pageUid);
263
            BackendUtility::workspaceOL('pages', $pageRecord, $workspaceUid);
264
            if (VersionState::cast($pageRecord['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
265
                return false;
266
            }
267
            return true;
268
        }
269
        return false;
270
    }
271
272
    /**
273
     * Gets the selected language.
274
     *
275
     * @return string
276
     */
277
    protected function getLanguageSelection(): string
278
    {
279
        $language = 'all';
280
        $backendUser = $this->getBackendUser();
281
        if (isset($backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'])) {
282
            $language = $backendUser->uc['moduleData']['Workspaces'][$backendUser->workspace]['language'];
283
        }
284
        return $language;
285
    }
286
287
    /**
288
     * Returns true if at least one custom workspace next to live workspace exists.
289
     *
290
     * @param array $workspaceList
291
     * @return bool
292
     */
293
    protected function customWorkspaceExists(array $workspaceList): bool
294
    {
295
        foreach (array_keys($workspaceList) as $workspaceId) {
296
            if ($workspaceId > 0) {
297
                return true;
298
            }
299
        }
300
        return false;
301
    }
302
303
    /**
304
     * @return LanguageService
305
     */
306
    protected function getLanguageService(): LanguageService
307
    {
308
        return $GLOBALS['LANG'];
309
    }
310
311
    /**
312
     * @return BackendUserAuthentication
313
     */
314
    protected function getBackendUser(): BackendUserAuthentication
315
    {
316
        return $GLOBALS['BE_USER'];
317
    }
318
}
319