‪TYPO3CMS  10.4
FileProvider.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
28 
33 {
37  protected ‪$record;
38 
42  protected ‪$itemsConfiguration = [
43  'edit' => [
44  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.edit',
45  'iconIdentifier' => 'actions-page-open',
46  'callbackAction' => 'editFile'
47  ],
48  'rename' => [
49  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.rename',
50  'iconIdentifier' => 'actions-edit-rename',
51  'callbackAction' => 'renameFile'
52  ],
53  'upload' => [
54  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.upload',
55  'iconIdentifier' => 'actions-edit-upload',
56  'callbackAction' => 'uploadFile'
57  ],
58  'new' => [
59  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.new',
60  'iconIdentifier' => 'actions-document-new',
61  'callbackAction' => 'createFile'
62  ],
63  'info' => [
64  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.info',
65  'iconIdentifier' => 'actions-document-info',
66  'callbackAction' => 'openInfoPopUp'
67  ],
68  'divider' => [
69  'type' => 'divider'
70  ],
71  'copy' => [
72  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.copy',
73  'iconIdentifier' => 'actions-edit-copy',
74  'callbackAction' => 'copyFile'
75  ],
76  'copyRelease' => [
77  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.copy',
78  'iconIdentifier' => 'actions-edit-copy-release',
79  'callbackAction' => 'copyReleaseFile'
80  ],
81  'cut' => [
82  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.cut',
83  'iconIdentifier' => 'actions-edit-cut',
84  'callbackAction' => 'cutFile'
85  ],
86  'cutRelease' => [
87  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.cutrelease',
88  'iconIdentifier' => 'actions-edit-cut-release',
89  'callbackAction' => 'cutReleaseFile'
90  ],
91  'pasteInto' => [
92  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.pasteinto',
93  'iconIdentifier' => 'actions-document-paste-into',
94  'callbackAction' => 'pasteFileInto'
95  ],
96  'divider2' => [
97  'type' => 'divider'
98  ],
99  'delete' => [
100  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete',
101  'iconIdentifier' => 'actions-edit-delete',
102  'callbackAction' => 'deleteFile'
103  ],
104  ];
105 
109  public function ‪canHandle(): bool
110  {
111  return $this->table === 'sys_file';
112  }
113 
117  protected function ‪initialize()
118  {
119  parent::initialize();
120  try {
121  $this->record = GeneralUtility::makeInstance(ResourceFactory::class)->retrieveFileOrFolderObject($this->identifier);
122  } catch (‪ResourceDoesNotExistException $e) {
123  $this->record = null;
124  }
125  }
126 
134  protected function ‪canRender(string $itemName, string $type): bool
135  {
136  if (in_array($type, ['divider', 'submenu'], true)) {
137  return true;
138  }
139  if (in_array($itemName, $this->disabledItems, true)) {
140  return false;
141  }
142  $canRender = false;
143  switch ($itemName) {
144  //just for files
145  case 'edit':
146  $canRender = $this->‪canBeEdited();
147  break;
148  case 'info':
149  $canRender = $this->‪canShowInfo();
150  break;
151 
152  //just for folders
153  case 'upload':
154  case 'new':
155  $canRender = $this->‪canCreateNew();
156  break;
157  case 'pasteInto':
158  $canRender = $this->‪canBePastedInto();
159  break;
160 
161  //for both files and folders
162  case 'rename':
163  $canRender = $this->‪canBeRenamed();
164  break;
165  case 'copy':
166  $canRender = $this->‪canBeCopied();
167  break;
168  case 'copyRelease':
169  $canRender = $this->‪isRecordInClipboard('copy');
170  break;
171  case 'cut':
172  $canRender = $this->‪canBeCut();
173  break;
174  case 'cutRelease':
175  $canRender = $this->‪isRecordInClipboard('cut');
176  break;
177  case 'delete':
178  $canRender = $this->‪canBeDeleted();
179  break;
180  }
181  return $canRender;
182  }
183 
187  protected function ‪canBeEdited(): bool
188  {
189  return $this->‪isFile()
190  && $this->record->checkActionPermission('write')
191  && $this->record->isTextFile();
192  }
193 
197  protected function ‪canBeRenamed(): bool
198  {
199  return $this->record->checkActionPermission('rename');
200  }
201 
205  protected function ‪canBeDeleted(): bool
206  {
207  return $this->record->checkActionPermission('delete');
208  }
209 
213  protected function ‪canShowInfo(): bool
214  {
215  return $this->‪isFile();
216  }
217 
221  protected function ‪canCreateNew(): bool
222  {
223  return $this->‪isFolder() && $this->record->checkActionPermission('write');
224  }
225 
229  protected function ‪canBeCopied(): bool
230  {
231  return $this->record->checkActionPermission('read') && $this->record->checkActionPermission('copy') && !$this->‪isRecordInClipboard('copy');
232  }
233 
237  protected function ‪canBeCut(): bool
238  {
239  return $this->record->checkActionPermission('move') && !$this->‪isRecordInClipboard('cut');
240  }
241 
245  protected function ‪canBePastedInto(): bool
246  {
247  $elArr = $this->clipboard->elFromTable('_FILE');
248  if (empty($elArr)) {
249  return false;
250  }
251  $selItem = reset($elArr);
252  $fileOrFolderInClipBoard = GeneralUtility::makeInstance(ResourceFactory::class)->retrieveFileOrFolderObject($selItem);
253 
254  return $this->‪isFolder()
255  && $this->record->checkActionPermission('write')
256  && (
257  !$fileOrFolderInClipBoard instanceof ‪Folder
258  || !$fileOrFolderInClipBoard->‪getStorage()->‪isWithinFolder($fileOrFolderInClipBoard, $this->record)
259  )
260  && $this->‪isFoldersAreInTheSameRoot($fileOrFolderInClipBoard);
261  }
262 
270  protected function ‪isFoldersAreInTheSameRoot($fileOrFolderInClipBoard): bool
271  {
272  return (!$fileOrFolderInClipBoard instanceof ‪Folder)
273  || (
274  $this->record->getStorage()->getRootLevelFolder()->getCombinedIdentifier()
275  == $fileOrFolderInClipBoard->getStorage()->getRootLevelFolder()->getCombinedIdentifier()
276  );
277  }
278 
285  protected function ‪isRecordInClipboard(string $mode = ''): bool
286  {
287  if ($mode !== '' && !$this->record->checkActionPermission($mode)) {
288  return false;
289  }
290  $isSelected = '';
291  // Pseudo table name for use in the clipboard.
292  ‪$table = '_FILE';
293  $uid = GeneralUtility::shortMD5($this->record->getCombinedIdentifier());
294  if ($this->clipboard->current === 'normal') {
295  $isSelected = $this->clipboard->isSelected(‪$table, $uid);
296  }
297  return $mode === '' ? !empty($isSelected) : $isSelected === $mode;
298  }
299 
303  protected function ‪isStorageRoot(): bool
304  {
305  return $this->record->getIdentifier() === $this->record->getStorage()->getRootLevelFolder()->getIdentifier();
306  }
307 
311  protected function ‪isFile(): bool
312  {
313  return $this->record instanceof ‪File;
314  }
315 
319  protected function ‪isFolder(): bool
320  {
321  return $this->record instanceof ‪Folder;
322  }
323 
328  protected function ‪getAdditionalAttributes(string $itemName): array
329  {
330  $attributes = [
331  'data-callback-module' => 'TYPO3/CMS/Filelist/ContextMenuActions'
332  ];
333  if ($itemName === 'delete' && $this->backendUser->jsConfirmation(‪JsConfirmation::DELETE)) {
334  $recordTitle = GeneralUtility::fixed_lgd_cs($this->record->getName(), $this->backendUser->uc['titleLen']);
335 
336  $title = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete');
337  $confirmMessage = sprintf(
338  $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.delete'),
339  $recordTitle
340  );
341  if ($this->‪isFolder()) {
342  $confirmMessage .= ‪BackendUtility::referenceCount(
343  '_FILE',
344  $this->record->getIdentifier(),
345  ' ' . $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.referencesToFolder')
346  );
347  } else {
348  $confirmMessage .= ‪BackendUtility::referenceCount(
349  'sys_file',
350  (string)$this->record->getUid(),
351  ' ' . $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.referencesToFile')
352  );
353  }
354  $closeText = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:button.cancel');
355  $deleteText = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:button.delete');
356  $attributes += [
357  'data-title' => htmlspecialchars($title),
358  'data-message' => htmlspecialchars($confirmMessage),
359  'data-button-close-text' => htmlspecialchars($closeText),
360  'data-button-ok-text' => htmlspecialchars($deleteText),
361  ];
362  }
363  if ($itemName === 'pasteInto' && $this->backendUser->jsConfirmation(‪JsConfirmation::COPY_MOVE_PASTE)) {
364  $elArr = $this->clipboard->elFromTable('_FILE');
365  $selItem = reset($elArr);
366  $fileOrFolderInClipBoard = GeneralUtility::makeInstance(ResourceFactory::class)->retrieveFileOrFolderObject($selItem);
367 
368  $title = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:clip_paste');
369 
370  $confirmMessage = sprintf(
371  $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.'
372  . ($this->clipboard->currentMode() === 'copy' ? 'copy' : 'move') . '_into'),
373  $fileOrFolderInClipBoard->getName(),
374  $this->record->getName()
375  );
376  $closeText = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:button.cancel');
377  $okLabel = $this->clipboard->currentMode() === 'copy' ? 'copy' : 'pasteinto';
378  $okText = $this->languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.' . $okLabel);
379  $attributes += [
380  'data-title' => htmlspecialchars($title),
381  'data-message' => htmlspecialchars($confirmMessage),
382  'data-button-close-text' => htmlspecialchars($closeText),
383  'data-button-ok-text' => htmlspecialchars($okText),
384  ];
385  }
386 
387  return $attributes;
388  }
389 
393  protected function ‪getIdentifier(): string
394  {
395  return $this->record->getCombinedIdentifier();
396  }
397 }
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\getIdentifier
‪string getIdentifier()
Definition: FileProvider.php:391
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\isStorageRoot
‪bool isStorageRoot()
Definition: FileProvider.php:301
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\isFoldersAreInTheSameRoot
‪bool isFoldersAreInTheSameRoot($fileOrFolderInClipBoard)
Definition: FileProvider.php:268
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\$record
‪File Folder $record
Definition: FileProvider.php:36
‪TYPO3\CMS\Backend\ContextMenu\ItemProviders\AbstractProvider\$table
‪string $table
Definition: AbstractProvider.php:63
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canHandle
‪bool canHandle()
Definition: FileProvider.php:107
‪TYPO3\CMS\Backend\ContextMenu\ItemProviders\AbstractProvider
Definition: AbstractProvider.php:31
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBeCopied
‪bool canBeCopied()
Definition: FileProvider.php:227
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBeDeleted
‪bool canBeDeleted()
Definition: FileProvider.php:203
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\isFolder
‪bool isFolder()
Definition: FileProvider.php:317
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation\COPY_MOVE_PASTE
‪const COPY_MOVE_PASTE
Definition: JsConfirmation.php:34
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\initialize
‪initialize()
Definition: FileProvider.php:115
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation\DELETE
‪const DELETE
Definition: JsConfirmation.php:39
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:149
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canRender
‪bool canRender(string $itemName, string $type)
Definition: FileProvider.php:132
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders
Definition: FileDragProvider.php:18
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider
Definition: FileProvider.php:33
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\$itemsConfiguration
‪array $itemsConfiguration
Definition: FileProvider.php:40
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
Definition: ResourceDoesNotExistException.php:24
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Core\Resource\ResourceStorage\isWithinFolder
‪bool isWithinFolder(Folder $folder, ResourceInterface $resource)
Definition: ResourceStorage.php:2596
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBeCut
‪bool canBeCut()
Definition: FileProvider.php:235
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canShowInfo
‪bool canShowInfo()
Definition: FileProvider.php:211
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\getAdditionalAttributes
‪array getAdditionalAttributes(string $itemName)
Definition: FileProvider.php:326
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBeEdited
‪bool canBeEdited()
Definition: FileProvider.php:185
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canCreateNew
‪bool canCreateNew()
Definition: FileProvider.php:219
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\isRecordInClipboard
‪bool isRecordInClipboard(string $mode='')
Definition: FileProvider.php:283
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Type\Bitmask\JsConfirmation
Definition: JsConfirmation.php:25
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\isFile
‪bool isFile()
Definition: FileProvider.php:309
‪TYPO3\CMS\Backend\Utility\BackendUtility\referenceCount
‪static string int referenceCount($table, $ref, $msg='', $count=null)
Definition: BackendUtility.php:3311
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBeRenamed
‪bool canBeRenamed()
Definition: FileProvider.php:195
‪TYPO3\CMS\Filelist\ContextMenu\ItemProviders\FileProvider\canBePastedInto
‪bool canBePastedInto()
Definition: FileProvider.php:243