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