‪TYPO3CMS  11.5
FileStorageTreeProvider.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 
32 
39 {
40  protected ?array ‪$expandedState = null;
41  protected string ‪$userSettingsIdentifier = 'BackendComponents.States.FileStorageTree';
42 
43  public function ‪prepareFolderInformation(‪Folder $folder, ?string $alternativeName = null): array
44  {
45  $name = $alternativeName ?? $folder->‪getName();
46  $storage = $folder->‪getStorage();
47  try {
48  $parentFolder = $folder->‪getParentFolder();
50  $parentFolder = null;
51  }
52  if (str_contains($folder->‪getRole(), ‪FolderInterface::ROLE_MOUNT)) {
53  $tableName = 'sys_filemount';
54  $isStorage = true;
55  } elseif ($parentFolder === null || $folder->‪getIdentifier() === $storage->getRootLevelFolder(true)->getIdentifier()) {
56  $tableName = 'sys_file_storage';
57  $isStorage = true;
58  } else {
59  $tableName = 'sys_file';
60  $isStorage = false;
61  }
62 
63  try {
64  $hasSubfolders = !empty($folder->getSubfolders());
65  } catch (\InvalidArgumentException | ‪InsufficientFolderReadPermissionsException $e) {
66  $hasSubfolders = false;
67  }
68 
69  return [
70  'resource' => $folder,
71  'stateIdentifier' => $this->‪getStateIdentifier($folder),
72  'identifier' => rawurlencode($folder->‪getCombinedIdentifier()),
73  'name' => $name,
74  'storage' => $storage->getUid(),
75  'pathIdentifier' => rawurlencode($folder->‪getIdentifier()),
76  'hasChildren' => $hasSubfolders,
77  'parentIdentifier' => $parentFolder instanceof ‪Folder && !$isStorage ? rawurlencode($parentFolder->getCombinedIdentifier()) : null,
78  'itemType' => $tableName,
79  ];
80  }
81 
88  public function ‪getRootNodes(‪BackendUserAuthentication $user): array
89  {
90  $items = [];
91  $storages = $user->‪getFileStorages();
92  foreach ($storages as $storageObject) {
93  $items = array_merge($items, $this->‪getFoldersInStorage($storageObject, $user));
94  }
95  return $items;
96  }
97 
105  protected function ‪getFoldersInStorage(‪ResourceStorage $resourceStorage, ‪BackendUserAuthentication $user): array
106  {
107  $rootLevelFolders = $this->‪getMountsInStorage($resourceStorage, $user);
108  $items = [];
109  foreach ($rootLevelFolders as $i => $rootLevelFolderInfo) {
111  $rootLevelFolder = $rootLevelFolderInfo['folder'];
112  // Root level is always expanded if not defined otherwise
113  $expanded = $this->‪isExpanded($rootLevelFolder, true);
114 
115  $itm = $this->‪prepareFolderInformation($rootLevelFolder, $rootLevelFolderInfo['name']);
116  $itm['depth'] = 0;
117  $itm['expanded'] = $expanded;
118  $itm['loaded'] = $expanded;
119  $itm['siblingsCount'] = count($rootLevelFolders) - 1;
120  $itm['siblingsPosition'] = $i;
121  $items[] = $itm;
122 
123  // If the mount is expanded, go down:
124  if ($expanded && $resourceStorage->‪isBrowsable()) {
125  $childItems = $this->‪getSubfoldersRecursively($rootLevelFolder, 1);
126  array_push($items, ...$childItems);
127  }
128  }
129  return $items;
130  }
131 
140  public function ‪getFilteredTree(‪BackendUserAuthentication $user, string $search): array
141  {
142  $foundFolders = [];
143  $storages = $user->‪getFileStorages();
144  foreach ($storages as $resourceStorage) {
145  $processingFolders = $resourceStorage->‪getProcessingFolders();
146  $processingFolderIdentifiers = array_map(static function ($folder) {
147  return $folder->getIdentifier();
148  }, $processingFolders);
149  $resourceStorage->addFileAndFolderNameFilter(static function ($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, ‪DriverInterface $driver) use ($resourceStorage, $search, $processingFolderIdentifiers) {
150  // Skip items in processing folders
151  $isInProcessingFolder = array_filter($processingFolderIdentifiers, static function ($processingFolderIdentifier) use ($parentIdentifier) {
152  return stripos($parentIdentifier, $processingFolderIdentifier) !== false;
153  });
154  if (!empty($isInProcessingFolder)) {
155  return -1;
156  }
157  if ($itemName instanceof ‪Folder) {
158  if ($resourceStorage->isProcessingFolder($itemName)) {
159  return -1;
160  }
161  $name = $itemName->getName();
162  } elseif (is_string($itemName)) {
163  $name = $itemName;
164  } else {
165  return -1;
166  }
167  if (stripos($name, $search) !== false) {
168  return true;
169  }
170  return -1;
171  });
172  try {
173  $files = $resourceStorage->getFilesInFolder($resourceStorage->getRootLevelFolder(), 0, 0, true, true);
174  foreach ($files as $file) {
175  $folder = $file->‪getParentFolder();
176  $foundFolders[$folder->getCombinedIdentifier()] = $folder;
177  }
178  $folders = $resourceStorage->getFolderIdentifiersInFolder($resourceStorage->getRootLevelFolder()->getIdentifier(), true, true);
179  foreach ($folders as $folder) {
180  $folderObj = $resourceStorage->getFolder($folder);
181  $foundFolders[$folderObj->getCombinedIdentifier()] = $folderObj;
182  }
184  // do nothing
185  }
186  $resourceStorage->resetFileAndFolderNameFiltersToDefault();
187  }
188  return $foundFolders;
189  }
190 
191  public function ‪getSubfoldersRecursively(‪Folder $folderObject, int $currentDepth): array
192  {
193  $items = [];
194  if ($folderObject instanceof ‪InaccessibleFolder) {
195  $subFolders = [];
196  } else {
197  $subFolders = $folderObject->getSubfolders();
198  $subFolders = ListUtility::resolveSpecialFolderNames($subFolders);
199  uksort($subFolders, 'strnatcasecmp');
200  }
201 
202  $subFolderCounter = 0;
203  foreach ($subFolders as $subFolderName => $subFolder) {
204  $subFolderName = (string)$subFolderName; // Enforce string cast in case $subFolderName contains numeric chars only
205  $expanded = $this->‪isExpanded($subFolder);
206  if (!($subFolder instanceof ‪InaccessibleFolder)) {
207  $children = $subFolder->getSubfolders();
208  } else {
209  $children = [];
210  }
211 
212  $items[] = array_merge(
213  $this->‪prepareFolderInformation($subFolder, $subFolderName),
214  [
215  'depth' => $currentDepth,
216  'expanded' => $expanded,
217  'loaded' => $expanded,
218  'siblingsCount' => count($subFolders) - 1,
219  'siblingsPosition' => ++$subFolderCounter,
220  ]
221  );
222 
223  if ($expanded && !empty($children)) {
224  $childItems = $this->‪getSubfoldersRecursively($subFolder, $currentDepth + 1);
225  array_push($items, ...$childItems);
226  }
227  }
228  return $items;
229  }
230 
238  protected function ‪getMountsInStorage(‪ResourceStorage $resourceStorage, ‪BackendUserAuthentication $user): array
239  {
240  $fileMounts = $resourceStorage->‪getFileMounts();
241  if (!empty($fileMounts)) {
242  return array_map(static function ($fileMountInfo) {
243  return [
244  'folder' => $fileMountInfo['folder'],
245  'name' => $fileMountInfo['title'],
246  ];
247  }, $fileMounts);
248  }
249 
250  if ($user->‪isAdmin()) {
251  return [
252  [
253  'folder' => $resourceStorage->‪getRootLevelFolder(),
254  'name' => $resourceStorage->‪getName(),
255  ],
256  ];
257  }
258  return [];
259  }
260 
268  protected function ‪getStateIdentifier(‪Folder $folder): string
269  {
270  return $folder->‪getStorage()->‪getUid() . '_' . GeneralUtility::md5int($folder->‪getIdentifier());
271  }
272 
280  protected function ‪isExpanded(‪Folder $folder, bool $fallback = false): bool
281  {
282  $stateIdentifier = $this->‪getStateIdentifier($folder);
283  if (!is_array($this->expandedState)) {
284  $this->expandedState = GeneralUtility::makeInstance(BackendUserConfiguration::class)->get($this->userSettingsIdentifier);
285  $this->expandedState = ($this->expandedState['stateHash'] ?? []) ?: [];
286  }
287  return (bool)($this->expandedState[$stateIdentifier] ?? $fallback);
288  }
289 }
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\isExpanded
‪bool isExpanded(Folder $folder, bool $fallback=false)
Definition: FileStorageTreeProvider.php:280
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getMountsInStorage
‪array array[] getMountsInStorage(ResourceStorage $resourceStorage, BackendUserAuthentication $user)
Definition: FileStorageTreeProvider.php:238
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:330
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
Definition: InsufficientFolderAccessPermissionsException.php:23
‪TYPO3\CMS\Core\Resource\Folder\getParentFolder
‪FolderInterface getParentFolder()
Definition: Folder.php:550
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\$expandedState
‪array $expandedState
Definition: FileStorageTreeProvider.php:40
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:245
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider
Definition: FileStorageTreeProvider.php:39
‪TYPO3\CMS\Core\Resource\Driver\DriverInterface
Definition: DriverInterface.php:23
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getFilteredTree
‪FolderInterface[] getFilteredTree(BackendUserAuthentication $user, string $search)
Definition: FileStorageTreeProvider.php:140
‪TYPO3\CMS\Backend\Tree
Definition: AbstractTree.php:16
‪TYPO3\CMS\Core\Resource\ResourceStorage\getProcessingFolders
‪Folder[] getProcessingFolders()
Definition: ResourceStorage.php:1705
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getRootNodes
‪array getRootNodes(BackendUserAuthentication $user)
Definition: FileStorageTreeProvider.php:88
‪TYPO3\CMS\Core\Resource\Utility\ListUtility
Definition: ListUtility.php:26
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getFileStorages
‪TYPO3 CMS Core Resource ResourceStorage[] getFileStorages()
Definition: BackendUserAuthentication.php:1506
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getFoldersInStorage
‪array getFoldersInStorage(ResourceStorage $resourceStorage, BackendUserAuthentication $user)
Definition: FileStorageTreeProvider.php:105
‪TYPO3\CMS\Core\Resource\ResourceStorage\getRootLevelFolder
‪Folder getRootLevelFolder($respectFileMounts=true)
Definition: ResourceStorage.php:2654
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getStateIdentifier
‪string getStateIdentifier(Folder $folder)
Definition: FileStorageTreeProvider.php:268
‪TYPO3\CMS\Core\Resource\Folder\getName
‪string getName()
Definition: Folder.php:94
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:149
‪TYPO3\CMS\Core\Resource\InaccessibleFolder
Definition: InaccessibleFolder.php:29
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\getSubfoldersRecursively
‪getSubfoldersRecursively(Folder $folderObject, int $currentDepth)
Definition: FileStorageTreeProvider.php:191
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\$userSettingsIdentifier
‪string $userSettingsIdentifier
Definition: FileStorageTreeProvider.php:41
‪TYPO3\CMS\Backend\Configuration\BackendUserConfiguration
Definition: BackendUserConfiguration.php:30
‪TYPO3\CMS\Core\Resource\ResourceStorage\isBrowsable
‪bool isBrowsable()
Definition: ResourceStorage.php:413
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException
Definition: FolderDoesNotExistException.php:21
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileMounts
‪array getFileMounts()
Definition: ResourceStorage.php:598
‪TYPO3\CMS\Core\Resource\Folder\getRole
‪string getRole()
Definition: Folder.php:535
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_MOUNT
‪const ROLE_MOUNT
Definition: FolderInterface.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪TYPO3\CMS\Backend\Tree\FileStorageTreeProvider\prepareFolderInformation
‪prepareFolderInformation(Folder $folder, ?string $alternativeName=null)
Definition: FileStorageTreeProvider.php:43
‪TYPO3\CMS\Core\Resource\FolderInterface
Definition: FolderInterface.php:22
‪TYPO3\CMS\Core\Resource\Folder\getIdentifier
‪string getIdentifier()
Definition: Folder.php:160
‪TYPO3\CMS\Core\Resource\Folder\getCombinedIdentifier
‪string getCombinedIdentifier()
Definition: Folder.php:181
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Resource\ResourceStorage\getName
‪string getName()
Definition: ResourceStorage.php:320
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderReadPermissionsException
Definition: InsufficientFolderReadPermissionsException.php:21