[TASK] Drop remaining getIndpEnv() in FileSystemNavigationFrameController
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / FileSystemNavigationFrameController.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Backend\Controller;
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 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use TYPO3\CMS\Backend\Routing\UriBuilder;
21 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
22 use TYPO3\CMS\Backend\Template\ModuleTemplate;
23 use TYPO3\CMS\Backend\Tree\View\ElementBrowserFolderTreeView;
24 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25 use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
26 use TYPO3\CMS\Core\Http\HtmlResponse;
27 use TYPO3\CMS\Core\Http\JsonResponse;
28 use TYPO3\CMS\Core\Imaging\Icon;
29 use TYPO3\CMS\Core\Imaging\IconFactory;
30 use TYPO3\CMS\Core\Localization\LanguageService;
31 use TYPO3\CMS\Core\Utility\GeneralUtility;
32 use TYPO3\CMS\Filelist\FileListFolderTree;
33 use TYPO3\CMS\Recordlist\Tree\View\DummyLinkParameterProvider;
34
35 /**
36 * Main script class for rendering of the folder tree
37 */
38 class FileSystemNavigationFrameController
39 {
40 use PublicPropertyDeprecationTrait;
41
42 /**
43 * Properties which have been moved to protected status from public
44 *
45 * @var array
46 */
47 protected $deprecatedPublicProperties = [
48 'content' => 'Using $content of class FileSystemNavigationFrameController from the outside is discouraged, as this variable is only used for internal storage.',
49 'foldertree' => 'Using $foldertree of class FileSystemNavigationFrameController from the outside is discouraged, as this variable is only used for internal storage.',
50 'currentSubScript' => 'Using $currentSubScript of class FileSystemNavigationFrameController from the outside is discouraged, as this variable is only used for internal storage.',
51 'cMR' => 'Using $cMR of class FileSystemNavigationFrameController from the outside is discouraged, as this variable is only used for internal storage.',
52 ];
53
54 /**
55 * Content accumulates in this variable.
56 *
57 * @var string
58 */
59 protected $content;
60
61 /**
62 * @var \TYPO3\CMS\Backend\Tree\View\FolderTreeView
63 */
64 protected $foldertree;
65
66 /**
67 * @var string
68 */
69 protected $currentSubScript;
70
71 /**
72 * @var bool
73 */
74 protected $cMR;
75
76 /**
77 * @var array
78 */
79 protected $scopeData;
80
81 /**
82 * ModuleTemplate Container
83 *
84 * @var ModuleTemplate
85 */
86 protected $moduleTemplate;
87
88 /**
89 * Constructor
90 */
91 public function __construct()
92 {
93 // @deprecated since v9, will be obsolete in v10 with removal of init()
94 $request = $GLOBALS['TYPO3_REQUEST'];
95 $GLOBALS['SOBE'] = $this;
96 // @deprecated since v9, will be moved out of __construct() in v10
97 $this->init($request);
98 }
99
100 /**
101 * @param ServerRequestInterface $request the current request
102 * @return ResponseInterface the response with the content
103 */
104 public function mainAction(ServerRequestInterface $request): ResponseInterface
105 {
106 $this->initializePageTemplate();
107 $this->renderFolderTree($request);
108 return new HtmlResponse($this->content);
109 }
110
111 /**
112 * Makes the AJAX call to expand or collapse the foldertree.
113 * Called by an AJAX Route, see AjaxRequestHandler
114 *
115 * @param ServerRequestInterface $request
116 * @return ResponseInterface
117 */
118 public function ajaxExpandCollapse(ServerRequestInterface $request): ResponseInterface
119 {
120 $tree = $this->foldertree->getBrowsableTree();
121 if ($this->foldertree->getAjaxStatus() === false) {
122 return new JsonResponse(null, 500);
123 }
124 return new JsonResponse([$tree]);
125 }
126
127 /**
128 * Initialization of the script class
129 *
130 * @param ServerRequestInterface $request the current request
131 */
132 protected function init(ServerRequestInterface $request = null)
133 {
134 if ($request === null) {
135 // Method signature in v10: protected function init(ServerRequestInterface $request)
136 trigger_error('Method init() will be set to protected in v10. Do not call from other extension', E_USER_DEPRECATED);
137 $request = $GLOBALS['TYPO3_REQUEST'];
138 }
139
140 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
141
142 $parsedBody = $request->getParsedBody();
143 $queryParams = $request->getQueryParams();
144
145 $this->currentSubScript = $parsedBody['currentSubScript'] ?? $queryParams['currentSubScript'] ?? null;
146 $this->cMR = (bool)($parsedBody['cMR'] ?? $queryParams['cMR'] ?? false);
147 $scopeData = $parsedBody['scopeData'] ?? $queryParams['scopeData'] ?? '';
148 $scopeHash = $parsedBody['scopeHash'] ?? $queryParams['scopeHash'] ?? '';
149
150 if (!empty($scopeData) && hash_equals(GeneralUtility::hmac($scopeData), $scopeHash)) {
151 $this->scopeData = unserialize($scopeData);
152 }
153
154 // Create folder tree object:
155 if (!empty($this->scopeData)) {
156 $this->foldertree = GeneralUtility::makeInstance($this->scopeData['class']);
157 $this->foldertree->thisScript = $this->scopeData['script'];
158 if ($this->foldertree instanceof ElementBrowserFolderTreeView) {
159 // create a fake provider to pass link data along properly
160 $linkParamProvider = GeneralUtility::makeInstance(
161 DummyLinkParameterProvider::class,
162 $this->scopeData['browser'],
163 $this->scopeData['script']
164 );
165 $this->foldertree->setLinkParameterProvider($linkParamProvider);
166 }
167 } else {
168 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
169 $this->foldertree = GeneralUtility::makeInstance(FileListFolderTree::class);
170 $this->foldertree->thisScript = (string)$uriBuilder->buildUriFromRoute('file_navframe');
171 }
172 }
173
174 /**
175 * initialization for the visual parts of the class
176 * Use template rendering only if this is a non-AJAX call
177 *
178 * @deprecated since v9, will be removed in v10
179 */
180 public function initPage()
181 {
182 trigger_error('Method initPage() will be replaced by protected method initializePageTemplate() in v10. Do not call from other extension', E_USER_DEPRECATED);
183 $this->initializePageTemplate();
184 }
185
186 /**
187 * Initialization for the visual parts of the class
188 * Use template rendering only if this is a non-AJAX call
189 */
190 protected function initializePageTemplate(): void
191 {
192 $this->moduleTemplate->setBodyTag('<body id="ext-backend-Modules-FileSystemNavigationFrame-index-php">');
193
194 // Adding javascript code for drag&drop and the file tree as well as the click menu code
195 $hlClass = $this->getBackendUser()->workspace === 0 ? 'active' : 'active active-ws wsver' . $GLOBALS['BE_USER']->workspace;
196 $dragDropCode = '
197 Tree.highlightClass = "' . $hlClass . '";
198 Tree.highlightActiveItem("", top.fsMod.navFrameHighlightedID["file"]);
199 ';
200
201 // Adding javascript for drag & drop activation and highlighting
202 $pageRenderer = $this->moduleTemplate->getPageRenderer();
203 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
204 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LegacyTree', 'function() {
205 DragDrop.table = "folders";
206 Tree.registerDragDropHandlers();
207 ' . $dragDropCode . '
208 }');
209
210 // Setting JavaScript for menu.
211 $inlineJs = ($this->currentSubScript ? 'top.currentSubScript=unescape("' . rawurlencode($this->currentSubScript) . '");' : '') . '
212 // Function, loading the list frame from navigation tree:
213 function jumpTo(id, linkObj, highlightID, bank) {
214 var theUrl = top.currentSubScript;
215 if (theUrl.indexOf("?") != -1) {
216 theUrl += "&id=" + id
217 } else {
218 theUrl += "?id=" + id
219 }
220 top.fsMod.currentBank = bank;
221 top.TYPO3.Backend.ContentContainer.setUrl(theUrl);
222
223 Tree.highlightActiveItem("file", highlightID + "_" + bank);
224 if (linkObj) { linkObj.blur(); }
225 return false;
226 }
227 ' . ($this->cMR ? ' jumpTo(top.fsMod.recentIds[\'file\'],\'\');' : '');
228
229 $this->moduleTemplate->getPageRenderer()->addJsInlineCode(
230 'FileSystemNavigationFrame',
231 $inlineJs
232 );
233 }
234
235 /**
236 * Main function, rendering the folder tree
237 *
238 * @deprecated since v9, will be removed in v10
239 */
240 public function main()
241 {
242 trigger_error('Method main() will be replaced by protected method renderFolderTree() in v10. Do not call from other extension', E_USER_DEPRECATED);
243 $this->renderFolderTree($GLOBALS['TYPO3_REQUEST']);
244 }
245
246 /**
247 * Main function, rendering the folder tree
248 *
249 * @param ServerRequestInterface $request
250 */
251 protected function renderFolderTree(ServerRequestInterface $request): void
252 {
253 // Produce browse-tree:
254 $tree = $this->foldertree->getBrowsableTree();
255 // Outputting page tree:
256 $this->moduleTemplate->setContent($tree);
257 // Setting up the buttons
258 $this->getButtons($request);
259 // Build the <body> for the module
260 $this->moduleTemplate->setTitle('TYPO3 Folder Tree');
261 $this->content = $this->moduleTemplate->renderContent();
262 }
263
264 /**
265 * Register docHeader buttons
266 *
267 * @param ServerRequestInterface $request
268 */
269 protected function getButtons(ServerRequestInterface $request): void
270 {
271 /** @var ButtonBar $buttonBar */
272 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
273 /** @var IconFactory $iconFactory */
274 $iconFactory = $this->moduleTemplate->getIconFactory();
275 /** @var \TYPO3\CMS\Core\Http\NormalizedParams */
276 $normalizedParams = $request->getAttribute('normalizedParams');
277
278 // Refresh
279 $refreshButton = $buttonBar->makeLinkButton()
280 ->setHref($normalizedParams->getRequestUri())
281 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.reload'))
282 ->setIcon($iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
283 $buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);
284
285 // CSH
286 $cshButton = $buttonBar->makeHelpButton()
287 ->setModuleName('xMOD_csh_corebe')
288 ->setFieldName('filetree');
289 $buttonBar->addButton($cshButton);
290 }
291
292 /**
293 * @return BackendUserAuthentication
294 */
295 protected function getBackendUser(): BackendUserAuthentication
296 {
297 return $GLOBALS['BE_USER'];
298 }
299
300 /**
301 * Returns an instance of LanguageService
302 *
303 * @return LanguageService
304 */
305 protected function getLanguageService(): LanguageService
306 {
307 return $GLOBALS['LANG'];
308 }
309 }