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