‪TYPO3CMS  11.5
TableManualRepository.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 
24 
30 {
37  public function ‪getTableManual($table)
38  {
39  $parts = [];
40 
41  // Load descriptions for table $table
42  $this->‪getLanguageService()->loadSingleTableDescription($table);
43  if (is_array(‪$GLOBALS['TCA_DESCR'][$table]['columns'] ?? null) && $this->‪checkAccess('tables_select', $table)) {
44  // Reserved for header of table
45  $parts[0] = '';
46  // Traverse table columns as listed in TCA_DESCR
47  foreach (‪$GLOBALS['TCA_DESCR'][$table]['columns'] as $field => $_) {
49  if (!$this->‪isExcludableField($table, $field) || $this->‪checkAccess('non_exclude_fields', $table . ':' . $field)) {
50  if (!$field) {
51  // Header
52  $parts[0] = $this->‪getItem($table, '', true);
53  } else {
54  // Field
55  $parts[] = $this->‪getItem($table, $field, true);
56  }
57  }
58  }
59  if (!$parts[0]) {
60  unset($parts[0]);
61  }
62  }
63  return $parts;
64  }
65 
73  public function ‪getSingleManual($table, $field)
74  {
75  $this->‪getLanguageService()->loadSingleTableDescription($table);
76  return $this->‪getItem($table, $field);
77  }
78 
85  public function ‪getSections($mode)
86  {
87  // Initialize
88  $cshKeys = array_flip(array_keys(‪$GLOBALS['TCA_DESCR']));
90  $tcaKeys = array_keys(‪$GLOBALS['TCA']);
91  $outputSections = [];
92  $tocArray = [];
93  // TYPO3 Core Features
94  $lang = $this->‪getLanguageService();
95  $lang->loadSingleTableDescription('xMOD_csh_corebe');
96  $this->‪renderTableOfContentItem($mode, 'xMOD_csh_corebe', 'core', $outputSections, $tocArray, $cshKeys);
97  // Backend Modules
98  $loadModules = GeneralUtility::makeInstance(ModuleLoader::class);
99  $loadModules->load(‪$GLOBALS['TBE_MODULES']);
100  foreach ($loadModules->getModules() as $mainMod => $info) {
101  $cshKey = '_MOD_' . $mainMod;
102  if ($cshKeys[$cshKey] ?? '') {
103  $lang->loadSingleTableDescription($cshKey);
104  $this->‪renderTableOfContentItem($mode, $cshKey, 'modules', $outputSections, $tocArray, $cshKeys);
105  }
106  if (is_array($info['sub'] ?? null)) {
107  foreach ($info['sub'] as $subMod => $subInfo) {
108  $cshKey = '_MOD_' . $mainMod . '_' . $subMod;
109  if ($cshKeys[$cshKey] ?? '') {
110  $lang->loadSingleTableDescription($cshKey);
111  $this->‪renderTableOfContentItem($mode, $cshKey, 'modules', $outputSections, $tocArray, $cshKeys);
112  }
113  }
114  }
115  }
116  // Database Tables
117  foreach ($tcaKeys as $table) {
118  // Load descriptions for table $table
119  $lang->loadSingleTableDescription($table);
120  if (is_array(‪$GLOBALS['TCA_DESCR'][$table]['columns'] ?? null) && $this->‪checkAccess('tables_select', $table)) {
121  $this->‪renderTableOfContentItem($mode, $table, 'tables', $outputSections, $tocArray, $cshKeys);
122  }
123  }
124  foreach ($cshKeys as $cshKey => $value) {
125  // Extensions
126  if (str_starts_with($cshKey, 'xEXT_') && !isset(‪$GLOBALS['TCA'][$cshKey])) {
127  $lang->loadSingleTableDescription($cshKey);
128  $this->‪renderTableOfContentItem($mode, $cshKey, 'extensions', $outputSections, $tocArray, $cshKeys);
129  }
130  // Other
131  if (!str_starts_with($cshKey, '_MOD_') && !isset(‪$GLOBALS['TCA'][$cshKey])) {
132  $lang->loadSingleTableDescription($cshKey);
133  $this->‪renderTableOfContentItem($mode, $cshKey, 'other', $outputSections, $tocArray, $cshKeys);
134  }
135  }
136 
137  if ($mode === ‪HelpController::TOC_ONLY) {
138  return $tocArray;
139  }
140 
141  return [
142  'toc' => $tocArray,
143  'content' => $outputSections,
144  ];
145  }
146 
157  protected function ‪renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
158  {
159  $tocArray[$tocCat][$table] = $this->‪getTableFieldLabel($table);
160  if (!$mode) {
161  // Render full manual right here!
162  $outputSections[$table]['content'] = $this->‪getTableManual($table);
163  if (!$outputSections[$table]) {
164  unset($outputSections[$table]);
165  }
166  }
167 
168  // Unset CSH key
169  unset($CSHkeys[$table]);
170  }
171 
181  protected function ‪getTableFieldLabel($key, $field = '', $mergeToken = ': ')
182  {
183  // Get table / field parts
184  [$tableName, $fieldName] = $this->‪getTableFieldNames($key, $field);
185  // Create label
186  return $this->‪getLanguageService()->sL($tableName) . ($field ? $mergeToken . rtrim(trim($this->‪getLanguageService()->sL($fieldName)), ':') : '');
187  }
188 
196  protected function ‪getTableFieldNames($key, $field)
197  {
198  $this->‪getLanguageService()->loadSingleTableDescription($key);
199  // Define the label for the key
200  if (!empty(‪$GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'])) {
201  // If there's an alternative title, use it
202  $keyName = ‪$GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'];
203  } elseif (isset(‪$GLOBALS['TCA'][$key])) {
204  // Otherwise, if it's a table, use its title
205  $keyName = ‪$GLOBALS['TCA'][$key]['ctrl']['title'];
206  } else {
207  // If no title was found, make sure to remove any "_MOD_"
208  $keyName = preg_replace('/^_MOD_/', '', $key);
209  }
210  // Define the label for the field
211  $fieldName = $field;
212  if (!empty(‪$GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'])) {
213  // If there's an alternative title, use it
214  $fieldName = ‪$GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'];
215  } elseif (!empty(‪$GLOBALS['TCA'][$key]['columns'][$field])) {
216  // Otherwise, if it's a table, use its title
217  $fieldName = ‪$GLOBALS['TCA'][$key]['columns'][$field]['label'];
218  }
219  return [$keyName, $fieldName];
220  }
221 
231  protected function ‪getItem($table, $field, $anchors = false)
232  {
233  if (!empty($table)) {
234  $field = !empty($field) ? $field : '';
235  $setup = ‪$GLOBALS['TCA_DESCR'][$table]['columns'][$field];
236  return [
237  'table' => $table,
238  'field' => $field,
239  'configuration' => $setup,
240  'headerLine' => $this->‪getTableFieldLabel($table, $field),
241  'content' => !empty($setup['description']) ? $setup['description'] : '',
242  'images' => !empty($setup['image']) ? $this->‪getImages($setup['image'], ($setup['image_descr'] ?? '')) : [],
243  'seeAlso' => !empty($setup['seeAlso']) ? $this->‪getSeeAlsoLinks($setup['seeAlso'], $anchors ? $table : '') : '',
244  ];
245  }
246  return [];
247  }
248 
256  protected function ‪getSeeAlsoLinks($value, $anchorTable = '')
257  {
258  // Split references by comma or linebreak
259  $items = preg_split('/[,' . LF . ']/', $value);
260  $lines = [];
261  foreach ($items as $itemValue) {
262  $itemValue = trim($itemValue);
263  if ($itemValue) {
264  $reference = ‪GeneralUtility::trimExplode(':', $itemValue);
265  $referenceUrl = ‪GeneralUtility::trimExplode('|', $itemValue);
266  if (strpos(($referenceUrl[1] ?? ''), 'http') === 0) {
267  // URL reference
268  $lines[] = [
269  'url' => $referenceUrl[1],
270  'title' => $referenceUrl[0],
271  'target' => '_blank',
272  ];
273  } elseif (strpos(($referenceUrl[1] ?? ''), 'FILE:') === 0) {
274  // File reference
275  $fileName = GeneralUtility::getFileAbsFileName(substr($referenceUrl[1], 5));
276  if ($fileName && @is_file($fileName)) {
277  $fileName = ‪PathUtility::getAbsoluteWebPath($fileName);
278  $lines[] = [
279  'url' => $fileName,
280  'title' => $referenceUrl[0],
281  'target' => '_blank',
282  ];
283  }
284  } else {
285  // Table reference
286  $table = !empty($reference[0]) ? $reference[0] : '';
287  $field = !empty($reference[1]) ? $reference[1] : '';
288  $accessAllowed = true;
289  // Check if table exists and current user can access it
290  if (!empty($table)) {
291  $accessAllowed = !$this->‪getTableSetup($table) || $this->‪checkAccess('tables_select', $table);
292  }
293  // Check if field exists and is excludable or user can access it
294  if ($accessAllowed && !empty($field)) {
295  $accessAllowed = !$this->‪isExcludableField($table, $field) || $this->‪checkAccess('non_exclude_fields', $table . ':' . $field);
296  }
297  // Check read access
298  if ($accessAllowed && isset(‪$GLOBALS['TCA_DESCR'][$table])) {
299  // Make see-also link
300  $label = $this->‪getTableFieldLabel($table, $field, ' / ');
301  if ($anchorTable && $table === $anchorTable) {
302  $lines[] = [
303  'url' => '#' . rawurlencode(implode('.', $reference)),
304  'title' => $label,
305  ];
306  } else {
307  $lines[] = [
308  'internal' => true,
309  'arguments' => [
310  'table' => $table,
311  'field' => $field,
312  'action' => 'detail',
313  ],
314  'title' => $label,
315  ];
316  }
317  }
318  }
319  }
320  }
321  return $lines;
322  }
323 
331  protected function ‪isExcludableField($table, $field)
332  {
333  $fieldSetup = $this->‪getFieldSetup($table, $field);
334  if (!empty($fieldSetup)) {
335  return !empty($fieldSetup['exclude']);
336  }
337  return false;
338  }
339 
347  protected function ‪getImages($images, $descriptions)
348  {
349  $imageData = [];
350  // Splitting
351  $imgArray = ‪GeneralUtility::trimExplode(',', $images, true);
352  if (!empty($imgArray)) {
353  $descrArray = explode(LF, $descriptions, count($imgArray));
354  foreach ($imgArray as $k => $image) {
355  $descriptions = $descrArray[$k] ?? '';
356  $absImagePath = GeneralUtility::getFileAbsFileName($image);
357  if ($absImagePath && @is_file($absImagePath)) {
358  $imgFile = ‪PathUtility::getAbsoluteWebPath($absImagePath);
359  $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $absImagePath);
360  if ($imageInfo->getWidth()) {
361  $imageData[] = [
362  'image' => $imgFile,
363  'description' => $descriptions,
364  ];
365  }
366  }
367  }
368  }
369  return $imageData;
370  }
371 
378  protected function ‪getTableSetup($table)
379  {
380  if (!empty($table) && !empty(‪$GLOBALS['TCA'][$table])) {
381  return ‪$GLOBALS['TCA'][$table];
382  }
383  return [];
384  }
385 
394  protected function ‪getFieldSetup($table, $field, $allowEmptyField = false)
395  {
396  $tableSetup = $this->‪getTableSetup($table);
397  if (!empty($tableSetup) && (!empty($field) || $allowEmptyField) && !empty($tableSetup['columns'][$field])) {
398  return $tableSetup['columns'][$field];
399  }
400  return [];
401  }
402 
410  protected function ‪checkAccess($type, $identifier)
411  {
412  if (!empty($type) && !empty($identifier)) {
413  return $this->‪getBackendUser()->‪check($type, $identifier);
414  }
415  return false;
416  }
417 
424  {
425  return ‪$GLOBALS['BE_USER'];
426  }
427 
433  protected function ‪getLanguageService()
434  {
435  return ‪$GLOBALS['LANG'];
436  }
437 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Backend\Domain\Repository
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: TableManualRepository.php:423
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\check
‪bool check($type, $value)
Definition: BackendUserAuthentication.php:585
‪TYPO3\CMS\Backend\Controller\HelpController
Definition: HelpController.php:42
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\renderTableOfContentItem
‪renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
Definition: TableManualRepository.php:157
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getSeeAlsoLinks
‪array getSeeAlsoLinks($value, $anchorTable='')
Definition: TableManualRepository.php:256
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getImages
‪array getImages($images, $descriptions)
Definition: TableManualRepository.php:347
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository
Definition: TableManualRepository.php:30
‪TYPO3\CMS\Backend\Controller\HelpController\TOC_ONLY
‪const TOC_ONLY
Definition: HelpController.php:53
‪TYPO3\CMS\Backend\Module\ModuleLoader
Definition: ModuleLoader.php:34
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getItem
‪array getItem($table, $field, $anchors=false)
Definition: TableManualRepository.php:231
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getSections
‪array getSections($mode)
Definition: TableManualRepository.php:85
‪TYPO3\CMS\Core\Type\File\ImageInfo
Definition: ImageInfo.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getTableFieldLabel
‪string getTableFieldLabel($key, $field='', $mergeToken=':')
Definition: TableManualRepository.php:181
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getLanguageService
‪TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: TableManualRepository.php:433
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getSingleManual
‪array getSingleManual($table, $field)
Definition: TableManualRepository.php:73
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\isExcludableField
‪bool isExcludableField($table, $field)
Definition: TableManualRepository.php:331
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getFieldSetup
‪array getFieldSetup($table, $field, $allowEmptyField=false)
Definition: TableManualRepository.php:394
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getTableManual
‪array getTableManual($table)
Definition: TableManualRepository.php:37
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getTableSetup
‪array getTableSetup($table)
Definition: TableManualRepository.php:378
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath($targetPath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\checkAccess
‪bool checkAccess($type, $identifier)
Definition: TableManualRepository.php:410
‪TYPO3\CMS\Backend\Domain\Repository\TableManualRepository\getTableFieldNames
‪array getTableFieldNames($key, $field)
Definition: TableManualRepository.php:196