TYPO3 CMS  TYPO3_7-6
TcaRecordTitle.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 
22 
30 {
37  public function addData(array $result)
38  {
39  if (!isset($result['processedTca']['ctrl']['label'])) {
40  throw new \UnexpectedValueException(
41  'TCA of table ' . $result['tableName'] . ' misses required [\'ctrl\'][\'label\'] definition.',
42  1443706103
43  );
44  }
45 
46  if ($result['isInlineChild'] && isset($result['processedTca']['ctrl']['formattedLabel_userFunc'])) {
47  // inline child with formatted user func is first
48  $parameters = [
49  'table' => $result['tableName'],
50  'row' => $result['databaseRow'],
51  'title' => '',
52  'isOnSymmetricSide' => $result['isOnSymmetricSide'],
53  'options' => isset($result['processedTca']['ctrl']['formattedLabel_userFunc_options'])
54  ? $result['processedTca']['ctrl']['formattedLabel_userFunc_options']
55  : [],
56  'parent' => [
57  'uid' => $result['databaseRow']['uid'],
58  'config' => $result['inlineParentConfig']
59  ]
60  ];
61  // callUserFunction requires a third parameter, but we don't want to give $this as reference!
62  $null = null;
63  GeneralUtility::callUserFunction($result['processedTca']['ctrl']['formattedLabel_userFunc'], $parameters, $null);
64  $result['recordTitle'] = $parameters['title'];
65  } elseif ($result['isInlineChild'] && (isset($result['inlineParentConfig']['foreign_label'])
66  || isset($result['inlineParentConfig']['symmetric_label']))
67  ) {
68  // inline child with foreign label or symmetric inline child with symmetric_label
69  $fieldName = $result['isOnSymmetricSide']
70  ? $result['inlineParentConfig']['symmetric_label']
71  : $result['inlineParentConfig']['foreign_label'];
72  $result['recordTitle'] = $this->getRecordTitleForField($fieldName, $result);
73  } elseif (isset($result['processedTca']['ctrl']['label_userFunc'])) {
74  // userFunc takes precedence over everything else
75  $parameters = [
76  'table' => $result['tableName'],
77  'row' => $result['databaseRow'],
78  'title' => '',
79  'options' => isset($result['processedTca']['ctrl']['label_userFunc_options'])
80  ? $result['processedTca']['ctrl']['label_userFunc_options']
81  : [],
82  ];
83  $null = null;
84  GeneralUtility::callUserFunction($result['processedTca']['ctrl']['label_userFunc'], $parameters, $null);
85  $result['recordTitle'] = $parameters['title'];
86  } else {
87  // standard record
88  $result = $this->getRecordTitleByLabelProperties($result);
89  }
90 
91  return $result;
92  }
93 
100  protected function getRecordTitleByLabelProperties(array $result)
101  {
102  $titles = [];
103  $titleByLabel = $this->getRecordTitleForField($result['processedTca']['ctrl']['label'], $result);
104  if (!empty($titleByLabel)) {
105  $titles[] = $titleByLabel;
106  }
107 
108  $labelAltForce = isset($result['processedTca']['ctrl']['label_alt_force'])
109  ? (bool)$result['processedTca']['ctrl']['label_alt_force']
110  : false;
111  if (!empty($result['processedTca']['ctrl']['label_alt']) && ($labelAltForce || empty($titleByLabel))) {
112  // Dive into label_alt evaluation if label_alt_force is set or if label did not came up with a title yet
113  $labelAltFields = GeneralUtility::trimExplode(',', $result['processedTca']['ctrl']['label_alt'], true);
114  foreach ($labelAltFields as $fieldName) {
115  $titleByLabelAlt = $this->getRecordTitleForField($fieldName, $result);
116  if (!empty($titleByLabelAlt)) {
117  $titles[] = $titleByLabelAlt;
118  }
119  if (!$labelAltForce && !empty($titleByLabelAlt)) {
120  // label_alt_force creates a comma separated list of multiple fields.
121  // If not set, one found field with content is enough
122  break;
123  }
124  }
125  }
126 
127  $result['recordTitle'] = implode(', ', $titles);
128  return $result;
129  }
130 
138  protected function getRecordTitleForField($fieldName, $result)
139  {
140  if ($fieldName === 'uid') {
141  // uid return field content directly since it usually has not TCA definition
142  return $result['databaseRow']['uid'];
143  }
144 
145  if (!isset($result['processedTca']['columns'][$fieldName]['config']['type'])
146  || !is_string($result['processedTca']['columns'][$fieldName]['config']['type'])
147  ) {
148  return '';
149  }
150 
151  $recordTitle = '';
152  $rawValue = null;
153  if (array_key_exists($fieldName, $result['databaseRow'])) {
154  $rawValue = $result['databaseRow'][$fieldName];
155  }
156  $fieldConfig = $result['processedTca']['columns'][$fieldName]['config'];
157  switch ($fieldConfig['type']) {
158  case 'radio':
159  $recordTitle = $this->getRecordTitleForRadioType($rawValue, $fieldConfig);
160  break;
161  case 'inline':
162  $recordTitle = $this->getRecordTitleForInlineType($rawValue, $result['processedTca']['columns'][$fieldName]['children']);
163  break;
164  case 'select':
165  $recordTitle = $this->getRecordTitleForSelectType($rawValue, $fieldConfig);
166  break;
167  case 'group':
168  $recordTitle = $this->getRecordTitleForGroupType($rawValue, $fieldConfig);
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  case 'flex':
179  // @todo: Check if and how a label could be generated from flex field data
180  default:
181 
182  }
183 
184  return $recordTitle;
185  }
186 
194  protected function getRecordTitleForRadioType($value, $fieldConfig)
195  {
196  if (!isset($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
197  return '';
198  }
199  foreach ($fieldConfig['items'] as $item) {
200  list($itemLabel, $itemValue) = $item;
201  if ((string)$value === (string)$itemValue) {
202  return $itemLabel;
203  }
204  }
205  return '';
206  }
207 
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  foreach ($value as $itemValue) {
239  $itemKey = array_search($itemValue, array_column($fieldConfig['items'], 1));
240  if ($itemKey !== false) {
241  $labelParts[] = $fieldConfig['items'][$itemKey][0];
242  }
243  }
244  $title = implode(', ', $labelParts);
245  if (empty($title) && !empty($value)) {
246  $title = implode(', ', $value);
247  }
248  return $title;
249  }
250 
258  protected function getRecordTitleForGroupType($value, $fieldConfig)
259  {
260  if ($fieldConfig['internal_type'] !== 'db') {
261  return implode(', ', GeneralUtility::trimExplode(',', $value, true));
262  }
263  $labelParts = array_map(
264  function ($rawLabelItem) {
265  return rawurldecode(
266  array_pop(GeneralUtility::trimExplode('|', $rawLabelItem, true, 2))
267  );
268  },
269  GeneralUtility::trimExplode(',', $value, true)
270  );
271  if (!empty($labelParts)) {
272  sort($labelParts);
273  return implode(', ', $labelParts);
274  }
275  return '';
276  }
277 
285  protected function getRecordTitleForCheckboxType($value, $fieldConfig)
286  {
287  $languageService = $this->getLanguageService();
288  if (empty($fieldConfig['items']) || !is_array($fieldConfig['items'])) {
289  $title = (bool)$value
290  ? $languageService->sL('LLL:EXT:lang/locallang_common.xlf:yes')
291  : $languageService->sL('LLL:EXT:lang/locallang_common.xlf:no');
292  } else {
293  $labelParts = [];
294  foreach ($fieldConfig['items'] as $key => $val) {
295  if ($value & pow(2, $key)) {
296  $labelParts[] = $val[0];
297  }
298  }
299  $title = implode(', ', $labelParts);
300  }
301  return $title;
302  }
303 
311  protected function getRecordTitleForInputType($value, $fieldConfig)
312  {
313  if (!isset($value)) {
314  return '';
315  }
316  $title = $value;
317  if (GeneralUtility::inList($fieldConfig['eval'], 'date')) {
318  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'date') {
319  $value = $value === '0000-00-00' ? 0 : (int)strtotime($value);
320  } else {
321  $value = (int)$value;
322  }
323  if (!empty($value)) {
324  $ageSuffix = '';
325  // Generate age suffix as long as not explicitly suppressed
326  if (!isset($fieldConfig['disableAgeDisplay']) || (bool)$fieldConfig['disableAgeDisplay'] === false) {
327  $ageDelta = $GLOBALS['EXEC_TIME'] - $value;
328  $calculatedAge = BackendUtility::calcAge(
329  abs($ageDelta),
330  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.minutesHoursDaysYears')
331  );
332  $ageSuffix = ' (' . ($ageDelta > 0 ? '-' : '') . $calculatedAge . ')';
333  }
334  $title = BackendUtility::date($value) . $ageSuffix;
335  }
336  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'time')) {
337  if (!empty($value)) {
338  $title = BackendUtility::time((int)$value, false);
339  }
340  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'timesec')) {
341  if (!empty($value)) {
342  $title = BackendUtility::time((int)$value);
343  }
344  } elseif (GeneralUtility::inList($fieldConfig['eval'], 'datetime')) {
345  // Handle native date/time field
346  if (isset($fieldConfig['dbType']) && $fieldConfig['dbType'] === 'datetime') {
347  $value = $value === '0000-00-00 00:00:00' ? 0 : (int)strtotime($value);
348  } else {
349  $value = (int)$value;
350  }
351  if (!empty($value)) {
352  $title = BackendUtility::datetime($value);
353  }
354  }
355  return $title;
356  }
357 
364  protected function getRecordTitleForTextType($value)
365  {
366  return trim(strip_tags($value));
367  }
368 
372  protected function getDatabaseConnection()
373  {
374  return $GLOBALS['TYPO3_DB'];
375  }
376 
380  protected function getLanguageService()
381  {
382  return $GLOBALS['LANG'];
383  }
384 }
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static calcAge($seconds, $labels=' min|hrs|days|yrs|min|hour|day|year')
static time($value, $withSeconds=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']