6fd78835526132d6e4dbd3999bd41838a7a10137
[Packages/TYPO3.CMS.git] / typo3 / sysext / filelist / Classes / Controller / FileListController.php
1 <?php
2 namespace TYPO3\CMS\Filelist\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 TYPO3\CMS\Backend\Clipboard\Clipboard;
18 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
19 use TYPO3\CMS\Backend\Template\DocumentTemplate;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
21 use TYPO3\CMS\Backend\View\BackendTemplateView;
22 use TYPO3\CMS\Core\Imaging\Icon;
23 use TYPO3\CMS\Core\Imaging\IconFactory;
24 use TYPO3\CMS\Core\Messaging\FlashMessage;
25 use TYPO3\CMS\Core\Resource\DuplicationBehavior;
26 use TYPO3\CMS\Core\Resource\Exception;
27 use TYPO3\CMS\Core\Resource\Folder;
28 use TYPO3\CMS\Core\Resource\ResourceFactory;
29 use TYPO3\CMS\Core\Resource\Utility\ListUtility;
30 use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
31 use TYPO3\CMS\Core\Utility\File\ExtendedFileUtility;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33 use TYPO3\CMS\Core\Utility\MathUtility;
34 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
35 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
36 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
37 use TYPO3\CMS\Filelist\Configuration\ThumbnailConfiguration;
38 use TYPO3\CMS\Filelist\FileList;
39
40 /**
41 * Script Class for creating the list of files in the File > Filelist module
42 */
43 class FileListController extends ActionController
44 {
45 /**
46 * @var array
47 */
48 public $MOD_MENU = [];
49
50 /**
51 * @var array
52 */
53 public $MOD_SETTINGS = [];
54
55 /**
56 * Document template object
57 *
58 * @var DocumentTemplate
59 */
60 public $doc;
61
62 /**
63 * "id" -> the path to list.
64 *
65 * @var string
66 */
67 public $id;
68
69 /**
70 * @var Folder
71 */
72 protected $folderObject;
73
74 /**
75 * @var FlashMessage
76 */
77 protected $errorMessage;
78
79 /**
80 * Pointer to listing
81 *
82 * @var int
83 */
84 public $pointer;
85
86 /**
87 * "Table"
88 * @var string
89 */
90 public $table;
91
92 /**
93 * Thumbnail mode.
94 *
95 * @var string
96 */
97 public $imagemode;
98
99 /**
100 * @var string
101 */
102 public $cmd;
103
104 /**
105 * Defines behaviour when uploading files with names that already exist; possible values are
106 * the values of the \TYPO3\CMS\Core\Resource\DuplicationBehavior enumeration
107 *
108 * @var \TYPO3\CMS\Core\Resource\DuplicationBehavior
109 */
110 protected $overwriteExistingFiles;
111
112 /**
113 * The filelist object
114 *
115 * @var FileList
116 */
117 public $filelist = null;
118
119 /**
120 * The name of the module
121 *
122 * @var string
123 */
124 protected $moduleName = 'file_list';
125
126 /**
127 * @var \TYPO3\CMS\Core\Resource\FileRepository
128 */
129 protected $fileRepository;
130
131 /**
132 * @var BackendTemplateView
133 */
134 protected $view;
135
136 /**
137 * BackendTemplateView Container
138 *
139 * @var BackendTemplateView
140 */
141 protected $defaultViewObjectName = BackendTemplateView::class;
142
143 /**
144 * @param \TYPO3\CMS\Core\Resource\FileRepository $fileRepository
145 */
146 public function injectFileRepository(\TYPO3\CMS\Core\Resource\FileRepository $fileRepository)
147 {
148 $this->fileRepository = $fileRepository;
149 }
150
151 /**
152 * Initialize variables, file object
153 * Incoming GET vars include id, pointer, table, imagemode
154 *
155 * @throws \RuntimeException
156 * @throws Exception\InsufficientFolderAccessPermissionsException
157 */
158 public function initializeObject()
159 {
160 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
161 $this->getLanguageService()->includeLLFile('EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf');
162 $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_misc.xlf');
163
164 // Setting GPvars:
165 $this->id = ($combinedIdentifier = GeneralUtility::_GP('id'));
166 $this->pointer = GeneralUtility::_GP('pointer');
167 $this->table = GeneralUtility::_GP('table');
168 $this->imagemode = GeneralUtility::_GP('imagemode');
169 $this->cmd = GeneralUtility::_GP('cmd');
170 $this->overwriteExistingFiles = DuplicationBehavior::cast(GeneralUtility::_GP('overwriteExistingFiles'));
171
172 try {
173 if ($combinedIdentifier) {
174 /** @var $resourceFactory ResourceFactory */
175 $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
176 $storage = $resourceFactory->getStorageObjectFromCombinedIdentifier($combinedIdentifier);
177 $identifier = substr($combinedIdentifier, strpos($combinedIdentifier, ':') + 1);
178 if (!$storage->hasFolder($identifier)) {
179 $identifier = $storage->getFolderIdentifierFromFileIdentifier($identifier);
180 }
181
182 $this->folderObject = $resourceFactory->getFolderObjectFromCombinedIdentifier($storage->getUid() . ':' . $identifier);
183 // Disallow access to fallback storage 0
184 if ($storage->getUid() === 0) {
185 throw new Exception\InsufficientFolderAccessPermissionsException(
186 'You are not allowed to access files outside your storages',
187 1434539815
188 );
189 }
190 // Disallow the rendering of the processing folder (e.g. could be called manually)
191 if ($this->folderObject && $storage->isProcessingFolder($this->folderObject)) {
192 $this->folderObject = $storage->getRootLevelFolder();
193 }
194 } else {
195 // Take the first object of the first storage
196 $fileStorages = $this->getBackendUser()->getFileStorages();
197 $fileStorage = reset($fileStorages);
198 if ($fileStorage) {
199 $this->folderObject = $fileStorage->getRootLevelFolder();
200 } else {
201 throw new \RuntimeException('Could not find any folder to be displayed.', 1349276894);
202 }
203 }
204
205 if ($this->folderObject && !$this->folderObject->getStorage()->isWithinFileMountBoundaries($this->folderObject)) {
206 throw new \RuntimeException('Folder not accessible.', 1430409089);
207 }
208 } catch (Exception\InsufficientFolderAccessPermissionsException $permissionException) {
209 $this->folderObject = null;
210 $this->errorMessage = GeneralUtility::makeInstance(
211 FlashMessage::class,
212 sprintf(
213 $this->getLanguageService()->getLL('missingFolderPermissionsMessage'),
214 $this->id
215 ),
216 $this->getLanguageService()->getLL('missingFolderPermissionsTitle'),
217 FlashMessage::NOTICE
218 );
219 } catch (Exception $fileException) {
220 // Set folder object to null and throw a message later on
221 $this->folderObject = null;
222 // Take the first object of the first storage
223 $fileStorages = $this->getBackendUser()->getFileStorages();
224 $fileStorage = reset($fileStorages);
225 if ($fileStorage instanceof \TYPO3\CMS\Core\Resource\ResourceStorage) {
226 $this->folderObject = $fileStorage->getRootLevelFolder();
227 if (!$fileStorage->isWithinFileMountBoundaries($this->folderObject)) {
228 $this->folderObject = null;
229 }
230 }
231 $this->errorMessage = GeneralUtility::makeInstance(
232 FlashMessage::class,
233 sprintf(
234 $this->getLanguageService()->getLL('folderNotFoundMessage'),
235 $this->id
236 ),
237 $this->getLanguageService()->getLL('folderNotFoundTitle'),
238 FlashMessage::NOTICE
239 );
240 } catch (\RuntimeException $e) {
241 $this->folderObject = null;
242 $this->errorMessage = GeneralUtility::makeInstance(
243 FlashMessage::class,
244 $e->getMessage() . ' (' . $e->getCode() . ')',
245 $this->getLanguageService()->getLL('folderNotFoundTitle'),
246 FlashMessage::NOTICE
247 );
248 }
249
250 if ($this->folderObject && !$this->folderObject->getStorage()->checkFolderActionPermission(
251 'read',
252 $this->folderObject
253 )
254 ) {
255 $this->folderObject = null;
256 }
257
258 // Configure the "menu" - which is used internally to save the values of sorting, displayThumbs etc.
259 $this->menuConfig();
260 }
261
262 /**
263 * Setting the menu/session variables
264 */
265 public function menuConfig()
266 {
267 // MENU-ITEMS:
268 // If array, then it's a selector box menu
269 // If empty string it's just a variable, that will be saved.
270 // Values NOT in this array will not be saved in the settings-array for the module.
271 $this->MOD_MENU = [
272 'sort' => '',
273 'reverse' => '',
274 'displayThumbs' => '',
275 'clipBoard' => '',
276 'bigControlPanel' => ''
277 ];
278 // CLEANSE SETTINGS
279 $this->MOD_SETTINGS = BackendUtility::getModuleData(
280 $this->MOD_MENU,
281 GeneralUtility::_GP('SET'),
282 $this->moduleName
283 );
284 }
285
286 /**
287 * Initialize the view
288 *
289 * @param ViewInterface $view The view
290 */
291 public function initializeView(ViewInterface $view)
292 {
293 /** @var BackendTemplateView $view */
294 parent::initializeView($view);
295 $pageRenderer = $this->view->getModuleTemplate()->getPageRenderer();
296 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileListLocalisation');
297 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileSearch');
298 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
299 $this->registerDocHeaderButtons();
300 }
301
302 /**
303 */
304 public function initializeIndexAction()
305 {
306 // Apply predefined values for hidden checkboxes
307 // Set predefined value for DisplayBigControlPanel:
308 $backendUser = $this->getBackendUser();
309 if ($backendUser->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'activated') {
310 $this->MOD_SETTINGS['bigControlPanel'] = true;
311 } elseif ($backendUser->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'deactivated') {
312 $this->MOD_SETTINGS['bigControlPanel'] = false;
313 }
314 // Set predefined value for DisplayThumbnails:
315 if ($backendUser->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'activated') {
316 $this->MOD_SETTINGS['displayThumbs'] = true;
317 } elseif ($backendUser->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'deactivated') {
318 $this->MOD_SETTINGS['displayThumbs'] = false;
319 }
320 // Set predefined value for Clipboard:
321 if ($backendUser->getTSConfigVal('options.file_list.enableClipBoard') === 'activated') {
322 $this->MOD_SETTINGS['clipBoard'] = true;
323 } elseif ($backendUser->getTSConfigVal('options.file_list.enableClipBoard') === 'deactivated') {
324 $this->MOD_SETTINGS['clipBoard'] = false;
325 }
326 // If user never opened the list module, set the value for displayThumbs
327 if (!isset($this->MOD_SETTINGS['displayThumbs'])) {
328 $this->MOD_SETTINGS['displayThumbs'] = $backendUser->uc['thumbnailsByDefault'];
329 }
330 if (!isset($this->MOD_SETTINGS['sort'])) {
331 // Set default sorting
332 $this->MOD_SETTINGS['sort'] = 'file';
333 $this->MOD_SETTINGS['reverse'] = 0;
334 }
335 }
336
337 /**
338 */
339 public function indexAction()
340 {
341 $pageRenderer = $this->view->getModuleTemplate()->getPageRenderer();
342 $pageRenderer->setTitle($this->getLanguageService()->getLL('files'));
343
344 // There there was access to this file path, continue, make the list
345 if ($this->folderObject) {
346 // Create fileListing object
347 $this->filelist = GeneralUtility::makeInstance(FileList::class, $this);
348 $this->filelist->thumbs = $GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] && $this->MOD_SETTINGS['displayThumbs'];
349 // Create clipboard object and initialize that
350 $this->filelist->clipObj = GeneralUtility::makeInstance(Clipboard::class);
351 $this->filelist->clipObj->fileMode = true;
352 $this->filelist->clipObj->initializeClipboard();
353 $CB = GeneralUtility::_GET('CB');
354 if ($this->cmd === 'setCB') {
355 $CB['el'] = $this->filelist->clipObj->cleanUpCBC(array_merge(
356 GeneralUtility::_POST('CBH'),
357 (array)GeneralUtility::_POST('CBC')
358 ), '_FILE');
359 }
360 if (!$this->MOD_SETTINGS['clipBoard']) {
361 $CB['setP'] = 'normal';
362 }
363 $this->filelist->clipObj->setCmd($CB);
364 $this->filelist->clipObj->cleanCurrent();
365 // Saves
366 $this->filelist->clipObj->endClipboard();
367 // If the "cmd" was to delete files from the list (clipboard thing), do that:
368 if ($this->cmd === 'delete') {
369 $items = $this->filelist->clipObj->cleanUpCBC(GeneralUtility::_POST('CBC'), '_FILE', 1);
370 if (!empty($items)) {
371 // Make command array:
372 $FILE = [];
373 foreach ($items as $v) {
374 $FILE['delete'][] = ['data' => $v];
375 }
376 // Init file processing object for deleting and pass the cmd array.
377 /** @var ExtendedFileUtility $fileProcessor */
378 $fileProcessor = GeneralUtility::makeInstance(ExtendedFileUtility::class);
379 $fileProcessor->setActionPermissions();
380 $fileProcessor->setExistingFilesConflictMode($this->overwriteExistingFiles);
381 $fileProcessor->start($FILE);
382 $fileProcessor->processData();
383 }
384 }
385 // Start up filelisting object, include settings.
386 $this->pointer = MathUtility::forceIntegerInRange($this->pointer, 0, 100000);
387 $this->filelist->start(
388 $this->folderObject,
389 $this->pointer,
390 $this->MOD_SETTINGS['sort'],
391 $this->MOD_SETTINGS['reverse'],
392 $this->MOD_SETTINGS['clipBoard'],
393 $this->MOD_SETTINGS['bigControlPanel']
394 );
395 // Generate the list
396 $this->filelist->generateList();
397 // Set top JavaScript:
398 $this->view->getModuleTemplate()->addJavaScriptCode(
399 'FileListIndex',
400 'if (top.fsMod) top.fsMod.recentIds["file"] = "' . rawurlencode($this->id) . '";' . $this->filelist->CBfunctions() . '
401 function jumpToUrl(URL) {
402 window.location.href = URL;
403 return false;
404 }
405 '
406 );
407 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileDelete');
408 $pageRenderer->addInlineLanguageLabelFile('EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf', 'buttons');
409
410 // Include DragUploader only if we have write access
411 if ($this->folderObject->getStorage()->checkUserActionPermission('add', 'File')
412 && $this->folderObject->checkActionPermission('write')
413 ) {
414 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DragUploader');
415 $pageRenderer->addInlineLanguageLabelFile('EXT:lang/Resources/Private/Language/locallang_core.xlf', 'file_upload');
416 $pageRenderer->addInlineLanguageLabelArray([
417 'permissions.read' => $this->getLanguageService()->getLL('read'),
418 'permissions.write' => $this->getLanguageService()->getLL('write'),
419 ]);
420 }
421
422 // Setting up the buttons
423 $this->registerButtons();
424
425 $pageRecord = [
426 '_additional_info' => $this->filelist->getFolderInfo(),
427 'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
428 ];
429 $this->view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation($pageRecord);
430
431 $this->view->assign('headline', $this->getModuleHeadline());
432 $this->view->assign('listHtml', $this->filelist->HTMLcode);
433
434 $this->view->assign('checkboxes', [
435 'bigControlPanel' => [
436 'enabled' => $this->getBackendUser()->getTSConfigVal('options.file_list.enableDisplayBigControlPanel') === 'selectable',
437 'label' => htmlspecialchars($this->getLanguageService()->getLL('bigControlPanel')),
438 'html' => BackendUtility::getFuncCheck(
439 $this->id,
440 'SET[bigControlPanel]',
441 $this->MOD_SETTINGS['bigControlPanel'] ?? '',
442 '',
443 '',
444 'id="bigControlPanel"'
445 ),
446 ],
447 'displayThumbs' => [
448 'enabled' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] && $this->getBackendUser()->getTSConfigVal('options.file_list.enableDisplayThumbnails') === 'selectable',
449 'label' => htmlspecialchars($this->getLanguageService()->getLL('displayThumbs')),
450 'html' => BackendUtility::getFuncCheck(
451 $this->id,
452 'SET[displayThumbs]',
453 $this->MOD_SETTINGS['displayThumbs'] ?? '',
454 '',
455 '',
456 'id="checkDisplayThumbs"'
457 ),
458 ],
459 'enableClipBoard' => [
460 'enabled' => $this->getBackendUser()->getTSConfigVal('options.file_list.enableClipBoard') === 'selectable',
461 'label' => htmlspecialchars($this->getLanguageService()->getLL('clipBoard')),
462 'html' => BackendUtility::getFuncCheck(
463 $this->id,
464 'SET[clipBoard]',
465 $this->MOD_SETTINGS['clipBoard'] ?? '',
466 '',
467 '',
468 'id="checkClipBoard"'
469 ),
470 ]
471 ]);
472 $this->view->assign('showClipBoard', (bool)$this->MOD_SETTINGS['clipBoard']);
473 $this->view->assign('clipBoardHtml', $this->filelist->clipObj->printClipboard());
474 $this->view->assign('folderIdentifier', $this->folderObject->getCombinedIdentifier());
475 $this->view->assign('fileDenyPattern', $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern']);
476 $this->view->assign('maxFileSize', GeneralUtility::getMaxUploadFileSize() * 1024);
477 } else {
478 $this->forward('missingFolder');
479 }
480 }
481
482 /**
483 */
484 public function missingFolderAction()
485 {
486 if ($this->errorMessage) {
487 $this->errorMessage->setSeverity(FlashMessage::ERROR);
488 $this->controllerContext->getFlashMessageQueue('core.template.flashMessages')->addMessage($this->errorMessage);
489 }
490 }
491
492 /**
493 * Search for files by name and pass them with a facade to fluid
494 *
495 * @param string $searchWord
496 */
497 public function searchAction($searchWord = '')
498 {
499 if (empty($searchWord)) {
500 $this->forward('index');
501 }
502
503 $fileFacades = [];
504 $files = $this->fileRepository->searchByName($this->folderObject, $searchWord);
505
506 if (empty($files)) {
507 $this->controllerContext->getFlashMessageQueue('core.template.flashMessages')->addMessage(
508 new FlashMessage(
509 LocalizationUtility::translate('flashmessage.no_results', 'filelist'),
510 '',
511 FlashMessage::INFO
512 )
513 );
514 } else {
515 foreach ($files as $file) {
516 $fileFacades[] = new \TYPO3\CMS\Filelist\FileFacade($file);
517 }
518 }
519
520 $pageRenderer = $this->view->getModuleTemplate()->getPageRenderer();
521 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileList');
522
523 $thumbnailConfiguration = GeneralUtility::makeInstance(ThumbnailConfiguration::class);
524 $this->view->assign('thumbnail', [
525 'width' => $thumbnailConfiguration->getWidth(),
526 'height' => $thumbnailConfiguration->getHeight(),
527 ]);
528
529 $this->view->assign('searchWord', $searchWord);
530 $this->view->assign('files', $fileFacades);
531 $this->view->assign('deleteUrl', BackendUtility::getModuleUrl('tce_file'));
532 $this->view->assign('settings', [
533 'jsConfirmationDelete' => $this->getBackendUser()->jsConfirmation(JsConfirmation::DELETE)
534 ]);
535
536 $pageRenderer->loadRequireJsModule('TYPO3/CMS/Filelist/FileDelete');
537 $pageRenderer->addInlineLanguageLabelFile('EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf', 'buttons');
538 }
539
540 /**
541 * Get main headline based on active folder or storage for backend module
542 * Folder names are resolved to their special names like done in the tree view.
543 *
544 * @return string
545 */
546 protected function getModuleHeadline()
547 {
548 $name = $this->folderObject->getName();
549 if ($name === '') {
550 // Show storage name on storage root
551 if ($this->folderObject->getIdentifier() === '/') {
552 $name = $this->folderObject->getStorage()->getName();
553 }
554 } else {
555 $name = key(ListUtility::resolveSpecialFolderNames(
556 [$name => $this->folderObject]
557 ));
558 }
559 return $name;
560 }
561
562 /**
563 * Registers the Icons into the docheader
564 *
565 * @throws \InvalidArgumentException
566 */
567 protected function registerDocHeaderButtons()
568 {
569 /** @var ButtonBar $buttonBar */
570 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
571
572 // CSH
573 $cshButton = $buttonBar->makeHelpButton()
574 ->setModuleName('xMOD_csh_corebe')
575 ->setFieldName('filelist_module');
576 $buttonBar->addButton($cshButton);
577 }
578
579 /**
580 * Create the panel of buttons for submitting the form or otherwise perform operations.
581 *
582 * @return array All available buttons as an assoc. array
583 */
584 protected function registerButtons()
585 {
586 /** @var ButtonBar $buttonBar */
587 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
588
589 /** @var IconFactory $iconFactory */
590 $iconFactory = $this->view->getModuleTemplate()->getIconFactory();
591
592 /** @var $resourceFactory ResourceFactory */
593 $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
594
595 $lang = $this->getLanguageService();
596
597 // Refresh page
598 $refreshLink = GeneralUtility::linkThisScript(
599 [
600 'target' => rawurlencode($this->folderObject->getCombinedIdentifier()),
601 'imagemode' => $this->filelist->thumbs
602 ]
603 );
604 $refreshButton = $buttonBar->makeLinkButton()
605 ->setHref($refreshLink)
606 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.reload'))
607 ->setIcon($iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
608 $buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);
609
610 // Level up
611 try {
612 $currentStorage = $this->folderObject->getStorage();
613 $parentFolder = $this->folderObject->getParentFolder();
614 if ($parentFolder->getIdentifier() !== $this->folderObject->getIdentifier()
615 && $currentStorage->isWithinFileMountBoundaries($parentFolder)
616 ) {
617 $levelUpClick = 'top.document.getElementsByName("navigation")[0].contentWindow.Tree.highlightActiveItem("file","folder'
618 . GeneralUtility::md5int($parentFolder->getCombinedIdentifier()) . '_"+top.fsMod.currentBank)';
619 $levelUpButton = $buttonBar->makeLinkButton()
620 ->setHref(BackendUtility::getModuleUrl('file_FilelistList', ['id' => $parentFolder->getCombinedIdentifier()]))
621 ->setOnClick($levelUpClick)
622 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.upOneLevel'))
623 ->setIcon($iconFactory->getIcon('actions-view-go-up', Icon::SIZE_SMALL));
624 $buttonBar->addButton($levelUpButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
625 }
626 } catch (\Exception $e) {
627 }
628
629 // Shortcut
630 if ($this->getBackendUser()->mayMakeShortcut()) {
631 $shortCutButton = $buttonBar->makeShortcutButton()->setModuleName('file_FilelistList');
632 $buttonBar->addButton($shortCutButton, ButtonBar::BUTTON_POSITION_RIGHT);
633 }
634
635 // Upload button (only if upload to this directory is allowed)
636 if ($this->folderObject && $this->folderObject->getStorage()->checkUserActionPermission(
637 'add',
638 'File'
639 ) && $this->folderObject->checkActionPermission('write')
640 ) {
641 $uploadButton = $buttonBar->makeLinkButton()
642 ->setHref(BackendUtility::getModuleUrl(
643 'file_upload',
644 [
645 'target' => $this->folderObject->getCombinedIdentifier(),
646 'returnUrl' => $this->filelist->listURL(),
647 ]
648 ))
649 ->setClasses('t3js-drag-uploader-trigger')
650 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.upload'))
651 ->setIcon($iconFactory->getIcon('actions-edit-upload', Icon::SIZE_SMALL));
652 $buttonBar->addButton($uploadButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
653 }
654
655 // New folder button
656 if ($this->folderObject && $this->folderObject->checkActionPermission('write')
657 && ($this->folderObject->getStorage()->checkUserActionPermission(
658 'add',
659 'File'
660 ) || $this->folderObject->checkActionPermission('add'))
661 ) {
662 $newButton = $buttonBar->makeLinkButton()
663 ->setHref(BackendUtility::getModuleUrl(
664 'file_newfolder',
665 [
666 'target' => $this->folderObject->getCombinedIdentifier(),
667 'returnUrl' => $this->filelist->listURL(),
668 ]
669 ))
670 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.new'))
671 ->setIcon($iconFactory->getIcon('actions-add', Icon::SIZE_SMALL));
672 $buttonBar->addButton($newButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
673 }
674
675 // Add paste button if clipboard is initialized
676 if ($this->filelist->clipObj instanceof Clipboard && $this->folderObject->checkActionPermission('write')) {
677 $elFromTable = $this->filelist->clipObj->elFromTable('_FILE');
678 if (!empty($elFromTable)) {
679 $addPasteButton = true;
680 $elToConfirm = [];
681 foreach ($elFromTable as $key => $element) {
682 $clipBoardElement = $resourceFactory->retrieveFileOrFolderObject($element);
683 if ($clipBoardElement instanceof Folder && $clipBoardElement->getStorage()->isWithinFolder(
684 $clipBoardElement,
685 $this->folderObject
686 )
687 ) {
688 $addPasteButton = false;
689 }
690 $elToConfirm[$key] = $clipBoardElement->getName();
691 }
692 if ($addPasteButton) {
693 $confirmText = $this->filelist->clipObj
694 ->confirmMsgText('_FILE', $this->folderObject->getReadablePath(), 'into', $elToConfirm);
695 $pasteButton = $buttonBar->makeLinkButton()
696 ->setHref($this->filelist->clipObj
697 ->pasteUrl('_FILE', $this->folderObject->getCombinedIdentifier()))
698 ->setClasses('t3js-modal-trigger')
699 ->setDataAttributes([
700 'severity' => 'warning',
701 'content' => $confirmText,
702 'title' => $lang->getLL('clip_paste')
703 ])
704 ->setTitle($lang->getLL('clip_paste'))
705 ->setIcon($iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL));
706 $buttonBar->addButton($pasteButton, ButtonBar::BUTTON_POSITION_LEFT, 2);
707 }
708 }
709 }
710 }
711
712 /**
713 * Returns an instance of LanguageService
714 *
715 * @return \TYPO3\CMS\Core\Localization\LanguageService
716 */
717 protected function getLanguageService()
718 {
719 return $GLOBALS['LANG'];
720 }
721
722 /**
723 * Returns the current BE user.
724 *
725 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
726 */
727 protected function getBackendUser()
728 {
729 return $GLOBALS['BE_USER'];
730 }
731 }