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

getBackendUser()   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
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Backend\Controller;
19
20
use Psr\Http\Message\ResponseInterface;
21
use Psr\Http\Message\ServerRequestInterface;
22
use TYPO3\CMS\Backend\Routing\UriBuilder;
23
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
24
use TYPO3\CMS\Backend\Template\ModuleTemplate;
25
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
26
use TYPO3\CMS\Backend\Tree\View\ElementBrowserFolderTreeView;
27
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
28
use TYPO3\CMS\Core\Http\HtmlResponse;
29
use TYPO3\CMS\Core\Http\JsonResponse;
30
use TYPO3\CMS\Core\Imaging\Icon;
31
use TYPO3\CMS\Core\Imaging\IconFactory;
32
use TYPO3\CMS\Core\Localization\LanguageService;
33
use TYPO3\CMS\Core\Page\PageRenderer;
34
use TYPO3\CMS\Core\Utility\GeneralUtility;
35
use TYPO3\CMS\Filelist\FileListFolderTree;
36
use TYPO3\CMS\Recordlist\Tree\View\DummyLinkParameterProvider;
37
38
/**
39
 * Main script class for rendering of the folder tree
40
 * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
41
 */
42
class FileSystemNavigationFrameController
43
{
44
    /**
45
     * Content accumulates in this variable.
46
     *
47
     * @var string
48
     */
49
    protected $content;
50
51
    /**
52
     * @var \TYPO3\CMS\Backend\Tree\View\FolderTreeView
53
     */
54
    protected $foldertree;
55
56
    /**
57
     * @var string
58
     */
59
    protected $currentSubScript;
60
61
    /**
62
     * @var array
63
     */
64
    protected $scopeData;
65
66
    /**
67
     * ModuleTemplate Container
68
     *
69
     * @var ModuleTemplate
70
     */
71
    protected $moduleTemplate;
72
73
    protected IconFactory $iconFactory;
74
    protected PageRenderer $pageRenderer;
75
    protected UriBuilder $uriBuilder;
76
    protected ModuleTemplateFactory $moduleTemplateFactory;
77
78
    public function __construct(
79
        IconFactory $iconFactory,
80
        PageRenderer $pageRenderer,
81
        UriBuilder $uriBuilder,
82
        ModuleTemplateFactory $moduleTemplateFactory
83
    ) {
84
        $this->iconFactory = $iconFactory;
85
        $this->pageRenderer = $pageRenderer;
86
        $this->uriBuilder = $uriBuilder;
87
        $this->moduleTemplateFactory = $moduleTemplateFactory;
88
    }
89
90
    /**
91
     * @param ServerRequestInterface $request the current request
92
     * @return ResponseInterface the response with the content
93
     */
94
    public function mainAction(ServerRequestInterface $request): ResponseInterface
95
    {
96
        $this->init($request);
97
        $this->initializePageTemplate();
98
        $this->renderFolderTree($request);
99
        return new HtmlResponse($this->content);
100
    }
101
102
    /**
103
     * Makes the AJAX call to expand or collapse the foldertree.
104
     * Called by an AJAX Route, see AjaxRequestHandler
105
     *
106
     * @param ServerRequestInterface $request
107
     * @return ResponseInterface
108
     */
109
    public function ajaxExpandCollapse(ServerRequestInterface $request): ResponseInterface
110
    {
111
        $this->init($request);
112
        $tree = $this->foldertree->getBrowsableTree();
113
        if ($this->foldertree->getAjaxStatus() === false) {
114
            return new JsonResponse(null, 500);
115
        }
116
        return new JsonResponse([$tree]);
117
    }
118
119
    /**
120
     * Initialization of the script class
121
     *
122
     * @param ServerRequestInterface $request the current request
123
     */
124
    protected function init(ServerRequestInterface $request)
125
    {
126
        $this->moduleTemplate = $this->moduleTemplateFactory->create($request);
127
128
        $parsedBody = $request->getParsedBody();
129
        $queryParams = $request->getQueryParams();
130
131
        $this->currentSubScript = $parsedBody['currentSubScript'] ?? $queryParams['currentSubScript'] ?? null;
132
        $scopeData = $parsedBody['scopeData'] ?? $queryParams['scopeData'] ?? '';
133
        $scopeHash = $parsedBody['scopeHash'] ?? $queryParams['scopeHash'] ?? '';
134
135
        if (!empty($scopeData) && hash_equals(GeneralUtility::hmac($scopeData), $scopeHash)) {
136
            $this->scopeData = json_decode($scopeData, true);
137
        }
138
139
        // Create folder tree object:
140
        if (!empty($this->scopeData)) {
141
            $this->foldertree = GeneralUtility::makeInstance($this->scopeData['class']);
142
            $this->foldertree->thisScript = $this->scopeData['script'];
143
            if ($this->foldertree instanceof ElementBrowserFolderTreeView) {
144
                // create a fake provider to pass link data along properly
145
                $linkParamProvider = GeneralUtility::makeInstance(
146
                    DummyLinkParameterProvider::class,
147
                    $this->scopeData['browser'],
148
                    $this->scopeData['script']
149
                );
150
                $this->foldertree->setLinkParameterProvider($linkParamProvider);
151
            }
152
        } else {
153
            $this->foldertree = GeneralUtility::makeInstance(FileListFolderTree::class);
154
            $this->foldertree->thisScript = (string)$this->uriBuilder->buildUriFromRoute('file_navframe');
155
        }
156
    }
157
158
    /**
159
     * Initialization for the visual parts of the class
160
     * Use template rendering only if this is a non-AJAX call
161
     */
162
    protected function initializePageTemplate(): void
163
    {
164
        $this->moduleTemplate->setBodyTag('<body id="ext-backend-Modules-FileSystemNavigationFrame-index-php">');
165
166
        // Adding javascript code for drag&drop and the file tree as well as the click menu code
167
        $hlClass = $this->getBackendUser()->workspace === 0 ? 'active' : 'active active-ws wsver' . $GLOBALS['BE_USER']->workspace;
168
        $dragDropCode = '
169
            Tree.highlightClass = "' . $hlClass . '";
170
            Tree.highlightActiveItem("", top.fsMod.navFrameHighlightedID["file"]);
171
        ';
172
173
        // Adding javascript for drag & drop activation and highlighting
174
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
175
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/BroadcastService', 'function(service) { service.listen(); }');
176
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LegacyTree', 'function() {
177
            DragDrop.table = "folders";
178
            Tree.registerDragDropHandlers();
179
            ' . $dragDropCode . '
180
        }');
181
182
        // Setting JavaScript for menu.
183
        $inlineJs = ($this->currentSubScript ? 'top.currentSubScript=unescape("' . rawurlencode($this->currentSubScript) . '");' : '') . '
184
        // Function, loading the list frame from navigation tree:
185
        function jumpTo(id, linkObj, highlightID, bank) {
186
            var theUrl = top.currentSubScript;
187
            if (theUrl.indexOf("?") != -1) {
188
                theUrl += "&id=" + id
189
            } else {
190
                theUrl += "?id=" + id
191
            }
192
            top.fsMod.currentBank = bank;
193
            top.TYPO3.Backend.ContentContainer.setUrl(theUrl);
194
195
            Tree.highlightActiveItem("file", highlightID + "_" + bank);
196
            if (linkObj) { linkObj.blur(); }
197
            return false;
198
        }
199
        ';
200
201
        $this->pageRenderer->addJsInlineCode('FileSystemNavigationFrame', $inlineJs);
202
    }
203
204
    /**
205
     * Main function, rendering the folder tree
206
     *
207
     * @param ServerRequestInterface $request
208
     */
209
    protected function renderFolderTree(ServerRequestInterface $request): void
210
    {
211
        // Produce browse-tree:
212
        $tree = $this->foldertree->getBrowsableTree();
213
        // Outputting page tree:
214
        $this->moduleTemplate->setContent($tree);
215
        // Setting up the buttons
216
        $this->getButtons($request);
217
        // Build the <body> for the module
218
        $this->moduleTemplate->setTitle('TYPO3 Folder Tree');
219
        $this->content = $this->moduleTemplate->renderContent();
220
    }
221
222
    /**
223
     * Register docHeader buttons
224
     *
225
     * @param ServerRequestInterface $request
226
     */
227
    protected function getButtons(ServerRequestInterface $request): void
228
    {
229
        /** @var ButtonBar $buttonBar */
230
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
231
        /** @var \TYPO3\CMS\Core\Http\NormalizedParams */
232
        $normalizedParams = $request->getAttribute('normalizedParams');
233
234
        // Refresh
235
        $refreshButton = $buttonBar->makeLinkButton()
236
            ->setHref($normalizedParams->getRequestUri())
237
            ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.reload'))
238
            ->setIcon($this->iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
239
        $buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);
240
241
        // CSH
242
        $cshButton = $buttonBar->makeHelpButton()
243
            ->setModuleName('xMOD_csh_corebe')
244
            ->setFieldName('filetree');
245
        $buttonBar->addButton($cshButton);
246
    }
247
248
    /**
249
     * @return BackendUserAuthentication
250
     */
251
    protected function getBackendUser(): BackendUserAuthentication
252
    {
253
        return $GLOBALS['BE_USER'];
254
    }
255
256
    /**
257
     * Returns an instance of LanguageService
258
     *
259
     * @return LanguageService
260
     */
261
    protected function getLanguageService(): LanguageService
262
    {
263
        return $GLOBALS['LANG'];
264
    }
265
}
266