4f9c49501a7f1ea8fd068c17c6572a185e545e59
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / FormDataProvider / TcaGroup.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\FormDataProvider;
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\Backend\Clipboard\Clipboard;
18 use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
20 use TYPO3\CMS\Core\Database\RelationHandler;
21 use TYPO3\CMS\Core\Resource\Exception;
22 use TYPO3\CMS\Core\Resource\Folder;
23 use TYPO3\CMS\Core\Resource\ResourceFactory;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25 use TYPO3\CMS\Core\Utility\MathUtility;
26
27 /**
28 * Resolve databaseRow field content to the real connected rows for type=group
29 */
30 class TcaGroup implements FormDataProviderInterface
31 {
32 /**
33 * Initialize new row with default values from various sources
34 *
35 * @param array $result
36 * @return array
37 * @throws \UnexpectedValueException
38 * @throws \RuntimeException
39 */
40 public function addData(array $result)
41 {
42 foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
43 if (empty($fieldConfig['config']['type'])
44 || $fieldConfig['config']['type'] !== 'group'
45 || empty($fieldConfig['config']['internal_type'])
46 ) {
47 continue;
48 }
49
50 // Sanitize max items, set to 99999 if not defined
51 $result['processedTca']['columns'][$fieldName]['config']['maxitems'] = MathUtility::forceIntegerInRange(
52 $fieldConfig['config']['maxitems'],
53 0,
54 99999
55 );
56 if ($result['processedTca']['columns'][$fieldName]['config']['maxitems'] === 0) {
57 $result['processedTca']['columns'][$fieldName]['config']['maxitems'] = 99999;
58 }
59
60 $databaseRowFieldContent = '';
61 if (!empty($result['databaseRow'][$fieldName])) {
62 $databaseRowFieldContent = (string)$result['databaseRow'][$fieldName];
63 }
64
65 $items = [];
66 $sanitizedClipboardElements = [];
67 $internalType = $fieldConfig['config']['internal_type'];
68
69 if ($internalType === 'file_reference' || $internalType === 'file') {
70 // Set 'allowed' config to "*" if not set
71 if (empty($fieldConfig['config']['allowed'])) {
72 $result['processedTca']['columns'][$fieldName]['config']['allowed'] = '*';
73 }
74 // Force empty uploadfolder for file_reference type
75 if ($internalType === 'file_reference') {
76 $result['processedTca']['columns'][$fieldName]['config']['uploadfolder'] = '';
77 }
78
79 // Simple list of files
80 $fileList = GeneralUtility::trimExplode(',', $databaseRowFieldContent, true);
81 $fileFactory = ResourceFactory::getInstance();
82 foreach ($fileList as $uidOrPath) {
83 $item = [
84 'uidOrPath' => $uidOrPath,
85 'title' => $uidOrPath,
86 ];
87 try {
88 if (MathUtility::canBeInterpretedAsInteger($uidOrPath)) {
89 $fileObject = $fileFactory->getFileObject($uidOrPath);
90 $item['title'] = $fileObject->getName();
91 }
92 } catch (Exception $exception) {
93 continue;
94 }
95 $items[] = $item;
96 }
97
98 // Register elements from clipboard
99 $allowed = GeneralUtility::trimExplode(',', $result['processedTca']['columns'][$fieldName]['config']['allowed'], true);
100 $clipboard = GeneralUtility::makeInstance(Clipboard::class);
101 $clipboard->initializeClipboard();
102 $clipboardElements = $clipboard->elFromTable('_FILE');
103 if ($allowed[0] !== '*') {
104 // If there are a set of allowed extensions, filter the content
105 foreach ($clipboardElements as $elementValue) {
106 $pathInfo = pathinfo($elementValue);
107 if (in_array(strtolower($pathInfo['extension']), $allowed)) {
108 $sanitizedClipboardElements[] = [
109 'title' => $elementValue,
110 'value' => $elementValue,
111 ];
112 }
113 }
114 } else {
115 // If all is allowed, insert all. This does NOT respect any disallowed extensions,
116 // but those will be filtered away by the DataHandler
117 foreach ($clipboardElements as $elementValue) {
118 $sanitizedClipboardElements[] = [
119 'title' => $elementValue,
120 'value' => $elementValue,
121 ];
122 }
123 }
124 } elseif ($internalType === 'db') {
125 if (empty($fieldConfig['config']['allowed'])) {
126 throw new \RuntimeException(
127 'Mandatory TCA config setting "allowed" missing in field "' . $fieldName . '" of table "' . $result['tableName'] . '"',
128 1482250512
129 );
130 }
131
132 $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
133 $relationHandler->start(
134 $databaseRowFieldContent,
135 $fieldConfig['config']['allowed'],
136 $fieldConfig['config']['MM'],
137 $result['databaseRow']['uid'],
138 $result['tableName'],
139 $fieldConfig['config']
140 );
141 $relationHandler->getFromDB();
142 $relations = $relationHandler->getResolvedItemArray();
143 foreach ($relations as $relation) {
144 $tableName = $relation['table'];
145 $uid = $relation['uid'];
146 $record = BackendUtility::getRecordWSOL($tableName, $uid);
147 $title = BackendUtility::getRecordTitle($tableName, $record, false, false);
148 $items[] = [
149 'table' => $tableName,
150 'uid' => $record['uid'],
151 'title' => $title,
152 'row' => $record,
153 ];
154 }
155
156 // Register elements from clipboard
157 $allowed = GeneralUtility::trimExplode(',', $fieldConfig['config']['allowed'], true);
158 $clipboard = GeneralUtility::makeInstance(Clipboard::class);
159 $clipboard->initializeClipboard();
160 if ($allowed[0] !== '*') {
161 // Only some tables, filter them:
162 foreach ($allowed as $tablename) {
163 $elementValue = key($clipboard->elFromTable($tablename));
164 if ($elementValue) {
165 list($elementTable, $elementUid) = explode('|', $elementValue);
166 $record = BackendUtility::getRecordWSOL($elementTable, $elementUid);
167 $sanitizedClipboardElements[] = [
168 'title' => BackendUtility::getRecordTitle($elementTable, $record),
169 'value' => $elementTable . '_' . $elementUid,
170 ];
171 }
172 }
173 } else {
174 // All tables allowed for relation:
175 $clipboardElements = array_keys($clipboard->elFromTable(''));
176 foreach ($clipboardElements as $elementValue) {
177 list($elementTable, $elementUid) = explode('|', $elementValue);
178 $record = BackendUtility::getRecordWSOL($elementTable, $elementUid);
179 $sanitizedClipboardElements[] = [
180 'title' => BackendUtility::getRecordTitle($elementTable, $record),
181 'value' => $elementTable . '_' . $elementUid,
182 ];
183 }
184 }
185 } elseif ($internalType === 'folder') {
186 // Simple list of folders
187 $folderList = GeneralUtility::trimExplode(',', $databaseRowFieldContent, true);
188 foreach ($folderList as $folder) {
189 if (empty($folder)) {
190 continue;
191 }
192 try {
193 $folderObject = ResourceFactory::getInstance()->retrieveFileOrFolderObject($folder);
194 if ($folderObject instanceof Folder) {
195 $items[] = [
196 'folder' => $folder,
197 ];
198 }
199 } catch (Exception $exception) {
200 continue;
201 }
202 }
203 } else {
204 throw new \UnexpectedValueException(
205 'TCA internal_type of field "' . $fieldName . '" in table ' . $result['tableName']
206 . ' must be set to either "db", "file" or "file_reference"',
207 1438780511
208 );
209 }
210
211 $result['databaseRow'][$fieldName] = $items;
212 $result['processedTca']['columns'][$fieldName]['config']['clipboardElements'] = $sanitizedClipboardElements;
213 }
214
215 return $result;
216 }
217 }