TYPO3 CMS  TYPO3_8-7
DatabaseRecordTypeValue.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 
20 
25 {
37  public function addData(array $result)
38  {
39  if (!isset($result['processedTca']['types'])
40  || !is_array($result['processedTca']['types'])
41  || empty($result['processedTca']['types'])
42  ) {
43  throw new \UnexpectedValueException(
44  'At least one "types" array must be defined for table ' . $result['tableName'] . ', preferred "0"',
45  1438185331
46  );
47  }
48 
49  // Guard clause to suppress any calculation if record type value has been set from outside already
50  if ($result['recordTypeValue'] !== '') {
51  return $result;
52  }
53 
54  $recordTypeValue = '0';
55  if (!empty($result['processedTca']['ctrl']['type'])) {
56  $tcaTypeField = $result['processedTca']['ctrl']['type'];
57 
58  if (strpos($tcaTypeField, ':') === false) {
59  // $tcaTypeField is the name of a field in database row
60  if (!array_key_exists($tcaTypeField, $result['databaseRow'])) {
61  throw new \UnexpectedValueException(
62  'TCA table ' . $result['tableName'] . ' ctrl[\'type\'] is set to ' . $tcaTypeField . ', but'
63  . ' this field does not exist in the database of this table',
64  1438183881
65  );
66  }
67  $recordTypeValue = $result['databaseRow'][$tcaTypeField];
68  } else {
69  // If type is configured as localField:foreignField, fetch the type value from
70  // a foreign table. localField then point to a group or select field in the own table,
71  // this points to a record in a foreign table and the value of foreignField is then
72  // used as type field. This was introduced for some FAL scenarios.
73  list($pointerField, $foreignTableTypeField) = explode(':', $tcaTypeField);
74 
75  $relationType = $result['processedTca']['columns'][$pointerField]['config']['type'];
76  if ($relationType !== 'select' && $relationType !== 'group') {
77  throw new \UnexpectedValueException(
78  'TCA foreign field pointer fields are only allowed to be used with group or select field types.'
79  . ' Handling field ' . $pointerField . ' with type configured as ' . $tcaTypeField,
80  1325862241
81  );
82  }
83 
84  $foreignUid = $result['databaseRow'][$pointerField];
85  // Resolve the foreign record only if there is a uid, otherwise fall back 0
86  if (!empty($foreignUid)) {
87  // Determine table name to fetch record from
88  if ($relationType === 'select') {
89  $foreignTable = $result['processedTca']['columns'][$pointerField]['config']['foreign_table'];
90  } else {
91  $allowedTables = explode(',', $result['processedTca']['columns'][$pointerField]['config']['allowed']);
92  // Always take the first configured table.
93  $foreignTable = $allowedTables[0];
94  }
95  if (empty($foreignTable)) {
96  throw new \UnexpectedValueException(
97  'No target table defined for type config field ' . $pointerField . ' of table ' . $result['tableName'],
98  1438253614
99  );
100  }
101  if (!MathUtility::canBeInterpretedAsInteger($foreignUid) && is_array($foreignUid[0])) {
102  // A group relation - has been resolved to array by TcaGroup data provider already
103  $foreignUid = $foreignUid[0]['uid'];
104  }
105  // Fetch field of this foreign row from db
106  $foreignRow = $this->getDatabaseRow($foreignTable, $foreignUid, $foreignTableTypeField);
107  if ($foreignRow[$foreignTableTypeField]) {
108  // @todo: It might be necessary to fetch the value from default language record as well here,
109  // @todo: this was buggy in the "old" implementation and never worked. It was therefor left out here for now.
110  // @todo: To implement that, see if the foreign row is a localized overlay, fetch default and merge exclude
111  $recordTypeValue = $foreignRow[$foreignTableTypeField];
112  }
113  }
114  }
115  }
116 
117  // Throw another exception if determined value and '0' and '1' do not exist
118  if (empty($result['processedTca']['types'][$recordTypeValue])
119  && empty($result['processedTca']['types']['0'])
120  && empty($result['processedTca']['types']['1'])
121  ) {
122  throw new \UnexpectedValueException(
123  'Type value ' . $recordTypeValue . ' from database record not defined in TCA of table '
124  . $result['tableName'] . ' and neither 0 nor 1 are defined as fallback.',
125  1438185437
126  );
127  }
128 
129  // Check the determined value actually exists as types key, otherwise fall back to 0 or 1, 1 for "historical reasons"
130  if (empty($result['processedTca']['types'][$recordTypeValue])) {
131  $recordTypeValue = !empty($result['processedTca']['types']['0']) ? '0' : '1';
132  }
133 
134  $result['recordTypeValue'] = (string)$recordTypeValue;
135  return $result;
136  }
137 
146  protected function getDatabaseRow(string $tableName, int $uid, string $fieldName): array
147  {
148  $row = BackendUtility::getRecord($tableName, $uid, $fieldName);
149 
150  return $row ?: [];
151  }
152 }
getDatabaseRow(string $tableName, int $uid, string $fieldName)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)