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