[SECURITY] Escape record title in RecordsOverview
[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\Messaging\FlashMessage;
18 use TYPO3\CMS\Core\Messaging\FlashMessageService;
19 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderReadPermissionsException;
20 use TYPO3\CMS\Core\Resource\Folder;
21 use TYPO3\CMS\Core\Resource\StorageRepository;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24 /**
25 * Service class for implementing the user filemounts,
26 * used for BE_USER (\TYPO3\CMS\Core\Authentication\BackendUserAuthentication)
27 * and TCEforms hooks
28 *
29 * Note: This is now also used by sys_file_category table (fieldname "folder")!
30 */
31 class UserFileMountService
32 {
33 /**
34 * User function for sys_filemounts (the userfilemounts)
35 * to render a dropdown for selecting a folder
36 * of a selected mount
37 *
38 * @param array $PA the array with additional configuration options.
39 * @return string The HTML code for the TCEform field
40 */
41 public function renderTceformsSelectDropdown(&$PA)
42 {
43 // If working for sys_filemounts table
44 $storageUid = (int)$PA['row']['base'][0];
45 if (!$storageUid) {
46 // If working for sys_file_collection table
47 $storageUid = (int)$PA['row']['storage'][0];
48 }
49 if ($storageUid > 0) {
50 /** @var $storageRepository StorageRepository */
51 $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
52 /** @var $storage \TYPO3\CMS\Core\Resource\ResourceStorage */
53 $storage = $storageRepository->findByUid($storageUid);
54 if ($storage === null) {
55 /** @var FlashMessageService $flashMessageService */
56 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
57 $queue = $flashMessageService->getMessageQueueByIdentifier();
58 $queue->enqueue(new FlashMessage('Storage #' . $storageUid . ' does not exist. No folder is currently selectable.', '', FlashMessage::ERROR));
59 if (empty($PA['items'])) {
60 $PA['items'][] = [
61 $PA['row'][$PA['field']],
62 $PA['row'][$PA['field']]
63 ];
64 }
65 } elseif ($storage->isBrowsable()) {
66 $rootLevelFolders = [];
67
68 $fileMounts = $storage->getFileMounts();
69 if (!empty($fileMounts)) {
70 foreach ($fileMounts as $fileMountInfo) {
71 $rootLevelFolders[] = $fileMountInfo['folder'];
72 }
73 } else {
74 $rootLevelFolders[] = $storage->getRootLevelFolder();
75 }
76
77 foreach ($rootLevelFolders as $rootLevelFolder) {
78 $folderItems = $this->getSubfoldersForOptionList($rootLevelFolder);
79 foreach ($folderItems as $item) {
80 $PA['items'][] = [
81 $item->getIdentifier(),
82 $item->getIdentifier()
83 ];
84 }
85 }
86 } else {
87 /** @var FlashMessageService $flashMessageService */
88 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
89 $queue = $flashMessageService->getMessageQueueByIdentifier();
90 $queue->enqueue(new FlashMessage('Storage "' . $storage->getName() . '" is not browsable. No folder is currently selectable.', '', FlashMessage::WARNING));
91 if (empty($PA['items'])) {
92 $PA['items'][] = [
93 $PA['row'][$PA['field']],
94 $PA['row'][$PA['field']]
95 ];
96 }
97 }
98 } else {
99 $PA['items'][] = ['', 'Please choose a FAL mount from above first.'];
100 }
101 }
102
103 /**
104 * Simple function to make a hierarchical subfolder request into
105 * a "flat" option list
106 *
107 * @param Folder $parentFolder
108 * @param int $level a limiter
109 * @return Folder[]
110 */
111 protected function getSubfoldersForOptionList(Folder $parentFolder, $level = 0)
112 {
113 $level++;
114 // hard break on recursion
115 if ($level > 99) {
116 return [];
117 }
118 $allFolderItems = [$parentFolder];
119 $subFolders = $parentFolder->getSubfolders();
120 foreach ($subFolders as $subFolder) {
121 try {
122 $subFolderItems = $this->getSubfoldersForOptionList($subFolder, $level);
123 } catch (InsufficientFolderReadPermissionsException $e) {
124 $subFolderItems = [];
125 }
126 $allFolderItems = array_merge($allFolderItems, $subFolderItems);
127 }
128 return $allFolderItems;
129 }
130 }