Revert "[TASK] Avoid slow array functions in loops"
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / Service / UserFileMountService.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource\Service;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
18 use TYPO3\CMS\Core\Messaging\FlashMessage;
19 use TYPO3\CMS\Core\Messaging\FlashMessageService;
20 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderReadPermissionsException;
21 use TYPO3\CMS\Core\Resource\Folder;
22 use TYPO3\CMS\Core\Resource\StorageRepository;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Service class for implementing the user filemounts,
27 * used for BE_USER (\TYPO3\CMS\Core\Authentication\BackendUserAuthentication)
28 * and TCEforms hooks
29 *
30 * Note: This is now also used by sys_file_category table (fieldname "folder")!
31 */
32 class UserFileMountService
33 {
34 /**
35 * User function for sys_filemounts (the userfilemounts)
36 * to render a dropdown for selecting a folder
37 * of a selected mount
38 *
39 * @param array $PA the array with additional configuration options.
40 */
41 public function renderTceformsSelectDropdown(&$PA)
42 {
43 $allowedStorageIds = array_map(
44 function (\TYPO3\CMS\Core\Resource\ResourceStorage $storage) {
45 return $storage->getUid();
46 },
47 $this->getBackendUserAuthentication()->getFileStorages()
48 );
49 // If working for sys_filemounts table
50 $storageUid = (int)$PA['row']['base'][0];
51 if (!$storageUid) {
52 // If working for sys_file_collection table
53 $storageUid = (int)$PA['row']['storage'][0];
54 }
55 if ($storageUid > 0 && in_array($storageUid, $allowedStorageIds, true)) {
56 /** @var StorageRepository $storageRepository */
57 $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
58 /** @var \TYPO3\CMS\Core\Resource\ResourceStorage $storage */
59 $storage = $storageRepository->findByUid($storageUid);
60 if ($storage === null) {
61 /** @var FlashMessageService $flashMessageService */
62 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
63 $queue = $flashMessageService->getMessageQueueByIdentifier();
64 $queue->enqueue(new FlashMessage('Storage #' . $storageUid . ' does not exist. No folder is currently selectable.', '', FlashMessage::ERROR));
65 if (empty($PA['items'])) {
66 $PA['items'][] = [
67 $PA['row'][$PA['field']],
68 $PA['row'][$PA['field']]
69 ];
70 }
71 } elseif ($storage->isBrowsable()) {
72 $rootLevelFolders = [];
73
74 $fileMounts = $storage->getFileMounts();
75 if (!empty($fileMounts)) {
76 foreach ($fileMounts as $fileMountInfo) {
77 $rootLevelFolders[] = $fileMountInfo['folder'];
78 }
79 } else {
80 $rootLevelFolders[] = $storage->getRootLevelFolder();
81 }
82
83 foreach ($rootLevelFolders as $rootLevelFolder) {
84 $folderItems = $this->getSubfoldersForOptionList($rootLevelFolder);
85 foreach ($folderItems as $item) {
86 $PA['items'][] = [
87 $item->getIdentifier(),
88 $item->getIdentifier()
89 ];
90 }
91 }
92 } else {
93 /** @var FlashMessageService $flashMessageService */
94 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
95 $queue = $flashMessageService->getMessageQueueByIdentifier();
96 $queue->enqueue(new FlashMessage('Storage "' . $storage->getName() . '" is not browsable. No folder is currently selectable.', '', FlashMessage::WARNING));
97 if (empty($PA['items'])) {
98 $PA['items'][] = [
99 $PA['row'][$PA['field']],
100 $PA['row'][$PA['field']]
101 ];
102 }
103 }
104 } else {
105 $PA['items'][] = ['', 'Please choose a FAL mount from above first.'];
106 }
107 }
108
109 /**
110 * Simple function to make a hierarchical subfolder request into
111 * a "flat" option list
112 *
113 * @param Folder $parentFolder
114 * @param int $level a limiter
115 * @return Folder[]
116 */
117 protected function getSubfoldersForOptionList(Folder $parentFolder, $level = 0)
118 {
119 $level++;
120 // hard break on recursion
121 if ($level > 99) {
122 return [];
123 }
124 $allFolderItems = [$parentFolder];
125 $subFolders = $parentFolder->getSubfolders();
126 foreach ($subFolders as $subFolder) {
127 try {
128 $subFolderItems = $this->getSubfoldersForOptionList($subFolder, $level);
129 } catch (InsufficientFolderReadPermissionsException $e) {
130 $subFolderItems = [];
131 }
132 $allFolderItems = array_merge($allFolderItems, $subFolderItems);
133 }
134 return $allFolderItems;
135 }
136
137 /**
138 * Returns the BE USER Object
139 *
140 * @return BackendUserAuthentication
141 */
142 protected function getBackendUserAuthentication(): BackendUserAuthentication
143 {
144 return $GLOBALS['BE_USER'];
145 }
146 }