‪TYPO3CMS  10.4
DatabaseRecordTypeValue.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
21 
26 {
38  public function ‪addData(array $result)
39  {
40  if (!isset($result['processedTca']['types'])
41  || !is_array($result['processedTca']['types'])
42  || empty($result['processedTca']['types'])
43  ) {
44  throw new \UnexpectedValueException(
45  'At least one "types" array must be defined for table ' . $result['tableName'] . ', preferred "0"',
46  1438185331
47  );
48  }
49 
50  // Guard clause to suppress any calculation if record type value has been set from outside already
51  if ($result['recordTypeValue'] !== '') {
52  return $result;
53  }
54 
55  $recordTypeValue = '0';
56  if (!empty($result['processedTca']['ctrl']['type'])) {
57  $tcaTypeField = $result['processedTca']['ctrl']['type'];
58 
59  if (strpos($tcaTypeField, ':') === false) {
60  // $tcaTypeField is the name of a field in database row
61  if (!array_key_exists($tcaTypeField, $result['databaseRow'])) {
62  throw new \UnexpectedValueException(
63  'TCA table ' . $result['tableName'] . ' ctrl[\'type\'] is set to ' . $tcaTypeField . ', but'
64  . ' this field does not exist in the database of this table',
65  1438183881
66  );
67  }
68  $recordTypeValue = $result['databaseRow'][$tcaTypeField];
69  } else {
70  // If type is configured as localField:foreignField, fetch the type value from
71  // a foreign table. localField then point to a group or select field in the own table,
72  // this points to a record in a foreign table and the value of foreignField is then
73  // used as type field. This was introduced for some FAL scenarios.
74  [$pointerField, $foreignTableTypeField] = explode(':', $tcaTypeField);
75 
76  $relationType = $result['processedTca']['columns'][$pointerField]['config']['type'];
77  if ($relationType !== 'select' && $relationType !== 'group') {
78  throw new \UnexpectedValueException(
79  'TCA foreign field pointer fields are only allowed to be used with group or select field types.'
80  . ' Handling field ' . $pointerField . ' with type configured as ' . $tcaTypeField,
81  1325862241
82  );
83  }
84 
85  $foreignUid = $result['databaseRow'][$pointerField];
86  // Resolve the foreign record only if there is a uid, otherwise fall back 0
87  if (!empty($foreignUid)) {
88  // Determine table name to fetch record from
89  if ($relationType === 'select') {
90  $foreignTable = $result['processedTca']['columns'][$pointerField]['config']['foreign_table'] ?? '';
91  } else {
92  $allowedTables = explode(',', $result['processedTca']['columns'][$pointerField]['config']['allowed']);
93  // Always take the first configured table.
94  $foreignTable = $allowedTables[0];
95  }
96  if (empty($foreignTable)) {
97  throw new \UnexpectedValueException(
98  'No target table defined for type config field ' . $pointerField . ' of table ' . $result['tableName'],
99  1438253614
100  );
101  }
102  if (!‪MathUtility::canBeInterpretedAsInteger($foreignUid) && is_array($foreignUid[0])) {
103  // A group relation - has been resolved to array by TcaGroup data provider already
104  $foreignUid = $foreignUid[0]['uid'];
105  }
106  // Fetch field of this foreign row from db
108  $foreignRow = $this->‪getDatabaseRow($foreignTable, (int)$foreignUid, $foreignTableTypeField);
109  if ($foreignRow[$foreignTableTypeField]) {
110  // @todo: It might be necessary to fetch the value from default language record as well here,
111  // @todo: this was buggy in the "old" implementation and never worked. It was therefor left out here for now.
112  // @todo: To implement that, see if the foreign row is a localized overlay, fetch default and merge exclude
113  $recordTypeValue = $foreignRow[$foreignTableTypeField];
114  }
115  }
116  }
117  }
118  }
119 
120  // Throw another exception if determined value and '0' and '1' do not exist
121  if (empty($result['processedTca']['types'][$recordTypeValue])
122  && empty($result['processedTca']['types']['0'])
123  && empty($result['processedTca']['types']['1'])
124  ) {
125  throw new \UnexpectedValueException(
126  'Type value ' . $recordTypeValue . ' from database record not defined in TCA of table '
127  . $result['tableName'] . ' and neither 0 nor 1 are defined as fallback.',
128  1438185437
129  );
130  }
131 
132  // Check the determined value actually exists as types key, otherwise fall back to 0 or 1, 1 for "historical reasons"
133  if (empty($result['processedTca']['types'][$recordTypeValue])) {
134  $recordTypeValue = !empty($result['processedTca']['types']['0']) ? '0' : '1';
135  }
136 
137  $result['recordTypeValue'] = (string)$recordTypeValue;
138  return $result;
139  }
140 
149  protected function ‪getDatabaseRow(string $tableName, int $uid, string $fieldName): array
150  {
151  $row = ‪BackendUtility::getRecord($tableName, $uid, $fieldName);
152 
153  return $row ?: [];
154  }
155 }
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue\getDatabaseRow
‪array getDatabaseRow(string $tableName, int $uid, string $fieldName)
Definition: DatabaseRecordTypeValue.php:149
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue
Definition: DatabaseRecordTypeValue.php:26
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:95
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue\addData
‪array addData(array $result)
Definition: DatabaseRecordTypeValue.php:38
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22