Completed
Push — master ( 175e11...08c540 )
by
unknown
15:46
created

ReviewController::canCreatePreviewLink()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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