‪TYPO3CMS  ‪main
FileList.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
16 namespace ‪TYPO3\CMS\Filelist;
17 
18 use Psr\EventDispatcher\EventDispatcherInterface;
19 use Psr\Http\Message\ServerRequestInterface;
31 use TYPO3\CMS\Backend\Utility\BackendUtility;
38 use TYPO3\CMS\Core\Imaging\IconSize;
68 
75 {
76  public ‪Mode ‪$mode = Mode::MANAGE;
78 
82  public int ‪$itemsPerPage = 40;
83 
87  public int ‪$currentPage = 1;
88 
92  public int ‪$totalbytes = 0;
93 
97  public int ‪$totalItems = 0;
98 
102  public string ‪$sort = '';
103 
107  public bool ‪$sortRev = true;
108 
112  public bool ‪$thumbs = false;
113 
117  public int ‪$maxTitleLength = 30;
118 
122  public array ‪$fieldArray = [];
123 
129  public array ‪$addElement_tdCssClass = [
130  '_CONTROL_' => 'col-control',
131  '_SELECTOR_' => 'col-checkbox',
132  'icon' => 'col-icon',
133  'name' => 'col-title col-responsive',
134  ];
135 
139  protected ‪$folderObject;
140 
144  public ‪$clipObj;
145 
146  // Evaluates if a resource can be downloaded
148  // Evaluates if a resource can be displayed
150  // Evaluates if a resource can be selected
152  // Evaluates if a resource is currently selected
154 
156  protected EventDispatcherInterface ‪$eventDispatcher;
157  protected ServerRequestInterface ‪$request;
163 
164  public function ‪__construct(ServerRequestInterface ‪$request)
165  {
166  $this->request = ‪$request;
167 
168  // Setting the maximum length of the filenames to the user's settings or minimum 30 (= $this->maxTitleLength)
169  $this->maxTitleLength = max($this->maxTitleLength, (int)($this->‪getBackendUser()->uc['titleLen'] ?? 1));
170  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
171  $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
172  $this->translateTools = GeneralUtility::makeInstance(TranslationConfigurationProvider::class);
173  $this->itemsPerPage = ‪MathUtility::forceIntegerInRange(
174  $this->‪getBackendUser()->getTSConfig()['options.']['file_list.']['filesPerPage'] ?? $this->itemsPerPage,
175  1
176  );
177  // Create clipboard object and initialize that
178  $this->clipObj = GeneralUtility::makeInstance(Clipboard::class);
179  $this->clipObj->initializeClipboard(‪$request);
180  $this->resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
181  $this->uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
182  $this->onlineMediaHelperRegistry = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class);
183 
184  // Initialize Resource Download
185  $this->resourceDownloadMatcher = GeneralUtility::makeInstance(Matcher::class);
186  $this->resourceDownloadMatcher->addMatcher(GeneralUtility::makeInstance(ResourceFolderTypeMatcher::class));
187 
188  // Create filter for file extensions
189  $fileExtensionMatcher = GeneralUtility::makeInstance(ResourceFileExtensionMatcher::class);
190  $fileDownloadConfiguration = (array)($this->‪getBackendUser()->getTSConfig()['options.']['file_list.']['fileDownload.'] ?? []);
191  if ($fileDownloadConfiguration !== []) {
192  $allowedExtensions = GeneralUtility::trimExplode(',', (string)($fileDownloadConfiguration['allowedFileExtensions'] ?? ''), true);
193  $disallowedExtensions = GeneralUtility::trimExplode(',', (string)($fileDownloadConfiguration['disallowedFileExtensions'] ?? ''), true);
194  $fileExtensionMatcher = GeneralUtility::makeInstance(ResourceFileExtensionMatcher::class);
195  $fileExtensionMatcher->setExtensions($allowedExtensions);
196  $fileExtensionMatcher->setIgnoredExtensions($disallowedExtensions);
197  } else {
198  $fileExtensionMatcher->addExtension('*');
199  }
200  $this->resourceDownloadMatcher->addMatcher($fileExtensionMatcher);
201  }
202 
203  public function ‪setResourceDownloadMatcher(?‪Matcher $matcher): self
204  {
205  $this->resourceDownloadMatcher = $matcher;
206  return $this;
207  }
208 
209  public function ‪setResourceDisplayMatcher(?‪Matcher $matcher): self
210  {
211  $this->resourceDisplayMatcher = $matcher;
212  return $this;
213  }
214 
215  public function ‪setResourceSelectableMatcher(?‪Matcher $matcher): self
216  {
217  $this->resourceSelectableMatcher = $matcher;
218  return $this;
219  }
220 
221  public function ‪setResourceSelectedMatcher(?‪Matcher $matcher): self
222  {
223  $this->resourceSelectedMatcher = $matcher;
224  return $this;
225  }
226 
236  public function ‪start(Folder ‪$folderObject, int ‪$currentPage, string ‪$sort, bool ‪$sortRev, ‪Mode ‪$mode = Mode::MANAGE)
237  {
238  $this->folderObject = ‪$folderObject;
239  $this->currentPage = ‪MathUtility::forceIntegerInRange(‪$currentPage, 1, 100000);
240  $this->sort = ‪$sort;
241  $this->sortRev = ‪$sortRev;
242  $this->totalbytes = 0;
243  $this->resourceDownloadMatcher = null;
244  $this->resourceDisplayMatcher = null;
245  $this->resourceSelectableMatcher = null;
246  $this->‪setMode($mode);
247  }
248 
249  public function ‪setMode(‪Mode ‪$mode)
250  {
251  $this->mode = ‪$mode;
252  $this->‪fieldArray = $mode->fieldArray();
253  }
254 
255  public function ‪setColumnsToRender(array $additionalFields = []): void
256  {
257  $this->‪fieldArray = array_unique(array_merge($this->‪fieldArray, $additionalFields));
258  }
259 
263  protected function ‪renderTiles(ResourceCollectionPaginator $paginator, array $resourceViews, ViewInterface $view): string
264  {
265  $view->assign('displayThumbs', $this->thumbs);
266  $view->assign('displayCheckbox', $this->resourceSelectableMatcher ? true : false);
267  $view->assign('pagination', [
268  'backward' => $this->‪getPaginationLinkForDirection($paginator, ‪NavigationDirection::BACKWARD),
269  'forward' => $this->‪getPaginationLinkForDirection($paginator, NavigationDirection::FORWARD),
270  ]);
271  $view->assign('resources', $resourceViews);
272 
273  return $view->render('Filelist/Tiles');
274  }
275 
279  protected function ‪renderList(ResourceCollectionPaginator $paginator, array $resourceViews, ViewInterface $view): string
280  {
281  $view->assign('tableHeader', $this->‪renderListTableHeader());
282  $view->assign('tableBackwardNavigation', $this->‪renderListTableForwardBackwardNavigation($paginator, ‪NavigationDirection::BACKWARD));
283  $view->assign('tableBody', $this->‪renderListTableBody($resourceViews));
284  $view->assign('tableForwardNavigation', $this->‪renderListTableForwardBackwardNavigation($paginator, NavigationDirection::FORWARD));
285 
286  return $view->render('Filelist/List');
287  }
288 
289  public function ‪render(?‪FileSearchDemand ‪$searchDemand, ‪ViewInterface $view): string
290  {
291  $storage = $this->folderObject->getStorage();
292  $storage->resetFileAndFolderNameFiltersToDefault();
293  if (!$this->folderObject->getStorage()->isBrowsable()) {
294  return '';
295  }
296 
297  if (‪$searchDemand !== null) {
299  $folders = [];
300  // Add special "Path" field for the search result
301  array_splice($this->‪fieldArray, 3, 0, '_PATH_');
302  } else {
303  $folders = $storage->getFoldersInFolder($this->folderObject);
304  }
305  $files = iterator_to_array($this->folderObject->searchFiles(‪$searchDemand));
306  } else {
307  $folders = $storage->getFoldersInFolder($this->folderObject);
308  $files = $this->folderObject->getFiles();
309  }
310 
311  // Cleanup field array
312  $this->‪fieldArray = array_filter($this->‪fieldArray, function (string $fieldName) {
313  if ($fieldName === '_SELECTOR_' && $this->resourceSelectableMatcher === null) {
314  return false;
315  }
316  return true;
317  });
318 
319  // Remove processing folders
320  $folders = array_filter($folders, function (Folder $folder) {
321  return $folder->getRole() !== ‪FolderInterface::ROLE_PROCESSING;
322  });
323 
324  // Apply filter
325  $resources = array_filter($folders + $files, function (ResourceInterface $resource) {
326  return $this->resourceDisplayMatcher === null || $this->resourceDisplayMatcher->match($resource);
327  });
328 
329  $resourceCollection = new ResourceCollection($resources);
330  $this->totalItems = $resourceCollection->getTotalCount();
331  $this->totalbytes = $resourceCollection->getTotalBytes();
332 
333  // Sort the files before sending it to the renderer
334  if (trim($this->sort) !== '') {
335  $resourceCollection->setResources($this->‪sortResources($resourceCollection->getResources(), $this->sort));
336  }
337 
338  $paginator = new ResourceCollectionPaginator($resourceCollection, $this->currentPage, $this->itemsPerPage);
339 
340  // Prepare Resources for View
341  $resourceViews = [];
342  $userPermissions = $this->‪getUserPermissions();
343  foreach ($paginator->getPaginatedItems() as $resource) {
344  $resourceView = new ResourceView(
345  $resource,
346  $userPermissions,
347  $this->iconFactory->getIconForResource($resource, IconSize::SMALL)
348  );
349  $resourceView->moduleUri = $this->‪createModuleUriForResource($resource);
350  $resourceView->editDataUri = $this->‪createEditDataUriForResource($resource);
351  $resourceView->editContentUri = $this->‪createEditContentUriForResource($resource);
352  $resourceView->replaceUri = $this->‪createReplaceUriForResource($resource);
353 
354  $resourceView->isDownloadable = $this->resourceDownloadMatcher !== null && $this->resourceDownloadMatcher->match($resource);
355  $resourceView->isSelectable = $this->resourceSelectableMatcher !== null && $this->resourceSelectableMatcher->match($resource);
356  if ($this->mode === Mode::BROWSE && $resource instanceof File) {
357  $resourceView->isSelectable = $this->eventDispatcher->dispatch(new IsFileSelectableEvent($resource))->isFileSelectable();
358  }
359  $resourceView->isSelected = $this->resourceSelectedMatcher !== null && $this->resourceSelectedMatcher->match($resource);
360 
361  $resourceViews[] = $resourceView;
362  }
363 
364  if ($this->viewMode === ‪ViewMode::TILES) {
365  return $this->‪renderTiles($paginator, $resourceViews, $view);
366  }
367 
368  return $this->‪renderList($paginator, $resourceViews, $view);
369  }
370 
381  public function ‪addElement(array $data, array $attributes = [], bool $isTableHeader = false): string
382  {
383  // Initialize rendering.
384  $cols = [];
385  $colType = $isTableHeader ? 'th' : 'td';
386  // Traverse field array which contains the data to present:
387  foreach ($this->‪fieldArray as $fieldName) {
388  $cellAttributes = [];
389  $cellAttributes['class'] = $this->addElement_tdCssClass[$fieldName] ?? 'col-nowrap';
390 
391  // Special handling to combine icon and name column
392  if ($isTableHeader && $fieldName === 'icon') {
393  continue;
394  }
395  if ($isTableHeader && $fieldName === 'name') {
396  $cellAttributes['colspan'] = 2;
397  }
398 
399  $cols[] = '<' . $colType . ' ' . GeneralUtility::implodeAttributes($cellAttributes, true) . '>' . ($data[$fieldName] ?? '') . '</' . $colType . '>';
400  }
401 
402  // Add the table row
403  return '
404  <tr ' . GeneralUtility::implodeAttributes($attributes, true) . '>
405  ' . implode(PHP_EOL, $cols) . '
406  </tr>';
407  }
408 
412  public function ‪getFolderInfo(): string
413  {
414  if ($this->totalItems == 1) {
415  $fileLabel = $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:file');
416  } else {
417  $fileLabel = $this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:files');
418  }
419  return $this->totalItems . ' ' . htmlspecialchars($fileLabel) . ', ' . GeneralUtility::formatSize(
420  $this->totalbytes,
421  htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits'))
422  );
423  }
424 
425  protected function ‪renderListTableHeader(): string
426  {
427  $data = [];
428  foreach ($this->‪fieldArray as $field) {
429  switch ($field) {
430  case 'icon':
431  $data[$field] = '';
432  break;
433  case '_SELECTOR_':
434  $data[$field] = $this->‪renderCheckboxActions();
435  break;
436  default:
437  $data[$field] = $this->‪renderListTableFieldHeader($field);
438  break;
439  }
440  }
441 
442  return $this->‪addElement($data, [], true);
443  }
444 
445  protected function ‪renderListTableFieldHeader(string $field): string
446  {
447  $label = $this->‪getFieldLabel($field);
448  if (in_array($field, ['_SELECTOR_', '_CONTROL_', '_PATH_'])) {
449  return $label;
450  }
451 
452  $params = ['sort' => $field, 'currentPage' => 0];
453  if ($this->sort === $field) {
454  // Check reverse sorting
455  $params['reverse'] = ($this->sortRev ? '0' : '1');
456  } else {
457  $params['reverse'] = 0;
458  }
459 
460  $icon = $this->sort === $field
461  ? $this->iconFactory->getIcon('actions-sort-amount-' . ($this->sortRev ? 'down' : 'up'), IconSize::SMALL)->‪render()
462  : $this->iconFactory->getIcon('actions-sort-amount', IconSize::SMALL)->render();
463 
464  $attributes = [
465  'class' => 'table-sorting-button ' . ($this->sort === $field ? 'table-sorting-button-active' : ''),
466  'href' => $this->‪createModuleUri($params),
467  ];
468 
469  return '<a ' . GeneralUtility::implodeAttributes($attributes, true) . '>
470  <span class="table-sorting-label">' . htmlspecialchars($label) . '</span>
471  <span class="table-sorting-icon">' . $icon . '</span>
472  </a>';
473 
474  }
475 
479  protected function ‪renderListTableBody(array $resourceViews): string
480  {
481  ‪$output = '';
482  foreach ($resourceViews as $resourceView) {
483  $data = [];
484  $attributes = [
485  'class' => $resourceView->isSelected ? 'selected' : '',
486  'data-filelist-element' => 'true',
487  'data-filelist-type' => $resourceView->getType(),
488  'data-filelist-identifier' => $resourceView->getIdentifier(),
489  'data-filelist-state-identifier' => $resourceView->getStateIdentifier(),
490  'data-filelist-name' => htmlspecialchars($resourceView->getName()),
491  'data-filelist-thumbnail' => $resourceView->getThumbnailUri(),
492  'data-filelist-uid' => $resourceView->getUid(),
493  'data-filelist-meta-uid' => $resourceView->getMetaDataUid(),
494  'data-filelist-selectable' => $resourceView->isSelectable ? 'true' : 'false',
495  'data-filelist-selected' => $resourceView->isSelected ? 'true' : 'false',
496  'data-multi-record-selection-element' => 'true',
497  'draggable' => $resourceView->canMove() ? 'true' : 'false',
498  ];
499  foreach ($this->‪fieldArray as $field) {
500  switch ($field) {
501  case 'icon':
502  $data[$field] = $this->‪renderIcon($resourceView);
503  break;
504  case 'name':
505  $data[$field] = $this->‪renderName($resourceView)
506  . $this->‪renderThumbnail($resourceView);
507  break;
508  case 'size':
509  $data[$field] = $this->‪renderSize($resourceView);
510  break;
511  case 'rw':
512  $data[$field] = $this->‪renderPermission($resourceView);
513  break;
514  case 'record_type':
515  $data[$field] = $this->‪renderType($resourceView);
516  break;
517  case 'crdate':
518  $data[$field] = $this->‪renderCreationTime($resourceView);
519  break;
520  case 'tstamp':
521  $data[$field] = $this->‪renderModificationTime($resourceView);
522  break;
523  case '_SELECTOR_':
524  $data[$field] = $this->‪renderSelector($resourceView);
525  break;
526  case '_PATH_':
527  $data[$field] = $this->‪renderPath($resourceView);
528  break;
529  case '_REF_':
530  $data[$field] = $this->‪renderReferenceCount($resourceView);
531  break;
532  case '_CONTROL_':
533  $data[$field] = $this->‪renderControl($resourceView);
534  break;
535  default:
536  $data[$field] = $this->‪renderField($resourceView, $field);
537  }
538  }
539  ‪$output .= $this->‪addElement($data, $attributes);
540  }
541 
542  return ‪$output;
543  }
544 
547  ‪NavigationDirection $direction
548  ): string {
549  if (!$link = $this->‪getPaginationLinkForDirection($paginator, $direction)) {
550  return '';
551  }
552 
553  $iconIdentifier = null;
554  switch ($direction) {
556  $iconIdentifier = 'actions-move-up';
557  break;
558  case NavigationDirection::FORWARD:
559  $iconIdentifier = 'actions-move-down';
560  break;
561  }
562 
563  $markup = [];
564  $markup[] = '<tr>';
565  $markup[] = ' <td colspan="' . count($this->‪fieldArray) . '">';
566  $markup[] = ' <a href="' . htmlspecialchars($link->uri) . '">';
567  $markup[] = ' ' . ($iconIdentifier !== null ? $this->iconFactory->getIcon($iconIdentifier, IconSize::SMALL)->render() : '');
568  $markup[] = ' <i>[' . $link->label . ']</i>';
569  $markup[] = ' </a>';
570  $markup[] = ' </td>';
571  $markup[] = '</tr>';
572 
573  return implode(PHP_EOL, $markup);
574  }
575 
582  protected function getTranslationsForMetaData($metaDataRecord)
583  {
584  $languageField = ‪$GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? '';
585  $languageParentField = ‪$GLOBALS['TCA']['sys_file_metadata']['ctrl']['transOrigPointerField'] ?? '';
586 
587  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_metadata');
588  $queryBuilder->getRestrictions()->removeAll();
589  ‪$translationRecords = $queryBuilder->select('*')
590  ->from('sys_file_metadata')
591  ->where(
592  $queryBuilder->expr()->eq(
593  $languageParentField,
594  $queryBuilder->createNamedParameter($metaDataRecord['uid'] ?? 0, ‪Connection::PARAM_INT)
595  ),
596  $queryBuilder->expr()->gt(
597  $languageField,
598  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
599  )
600  )
601  ->executeQuery()
602  ->fetchAllAssociative();
603 
604  ‪$translations = [];
605  foreach (‪$translationRecords as ‪$record) {
606  $languageId = ‪$record[$languageField];
607  ‪$translations[$languageId] = ‪$record;
608  }
609  return ‪$translations;
610  }
611 
615  protected function ‪renderIcon(ResourceView $resourceView): string
616  {
617  return BackendUtility::wrapClickMenuOnIcon($resourceView->getIconSmall()->render(), 'sys_file', $resourceView->getIdentifier());
618  }
619 
623  protected function ‪renderName(ResourceView $resourceView): string
624  {
625  $resourceName = htmlspecialchars($resourceView->getName());
626  if ($resourceView->resource instanceof Folder
627  && $resourceView->resource->getRole() !== ‪FolderInterface::ROLE_DEFAULT) {
628  $resourceName = '<strong>' . $resourceName . '</strong>';
629  }
630 
631  $attributes = [];
632  $attributes['title'] = $resourceView->getName();
633  $attributes['type'] = 'button';
634  $attributes['class'] = 'btn btn-link p-0';
635  $attributes['data-filelist-action'] = 'primary';
636 
637  ‪$output = '<button ' . GeneralUtility::implodeAttributes($attributes, true) . '>' . $resourceName . '</button>';
638  if ($resourceView->isMissing()) {
639  $label = htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing'));
640  ‪$output = '<span class="badge badge-danger">' . $label . '</span> ' . ‪$output;
641  }
642 
643  return ‪$output;
644  }
645 
649  protected function ‪renderThumbnail(ResourceView $resourceView): string
650  {
651  if ($this->thumbs === false
652  || $resourceView->getPreview() === null
653  || !($resourceView->getPreview()->isImage() || $resourceView->getPreview()->isMediaFile())
654  ) {
655  return '';
656  }
657 
658  $processedFile = $resourceView->getPreview()->process(
660  [
661  'width' => (int)($this->‪getBackendUser()->getTSConfig()['options.']['file_list.']['thumbnail.']['width'] ?? 64),
662  'height' => (int)($this->‪getBackendUser()->getTSConfig()['options.']['file_list.']['thumbnail.']['height'] ?? 64),
663  ]
664  );
665 
666  if (($thumbnailUrl = ($processedFile->getPublicUrl() ?? '')) === '') {
667  // Prevent rendering of a "img" tag with an empty "src" attribute
668  return '';
669  }
670 
671  if (‪PathUtility::isAbsolutePath($thumbnailUrl)) {
672  $thumbnailUrl .= '?' . filemtime($processedFile->getForLocalProcessing(false));
673  }
674 
675  return '<br><img src="' . htmlspecialchars($thumbnailUrl) . '" ' .
676  'width="' . htmlspecialchars($processedFile->getProperty('width')) . '" ' .
677  'height="' . htmlspecialchars($processedFile->getProperty('height')) . '" ' .
678  'title="' . htmlspecialchars($resourceView->getName()) . '" />';
679  }
680 
684  protected function ‪renderType(ResourceView $resourceView): string
685  {
686  $type = $resourceView->getType();
687  $content = $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:' . $type);
688  if ($resourceView->resource instanceof File && $resourceView->resource->getExtension() !== '') {
689  $content .= ' (' . strtoupper($resourceView->resource->getExtension()) . ')';
690  }
691 
692  return htmlspecialchars($content);
693  }
694 
698  protected function ‪renderCreationTime(ResourceView $resourceView): string
699  {
700  $timestamp = ($resourceView->resource instanceof File) ? $resourceView->getCreatedAt() : null;
701  return $timestamp ? BackendUtility::datetime($timestamp) : '';
702  }
703 
707  protected function ‪renderModificationTime(ResourceView $resourceView): string
708  {
709  $timestamp = ($resourceView->resource instanceof File) ? $resourceView->getUpdatedAt() : null;
710  return $timestamp ? BackendUtility::datetime($timestamp) : '';
711  }
712 
716  protected function ‪renderSize(ResourceView $resourceView): string
717  {
718  if ($resourceView->resource instanceof File) {
719  return GeneralUtility::formatSize((int)$resourceView->resource->getSize(), htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits')));
720  }
721 
722  if ($resourceView->resource instanceof Folder) {
723  try {
724  $numFiles = $resourceView->resource->getFileCount();
725  } catch (InsufficientFolderAccessPermissionsException $e) {
726  $numFiles = 0;
727  }
728  if ($numFiles === 1) {
729  return $numFiles . ' ' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:file'));
730  }
731  return $numFiles . ' ' . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:files'));
732  }
733 
734  return '';
735  }
736 
740  protected function ‪renderPermission(ResourceView $resourceView): string
741  {
742  return '<strong class="text-danger">'
743  . htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:read'))
744  . ($resourceView->canWrite() ? htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:write')) : '')
745  . '</strong>';
746  }
747 
751  protected function ‪renderField(ResourceView $resourceView, string $field): string
752  {
753  if ($resourceView->resource instanceof File && $resourceView->resource->hasProperty($field)) {
754  if ($field === 'storage') {
755  // Fetch storage name of the current file
756  $storage = GeneralUtility::makeInstance(StorageRepository::class)->findByUid((int)$resourceView->resource->getProperty($field));
757  if ($storage !== null) {
758  return htmlspecialchars($storage->getName());
759  }
760  } else {
761  return htmlspecialchars(
762  (string)BackendUtility::getProcessedValueExtra(
763  $this->‪getConcreteTableName($field),
764  $field,
765  $resourceView->resource->getProperty($field),
766  $this->maxTitleLength,
767  $resourceView->resource->getMetaData()->offsetGet('uid')
768  )
769  );
770  }
771  }
772 
773  return '';
774  }
775 
779  protected function ‪renderSelector(ResourceView $resourceView): string
780  {
781  $checkboxConfig = $resourceView->getCheckboxConfig();
782  if ($checkboxConfig === null) {
783  return '';
784  }
785  if (!$resourceView->isSelectable) {
786  return '';
787  }
788 
789  $attributes = [
790  'class' => 'form-check-input ' . $checkboxConfig['class'],
791  'type' => 'checkbox',
792  'name' => $checkboxConfig['name'],
793  'value' => $checkboxConfig['value'],
794  'checked' => $checkboxConfig['checked'],
795  ];
796 
797  return '<span class="form-check form-check-type-toggle">'
798  . '<input ' . GeneralUtility::implodeAttributes($attributes, true) . ' />'
799  . '</span>';
800  }
801 
805  protected function ‪renderPath(ResourceView $resourceView): string
806  {
807  return htmlspecialchars($resourceView->getPath());
808  }
809 
814  protected function ‪renderReferenceCount(ResourceView $resourceView): string
815  {
816  if (!$resourceView->resource instanceof File) {
817  return '-';
818  }
819 
820  $referenceCount = $this->‪getFileReferenceCount($resourceView->resource);
821  if (!$referenceCount) {
822  return '-';
823  }
824 
825  $attributes = [
826  'type' => 'button',
827  'class' => 'btn btn-sm btn-link',
828  'data-filelist-action' => 'show',
829  'title' => $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:show_references') . ' (' . $referenceCount . ')',
830  ];
831 
832  return '<button ' . GeneralUtility::implodeAttributes($attributes, true) . '>' . $referenceCount . '</button>';
833  }
834 
838  protected function ‪renderControl(ResourceView $resourceView): string
839  {
840  if ($this->mode === Mode::MANAGE) {
841  return $this->‪renderControlManage($resourceView);
842  }
843  if ($this->mode === Mode::BROWSE) {
844  return $this->‪renderControlBrowse($resourceView);
845  }
846 
847  return '';
848  }
849 
853  protected function ‪renderControlManage(ResourceView $resourceView): string
854  {
855  if (!$resourceView->resource instanceof File && !$resourceView->resource instanceof Folder) {
856  return '';
857  }
858 
859  // primary actions
860  $primaryActions = ['view', 'metadata', 'translations', 'delete'];
861  $userTsConfig = $this->‪getBackendUser()->getTSConfig();
862  if ($userTsConfig['options.']['file_list.']['primaryActions'] ?? false) {
863  $primaryActions = GeneralUtility::trimExplode(',', $userTsConfig['options.']['file_list.']['primaryActions']);
864  // Always add "translations" as this action has an own dropdown container and therefore cannot be a secondary action
865  if (!in_array('translations', $primaryActions, true)) {
866  $primaryActions[] = 'translations';
867  }
868  }
869 
870  $actions = [
871  'edit' => $this->‪createControlEditContent($resourceView),
872  'metadata' => $this->‪createControlEditMetaData($resourceView),
873  'translations' => $this->‪createControlTranslation($resourceView),
874  'view' => $this->‪createControlView($resourceView),
875  'replace' => $this->‪createControlReplace($resourceView),
876  'rename' => $this->‪createControlRename($resourceView),
877  'download' => $this->‪createControlDownload($resourceView),
878  'upload' => $this->‪createControlUpload($resourceView),
879  'info' => $this->‪createControlInfo($resourceView),
880  'delete' => $this->‪createControlDelete($resourceView),
881  'copy' => $this->‪createControlCopy($resourceView),
882  'cut' => $this->‪createControlCut($resourceView),
883  'paste' => $this->‪createControlPaste($resourceView),
884  'updateOnlineMedia' => $this->‪createControlUpdateOnlineMedia($resourceView),
885  ];
886 
887  $event = new ProcessFileListActionsEvent($resourceView->resource, $actions);
888  $event = $this->eventDispatcher->dispatch($event);
889  $actions = $event->getActionItems();
890 
891  // Remove empty actions
892  $actions = array_filter($actions, static fn ($action) => $action !== null && trim($action) !== '');
893 
894  // Compile items into a dropdown
895  $cellOutput = '';
896  ‪$output = '';
897  foreach ($actions as $key => $action) {
898  if (in_array($key, $primaryActions, true)) {
899  ‪$output .= $action;
900  continue;
901  }
902  // This is a backwards-compat layer for the existing hook items, which will be removed in TYPO3 v12.
903  $action = str_replace('btn btn-sm btn-default', 'dropdown-item dropdown-item-spaced', $action);
904  $title = [];
905  preg_match('/title="([^"]*)"/', $action, $title);
906  if (empty($title)) {
907  preg_match('/aria-label="([^"]*)"/', $action, $title);
908  }
909  if (!empty($title[1])) {
910  $action = str_replace(
911  [
912  '</a>',
913  '</button>',
914  ],
915  [
916  ' ' . $title[1] . '</a>',
917  ' ' . $title[1] . '</button>',
918  ],
919  $action
920  );
921  // In case we added the title as tag content, we can remove the attribute,
922  // since this is duplicated and would trigger a tooltip with the same content.
923  if (!empty($title[0])) {
924  $action = str_replace($title[0], '', $action);
925  }
926  $cellOutput .= '<li>' . $action . '</li>';
927  }
928  }
929 
930  if ($cellOutput !== '') {
931  $title = $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.more');
932  ‪$output .= '<div class="btn-group dropdown" title="' . htmlspecialchars($title) . '" >'
933  . '<a href="#actions_' . $resourceView->resource->getHashedIdentifier() . '" class="btn btn-sm btn-default dropdown-toggle dropdown-toggle-no-chevron" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">'
934  . $this->iconFactory->getIcon('actions-menu-alternative', IconSize::SMALL)->render()
935  . '</a>'
936  . '<ul id="actions_' . $resourceView->resource->getHashedIdentifier() . '" class="dropdown-menu">' . $cellOutput . '</ul>'
937  . '</div>';
938  }
939 
940  return '<div class="btn-group">' . ‪$output . '</div>';
941  }
942 
946  protected function ‪renderControlBrowse(ResourceView $resourceView): string
947  {
948  $fileOrFolderObject = $resourceView->resource;
949  if (!$fileOrFolderObject instanceof File && !$fileOrFolderObject instanceof Folder) {
950  return '';
951  }
952 
953  $actions = [
954  'select' => $this->‪createControlSelect($resourceView),
955  'info' => $this->‪createControlInfo($resourceView),
956  ];
957 
958  // Remove empty actions
959  $actions = array_filter($actions, static fn ($action) => $action !== null && trim($action) !== '');
960  if (empty($actions)) {
961  return '';
962  }
963 
964  return '<div class="btn-group">' . implode(' ', $actions) . '</div>';
965  }
966 
967  protected function ‪createControlSelect(‪ResourceView $resourceView): ?‪ButtonInterface
968  {
969  if (!$resourceView->isSelectable) {
970  return null;
971  }
972 
973  $button = GeneralUtility::makeInstance(InputButton::class);
974  $button->setTitle($resourceView->‪getName());
975  $button->setIcon($this->iconFactory->getIcon('actions-plus', IconSize::SMALL));
976  $button->setDataAttributes(['filelist-action' => 'select']);
977 
978  return $button;
979  }
980 
981  protected function ‪createControlEditContent(‪ResourceView $resourceView): ?‪ButtonInterface
982  {
983  if (!($resourceView->resource instanceof ‪File && $resourceView->resource->isTextFile())
984  || !$resourceView->‪canWrite()) {
985  return null;
986  }
987 
988  $button = GeneralUtility::makeInstance(LinkButton::class);
989  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editcontent'));
990  $button->setHref($resourceView->editContentUri);
991  $button->setIcon($this->iconFactory->getIcon('actions-page-open', IconSize::SMALL));
992 
993  return $button;
994  }
995 
996  protected function ‪createControlEditMetaData(‪ResourceView $resourceView): ?‪ButtonInterface
997  {
998  if (!$resourceView->‪getMetaDataUid()) {
999  return null;
1000  }
1001 
1002  $button = GeneralUtility::makeInstance(LinkButton::class);
1003  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata'));
1004  $button->setHref($resourceView->editDataUri);
1005  $button->setIcon($this->iconFactory->getIcon('actions-open', IconSize::SMALL));
1006 
1007  return $button;
1008  }
1009 
1010  protected function ‪createControlView(‪ResourceView $resourceView): ?‪ButtonInterface
1011  {
1012  if (!$resourceView->‪getPublicUrl()) {
1013  return null;
1014  }
1015 
1016  $button = GeneralUtility::makeInstance(GenericButton::class);
1017  $button->setTag('a');
1018  $button->setLabel($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.view'));
1019  $button->setHref($resourceView->‪getPublicUrl());
1020  $button->setAttributes(['target' => '_blank']);
1021  $button->setIcon($this->iconFactory->getIcon('actions-document-view', IconSize::SMALL));
1022 
1023  return $button;
1024  }
1025 
1026  protected function ‪createControlReplace(‪ResourceView $resourceView): ?‪ButtonInterface
1027  {
1028  if (!$resourceView->replaceUri) {
1029  return null;
1030  }
1031 
1032  $button = GeneralUtility::makeInstance(LinkButton::class);
1033  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.replace'));
1034  $button->setHref($resourceView->replaceUri);
1035  $button->setIcon($this->iconFactory->getIcon('actions-edit-replace', IconSize::SMALL));
1036 
1037  return $button;
1038  }
1039 
1040  protected function ‪createControlRename(‪ResourceView $resourceView): ?‪ButtonInterface
1041  {
1042  if (!$resourceView->‪canRename()) {
1043  return null;
1044  }
1045 
1046  $button = GeneralUtility::makeInstance(GenericButton::class);
1047  $button->setLabel($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.rename'));
1048  $button->setAttributes(['type' => 'button', 'data-filelist-action' => 'rename']);
1049  $button->setIcon($this->iconFactory->getIcon('actions-edit-rename', IconSize::SMALL));
1050 
1051  return $button;
1052  }
1053 
1054  protected function ‪createControlDownload(‪ResourceView $resourceView): ?‪ButtonInterface
1055  {
1056  if (!$resourceView->‪canRead() || !(bool)($this->getBackendUser()->getTSConfig()['options.']['file_list.']['fileDownload.']['enabled'] ?? true)) {
1057  return null;
1058  }
1059 
1060  if (!$resourceView->isDownloadable) {
1061  return null;
1062  }
1063 
1064  $button = GeneralUtility::makeInstance(GenericButton::class);
1065  $button->setLabel($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:download'));
1066  $button->setAttributes([
1067  'type' => 'button',
1068  'data-filelist-action' => 'download',
1069  'data-filelist-action-url' => $this->uriBuilder->buildUriFromRoute('file_download'),
1070  ]);
1071  $button->setIcon($this->iconFactory->getIcon('actions-download', IconSize::SMALL));
1072 
1073  return $button;
1074  }
1075 
1076  protected function ‪createControlUpload(‪ResourceView $resourceView): ?‪ButtonInterface
1077  {
1078  if (!$resourceView->resource->getStorage()->checkUserActionPermission('add', 'File')
1079  || !$resourceView->resource instanceof ‪Folder
1080  || !$resourceView->‪canWrite()) {
1081  return null;
1082  }
1083 
1084  $button = GeneralUtility::makeInstance(LinkButton::class);
1085  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.upload'));
1086  $button->setHref($this->uriBuilder->buildUriFromRoute('file_upload', ['target' => $resourceView->‪getIdentifier(), 'returnUrl' => $this->createModuleUri()]));
1087  $button->setIcon($this->iconFactory->getIcon('actions-edit-upload', IconSize::SMALL));
1088 
1089  return $button;
1090  }
1091 
1092  protected function ‪createControlInfo(‪ResourceView $resourceView): ?‪ButtonInterface
1093  {
1094  if (!$resourceView->‪canRead()) {
1095  return null;
1096  }
1097 
1098  $button = GeneralUtility::makeInstance(GenericButton::class);
1099  $button->setLabel($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.info'));
1100  $button->setAttributes([
1101  'type' => 'button',
1102  'data-filelist-action' => 'show',
1103  ]);
1104  $button->setIcon($this->iconFactory->getIcon('actions-document-info', IconSize::SMALL));
1105 
1106  return $button;
1107  }
1108 
1109  protected function ‪createControlDelete(‪ResourceView $resourceView): ?‪ButtonInterface
1110  {
1111  if (!$resourceView->‪canDelete()) {
1112  return null;
1113  }
1114 
1115  $recordInfo = $resourceView->‪getName();
1116 
1117  if ($resourceView->resource instanceof Folder) {
1118  ‪$identifier = $resourceView->‪getIdentifier();
1119  $referenceCountText = BackendUtility::referenceCount('_FILE', ‪$identifier, LF . $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.referencesToFolder'));
1120  $deleteType = 'delete_folder';
1121  if ($this->‪getBackendUser()->shallDisplayDebugInformation()) {
1122  $recordInfo .= ' [' . ‪$identifier . ']';
1123  }
1124  } else {
1125  $referenceCountText = BackendUtility::referenceCount('sys_file', (string)$resourceView->‪getUid(), LF . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.referencesToFile'));
1126  $deleteType = 'delete_file';
1127  if ($this->‪getBackendUser()->shallDisplayDebugInformation()) {
1128  $recordInfo .= ' [sys_file:' . $resourceView->‪getUid() . ']';
1129  }
1130  }
1131 
1132  $title = $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete');
1133  $button = GeneralUtility::makeInstance(GenericButton::class);
1134  $button->setLabel($title);
1135  $button->setIcon($this->iconFactory->getIcon('actions-edit-delete', IconSize::SMALL));
1136  $button->setAttributes([
1137  'type' => 'button',
1138  'data-title' => $title,
1139  'data-bs-content' => sprintf($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.delete'), trim($recordInfo)) . $referenceCountText,
1140  'data-filelist-action' => 'delete',
1141  'data-filelist-delete' => 'true',
1142  'data-filelist-delete-identifier' => $resourceView->‪getIdentifier(),
1143  'data-filelist-delete-url' => $this->uriBuilder->buildUriFromRoute('tce_file'),
1144  'data-filelist-delete-type' => $deleteType,
1145  'data-filelist-delete-check' => $this->getBackendUser()->jsConfirmation(‪JsConfirmation::DELETE) ? '1' : '0',
1146  ]);
1147 
1148  return $button;
1149  }
1150 
1157  protected function ‪createControlTranslation(ResourceView $resourceView): ?ButtonInterface
1158  {
1159  if (!$resourceView->resource instanceof File) {
1160  return null;
1161  }
1162 
1163  $backendUser = $this->‪getBackendUser();
1164 
1165  // Fetch all system languages except "default (0)" and "all languages (-1)"
1166  $systemLanguages = array_filter(
1167  $this->translateTools->getSystemLanguages(),
1168  static fn (array $languageRecord): bool => $languageRecord['uid'] > 0 && $backendUser->checkLanguageAccess($languageRecord['uid'])
1169  );
1170 
1171  if ($systemLanguages === []
1172  || !(‪$GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? false)
1173  || !$resourceView->resource->isIndexed()
1174  || !$resourceView->resource->checkActionPermission('editMeta')
1175  || !$backendUser->check('tables_modify', 'sys_file_metadata')
1176  ) {
1177  // Early return in case no system languages exists or metadata
1178  // of this file can not be created / edited by the current user.
1179  return null;
1180  }
1181 
1182  $dropdownItems = [];
1183  $metaDataRecord = $resourceView->resource->getMetaData()->get();
1184  $existingTranslations = $this->getTranslationsForMetaData($metaDataRecord);
1185 
1186  foreach ($systemLanguages as $languageId => $language) {
1187  if (!isset($existingTranslations[$languageId]) && !($metaDataRecord['uid'] ?? false)) {
1188  // Skip if neither a translation nor the metadata uid exists
1189  continue;
1190  }
1191 
1192  if (isset($existingTranslations[$languageId])) {
1193  // Set options for edit action of an existing translation
1194  $title = sprintf($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:editMetadataForLanguage'), $language['title']);
1195  $actionType = 'edit';
1196  ‪$url = (string)$this->uriBuilder->buildUriFromRoute(
1197  'record_edit',
1198  [
1199  'edit' => [
1200  'sys_file_metadata' => [
1201  $existingTranslations[$languageId]['uid'] => 'edit',
1202  ],
1203  ],
1204  'returnUrl' => $this->createModuleUri(),
1205  ]
1206  );
1207  } else {
1208  // Set options for "create new" action of a new translation
1209  $title = sprintf($this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:createMetadataForLanguage'), $language['title']);
1210  $actionType = 'new';
1211  $metaDataRecordId = (int)($metaDataRecord['uid'] ?? 0);
1212  ‪$url = (string)$this->uriBuilder->buildUriFromRoute(
1213  'tce_db',
1214  [
1215  'cmd' => [
1216  'sys_file_metadata' => [
1217  $metaDataRecordId => [
1218  'localize' => $languageId,
1219  ],
1220  ],
1221  ],
1222  'redirect' => (string)$this->uriBuilder->buildUriFromRoute(
1223  'record_edit',
1224  [
1225  'justLocalized' => 'sys_file_metadata:' . $metaDataRecordId . ':' . $languageId,
1226  'returnUrl' => $this->‪createModuleUri(),
1227  ]
1228  ),
1229  ]
1230  );
1231  }
1232 
1233  $dropdownItem = GeneralUtility::makeInstance(DropDownItem::class);
1234  $dropdownItem->setLabel($title);
1235  $dropdownItem->setHref(‪$url);
1236  $dropdownItem->setIcon($this->iconFactory->getIcon($language['flagIcon'], IconSize::SMALL, 'overlay-' . $actionType));
1237  $dropdownItems[] = $dropdownItem;
1238  }
1239 
1240  if (empty($dropdownItems)) {
1241  return null;
1242  }
1243 
1244  $dropdownButton = GeneralUtility::makeInstance(DropDownButton::class);
1245  $dropdownButton->setLabel('Translations');
1246  $dropdownButton->setIcon($this->iconFactory->getIcon('actions-translate', IconSize::SMALL));
1247  foreach ($dropdownItems as $dropdownItem) {
1248  $dropdownButton->addItem($dropdownItem);
1249  }
1250 
1251  return $dropdownButton;
1252  }
1253 
1254  protected function ‪createControlCopy(‪ResourceView $resourceView): ?‪ButtonInterface
1255  {
1256  if (!$resourceView->‪canRead() || !$resourceView->‪canCopy()) {
1257  return null;
1258  }
1259 
1260  if ($this->clipObj->current === 'normal') {
1261  $isSelected = $this->clipObj->isSelected('_FILE', md5($resourceView->‪getIdentifier()));
1262  $button = GeneralUtility::makeInstance(LinkButton::class);
1263  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.' . ($isSelected === 'copy' ? 'copyrelease' : 'copy')));
1264  $button->setHref($this->clipObj->selUrlFile($resourceView->‪getIdentifier(), true, $isSelected === 'copy'));
1265  $button->setIcon($this->iconFactory->getIcon($isSelected === 'copy' ? 'actions-edit-copy-release' : 'actions-edit-copy', IconSize::SMALL));
1266  return $button;
1267  }
1268 
1269  return null;
1270  }
1271 
1272  protected function ‪createControlCut(‪ResourceView $resourceView): ?‪ButtonInterface
1273  {
1274  if (!$resourceView->‪canRead() || !$resourceView->‪canMove()) {
1275  return null;
1276  }
1277 
1278  if ($this->clipObj->current === 'normal') {
1279  $isSelected = $this->clipObj->isSelected('_FILE', md5($resourceView->‪getIdentifier()));
1280  $button = GeneralUtility::makeInstance(LinkButton::class);
1281  $button->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.' . ($isSelected === 'cut' ? 'cutrelease' : 'cut')));
1282  $button->setHref($this->clipObj->selUrlFile($resourceView->‪getIdentifier(), true, $isSelected === 'cut'));
1283  $button->setIcon($this->iconFactory->getIcon($isSelected === 'cut' ? 'actions-edit-cut-release' : 'actions-edit-cut', IconSize::SMALL));
1284  $actions['cut'] = $button;
1285 
1286  return $button;
1287  }
1288 
1289  return null;
1290  }
1291 
1292  protected function ‪createControlPaste(‪ResourceView $resourceView): ?‪ButtonInterface
1293  {
1294  $permission = ($this->clipObj->clipData[$this->clipObj->current]['mode'] ?? '') === 'copy' ? 'copy' : 'move';
1295  $addPasteButton = $this->folderObject->checkActionPermission($permission);
1296  $elementFromTable = $this->clipObj->elFromTable('_FILE');
1297  if ($elementFromTable === []
1298  || !$addPasteButton
1299  || !$resourceView->‪canRead()
1300  || !$resourceView->‪canWrite()
1301  || !$resourceView->resource instanceof ‪Folder) {
1302  return null;
1303  }
1304 
1305  $elementsToConfirm = [];
1306  foreach ($elementFromTable as $key => $element) {
1307  $clipBoardElement = $this->resourceFactory->retrieveFileOrFolderObject($element);
1308  if ($clipBoardElement instanceof Folder
1309  && $clipBoardElement->getStorage()->isWithinFolder($clipBoardElement, $resourceView->resource)
1310  ) {
1311  // In case folder is already present in the target folder, return actions without paste button
1312  return null;
1313  }
1314  $elementsToConfirm[$key] = $clipBoardElement->getName();
1315  }
1316 
1317  $pasteTitle = $this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:clip_pasteInto');
1318  $button = GeneralUtility::makeInstance(LinkButton::class);
1319  $button->setTitle($pasteTitle);
1320  $button->setHref($this->clipObj->pasteUrl('_FILE', $resourceView->‪getIdentifier()));
1321  $button->setDataAttributes([
1322  'title' => $pasteTitle,
1323  'bs-content' => $this->clipObj->confirmMsgText('_FILE', $resourceView->‪getName(), 'into', $elementsToConfirm),
1324  ]);
1325  $button->setIcon($this->iconFactory->getIcon('actions-document-paste-into', IconSize::SMALL));
1326 
1327  return $button;
1328  }
1329 
1330  protected function ‪createControlUpdateOnlineMedia(‪ResourceView $resourceView): ?‪ButtonInterface
1331  {
1332  if (!($resourceView->resource instanceof ‪File)
1333  || !$resourceView->‪canEditMetadata()
1334  || !$this->onlineMediaHelperRegistry->hasOnlineMediaHelper($resourceView->resource->getExtension())
1335  ) {
1336  return null;
1337  }
1338 
1339  $title = $this->‪getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:reloadMetadata');
1340  $button = GeneralUtility::makeInstance(GenericButton::class);
1341  $button->setLabel($title);
1342  $button->setIcon($this->iconFactory->getIcon('actions-refresh', IconSize::SMALL));
1343  $button->setAttributes([
1344  'type' => 'button',
1345  'data-title' => $title,
1346  'data-filelist-action' => 'updateOnlineMedia',
1347  'data-filelist-action-url' => $this->uriBuilder->buildUriFromRoute('file_update_online_media'),
1348  ]);
1349 
1350  return $button;
1351  }
1352 
1353  protected function ‪isEditMetadataAllowed(‪File $file): bool
1354  {
1355  return $file->‪isIndexed()
1356  && $file->‪checkActionPermission('editMeta')
1357  && $this->‪getUserPermissions()->editMetaData;
1358  }
1359 
1365  protected function ‪renderCheckboxActions(): string
1366  {
1367  // Early return in case there are no items
1368  if (!$this->totalItems) {
1369  return '';
1370  }
1371 
1372  $lang = $this->‪getLanguageService();
1373 
1374  $dropdownItems['checkAll'] = '
1375  <li>
1376  <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-all" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll')) . '">
1377  <span class="dropdown-item-columns">
1378  <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
1379  ' . $this->iconFactory->getIcon('actions-selection-elements-all', IconSize::SMALL)->render() . '
1380  </span>
1381  <span class="dropdown-item-column dropdown-item-column-title">
1382  ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.checkAll')) . '
1383  </span>
1384  </span>
1385  </button>
1386  </li>';
1387 
1388  $dropdownItems['checkNone'] = '
1389  <li>
1390  <button type="button" class="dropdown-item disabled" data-multi-record-selection-check-action="check-none" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll')) . '">
1391  <span class="dropdown-item-columns">
1392  <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
1393  ' . $this->iconFactory->getIcon('actions-selection-elements-none', IconSize::SMALL)->render() . '
1394  </span>
1395  <span class="dropdown-item-column dropdown-item-column-title">
1396  ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.uncheckAll')) . '
1397  </span>
1398  </span>
1399  </button>
1400  </li>';
1401 
1402  $dropdownItems['toggleSelection'] = '
1403  <li>
1404  <button type="button" class="dropdown-item" data-multi-record-selection-check-action="toggle" title="' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection')) . '">
1405  <span class="dropdown-item-columns">
1406  <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
1407  ' . $this->iconFactory->getIcon('actions-selection-elements-invert', IconSize::SMALL)->render() . '
1408  </span>
1409  <span class="dropdown-item-column dropdown-item-column-title">
1410  ' . htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleSelection')) . '
1411  </span>
1412  </span>
1413  </button>
1414  </li>';
1415 
1416  return '
1417  <div class="btn-group dropdown">
1418  <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false">
1419  ' . $this->iconFactory->getIcon('actions-selection', IconSize::SMALL) . '
1420  </button>
1421  <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
1422  ' . implode(PHP_EOL, $dropdownItems) . '
1423  </ul>
1424  </div>';
1425  }
1426 
1431  protected function ‪getConcreteTableName(string $fieldName): string
1432  {
1433  return (‪$GLOBALS['TCA']['sys_file']['columns'][$fieldName] ?? false) ? 'sys_file' : 'sys_file_metadata';
1434  }
1435 
1437  {
1438  $currentPagination = new ‪SimplePagination($paginator);
1439  $targetPage = null;
1440  switch ($direction) {
1442  $targetPage = $currentPagination->getPreviousPageNumber();
1443  break;
1444  case NavigationDirection::FORWARD:
1445  $targetPage = $currentPagination->getNextPageNumber();
1446  break;
1447  }
1448 
1449  return $this->‪getPaginationLinkForPage($paginator, $targetPage);
1450  }
1451 
1452  protected function ‪getPaginationLinkForPage(‪ResourceCollectionPaginator $paginator, ?int $targetPage = null): ?‪PaginationLink
1453  {
1454  if ($targetPage === null) {
1455  return null;
1456  }
1457  if ($targetPage > $paginator->‪getNumberOfPages()) {
1458  return null;
1459  }
1460  if ($targetPage < 1) {
1461  return null;
1462  }
1463 
1464  $targetPaginator = $paginator->‪withCurrentPageNumber($targetPage);
1465  $targetPagination = new SimplePagination($targetPaginator);
1466 
1467  $uri = new Uri($this->request->getAttribute('normalizedParams')->getRequestUri());
1468  parse_str($uri->getQuery(), $queryParameters);
1469  unset($queryParameters['contentOnly']);
1470  $queryParameters = array_merge($queryParameters, ['currentPage' => $targetPage]);
1471  $uri = $uri->withQuery(‪HttpUtility::buildQueryString($queryParameters, '&'));
1472 
1473  return new PaginationLink(
1474  $targetPagination->getStartRecordNumber() . '-' . $targetPagination->getEndRecordNumber(),
1475  (string)$uri,
1476  );
1477  }
1478 
1482  public function ‪createModuleUri(array $params = []): ?string
1483  {
1485  $queryParams = ‪$request->getQueryParams();
1486  $parsedBody = ‪$request->getParsedBody();
1487 
1488  $route = ‪$request->getAttribute('route');
1489  if (!$route instanceof Route) {
1490  return null;
1491  }
1492 
1493  $baseParams = [
1494  'currentPage' => ‪$this->currentPage,
1495  'id' => $this->folderObject->getCombinedIdentifier(),
1496  'searchTerm' => $this->searchDemand ? $this->searchDemand->getSearchTerm() : '',
1497  ];
1498 
1499  // Keep ElementBrowser Settings
1500  if (‪$mode = $parsedBody['mode'] ?? $queryParams['mode'] ?? null) {
1501  $baseParams['mode'] = ‪$mode;
1502  }
1503  if ($bparams = $parsedBody['bparams'] ?? $queryParams['bparams'] ?? null) {
1504  $baseParams['bparams'] = $bparams;
1505  }
1506 
1507  // Keep LinkHandler Settings
1508  if ($act = ($parsedBody['act'] ?? $queryParams['act'] ?? null)) {
1509  $baseParams['act'] = $act;
1510  }
1511  if ($linkHandlerParams = ($parsedBody['P'] ?? $queryParams['P'] ?? null)) {
1512  $baseParams['P'] = $linkHandlerParams;
1513  }
1514 
1515  $params = array_replace_recursive($baseParams, $params);
1516 
1517  // Expanded folder is used in the element browser.
1518  // We always map it to the id here.
1519  $params['expandFolder'] = $params['id'];
1520  $params = array_filter($params, static function ($value) {
1521  return (is_array($value) && $value !== []) || (trim((string)$value) !== '');
1522  });
1523 
1524  return (string)$this->uriBuilder->buildUriFromRequest(‪$request, $params);
1525  }
1526 
1527  protected function ‪createEditDataUriForResource(‪ResourceInterface $resource): ?string
1528  {
1529  if ($resource instanceof ‪File
1530  && $this->‪isEditMetadataAllowed($resource)
1531  && ($metaDataUid = $resource->getMetaData()->offsetGet('uid'))
1532  ) {
1533  $parameter = [
1534  'edit' => ['sys_file_metadata' => [$metaDataUid => 'edit']],
1535  'returnUrl' => $this->‪createModuleUri(),
1536  ];
1537  return (string)$this->uriBuilder->buildUriFromRoute('record_edit', $parameter);
1538  }
1539 
1540  return null;
1541  }
1542 
1543  protected function ‪createEditContentUriForResource(‪ResourceInterface $resource): ?string
1544  {
1545  if ($resource instanceof ‪File
1546  && $resource->checkActionPermission('write')
1547  && $resource->isTextFile()
1548  ) {
1549  $parameter = [
1550  'target' => $resource->getCombinedIdentifier(),
1551  'returnUrl' => $this->‪createModuleUri(),
1552  ];
1553  return (string)$this->uriBuilder->buildUriFromRoute('file_edit', $parameter);
1554  }
1555 
1556  return null;
1557  }
1558 
1559  protected function ‪createModuleUriForResource(‪ResourceInterface $resource): ?string
1560  {
1561  if ($resource instanceof ‪Folder) {
1562  $parameter = [
1563  'id' => $resource->getCombinedIdentifier(),
1564  'searchTerm' => '',
1565  'currentPage' => 1,
1566  ];
1567  return (string)$this->‪createModuleUri($parameter);
1568  }
1569 
1570  if ($resource instanceof File) {
1571  return $this->‪createEditDataUriForResource($resource);
1572  }
1573 
1574  return null;
1575  }
1576 
1577  protected function ‪createReplaceUriForResource(‪ResourceInterface $resource): ?string
1578  {
1579  if ($resource instanceof ‪File
1580  && $resource->checkActionPermission('replace')
1581  ) {
1582  $parameter = [
1583  'target' => $resource->getCombinedIdentifier(),
1584  'uid' => $resource->getUid(),
1585  'returnUrl' => $this->‪createModuleUri(),
1586  ];
1587  return (string)$this->uriBuilder->buildUriFromRoute('file_replace', $parameter);
1588  }
1589  return null;
1590  }
1591 
1595  protected function ‪sortResources(array $resources, string $sortField): array
1596  {
1597  $collator = new \Collator((string)($this->‪getLanguageService()->getLocale() ?? 'en'));
1598  uksort($resources, function (int $index1, int $index2) use ($sortField, $resources, $collator) {
1599  $resource1 = $resources[$index1];
1600  $resource2 = $resources[$index2];
1601 
1602  // Folders are always prioritized above files
1603  if ($resource1 instanceof File && $resource2 instanceof Folder) {
1604  return 1;
1605  }
1606  if ($resource1 instanceof Folder && $resource2 instanceof File) {
1607  return -1;
1608  }
1609 
1610  return (int)$collator->compare(
1611  $this->getSortingValue($resource1, $sortField) . $index1,
1612  $this->getSortingValue($resource2, $sortField) . $index2
1613  );
1614  });
1615 
1616  if ($this->sortRev) {
1617  $resources = array_reverse($resources);
1618  }
1619 
1620  return $resources;
1621  }
1622 
1623  protected function ‪getSortingValue(‪ResourceInterface $resource, string $sortField): string
1624  {
1625  if ($resource instanceof ‪File) {
1626  return $this->‪getSortingValueForFile($resource, $sortField);
1627  }
1628  if ($resource instanceof Folder) {
1629  return $this->‪getSortingValueForFolder($resource, $sortField);
1630  }
1631 
1632  return '';
1633  }
1634 
1635  protected function ‪getSortingValueForFile(‪File $resource, string $sortField): string
1636  {
1637  switch ($sortField) {
1638  case 'fileext':
1639  return $resource->‪getExtension();
1640  case 'size':
1641  return $resource->getSize() . 's';
1642  case 'rw':
1643  return ($resource->‪checkActionPermission('read') ? 'R' : '')
1644  . ($resource->‪checkActionPermission('write') ? 'W' : '');
1645  case '_REF_':
1646  return $this->‪getFileReferenceCount($resource) . 'ref';
1647  case 'tstamp':
1648  return $resource->‪getModificationTime() . 't';
1649  case 'crdate':
1650  return $resource->‪getCreationTime() . 'c';
1651  default:
1652  return $resource->‪hasProperty($sortField) ? (string)$resource->‪getProperty($sortField) : '';
1653  }
1654  }
1655 
1656  protected function ‪getSortingValueForFolder(‪Folder $resource, string $sortField): string
1657  {
1658  switch ($sortField) {
1659  case 'size':
1660  try {
1661  $fileCount = $resource->‪getFileCount();
1663  $fileCount = 0;
1664  }
1665  return '0' . $fileCount . 's';
1666  case 'rw':
1667  return ($resource->‪checkActionPermission('read') ? 'R' : '')
1668  . ($resource->‪checkActionPermission('write') ? 'W' : '');
1669  case 'name':
1670  return $resource->‪getName();
1671  default:
1672  return '';
1673  }
1674  }
1675 
1676  protected function ‪getFieldLabel(string $field): string
1677  {
1678  $lang = $this->‪getLanguageService();
1679 
1680  if ($specialLabel = $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.' . $field)) {
1681  return $specialLabel;
1682  }
1683  if ($customLabel = $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:c_' . $field)) {
1684  return $customLabel;
1685  }
1686 
1687  $concreteTableName = $this->‪getConcreteTableName($field);
1688  $label = BackendUtility::getItemLabel($concreteTableName, $field);
1689 
1690  // In case global TSconfig exists we have to check if the label is overridden there
1691  $tsConfig = BackendUtility::getPagesTSconfig(0);
1692  $label = $lang->translateLabel(
1693  $tsConfig['TCEFORM.'][$concreteTableName . '.'][$field . '.']['label.'] ?? [],
1694  $tsConfig['TCEFORM.'][$concreteTableName . '.'][$field . '.']['label'] ?? $label
1695  );
1696 
1697  return $label;
1698  }
1699 
1705  protected function ‪getFileReferenceCount(File $file): int
1706  {
1707  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
1708  return (int)$queryBuilder
1709  ->count('*')
1710  ->from('sys_refindex')
1711  ->where(
1712  $queryBuilder->expr()->eq(
1713  'ref_table',
1714  $queryBuilder->createNamedParameter('sys_file')
1715  ),
1716  $queryBuilder->expr()->eq(
1717  'ref_uid',
1718  $queryBuilder->createNamedParameter($file->getUid(), ‪Connection::PARAM_INT)
1719  ),
1720  $queryBuilder->expr()->neq(
1721  'tablename',
1722  $queryBuilder->createNamedParameter('sys_file_metadata')
1723  )
1724  )
1725  ->executeQuery()
1726  ->fetchOne();
1727  }
1728 
1729  protected function ‪getUserPermissions(): ‪UserPermissions
1730  {
1731  return new ‪UserPermissions($this->‪getBackendUser()->check('tables_modify', 'sys_file_metadata'));
1732  }
1733 
1734  protected function ‪getLanguageService(): ‪LanguageService
1735  {
1736  return ‪$GLOBALS['LANG'];
1737  }
1738 
1739  protected function ‪getBackendUser(): ‪BackendUserAuthentication
1740  {
1741  return ‪$GLOBALS['BE_USER'];
1742  }
1743 }
‪TYPO3\CMS\Filelist\FileList\$addElement_tdCssClass
‪array $addElement_tdCssClass
Definition: FileList.php:129
‪TYPO3\CMS\Filelist\Dto\UserPermissions
Definition: UserPermissions.php:24
‪TYPO3\CMS\Filelist\FileList\setMode
‪setMode(Mode $mode)
Definition: FileList.php:247
‪TYPO3\CMS\Core\View\ViewInterface\render
‪render(string $templateFileName='')
‪TYPO3\CMS\Filelist\FileList\renderControl
‪renderControl(ResourceView $resourceView)
Definition: FileList.php:836
‪TYPO3\CMS\Filelist\Matcher\ResourceFolderTypeMatcher
Definition: ResourceFolderTypeMatcher.php:27
‪TYPO3\CMS\Core\Resource\ProcessedFile\CONTEXT_IMAGEPREVIEW
‪const CONTEXT_IMAGEPREVIEW
Definition: ProcessedFile.php:55
‪TYPO3\CMS\Filelist\Pagination\ResourceCollectionPaginator
Definition: ResourceCollectionPaginator.php:27
‪TYPO3\CMS\Filelist\FileList\createControlTranslation
‪createControlTranslation(ResourceView $resourceView)
Definition: FileList.php:1155
‪TYPO3\CMS\Filelist\FileList\$onlineMediaHelperRegistry
‪OnlineMediaHelperRegistry $onlineMediaHelperRegistry
Definition: FileList.php:160
‪TYPO3\CMS\Filelist\FileList\getBackendUser
‪getBackendUser()
Definition: FileList.php:1737
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:46
‪TYPO3\CMS\Filelist\FileList\createEditContentUriForResource
‪createEditContentUriForResource(ResourceInterface $resource)
Definition: FileList.php:1541
‪TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry
Definition: OnlineMediaHelperRegistry.php:27
‪TYPO3\CMS\Filelist\Matcher\ResourceFileExtensionMatcher
Definition: ResourceFileExtensionMatcher.php:26
‪TYPO3\CMS\Core\Utility\PathUtility\isAbsolutePath
‪static isAbsolutePath(string $path)
Definition: PathUtility.php:286
‪TYPO3\CMS\Filelist\Type\BACKWARD
‪@ BACKWARD
Definition: NavigationDirection.php:26
‪TYPO3\CMS\Core\View\ViewInterface
Definition: ViewInterface.php:24
‪TYPO3\CMS\Filelist\FileList\setColumnsToRender
‪setColumnsToRender(array $additionalFields=[])
Definition: FileList.php:253
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
Definition: InsufficientFolderAccessPermissionsException.php:24
‪TYPO3\CMS\Filelist\FileList\$translateTools
‪TranslationConfigurationProvider $translateTools
Definition: FileList.php:159
‪TYPO3\CMS\Backend\Clipboard\Clipboard
Definition: Clipboard.php:48
‪TYPO3\CMS\Filelist\FileList\createControlCopy
‪createControlCopy(ResourceView $resourceView)
Definition: FileList.php:1252
‪TYPO3\CMS\Backend\Template\Components\Buttons\GenericButton
Definition: GenericButton.php:34
‪TYPO3\CMS\Filelist\FileList\getFolderInfo
‪getFolderInfo()
Definition: FileList.php:410
‪TYPO3\CMS\Backend\Template\Components\Buttons\DropDownButton
Definition: DropDownButton.php:48
‪TYPO3\CMS\Filelist\FileList\$searchDemand
‪FileSearchDemand $searchDemand
Definition: FileList.php:153
‪TYPO3\CMS\Filelist\FileList\createControlUpload
‪createControlUpload(ResourceView $resourceView)
Definition: FileList.php:1074
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_DEFAULT
‪const ROLE_DEFAULT
Definition: FolderInterface.php:28
‪TYPO3\CMS\Filelist\Dto\ResourceView\isMissing
‪isMissing()
Definition: ResourceView.php:212
‪TYPO3\CMS\Filelist\Dto\ResourceView\getType
‪getType()
Definition: ResourceView.php:83
‪TYPO3\CMS\Filelist\FileList\renderType
‪renderType(ResourceView $resourceView)
Definition: FileList.php:682
‪TYPO3\CMS\Filelist\FileList\$resourceSelectableMatcher
‪Matcher $resourceSelectableMatcher
Definition: FileList.php:149
‪TYPO3\CMS\Filelist\FileList\$request
‪ServerRequestInterface $request
Definition: FileList.php:155
‪TYPO3\CMS\Filelist\FileList\$maxTitleLength
‪int $maxTitleLength
Definition: FileList.php:117
‪TYPO3\CMS\Core\Resource\File\isIndexed
‪isIndexed()
Definition: File.php:139
‪TYPO3\CMS\Filelist\FileList\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: FileList.php:154
‪TYPO3\CMS\Filelist\Dto\ResourceView\getPublicUrl
‪getPublicUrl()
Definition: ResourceView.php:117
‪TYPO3\CMS\Filelist\FileList\renderTiles
‪renderTiles(ResourceCollectionPaginator $paginator, array $resourceViews, ViewInterface $view)
Definition: FileList.php:261
‪TYPO3\CMS\Filelist\Dto\ResourceView\getUpdatedAt
‪getUpdatedAt()
Definition: ResourceView.php:185
‪TYPO3\CMS\Filelist\FileList\$resourceFactory
‪ResourceFactory $resourceFactory
Definition: FileList.php:157
‪TYPO3\CMS\Core\Resource\Folder\getFileCount
‪int getFileCount(array $filterMethods=[], $recursive=false)
Definition: Folder.php:241
‪TYPO3\CMS\Filelist\FileList\renderSize
‪renderSize(ResourceView $resourceView)
Definition: FileList.php:714
‪TYPO3\CMS\Filelist\FileList\createControlUpdateOnlineMedia
‪createControlUpdateOnlineMedia(ResourceView $resourceView)
Definition: FileList.php:1328
‪TYPO3\CMS\Filelist\FileList\getConcreteTableName
‪getConcreteTableName(string $fieldName)
Definition: FileList.php:1429
‪TYPO3\CMS\Filelist\Matcher\Matcher
Definition: Matcher.php:24
‪TYPO3\CMS\Filelist\FileList\renderListTableForwardBackwardNavigation
‪renderListTableForwardBackwardNavigation(ResourceCollectionPaginator $paginator, NavigationDirection $direction)
Definition: FileList.php:543
‪TYPO3\CMS\Core\Resource\AbstractFile\getExtension
‪getExtension()
Definition: AbstractFile.php:236
‪TYPO3\CMS\Filelist\FileList\$viewMode
‪ViewMode $viewMode
Definition: FileList.php:77
‪TYPO3\CMS\Core\Authentication\JsConfirmation
Definition: JsConfirmation.php:28
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Filelist\Type\NavigationDirection
‪NavigationDirection
Definition: NavigationDirection.php:24
‪TYPO3\CMS\Filelist\FileList\$clipObj
‪Clipboard $clipObj
Definition: FileList.php:142
‪TYPO3\CMS\Filelist\FileList\$thumbs
‪bool $thumbs
Definition: FileList.php:112
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getNumberOfPages
‪getNumberOfPages()
Definition: AbstractPaginator.php:68
‪TYPO3\CMS\Filelist\FileList\renderModificationTime
‪renderModificationTime(ResourceView $resourceView)
Definition: FileList.php:705
‪TYPO3\CMS\Filelist\Dto\ResourceView\getCheckboxConfig
‪getCheckboxConfig()
Definition: ResourceView.php:197
‪TYPO3\CMS\Filelist\FileList\renderReferenceCount
‪renderReferenceCount(ResourceView $resourceView)
Definition: FileList.php:812
‪TYPO3\CMS\Backend\Routing\Route
Definition: Route.php:24
‪TYPO3\CMS\Filelist\FileList\renderList
‪renderList(ResourceCollectionPaginator $paginator, array $resourceViews, ViewInterface $view)
Definition: FileList.php:277
‪TYPO3\CMS\Filelist\FileList\getUserPermissions
‪getUserPermissions()
Definition: FileList.php:1727
‪TYPO3\CMS\Filelist\Type\fieldArray
‪@ fieldArray
Definition: Mode.php:28
‪TYPO3\CMS\Core\View\ViewInterface\assign
‪assign(string $key, mixed $value)
‪TYPO3\CMS\Filelist\Event\ProcessFileListActionsEvent
Definition: ProcessFileListActionsEvent.php:27
‪TYPO3\CMS\Filelist\FileList\createModuleUriForResource
‪createModuleUriForResource(ResourceInterface $resource)
Definition: FileList.php:1557
‪TYPO3\CMS\Core\Pagination\SimplePagination
Definition: SimplePagination.php:21
‪TYPO3\CMS\Filelist\FileList\$sortRev
‪bool $sortRev
Definition: FileList.php:107
‪TYPO3\CMS\Filelist
‪TYPO3\CMS\Filelist\FileList\createControlDownload
‪createControlDownload(ResourceView $resourceView)
Definition: FileList.php:1052
‪TYPO3\CMS\Filelist\FileList\getSortingValueForFolder
‪getSortingValueForFolder(Folder $resource, string $sortField)
Definition: FileList.php:1654
‪TYPO3\CMS\Filelist\FileList\$resourceSelectedMatcher
‪Matcher $resourceSelectedMatcher
Definition: FileList.php:151
‪TYPO3\CMS\Filelist\Dto\ResourceView\canDelete
‪canDelete()
Definition: ResourceView.php:256
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:30
‪TYPO3\CMS\Filelist\FileList\$totalbytes
‪int $totalbytes
Definition: FileList.php:92
‪TYPO3\CMS\Core\Resource\File\getProperty
‪getProperty(string $key)
Definition: File.php:62
‪TYPO3\CMS\Filelist\FileList\$folderObject
‪Folder $folderObject
Definition: FileList.php:138
‪TYPO3\CMS\Backend\ElementBrowser\Event\IsFileSelectableEvent
Definition: IsFileSelectableEvent.php:26
‪TYPO3\CMS\Filelist\FileList\getFileReferenceCount
‪getFileReferenceCount(File $file)
Definition: FileList.php:1703
‪TYPO3\CMS\Filelist\FileList\$mode
‪Mode $mode
Definition: FileList.php:76
‪TYPO3\CMS\Filelist\FileList\renderPath
‪renderPath(ResourceView $resourceView)
Definition: FileList.php:803
‪TYPO3\CMS\Filelist\FileList\$resourceDownloadMatcher
‪Matcher $resourceDownloadMatcher
Definition: FileList.php:145
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\withCurrentPageNumber
‪withCurrentPageNumber(int $currentPageNumber)
Definition: AbstractPaginator.php:55
‪TYPO3\CMS\Filelist\FileList\$translationRecords
‪$translationRecords
Definition: FileList.php:587
‪TYPO3\CMS\Filelist\FileList\render
‪render(?FileSearchDemand $searchDemand, ViewInterface $view)
Definition: FileList.php:287
‪TYPO3\CMS\Filelist\FileList
Definition: FileList.php:75
‪TYPO3\CMS\Filelist\FileList\getSortingValueForFile
‪getSortingValueForFile(File $resource, string $sortField)
Definition: FileList.php:1633
‪TYPO3\CMS\Filelist\FileList\renderThumbnail
‪renderThumbnail(ResourceView $resourceView)
Definition: FileList.php:647
‪TYPO3\CMS\Filelist\Dto\ResourceView
Definition: ResourceView.php:34
‪TYPO3\CMS\Filelist\FileList\createControlInfo
‪createControlInfo(ResourceView $resourceView)
Definition: FileList.php:1090
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:26
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Filelist\FileList\createControlReplace
‪createControlReplace(ResourceView $resourceView)
Definition: FileList.php:1024
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Utility\HttpUtility\buildQueryString
‪static string buildQueryString(array $parameters, string $prependCharacter='', bool $skipEmptyParameters=false)
Definition: HttpUtility.php:124
‪TYPO3\CMS\Filelist\FileList\renderControlBrowse
‪renderControlBrowse(ResourceView $resourceView)
Definition: FileList.php:944
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:38
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Filelist\FileList\addElement
‪string addElement(array $data, array $attributes=[], bool $isTableHeader=false)
Definition: FileList.php:379
‪TYPO3\CMS\Filelist\Dto\ResourceView\canRename
‪canRename()
Definition: ResourceView.php:274
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Filelist\FileList\createControlSelect
‪createControlSelect(ResourceView $resourceView)
Definition: FileList.php:965
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪getStorage()
Definition: Folder.php:138
‪TYPO3\CMS\Core\Resource\Folder\checkActionPermission
‪bool checkActionPermission($action)
Definition: Folder.php:400
‪TYPO3\CMS\Filelist\Dto\ResourceView\getName
‪getName()
Definition: ResourceView.php:95
‪TYPO3\CMS\Filelist\FileList\$fieldArray
‪array $fieldArray
Definition: FileList.php:122
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:64
‪TYPO3\CMS\Core\Resource\Folder\getName
‪getName()
Definition: Folder.php:88
‪TYPO3\CMS\Filelist\FileList\renderListTableHeader
‪renderListTableHeader()
Definition: FileList.php:423
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_PROCESSING
‪const ROLE_PROCESSING
Definition: FolderInterface.php:30
‪TYPO3\CMS\Filelist\Type\Mode
‪Mode
Definition: Mode.php:24
‪TYPO3\CMS\Core\Resource\Folder\getRole
‪string getRole()
Definition: Folder.php:497
‪TYPO3\CMS\Filelist\Dto\ResourceView\getPreview
‪getPreview()
Definition: ResourceView.php:126
‪TYPO3\CMS\Filelist\FileList\$uriBuilder
‪UriBuilder $uriBuilder
Definition: FileList.php:158
‪TYPO3\CMS\Filelist\Dto\ResourceView\getUid
‪getUid()
Definition: ResourceView.php:51
‪TYPO3\CMS\Filelist\Dto\ResourceView\getIdentifier
‪getIdentifier()
Definition: ResourceView.php:60
‪TYPO3\CMS\Filelist\FileList\start
‪start(Folder $folderObject, int $currentPage, string $sort, bool $sortRev, Mode $mode=Mode::MANAGE)
Definition: FileList.php:234
‪TYPO3\CMS\Filelist\Dto\ResourceView\getMetaDataUid
‪getMetaDataUid()
Definition: ResourceView.php:73
‪TYPO3\CMS\Filelist\Dto\ResourceView\getCreatedAt
‪getCreatedAt()
Definition: ResourceView.php:173
‪TYPO3\CMS\Filelist\FileList\createControlEditContent
‪createControlEditContent(ResourceView $resourceView)
Definition: FileList.php:979
‪TYPO3\CMS\Filelist\FileList\createControlRename
‪createControlRename(ResourceView $resourceView)
Definition: FileList.php:1038
‪TYPO3\CMS\Filelist\FileList\createControlView
‪createControlView(ResourceView $resourceView)
Definition: FileList.php:1008
‪TYPO3\CMS\Filelist\FileList\getPaginationLinkForDirection
‪getPaginationLinkForDirection(ResourceCollectionPaginator $paginator, NavigationDirection $direction)
Definition: FileList.php:1434
‪TYPO3\CMS\Core\Resource\File\checkActionPermission
‪bool checkActionPermission($action)
Definition: File.php:208
‪TYPO3\CMS\Filelist\FileList\createEditDataUriForResource
‪createEditDataUriForResource(ResourceInterface $resource)
Definition: FileList.php:1525
‪TYPO3\CMS\Core\Resource\AbstractFile\getCreationTime
‪getCreationTime()
Definition: AbstractFile.php:212
‪TYPO3\CMS\Core\Authentication\JsConfirmation\DELETE
‪const DELETE
Definition: JsConfirmation.php:31
‪TYPO3\CMS\Filelist\FileList\$translations
‪foreach($translationRecords as $record) return $translations
Definition: FileList.php:603
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:47
‪TYPO3\CMS\Filelist\Dto\ResourceView\canRead
‪canRead()
Definition: ResourceView.php:238
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪return MathUtility::canBeInterpretedAsInteger($size) ?(int) $size int getUid()
Definition: AbstractFile.php:188
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:35
‪TYPO3\CMS\Filelist\FileList\setResourceSelectedMatcher
‪setResourceSelectedMatcher(?Matcher $matcher)
Definition: FileList.php:219
‪TYPO3\CMS\Webhooks\Message\$url
‪identifier readonly UriInterface $url
Definition: LoginErrorOccurredMessage.php:36
‪TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider
Definition: TranslationConfigurationProvider.php:39
‪TYPO3\CMS\Filelist\FileList\renderField
‪renderField(ResourceView $resourceView, string $field)
Definition: FileList.php:749
‪TYPO3\CMS\Filelist\FileList\createReplaceUriForResource
‪createReplaceUriForResource(ResourceInterface $resource)
Definition: FileList.php:1575
‪TYPO3\CMS\Filelist\FileList\$currentPage
‪int $currentPage
Definition: FileList.php:87
‪TYPO3\CMS\Filelist\FileList\createModuleUri
‪createModuleUri(array $params=[])
Definition: FileList.php:1480
‪TYPO3\CMS\Backend\Template\Components\Buttons\InputButton
Definition: InputButton.php:40
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Filelist\FileList\getPaginationLinkForPage
‪getPaginationLinkForPage(ResourceCollectionPaginator $paginator, ?int $targetPage=null)
Definition: FileList.php:1450
‪TYPO3\CMS\Filelist\FileList\renderListTableBody
‪renderListTableBody(array $resourceViews)
Definition: FileList.php:477
‪TYPO3\CMS\Filelist\FileList\$itemsPerPage
‪int $itemsPerPage
Definition: FileList.php:82
‪TYPO3\CMS\Filelist\FileList\renderPermission
‪renderPermission(ResourceView $resourceView)
Definition: FileList.php:738
‪TYPO3\CMS\Core\Resource\FolderInterface
Definition: FolderInterface.php:24
‪TYPO3\CMS\Filelist\FileList\renderIcon
‪renderIcon(ResourceView $resourceView)
Definition: FileList.php:613
‪TYPO3\CMS\Filelist\Type\TILES
‪@ TILES
Definition: ViewMode.php:26
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Filelist\FileList\getFieldLabel
‪getFieldLabel(string $field)
Definition: FileList.php:1674
‪TYPO3\CMS\Filelist\Dto\ResourceView\canEditMetadata
‪canEditMetadata()
Definition: ResourceView.php:230
‪TYPO3\CMS\Core\Resource\ResourceInterface
Definition: ResourceInterface.php:21
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:24
‪TYPO3\CMS\Filelist\FileList\renderSelector
‪renderSelector(ResourceView $resourceView)
Definition: FileList.php:777
‪TYPO3\CMS\Filelist\FileList\getLanguageService
‪getLanguageService()
Definition: FileList.php:1732
‪TYPO3\CMS\Filelist\Dto\ResourceView\canCopy
‪canCopy()
Definition: ResourceView.php:265
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Filelist\FileList\setResourceDownloadMatcher
‪setResourceDownloadMatcher(?Matcher $matcher)
Definition: FileList.php:201
‪TYPO3\CMS\Filelist\Dto\ResourceView\canMove
‪canMove()
Definition: ResourceView.php:283
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Filelist\FileList\sortResources
‪ResourceInterface[] sortResources(array $resources, string $sortField)
Definition: FileList.php:1593
‪TYPO3\CMS\Filelist\FileList\renderCheckboxActions
‪string renderCheckboxActions()
Definition: FileList.php:1363
‪TYPO3\CMS\Filelist\Dto\ResourceView\canWrite
‪canWrite()
Definition: ResourceView.php:247
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\getSearchTerm
‪getSearchTerm()
Definition: FileSearchDemand.php:75
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange(mixed $theInt, int $min, int $max=2000000000, int $defaultValue=0)
Definition: MathUtility.php:34
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Filelist\Type\ViewMode
‪ViewMode
Definition: ViewMode.php:24
‪TYPO3\CMS\Filelist\FileList\$resourceDisplayMatcher
‪Matcher $resourceDisplayMatcher
Definition: FileList.php:147
‪TYPO3\CMS\Core\Resource\AbstractFile\getModificationTime
‪getModificationTime()
Definition: AbstractFile.php:225
‪TYPO3\CMS\Filelist\FileList\getSortingValue
‪getSortingValue(ResourceInterface $resource, string $sortField)
Definition: FileList.php:1621
‪TYPO3\CMS\Filelist\FileList\__construct
‪__construct(ServerRequestInterface $request)
Definition: FileList.php:162
‪TYPO3\CMS\Filelist\FileList\$sort
‪string $sort
Definition: FileList.php:102
‪TYPO3\CMS\Filelist\Dto\ResourceCollection
Definition: ResourceCollection.php:28
‪TYPO3\CMS\Filelist\Dto\ResourceView\getPath
‪getPath()
Definition: ResourceView.php:104
‪TYPO3\CMS\Filelist\FileList\renderCreationTime
‪renderCreationTime(ResourceView $resourceView)
Definition: FileList.php:696
‪TYPO3\CMS\Filelist\FileList\$totalItems
‪int $totalItems
Definition: FileList.php:97
‪TYPO3\CMS\Filelist\FileList\renderListTableFieldHeader
‪renderListTableFieldHeader(string $field)
Definition: FileList.php:443
‪TYPO3\CMS\Filelist\FileList\setResourceDisplayMatcher
‪setResourceDisplayMatcher(?Matcher $matcher)
Definition: FileList.php:207
‪TYPO3\CMS\Filelist\FileList\$translations
‪$translations
Definition: FileList.php:602
‪TYPO3\CMS\Filelist\FileList\createControlDelete
‪createControlDelete(ResourceView $resourceView)
Definition: FileList.php:1107
‪TYPO3\CMS\Filelist\FileList\renderName
‪renderName(ResourceView $resourceView)
Definition: FileList.php:621
‪TYPO3\CMS\Filelist\FileList\createControlCut
‪createControlCut(ResourceView $resourceView)
Definition: FileList.php:1270
‪TYPO3\CMS\Filelist\FileList\isEditMetadataAllowed
‪isEditMetadataAllowed(File $file)
Definition: FileList.php:1351
‪TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownItem
Definition: DropDownItem.php:34
‪TYPO3\CMS\Filelist\FileList\renderControlManage
‪renderControlManage(ResourceView $resourceView)
Definition: FileList.php:851
‪TYPO3\CMS\Filelist\FileList\createControlEditMetaData
‪createControlEditMetaData(ResourceView $resourceView)
Definition: FileList.php:994
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Filelist\Dto\ResourceView\getIconSmall
‪getIconSmall()
Definition: ResourceView.php:149
‪TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface
Definition: ButtonInterface.php:22
‪TYPO3\CMS\Filelist\FileList\setResourceSelectableMatcher
‪setResourceSelectableMatcher(?Matcher $matcher)
Definition: FileList.php:213
‪TYPO3\CMS\Filelist\FileList\$iconFactory
‪IconFactory $iconFactory
Definition: FileList.php:156
‪TYPO3\CMS\Filelist\FileList\createControlPaste
‪createControlPaste(ResourceView $resourceView)
Definition: FileList.php:1290
‪TYPO3\CMS\Core\Resource\File\hasProperty
‪hasProperty($key)
Definition: File.php:76