‪TYPO3CMS  ‪main
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 
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
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  case 'file':
160  $recordTitle = $this->‪getRecordTitleForInlineType(
161  $rawValue,
162  $result['processedTca']['columns'][$fieldName]['children'] ?? []
163  );
164  break;
165  case 'select':
166  case 'category':
167  $recordTitle = $this->‪getRecordTitleForSelectType($rawValue, $fieldConfig);
168  break;
169  case 'group':
170  $recordTitle = $this->‪getRecordTitleForGroupType($rawValue);
171  break;
172  case 'folder':
173  $recordTitle = $this->‪getRecordTitleForFolderType($rawValue);
174  break;
175  case 'check':
176  $recordTitle = $this->‪getRecordTitleForCheckboxType($rawValue, $fieldConfig);
177  break;
178  case 'input':
179  case 'number':
180  case 'uuid':
181  $recordTitle = $rawValue ?? '';
182  break;
183  case 'text':
184  case 'email':
185  case 'link':
186  case 'color':
187  $recordTitle = $this->‪getRecordTitleForStandardTextField($rawValue);
188  break;
189  case 'datetime':
190  $recordTitle = $this->‪getRecordTitleForDatetimeType($rawValue, $fieldConfig);
191  break;
192  case 'password':
193  $recordTitle = $this->‪getRecordTitleForPasswordType($rawValue);
194  break;
195  case 'flex':
196  // @todo: Check if and how a label could be generated from flex field data
197  break;
198  case 'json':
199  // @todo: Check if and how a label could be generated from json field data
200  default:
201  }
202 
203  return $recordTitle;
204  }
205 
213  protected function ‪getRecordTitleForRadioType($value, $fieldConfig)
214  {
215  if (!isset($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
216  return '';
217  }
218  foreach ($fieldConfig['items'] as $item) {
219  if ((string)$value === (string)$item['value']) {
220  return $item['label'];
221  }
222  }
223  return '';
224  }
225 
230  protected function ‪getRecordTitleForInlineType($value, array $children)
231  {
232  foreach ($children as $child) {
233  if ((int)$value === $child['vanillaUid']) {
234  return $child['recordTitle'];
235  }
236  }
237 
238  return '';
239  }
240 
248  protected function ‪getRecordTitleForSelectType($value, $fieldConfig)
249  {
250  if (!is_array($value)) {
251  return '';
252  }
253  $labelParts = [];
254  if (!empty($fieldConfig['items'])) {
255  $listOfValues = array_column($fieldConfig['items'], 'value');
256  foreach ($value as $itemValue) {
257  $itemKey = array_search($itemValue, $listOfValues);
258  if ($itemKey !== false) {
259  $labelParts[] = $fieldConfig['items'][$itemKey]['label'];
260  }
261  }
262  }
263  $title = implode(', ', $labelParts);
264  if (empty($title) && !empty($value)) {
265  $title = implode(', ', $value);
266  }
267  return $title;
268  }
269 
276  protected function ‪getRecordTitleForGroupType($value)
277  {
278  $labelParts = [];
279  foreach ($value as $singleValue) {
280  $labelParts[] = $singleValue['title'];
281  }
282  return implode(', ', $labelParts);
283  }
284 
290  protected function ‪getRecordTitleForFolderType(array $value): string
291  {
292  $labelParts = [];
293  foreach ($value as $singleValue) {
294  $labelParts[] = $singleValue['folder'];
295  }
296  return implode(', ', $labelParts);
297  }
298 
306  protected function ‪getRecordTitleForCheckboxType($value, $fieldConfig)
307  {
308  $languageService = $this->‪getLanguageService();
309  if (empty($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
310  $title = $value
311  ? $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:yes')
312  : $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:no');
313  } else {
314  $labelParts = [];
315  foreach ($fieldConfig['items'] as $key => $val) {
316  if ((int)$value & 2 ** $key) {
317  $labelParts[] = $val['label'];
318  }
319  }
320  $title = implode(', ', $labelParts);
321  }
322  return $title;
323  }
324 
330  protected function ‪getRecordTitleForStandardTextField(mixed $value): string
331  {
332  if (!is_string($value)) {
333  return '';
334  }
335 
336  return trim(strip_tags($value));
337  }
338 
339  protected function ‪getRecordTitleForDatetimeType(mixed $value, array $fieldConfig): string
340  {
341  if (!isset($value)) {
342  return '';
343  }
344  $title = $value;
345  $format = (string)($fieldConfig['format'] ?? 'datetime');
346  $dateTimeFormats = ‪QueryHelper::getDateTimeFormats();
347  if ($format === 'date') {
348  // Handle native date field
349  if (($fieldConfig['dbType'] ?? '') === 'date') {
350  $value = $value === $dateTimeFormats['date']['empty'] ? 0 : (int)strtotime($value);
351  } else {
352  $value = (int)$value;
353  }
354  if (!empty($value)) {
355  $ageSuffix = '';
356  // Generate age suffix as long as not explicitly suppressed
357  if (!($fieldConfig['disableAgeDisplay'] ?? false)) {
358  $ageDelta = ‪$GLOBALS['EXEC_TIME'] - $value;
359  $calculatedAge = BackendUtility::calcAge(
360  (int)abs($ageDelta),
361  $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears')
362  );
363  $ageSuffix = ' (' . ($ageDelta > 0 ? '-' : '') . $calculatedAge . ')';
364  }
365  $title = BackendUtility::date($value) . $ageSuffix;
366  }
367  } elseif ($format === 'time') {
368  // Handle native time field
369  if (($fieldConfig['dbType'] ?? '') === 'time') {
370  $value = $value === $dateTimeFormats['time']['empty'] ? 0 : (int)strtotime('1970-01-01 ' . $value . ' UTC');
371  } else {
372  $value = (int)$value;
373  }
374  if (!empty($value)) {
375  $title = gmdate('H:i', $value);
376  }
377  } elseif ($format === 'timesec') {
378  // Handle native time field
379  if (($fieldConfig['dbType'] ?? '') === 'time') {
380  $value = $value === $dateTimeFormats['time']['empty'] ? 0 : (int)strtotime('1970-01-01 ' . $value . ' UTC');
381  } else {
382  $value = (int)$value;
383  }
384  if (!empty($value)) {
385  $title = gmdate('H:i:s', $value);
386  }
387  } elseif ($format === 'datetime') {
388  // Handle native datetime field
389  if (($fieldConfig['dbType'] ?? '') === 'datetime') {
390  $value = $value === $dateTimeFormats['datetime']['empty'] ? 0 : (int)strtotime($value);
391  } else {
392  $value = (int)$value;
393  }
394  if (!empty($value)) {
395  $title = BackendUtility::datetime($value);
396  }
397  }
398  return $title;
399  }
400 
406  protected function ‪getRecordTitleForPasswordType(mixed $value): string
407  {
408  return $value ? '********' : '';
409  }
410 
412  {
413  return ‪$GLOBALS['LANG'];
414  }
415 }
‪TYPO3\CMS\Core\Database\Query\QueryHelper\getDateTimeFormats
‪static array getDateTimeFormats()
Definition: QueryHelper.php:183
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForGroupType
‪string getRecordTitleForGroupType($value)
Definition: TcaRecordTitle.php:276
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForDatetimeType
‪getRecordTitleForDatetimeType(mixed $value, array $fieldConfig)
Definition: TcaRecordTitle.php:339
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForSelectType
‪string getRecordTitleForSelectType($value, $fieldConfig)
Definition: TcaRecordTitle.php:248
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForInlineType
‪string getRecordTitleForInlineType($value, array $children)
Definition: TcaRecordTitle.php:230
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getLanguageService
‪getLanguageService()
Definition: TcaRecordTitle.php:411
‪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:306
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForPasswordType
‪getRecordTitleForPasswordType(mixed $value)
Definition: TcaRecordTitle.php:406
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪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\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForStandardTextField
‪getRecordTitleForStandardTextField(mixed $value)
Definition: TcaRecordTitle.php:330
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForField
‪string getRecordTitleForField($fieldName, $result)
Definition: TcaRecordTitle.php:135
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleByLabelProperties
‪array getRecordTitleByLabelProperties(array $result)
Definition: TcaRecordTitle.php:97
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForFolderType
‪getRecordTitleForFolderType(array $value)
Definition: TcaRecordTitle.php:290
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaRecordTitle\getRecordTitleForRadioType
‪string getRecordTitleForRadioType($value, $fieldConfig)
Definition: TcaRecordTitle.php:213