TYPO3 CMS  TYPO3_8-7
TcaInlineConfiguration.php
Go to the documentation of this file.
1 <?php
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 
19 
24 {
32  public function addData(array $result)
33  {
34  foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
35  if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'inline') {
36  continue;
37  }
38 
39  // Throw if an inline field without foreign_table is set
40  if (!isset($fieldConfig['config']['foreign_table'])) {
41  throw new \UnexpectedValueException(
42  'Inline field ' . $fieldName . ' of table ' . $result['tableName'] . ' must have a foreign_table config',
43  1443793404
44  );
45  }
46 
47  $result = $this->initializeMinMaxItems($result, $fieldName);
48  $result = $this->initializeLocalizationMode($result, $fieldName);
49  $result = $this->initializeChildrenLanguage($result, $fieldName);
50  $result = $this->initializeAppearance($result, $fieldName);
51  $result = $this->addInlineSelectorAndUniqueConfiguration($result, $fieldName);
52  }
53 
54  return $result;
55  }
56 
65  protected function initializeMinMaxItems(array $result, $fieldName)
66  {
67  $config = $result['processedTca']['columns'][$fieldName]['config'];
68 
69  $minItems = 0;
70  if (isset($config['minitems'])) {
71  $minItems = MathUtility::forceIntegerInRange($config['minitems'], 0);
72  }
73  $result['processedTca']['columns'][$fieldName]['config']['minitems'] = $minItems;
74 
75  $maxItems = 99999;
76  if (isset($config['maxitems'])) {
77  $maxItems = MathUtility::forceIntegerInRange($config['maxitems'], 1);
78  }
79  $result['processedTca']['columns'][$fieldName]['config']['maxitems'] = $maxItems;
80 
81  return $result;
82  }
83 
92  protected function initializeAppearance(array $result, $fieldName)
93  {
94  $config = $result['processedTca']['columns'][$fieldName]['config'];
95  if (!isset($config['appearance']) || !is_array($config['appearance'])) {
96  // Init appearance if not set
97  $config['appearance'] = [];
98  }
99  // Set the position/appearance of the "Create new record" link
100  if (isset($config['foreign_selector']) && $config['foreign_selector']
101  && (!isset($config['appearance']['useCombination']) || !$config['appearance']['useCombination'])
102  ) {
103  $config['appearance']['levelLinksPosition'] = 'none';
104  } elseif (!isset($config['appearance']['levelLinksPosition'])
105  || !in_array($config['appearance']['levelLinksPosition'], ['top', 'bottom', 'both', 'none'], true)
106  ) {
107  $config['appearance']['levelLinksPosition'] = 'top';
108  }
109  $config['appearance']['showPossibleLocalizationRecords']
110  = isset($config['appearance']['showPossibleLocalizationRecords']) && $config['appearance']['showPossibleLocalizationRecords'];
111  $config['appearance']['showRemovedLocalizationRecords']
112  = isset($config['appearance']['showRemovedLocalizationRecords']) && $config['appearance']['showRemovedLocalizationRecords'];
113  // Defines which controls should be shown in header of each record
114  $enabledControls = [
115  'info' => true,
116  'new' => true,
117  'dragdrop' => true,
118  'sort' => true,
119  'hide' => true,
120  'delete' => true,
121  'localize' => true,
122  ];
123  if (isset($config['appearance']['enabledControls']) && is_array($config['appearance']['enabledControls'])) {
124  $config['appearance']['enabledControls'] = array_merge($enabledControls, $config['appearance']['enabledControls']);
125  } else {
126  $config['appearance']['enabledControls'] = $enabledControls;
127  }
128  $result['processedTca']['columns'][$fieldName]['config'] = $config;
129 
130  return $result;
131  }
132 
144  protected function initializeLocalizationMode(array $result, $fieldName)
145  {
146  if ($result['defaultLanguageRow'] === null) {
147  // Currently handled parent is a localized row if a former provider added the "default" row
148  // If handled record is not localized, set localizationMode to 'none' and return
149  // @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
150  $result['processedTca']['columns'][$fieldName]['config']['behaviour']['localizationMode'] = 'none';
151 
152  return $result;
153  }
154 
155  $childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
156  $parentConfig = $result['processedTca']['columns'][$fieldName]['config'];
157 
158  $isChildTableLocalizable = false;
159  if (isset($GLOBALS['TCA'][$childTableName]['ctrl']) && is_array($GLOBALS['TCA'][$childTableName]['ctrl'])
160  && isset($GLOBALS['TCA'][$childTableName]['ctrl']['languageField'])
161  && $GLOBALS['TCA'][$childTableName]['ctrl']['languageField']
162  && isset($GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField'])
163  && $GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField']
164  ) {
165  $isChildTableLocalizable = true;
166  }
167 
168  $mode = null;
169 
170  if (isset($parentConfig['behaviour']['localizationMode'])) {
171  // Use explicit set mode, but validate before use
172  // Use mode if set, but throw if not set to either 'select' or 'keep'
173  if ($parentConfig['behaviour']['localizationMode'] !== 'keep' && $parentConfig['behaviour']['localizationMode'] !== 'select') {
174  throw new \UnexpectedValueException(
175  'localizationMode of table ' . $result['tableName'] . ' field ' . $fieldName . ' is not valid, set to either \'keep\' or \'select\'',
176  1443829370
177  );
178  }
179  // Throw if is set to select, but child can not be localized
180  if ($parentConfig['behaviour']['localizationMode'] === 'select' && !$isChildTableLocalizable) {
181  throw new \UnexpectedValueException(
182  'Wrong configuration: localizationMode of table ' . $result['tableName'] . ' field ' . $fieldName . ' is set to \'select\', but table is not localizable.',
183  1443944274
184  );
185  }
186  $mode = $parentConfig['behaviour']['localizationMode'];
187  } else {
188  // Not set explicitly -> use "none"
189  $mode = 'none';
190  if ($isChildTableLocalizable) {
191  // Except if child is localizable, then use "select"
192  $mode = 'select';
193  }
194  }
195 
196  // @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
197  $result['processedTca']['columns'][$fieldName]['config']['behaviour']['localizationMode'] = $mode;
198 
199  return $result;
200  }
201 
215  protected function initializeChildrenLanguage(array $result, $fieldName)
216  {
217  $childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
218 
219  if (empty($result['processedTca']['ctrl']['languageField'])
220  || empty($GLOBALS['TCA'][$childTableName]['ctrl']['languageField'])
221  ) {
222  return $result;
223  }
224 
225  $parentConfig = $result['processedTca']['columns'][$fieldName]['config'];
226  if ($parentConfig['behaviour']['localizationMode'] === 'keep') {
227  return $result;
228  }
229 
230  $parentLanguageField = $result['processedTca']['ctrl']['languageField'];
231  if (!isset($parentConfig['inline']['parentSysLanguageUid'])
232  && isset($result['databaseRow'][$parentLanguageField])
233  ) {
234  if (is_array($result['databaseRow'][$parentLanguageField])) {
235  $result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid']
236  = (int)$result['databaseRow'][$parentLanguageField][0];
237  } else {
238  $result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid']
239  = (int)$result['databaseRow'][$parentLanguageField];
240  }
241  }
242 
243  return $result;
244  }
245 
260  protected function addInlineSelectorAndUniqueConfiguration(array $result, $fieldName)
261  {
262  $config = $result['processedTca']['columns'][$fieldName]['config'];
263 
264  // Early return if neither foreign_unique nor foreign_selector are set
265  if (!isset($config['foreign_unique']) && !isset($config['foreign_selector'])) {
266  return $result;
267  }
268 
269  // If both are set, they must point to the same field
270  if (isset($config['foreign_unique']) && isset($config['foreign_selector'])
271  && $config['foreign_unique'] !== $config['foreign_selector']
272  ) {
273  throw new \UnexpectedValueException(
274  'Table ' . $result['tableName'] . ' field ' . $fieldName . ': If both foreign_unique and'
275  . ' foreign_selector are set, they must point to the same field',
276  1444995464
277  );
278  }
279 
280  if (isset($config['foreign_unique'])) {
281  $fieldNameInChildConfiguration = $config['foreign_unique'];
282  } else {
283  $fieldNameInChildConfiguration = $config['foreign_selector'];
284  }
285 
286  // Throw if field name in globals does not exist or is not of type select or group
287  if (!isset($GLOBALS['TCA'][$config['foreign_table']]['columns'][$fieldNameInChildConfiguration]['config']['type'])
288  || ($GLOBALS['TCA'][$config['foreign_table']]['columns'][$fieldNameInChildConfiguration]['config']['type'] !== 'select'
289  && $GLOBALS['TCA'][$config['foreign_table']]['columns'][$fieldNameInChildConfiguration]['config']['type'] !== 'group')
290  ) {
291  throw new \UnexpectedValueException(
292  'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points in foreign_selector or foreign_unique'
293  . ' to field ' . $fieldNameInChildConfiguration . ' of table ' . $config['foreign_table'] . ', but this field'
294  . ' is either not defined or is not of type select or group',
295  1444996537
296  );
297  }
298 
299  $selectorOrUniqueConfiguration = [
300  'config' => $GLOBALS['TCA'][$config['foreign_table']]['columns'][$fieldNameInChildConfiguration]['config'],
301  ];
302 
303  // Throw if field is type group, but not internal_type db
304  if ($selectorOrUniqueConfiguration['config']['type'] === 'group'
305  && (!isset($selectorOrUniqueConfiguration['config']['internal_type']) || $selectorOrUniqueConfiguration['config']['internal_type'] !== 'db')
306  ) {
307  throw new \UnexpectedValueException(
308  'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points in foreign_selector or foreign_unique'
309  . ' to field ' . $fieldNameInChildConfiguration . ' of table ' . $config['foreign_table'] . '. This field'
310  . ' is of type group and must be of internal_type db, which is not the case',
311  1444999130
312  );
313  }
314 
315  // Merge overrideChildTca of foreign_selector if given
316  if (isset($config['foreign_selector'], $config['overrideChildTca']['columns'][$config['foreign_selector']]['config'])
317  && is_array($config['overrideChildTca']['columns'][$config['foreign_selector']]['config'])
318  ) {
319  $selectorOrUniqueConfiguration['config'] = array_replace_recursive($selectorOrUniqueConfiguration['config'], $config['overrideChildTca']['columns'][$config['foreign_selector']]['config']);
320  }
321 
322  // Add field name to config for easy access later
323  $selectorOrUniqueConfiguration['fieldName'] = $fieldNameInChildConfiguration;
324 
325  // Add remote table name for easy access later
326  if ($selectorOrUniqueConfiguration['config']['type'] === 'select') {
327  if (!isset($selectorOrUniqueConfiguration['config']['foreign_table'])) {
328  throw new \UnexpectedValueException(
329  'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points in foreign_selector or foreign_unique'
330  . ' to field ' . $fieldNameInChildConfiguration . ' of table ' . $config['foreign_table'] . '. This field'
331  . ' is of type select and must define foreign_table',
332  1445078627
333  );
334  }
335  $foreignTable = $selectorOrUniqueConfiguration['config']['foreign_table'];
336  } else {
337  if (!isset($selectorOrUniqueConfiguration['config']['allowed'])) {
338  throw new \UnexpectedValueException(
339  'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points in foreign_selector or foreign_unique'
340  . ' to field ' . $fieldNameInChildConfiguration . ' of table ' . $config['foreign_table'] . '. This field'
341  . ' is of type select and must define allowed',
342  1445078628
343  );
344  }
345  $foreignTable = $selectorOrUniqueConfiguration['config']['allowed'];
346  }
347  $selectorOrUniqueConfiguration['foreignTable'] = $foreignTable;
348 
349  // If this is a foreign_selector field, mark it as such for data fetching later
350  $selectorOrUniqueConfiguration['isSelector'] = false;
351  if (isset($config['foreign_selector'])) {
352  $selectorOrUniqueConfiguration['isSelector'] = true;
353  }
354 
355  // If this is a foreign_unique field, mark it a such for unique data fetching later
356  $selectorOrUniqueConfiguration['isUnique'] = false;
357  if (isset($config['foreign_unique'])) {
358  $selectorOrUniqueConfiguration['isUnique'] = true;
359  }
360 
361  // Add field configuration to inline configuration
362  $result['processedTca']['columns'][$fieldName]['config']['selectorOrUniqueConfiguration'] = $selectorOrUniqueConfiguration;
363 
364  return $result;
365  }
366 }
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']