d38aabbf589c11c17658e7e9aaee77638794e2d2
[Packages/TYPO3.CMS.git] / typo3 / sysext / filelist / Classes / Controller / FileListController.php
1 <?php
2 namespace TYPO3\CMS\Filelist\Controller;
3
4 /**
5 * Script Class for creating the list of files in the File > Filelist module
6 *
7 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
8 * @package TYPO3
9 * @subpackage core
10 */
11 class FileListController {
12
13 // Module configuration
14 /**
15 * @todo Define visibility
16 */
17 public $MCONF = array();
18
19 /**
20 * @todo Define visibility
21 */
22 public $MOD_MENU = array();
23
24 /**
25 * @todo Define visibility
26 */
27 public $MOD_SETTINGS = array();
28
29 // Internal:
30 // Accumulated HTML output
31 /**
32 * @todo Define visibility
33 */
34 public $content;
35
36 /**
37 * Document template object
38 *
39 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
40 * @todo Define visibility
41 */
42 public $doc;
43
44 // Internal, static: GPvars:
45 // "id" -> the path to list.
46 /**
47 * @todo Define visibility
48 */
49 public $id;
50
51 /* @var \TYPO3\CMS\Core\Resource\Folder $folderObject */
52 protected $folderObject;
53
54 /* @var \TYPO3\CMS\Core\Messaging\FlashMessage $errorMessage */
55 protected $errorMessage;
56
57 // Pointer to listing
58 /**
59 * @todo Define visibility
60 */
61 public $pointer;
62
63 // "Table"
64 /**
65 * @todo Define visibility
66 */
67 public $table;
68
69 // Thumbnail mode.
70 /**
71 * @todo Define visibility
72 */
73 public $imagemode;
74
75 /**
76 * @todo Define visibility
77 */
78 public $cmd;
79
80 /**
81 * @todo Define visibility
82 */
83 public $overwriteExistingFiles;
84
85 /**
86 * Initialize variables, file object
87 * Incoming GET vars include id, pointer, table, imagemode
88 *
89 * @return void
90 * @todo Define visibility
91 */
92 public function init() {
93 // Setting GPvars:
94 $this->id = ($combinedIdentifier = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'));
95 $this->pointer = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('pointer');
96 $this->table = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('table');
97 $this->imagemode = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('imagemode');
98 $this->cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cmd');
99 $this->overwriteExistingFiles = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('overwriteExistingFiles');
100 // Setting module name:
101 $this->MCONF = $GLOBALS['MCONF'];
102 // Create the folder object, even try parent folders
103 while ($this->folderObject === NULL && count(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('/', $combinedIdentifier, TRUE)) >= 1) {
104 try {
105 if ($combinedIdentifier) {
106 $fileFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
107 $this->folderObject = $fileFactory->getFolderObjectFromCombinedIdentifier($combinedIdentifier);
108 // Disallow the rendering of the processing folder (e.g. could be called manually)
109 // and all folders without any defined storage
110 if ($this->folderObject && ($this->folderObject->getStorage()->getUid() == 0 || trim($this->folderObject->getStorage()->getProcessingFolder()->getIdentifier(), '/') == trim($this->folderObject->getIdentifier(), '/'))) {
111 $this->folderObject = NULL;
112 }
113 } else {
114 // Take the first object of the first storage
115 $fileStorages = $GLOBALS['BE_USER']->getFileStorages();
116 $fileStorage = reset($fileStorages);
117 if ($fileStorage) {
118 // Validating the input "id" (the path, directory!) and
119 // checking it against the mounts of the user. - now done in the controller
120 $this->folderObject = $fileStorage->getRootLevelFolder();
121 } else {
122 $this->folderObject = NULL;
123 }
124 }
125 } catch (\TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException $fileException) {
126 // Set folder object to null and throw a message later on
127 $this->folderObject = NULL;
128 if ($this->id == $combinedIdentifier) {
129 $this->errorMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
130 sprintf($GLOBALS['LANG']->getLL('folderNotFoundMessage', TRUE),
131 htmlspecialchars($this->id)
132 ),
133 $GLOBALS['LANG']->getLL('folderNotFoundTitle', TRUE),
134 \TYPO3\CMS\Core\Messaging\FlashMessage::NOTICE);
135 }
136
137 $combinedIdentifierParts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('/', $combinedIdentifier, TRUE);
138 array_pop($combinedIdentifierParts);
139 $combinedIdentifier = implode('/', $combinedIdentifierParts) . '/';
140 }
141 }
142 // Configure the "menu" - which is used internally to save the values of sorting, displayThumbs etc.
143 $this->menuConfig();
144 }
145
146 /**
147 * Setting the menu/session variables
148 *
149 * @return void
150 * @todo Define visibility
151 */
152 public function menuConfig() {
153 // MENU-ITEMS:
154 // If array, then it's a selector box menu
155 // If empty string it's just a variable, that'll be saved.
156 // Values NOT in this array will not be saved in the settings-array for the module.
157 $this->MOD_MENU = array(
158 'sort' => '',
159 'reverse' => '',
160 'displayThumbs' => '',
161 'clipBoard' => '',
162 'bigControlPanel' => ''
163 );
164 // CLEANSE SETTINGS
165 $this->MOD_SETTINGS = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData($this->MOD_MENU, \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('SET'), $this->MCONF['name']);
166 }
167
168 /**
169 * Main function, creating the listing
170 *
171 * @return void
172 * @todo Define visibility
173 */
174 public function main() {
175 // Initialize the template object
176 $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
177 $this->doc->backPath = $GLOBALS['BACK_PATH'];
178 $this->doc->setModuleTemplate('templates/file_list.html');
179 $this->doc->getPageRenderer()->loadPrototype();
180 // There there was access to this file path, continue, make the list
181 if ($this->folderObject) {
182 // Include the initialization for the flash uploader
183 if ($GLOBALS['BE_USER']->uc['enableFlashUploader']) {
184 $this->doc->JScodeArray['flashUploader'] = '
185 if (top.TYPO3.FileUploadWindow.isFlashAvailable()) {
186 document.observe("dom:loaded", function() {
187 // monitor the button
188 $("button-upload").observe("click", initFlashUploader);
189
190 function initFlashUploader(event) {
191 // set the page specific options for the flashUploader
192 var flashUploadOptions = {
193 uploadURL: top.TS.PATH_typo3 + "ajax.php",
194 uploadFileSizeLimit: "' . \TYPO3\CMS\Core\Utility\GeneralUtility::getMaxUploadFileSize() . '",
195 uploadFileTypes: {
196 allow: "' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']['webspace']['allow'] . '",
197 deny: "' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']['webspace']['deny'] . '"
198 },
199 uploadFilePostName: "upload_1",
200 uploadPostParams: {
201 "file[upload][1][target]": "' . ($this->folderObject ? $this->folderObject->getCombinedIdentifier() : '') . '",
202 "file[upload][1][data]": 1,
203 "file[upload][1][charset]": "utf-8",
204 "ajaxID": "TYPO3\\CMS\\Backend\\Controller\\File\\FileController::process"
205 }
206 };
207
208 // get the flashUploaderWindow instance from the parent frame
209 var flashUploader = top.TYPO3.FileUploadWindow.getInstance(flashUploadOptions);
210 // add an additional function inside the container to show the checkbox option
211 var infoComponent = new top.Ext.Panel({
212 autoEl: { tag: "div" },
213 height: "auto",
214 bodyBorder: false,
215 border: false,
216 hideBorders: true,
217 cls: "t3-upload-window-infopanel",
218 id: "t3-upload-window-infopanel-addition",
219 html: \'<label for="overrideExistingFilesCheckbox"><input id="overrideExistingFilesCheckbox" type="checkbox" onclick="setFlashPostOptionOverwriteExistingFiles(this);" />\' + top.String.format(top.TYPO3.LLL.fileUpload.infoComponentOverrideFiles) + \'</label>\'
220 });
221 flashUploader.add(infoComponent);
222
223 // do a reload of this frame once all uploads are done
224 flashUploader.on("totalcomplete", function() {
225 window.location.reload();
226 });
227
228 // this is the callback function that delivers the additional post parameter to the flash application
229 top.setFlashPostOptionOverwriteExistingFiles = function(checkbox) {
230 var uploader = top.TYPO3.getInstance("FileUploadWindow");
231 if (uploader.isVisible()) {
232 uploader.swf.addPostParam("overwriteExistingFiles", (checkbox.checked == true ? 1 : 0));
233 }
234 };
235
236 event.stop();
237 };
238 });
239 }
240 ';
241 }
242 // Create filelisting object
243 $this->filelist = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Filelist\\FileList');
244 $this->filelist->backPath = $GLOBALS['BACK_PATH'];
245 // Apply predefined values for hidden checkboxes
246 // Set predefined value for DisplayBigControlPanel:
247 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'activated') {
248 $this->MOD_SETTINGS['bigControlPanel'] = TRUE;
249 } elseif ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'deactivated') {
250 $this->MOD_SETTINGS['bigControlPanel'] = FALSE;
251 }
252 // Set predefined value for DisplayThumbnails:
253 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'activated') {
254 $this->MOD_SETTINGS['displayThumbs'] = TRUE;
255 } elseif ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'deactivated') {
256 $this->MOD_SETTINGS['displayThumbs'] = FALSE;
257 }
258 // Set predefined value for Clipboard:
259 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableClipBoard') === 'activated') {
260 $this->MOD_SETTINGS['clipBoard'] = TRUE;
261 } elseif ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableClipBoard') === 'deactivated') {
262 $this->MOD_SETTINGS['clipBoard'] = FALSE;
263 }
264 // If user never opened the list module, set the value for displayThumbs
265 if (!isset($this->MOD_SETTINGS['displayThumbs'])) {
266 $this->MOD_SETTINGS['displayThumbs'] = $GLOBALS['BE_USER']->uc['thumbnailsByDefault'];
267 }
268 $this->filelist->thumbs = $this->MOD_SETTINGS['displayThumbs'];
269 // Create clipboard object and initialize that
270 $this->filelist->clipObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Clipboard\\Clipboard');
271 $this->filelist->clipObj->fileMode = 1;
272 $this->filelist->clipObj->initializeClipboard();
273 $CB = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('CB');
274 if ($this->cmd == 'setCB') {
275 $CB['el'] = $this->filelist->clipObj->cleanUpCBC(array_merge(\TYPO3\CMS\Core\Utility\GeneralUtility::_POST('CBH'), \TYPO3\CMS\Core\Utility\GeneralUtility::_POST('CBC')), '_FILE');
276 }
277 if (!$this->MOD_SETTINGS['clipBoard']) {
278 $CB['setP'] = 'normal';
279 }
280 $this->filelist->clipObj->setCmd($CB);
281 $this->filelist->clipObj->cleanCurrent();
282 // Saves
283 $this->filelist->clipObj->endClipboard();
284 // If the "cmd" was to delete files from the list (clipboard thing), do that:
285 if ($this->cmd == 'delete') {
286 $items = $this->filelist->clipObj->cleanUpCBC(\TYPO3\CMS\Core\Utility\GeneralUtility::_POST('CBC'), '_FILE', 1);
287 if (count($items)) {
288 // Make command array:
289 $FILE = array();
290 foreach ($items as $v) {
291 $FILE['delete'][] = array('data' => $v);
292 }
293 // Init file processing object for deleting and pass the cmd array.
294 $fileProcessor = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Utility\\File\\ExtendedFileUtility');
295 $fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
296 $fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
297 $fileProcessor->dontCheckForUnique = $this->overwriteExistingFiles ? 1 : 0;
298 $fileProcessor->start($FILE);
299 $fileProcessor->processData();
300 $fileProcessor->printLogErrorMessages();
301 }
302 }
303 if (!isset($this->MOD_SETTINGS['sort'])) {
304 // Set default sorting
305 $this->MOD_SETTINGS['sort'] = 'file';
306 $this->MOD_SETTINGS['reverse'] = 0;
307 }
308 // Start up filelisting object, include settings.
309 $this->pointer = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->pointer, 0, 100000);
310 $this->filelist->start($this->folderObject, $this->pointer, $this->MOD_SETTINGS['sort'], $this->MOD_SETTINGS['reverse'], $this->MOD_SETTINGS['clipBoard'], $this->MOD_SETTINGS['bigControlPanel']);
311 // Generate the list
312 $this->filelist->generateList();
313 // Write the footer
314 $this->filelist->writeBottom();
315 // Set top JavaScript:
316 $this->doc->JScode = $this->doc->wrapScriptTags('
317
318 if (top.fsMod) top.fsMod.recentIds["file"] = unescape("' . rawurlencode($this->id) . '");
319 function jumpToUrl(URL) { //
320 window.location.href = URL;
321 }
322
323 ' . $this->filelist->CBfunctions());
324 // This will return content necessary for the context sensitive clickmenus to work: bodytag events, JavaScript functions and DIV-layers.
325 $this->doc->getContextMenuCode();
326 // Setting up the buttons and markers for docheader
327 list($buttons, $otherMarkers) = $this->filelist->getButtonsAndOtherMarkers($this->folderObject);
328 // add the folder info to the marker array
329 $otherMarkers['FOLDER_INFO'] = $this->filelist->getFolderInfo();
330 $docHeaderButtons = array_merge($this->getButtons(), $buttons);
331 // Build the <body> for the module
332 // Create output
333 $pageContent = '';
334 $pageContent .= '<form action="' . htmlspecialchars($this->filelist->listURL()) . '" method="post" name="dblistForm">';
335 $pageContent .= $this->filelist->HTMLcode;
336 $pageContent .= '<input type="hidden" name="cmd" /></form>';
337 // Making listing options:
338 if ($this->filelist->HTMLcode) {
339 $pageContent .= '
340
341 <!--
342 Listing options for extended view, clipboard and thumbnails
343 -->
344 <div id="typo3-listOptions">
345 ';
346 // Add "display bigControlPanel" checkbox:
347 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'selectable') {
348 $pageContent .= \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncCheck($this->id, 'SET[bigControlPanel]', $this->MOD_SETTINGS['bigControlPanel'], '', '', 'id="bigControlPanel"') . '<label for="bigControlPanel"> ' . $GLOBALS['LANG']->getLL('bigControlPanel', TRUE) . '</label><br />';
349 }
350 // Add "display thumbnails" checkbox:
351 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'selectable') {
352 $pageContent .= \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncCheck($this->id, 'SET[displayThumbs]', $this->MOD_SETTINGS['displayThumbs'], '', '', 'id="checkDisplayThumbs"') . ' <label for="checkDisplayThumbs">' . $GLOBALS['LANG']->getLL('displayThumbs', TRUE) . '</label><br />';
353 }
354 // Add "clipboard" checkbox:
355 if ($GLOBALS['BE_USER']->getTSConfigVal('options.file_list.enableClipBoard') === 'selectable') {
356 $pageContent .= \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncCheck($this->id, 'SET[clipBoard]', $this->MOD_SETTINGS['clipBoard'], '', '', 'id="checkClipBoard"') . ' <label for="checkClipBoard">' . $GLOBALS['LANG']->getLL('clipBoard', TRUE) . '</label>';
357 }
358 $pageContent .= '
359 </div>
360 ';
361 // Set clipboard:
362 if ($this->MOD_SETTINGS['clipBoard']) {
363 $pageContent .= $this->filelist->clipObj->printClipboard();
364 $pageContent .= \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem('xMOD_csh_corebe', 'filelist_clipboard', $GLOBALS['BACK_PATH']);
365 }
366 }
367 $markerArray = array(
368 'CSH' => $docHeaderButtons['csh'],
369 'FUNC_MENU' => \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncMenu($this->id, 'SET[function]', $this->MOD_SETTINGS['function'], $this->MOD_MENU['function']),
370 'CONTENT' => ($this->errorMessage ? $this->errorMessage->render() : '') . $pageContent
371 );
372 $this->content = $this->doc->moduleBody(array(), $docHeaderButtons, array_merge($markerArray, $otherMarkers));
373 // Renders the module page
374 $this->content = $this->doc->render($GLOBALS['LANG']->getLL('files'), $this->content);
375 } else {
376 $content = '';
377 if ($this->errorMessage) {
378 $this->errorMessage->setSeverity(\TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
379 $content = $this->doc->moduleBody(array(), array_merge(array('LEVEL_UP' => '', 'REFRESH' => ''), $this->getButtons()), array('CSH' => '', 'TITLE' => '', 'FOLDER_INFO' => '', 'PAGE_ICON' => '', 'FUNC_MENU' => '', 'CONTENT' => $this->errorMessage->render()));
380 }
381 // Create output - no access (no warning though)
382 $this->content = $this->doc->render($GLOBALS['LANG']->getLL('files'), $content);
383 }
384 }
385
386 /**
387 * Outputting the accumulated content to screen
388 *
389 * @return void
390 * @todo Define visibility
391 */
392 public function printContent() {
393 echo $this->content;
394 }
395
396 /**
397 * Create the panel of buttons for submitting the form or otherwise perform operations.
398 *
399 * @return array All available buttons as an assoc. array
400 * @todo Define visibility
401 */
402 public function getButtons() {
403 $buttons = array(
404 'csh' => '',
405 'shortcut' => '',
406 'upload' => '',
407 'new' => ''
408 );
409 // Add shortcut
410 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
411 $buttons['shortcut'] = $this->doc->makeShortcutIcon('pointer,id,target,table', implode(',', array_keys($this->MOD_MENU)), $this->MCONF['name']);
412 }
413 // FileList Module CSH:
414 $buttons['csh'] = \TYPO3\CMS\Backend\Utility\BackendUtility::cshItem('xMOD_csh_corebe', 'filelist_module', $GLOBALS['BACK_PATH'], '', TRUE);
415 // Upload button (only if upload to this directory is allowed)
416 if ($this->folderObject && $this->folderObject->getStorage()->checkUserActionPermission('upload', 'File') && $this->folderObject->checkActionPermission('write')) {
417 $buttons['upload'] = '<a href="' . $GLOBALS['BACK_PATH'] . 'file_upload.php?target=' . rawurlencode($this->folderObject->getCombinedIdentifier()) . '&amp;returnUrl=' . rawurlencode($this->filelist->listURL()) . '" id="button-upload" title="' . $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.upload', 1)) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-upload') . '</a>';
418 }
419 // New folder button
420 if ($this->folderObject && $this->folderObject->checkActionPermission('add')) {
421 $buttons['new'] = '<a href="' . $GLOBALS['BACK_PATH'] . 'file_newfolder.php?target=' . rawurlencode($this->folderObject->getCombinedIdentifier()) . '&amp;returnUrl=' . rawurlencode($this->filelist->listURL()) . '" title="' . $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:cm.new', 1)) . '">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-new') . '</a>';
422 }
423 return $buttons;
424 }
425
426 }
427
428
429 ?>