‪TYPO3CMS  10.4
TcaRecordTitle.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 
23 
31 {
38  public function ‪addData(array $result)
39  {
40  if (!isset($result['processedTca']['ctrl']['label'])) {
41  throw new \UnexpectedValueException(
42  'TCA of table ' . $result['tableName'] . ' misses required [\'ctrl\'][\'label\'] definition.',
43  1443706103
44  );
45  }
46 
47  if ($result['isInlineChild'] && isset($result['processedTca']['ctrl']['formattedLabel_userFunc'])) {
48  // inline child with formatted user func is first
49  $parameters = [
50  'table' => $result['tableName'],
51  'row' => $result['databaseRow'],
52  'title' => '',
53  'isOnSymmetricSide' => $result['isOnSymmetricSide'],
54  'options' => $result['processedTca']['ctrl']['formattedLabel_userFunc_options'] ?? [],
55  'parent' => [
56  'uid' => $result['databaseRow']['uid'],
57  'config' => $result['inlineParentConfig']
58  ]
59  ];
60  // callUserFunction requires a third parameter, but we don't want to give $this as reference!
61  $null = null;
62  GeneralUtility::callUserFunction($result['processedTca']['ctrl']['formattedLabel_userFunc'], $parameters, $null);
63  $result['recordTitle'] = $parameters['title'];
64  } elseif ($result['isInlineChild'] && (isset($result['inlineParentConfig']['foreign_label'])
65  || isset($result['inlineParentConfig']['symmetric_label']))
66  ) {
67  // inline child with foreign label or symmetric inline child with symmetric_label
68  $fieldName = $result['isOnSymmetricSide']
69  ? $result['inlineParentConfig']['symmetric_label']
70  : $result['inlineParentConfig']['foreign_label'];
71  $result['recordTitle'] = $this->‪getRecordTitleForField($fieldName, $result);
72  } elseif (isset($result['processedTca']['ctrl']['label_userFunc'])) {
73  // userFunc takes precedence over everything else
74  $parameters = [
75  'table' => $result['tableName'],
76  'row' => $result['databaseRow'],
77  'title' => '',
78  'options' => $result['processedTca']['ctrl']['label_userFunc_options'] ?? [],
79  ];
80  $null = null;
81  GeneralUtility::callUserFunction($result['processedTca']['ctrl']['label_userFunc'], $parameters, $null);
82  $result['recordTitle'] = $parameters['title'];
83  } else {
84  // standard record
85  $result = $this->‪getRecordTitleByLabelProperties($result);
86  }
87 
88  return $result;
89  }
90 
97  protected function ‪getRecordTitleByLabelProperties(array $result)
98  {
99  $titles = [];
100  $titleByLabel = $this->‪getRecordTitleForField($result['processedTca']['ctrl']['label'], $result);
101  if (!empty($titleByLabel)) {
102  $titles[] = $titleByLabel;
103  }
104 
105  $labelAltForce = isset($result['processedTca']['ctrl']['label_alt_force'])
106  ? (bool)$result['processedTca']['ctrl']['label_alt_force']
107  : false;
108  if (!empty($result['processedTca']['ctrl']['label_alt']) && ($labelAltForce || empty($titleByLabel))) {
109  // Dive into label_alt evaluation if label_alt_force is set or if label did not came up with a title yet
110  $labelAltFields = ‪GeneralUtility::trimExplode(',', $result['processedTca']['ctrl']['label_alt'], true);
111  foreach ($labelAltFields as $fieldName) {
112  $titleByLabelAlt = $this->‪getRecordTitleForField($fieldName, $result);
113  if (!empty($titleByLabelAlt)) {
114  $titles[] = $titleByLabelAlt;
115  }
116  if (!$labelAltForce && !empty($titleByLabelAlt)) {
117  // label_alt_force creates a comma separated list of multiple fields.
118  // If not set, one found field with content is enough
119  break;
120  }
121  }
122  }
123 
124  $result['recordTitle'] = implode(', ', $titles);
125  return $result;
126  }
127 
135  protected function ‪getRecordTitleForField($fieldName, $result)
136  {
137  if ($fieldName === 'uid') {
138  // uid return field content directly since it usually has not TCA definition
139  return $result['databaseRow']['uid'];
140  }
141 
142  if (!isset($result['processedTca']['columns'][$fieldName]['config']['type'])
143  || !is_string($result['processedTca']['columns'][$fieldName]['config']['type'])
144  ) {
145  return '';
146  }
147 
148  $recordTitle = '';
149  $rawValue = null;
150  if (array_key_exists($fieldName, $result['databaseRow'])) {
151  $rawValue = $result['databaseRow'][$fieldName];
152  }
153  $fieldConfig = $result['processedTca']['columns'][$fieldName]['config'];
154  switch ($fieldConfig['type']) {
155  case 'radio':
156  $recordTitle = $this->‪getRecordTitleForRadioType($rawValue, $fieldConfig);
157  break;
158  case 'inline':
159  $recordTitle = $this->‪getRecordTitleForInlineType(
160  $rawValue,
161  $result['processedTca']['columns'][$fieldName]['children']
162  );
163  break;
164  case 'select':
165  $recordTitle = $this->‪getRecordTitleForSelectType($rawValue, $fieldConfig);
166  break;
167  case 'group':
168  $recordTitle = $this->‪getRecordTitleForGroupType($rawValue);
169  break;
170  case 'check':
171  $recordTitle = $this->‪getRecordTitleForCheckboxType($rawValue, $fieldConfig);
172  break;
173  case 'input':
174  $recordTitle = $this->‪getRecordTitleForInputType($rawValue, $fieldConfig);
175  break;
176  case 'text':
177  $recordTitle = $this->‪getRecordTitleForTextType($rawValue);
178  break;
179  case 'flex':
180  // @todo: Check if and how a label could be generated from flex field data
181  default:
182 
183  }
184 
185  return $recordTitle;
186  }
187 
195  protected function ‪getRecordTitleForRadioType($value, $fieldConfig)
196  {
197  if (!isset($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
198  return '';
199  }
200  foreach ($fieldConfig['items'] as $item) {
201  [$itemLabel, $itemValue] = $item;
202  if ((string)$value === (string)$itemValue) {
203  return $itemLabel;
204  }
205  }
206  return '';
207  }
208 
214  protected function ‪getRecordTitleForInlineType($value, array $children)
215  {
216  foreach ($children as $child) {
217  if ((int)$value === $child['vanillaUid']) {
218  return $child['recordTitle'];
219  }
220  }
221 
222  return '';
223  }
224 
232  protected function ‪getRecordTitleForSelectType($value, $fieldConfig)
233  {
234  if (!is_array($value)) {
235  return '';
236  }
237  $labelParts = [];
238  if (!empty($fieldConfig['items'])) {
239  $listOfValues = array_column($fieldConfig['items'], 1);
240  foreach ($value as $itemValue) {
241  $itemKey = array_search($itemValue, $listOfValues);
242  if ($itemKey !== false) {
243  $labelParts[] = $fieldConfig['items'][$itemKey][0];
244  }
245  }
246  }
247  $title = implode(', ', $labelParts);
248  if (empty($title) && !empty($value)) {
249  $title = implode(', ', $value);
250  }
251  return $title;
252  }
253 
260  protected function ‪getRecordTitleForGroupType($value)
261  {
262  $labelParts = [];
263  foreach ($value as $singleValue) {
264  if (isset($singleValue['uidOrPath'])) {
265  $labelParts[] = $singleValue['uidOrPath'];
266  } elseif (isset($singleValue['folder'])) {
267  $labelParts[] = $singleValue['folder'];
268  } else {
269  $labelParts[] = $singleValue['title'];
270  }
271  }
272  return implode(', ', $labelParts);
273  }
274 
282  protected function ‪getRecordTitleForCheckboxType($value, $fieldConfig)
283  {
284  $languageService = $this->‪getLanguageService();
285  if (empty($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
286  $title = (bool)$value
287  ? $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:yes')
288  : $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:no');
289  } else {
290  $labelParts = [];
291  foreach ($fieldConfig['items'] as $key => $val) {
292  if ($value & 2 ** $key) {
293  $labelParts[] = $val[0];
294  }
295  }
296  $title = implode(', ', $labelParts);
297  }
298  return $title;
299  }
300 
308  protected function ‪getRecordTitleForInputType($value, $fieldConfig)
309  {
310  if (!isset($value)) {
311  return '';
312  }
313  if (!isset($fieldConfig['eval'])) {
314  return $value;
315  }
316  $title = $value;
317  $dateTimeFormats = ‪QueryHelper::getDateTimeFormats();
318  if (GeneralUtility::inList($fieldConfig['eval'], 'date')) {
319  // Handle native date field
320  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'date') {
321  $value = $value === $dateTimeFormats['date']['empty'] ? 0 : (int)strtotime($value);
322  } else {
323  $value = (int)$value;
324  }
325  if (!empty($value)) {
326  $ageSuffix = '';
327  // Generate age suffix as long as not explicitly suppressed
328  if (!isset($fieldConfig['disableAgeDisplay']) || (bool)$fieldConfig['disableAgeDisplay'] === false) {
329  $ageDelta = ‪$GLOBALS['EXEC_TIME'] - $value;
330  $calculatedAge = ‪BackendUtility::calcAge(
331  (int)abs($ageDelta),
332  $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears')
333  );
334  $ageSuffix = ' (' . ($ageDelta > 0 ? '-' : '') . $calculatedAge . ')';
335  }
336  $title = ‪BackendUtility::date($value) . $ageSuffix;
337  }
338  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'time')) {
339  // Handle native time field
340  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'time') {
341  $value = $value === $dateTimeFormats['time']['empty'] ? 0 : (int)strtotime('1970-01-01 ' . $value . ' UTC');
342  } else {
343  $value = (int)$value;
344  }
345  if (!empty($value)) {
346  $title = gmdate('H:i', (int)$value);
347  }
348  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'timesec')) {
349  // Handle native time field
350  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'time') {
351  $value = $value === $dateTimeFormats['time']['empty'] ? 0 : (int)strtotime('1970-01-01 ' . $value . ' UTC');
352  } else {
353  $value = (int)$value;
354  }
355  if (!empty($value)) {
356  $title = gmdate('H:i:s', (int)$value);
357  }
358  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'datetime')) {
359  // Handle native datetime field
360  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'datetime') {
361  $value = $value === $dateTimeFormats['datetime']['empty'] ? 0 : (int)strtotime($value);
362  } else {
363  $value = (int)$value;
364  }
365  if (!empty($value)) {
366  $title = ‪BackendUtility::datetime($value);
367  }
368  }
369  return $title;
370  }
371 
378  protected function ‪getRecordTitleForTextType($value)
379  {
380  return trim(strip_tags($value));
381  }
382 
386  protected function ‪getLanguageService()
387  {
388  return ‪$GLOBALS['LANG'];
389  }
390 }
‪TYPO3\CMS\Core\Database\Query\QueryHelper\getDateTimeFormats
‪static array getDateTimeFormats()
Definition: QueryHelper.php:177
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForGroupType
‪string getRecordTitleForGroupType($value)
Definition: TcaRecordTitle.php:260
‪TYPO3\CMS\Backend\Utility\BackendUtility\datetime
‪static string datetime($value)
Definition: BackendUtility.php:989
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForSelectType
‪string getRecordTitleForSelectType($value, $fieldConfig)
Definition: TcaRecordTitle.php:232
‪TYPO3\CMS\Backend\Utility\BackendUtility\calcAge
‪static string calcAge($seconds, $labels='min|hrs|days|yrs|min|hour|day|year')
Definition: BackendUtility.php:1017
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForInlineType
‪string getRecordTitleForInlineType($value, array $children)
Definition: TcaRecordTitle.php:214
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForInputType
‪string getRecordTitleForInputType($value, $fieldConfig)
Definition: TcaRecordTitle.php:308
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:32
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle
Definition: TcaRecordTitle.php:31
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForCheckboxType
‪string getRecordTitleForCheckboxType($value, $fieldConfig)
Definition: TcaRecordTitle.php:282
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\addData
‪array addData(array $result)
Definition: TcaRecordTitle.php:38
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForField
‪string getRecordTitleForField($fieldName, $result)
Definition: TcaRecordTitle.php:135
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getLanguageService
‪LanguageService getLanguageService()
Definition: TcaRecordTitle.php:386
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForTextType
‪string getRecordTitleForTextType($value)
Definition: TcaRecordTitle.php:378
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Utility\BackendUtility\date
‪static string date($tstamp)
Definition: BackendUtility.php:978
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleByLabelProperties
‪array getRecordTitleByLabelProperties(array $result)
Definition: TcaRecordTitle.php:97
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForRadioType
‪string getRecordTitleForRadioType($value, $fieldConfig)
Definition: TcaRecordTitle.php:195