TYPO3 CMS  TYPO3_7-6
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  $recordTypeValue = '0';
50  if (!empty($result['processedTca']['ctrl']['type'])) {
51  $tcaTypeField = $result['processedTca']['ctrl']['type'];
52 
53  if (strpos($tcaTypeField, ':') === false) {
54  // $tcaTypeField is the name of a field in database row
55  if (!array_key_exists($tcaTypeField, $result['databaseRow'])) {
56  throw new \UnexpectedValueException(
57  'TCA table ' . $result['tableName'] . ' ctrl[\'type\'] is set to ' . $tcaTypeField . ', but'
58  . ' this field does not exist in the database of this table',
59  1438183881
60  );
61  }
62  $recordTypeValue = $this->getValueFromDefaultLanguageRecordIfConfigured($result, $tcaTypeField);
63  } else {
64  // If type is configured as localField:foreignField, fetch the type value from
65  // a foreign table. localField then point to a group or select field in the own table,
66  // this points to a record in a foreign table and the value of foreignField is then
67  // used as type field. This was introduced for some FAL scenarios.
68  list($pointerField, $foreignTableTypeField) = explode(':', $tcaTypeField);
69 
70  $relationType = $result['processedTca']['columns'][$pointerField]['config']['type'];
71  if ($relationType !== 'select' && $relationType !== 'group') {
72  throw new \UnexpectedValueException(
73  'TCA foreign field pointer fields are only allowed to be used with group or select field types.'
74  . ' Handling field ' . $pointerField . ' with type configured as ' . $tcaTypeField,
75  1325862241
76  );
77  }
78 
79  $foreignUid = $this->getValueFromDefaultLanguageRecordIfConfigured($result, $pointerField);
80  // Resolve the foreign record only if there is a uid, otherwise fall back 0
81  if (!empty($foreignUid)) {
82  // Determine table name to fetch record from
83  if ($relationType === 'select') {
84  $foreignTable = $result['processedTca']['columns'][$pointerField]['config']['foreign_table'];
85  } else {
86  $allowedTables = explode(',', $result['processedTca']['columns'][$pointerField]['config']['allowed']);
87  // Always take the first configured table.
88  $foreignTable = $allowedTables[0];
89  }
90  if (empty($foreignTable)) {
91  throw new \UnexpectedValueException(
92  'No target table defined for type config field ' . $pointerField . ' of table ' . $result['tableName'],
93  1438253614
94  );
95  }
96  // Extract UID from value formed like {table_name}_{uid}|{default_value}
97  // @todo: This needs adaption as soon as the group format is changed
98  if (!MathUtility::canBeInterpretedAsInteger($foreignUid)) {
99  list($foreignUid) = explode('|', $foreignUid);
100  $foreignUid = str_replace($foreignTable . '_', '', $foreignUid);
101  }
102  // Fetch field of this foreign row from db
103  $foreignRow = BackendUtility::getRecord($foreignTable, $foreignUid, $foreignTableTypeField);
104  if ($foreignRow[$foreignTableTypeField]) {
105  // @todo: It might be necessary to fetch the value from default language record as well here,
106  // @todo: this was buggy in the "old" implementation and never worked. It was therefor left out here for now.
107  // @todo: To implement that, see if the foreign row is a localized overlay, fetch default and merge exclude
108  // @todo: and mergeIfNotBlank if needed.
109  $recordTypeValue = $foreignRow[$foreignTableTypeField];
110  }
111  }
112  }
113  }
114 
115  // Throw another exception if determined value and '0' and '1' do not exist
116  if (empty($result['processedTca']['types'][$recordTypeValue])
117  && empty($result['processedTca']['types']['0'])
118  && empty($result['processedTca']['types']['1'])
119  ) {
120  throw new \UnexpectedValueException(
121  'Type value ' . $recordTypeValue . ' from database record not defined in TCA of table '
122  . $result['tableName'] . ' and neither 0 nor 1 are defined as fallback.',
123  1438185437
124  );
125  }
126 
127  // Check the determined value actually exists as types key, otherwise fall back to 0 or 1, 1 for "historical reasons"
128  if (empty($result['processedTca']['types'][$recordTypeValue])) {
129  $recordTypeValue = !empty($result['processedTca']['types']['0']) ? '0' : '1';
130  }
131 
132  $result['recordTypeValue'] = (string)$recordTypeValue;
133  return $result;
134  }
135 
145  protected function getValueFromDefaultLanguageRecordIfConfigured($result, $field)
146  {
147  $value = $result['databaseRow'][$field];
148  if (
149  // is a localized record
150  !empty($result['processedTca']['ctrl']['languageField'])
151  && $result['databaseRow'][$result['processedTca']['ctrl']['languageField']] > 0
152  // l10n_mode for field is configured
153  && !empty($result['processedTca']['columns'][$field]['l10n_mode'])
154  && (
155  // is exclude -> fall back to value of default record
156  $result['processedTca']['columns'][$field]['l10n_mode'] === 'exclude'
157  // is mergeIfNotBlank and own value is empty -> fall back to value of default record
158  || (
159  $result['processedTca']['columns'][$field]['l10n_mode'] === 'mergeIfNotBlank'
160  // 0 means "not empty"
161  && $result['databaseRow'][$field] === ''
162  )
163  )
164  ) {
165  $value = $result['defaultLanguageRow'][$field];
166  }
167  return $value;
168  }
169 }
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)