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