TYPO3 CMS  TYPO3_8-7
TableManualRepository.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 
19 
24 {
28  protected $accessService;
29 
33  public function __construct()
34  {
35  $this->accessService = GeneralUtility::makeInstance(\TYPO3\CMS\Cshmanual\Service\AccessService::class);
36  }
37 
44  public function getTableManual($table)
45  {
46  $parts = [];
47 
48  // Load descriptions for table $table
49  $this->getLanguageService()->loadSingleTableDescription($table);
50  if (is_array($GLOBALS['TCA_DESCR'][$table]['columns']) && ($this->accessService->checkAccess('tables_select', $table))) {
51  // Reserved for header of table
52  $parts[0] = '';
53  // Traverse table columns as listed in TCA_DESCR
54  foreach ($GLOBALS['TCA_DESCR'][$table]['columns'] as $field => $_) {
55  if (!$this->isExcludableField($table, $field) || $this->accessService->checkAccess('non_exclude_fields', $table . ':' . $field)) {
56  if (!$field) {
57  // Header
58  $parts[0] = $this->getItem($table, '', true);
59  } else {
60  // Field
61  $parts[] = $this->getItem($table, $field, true);
62  }
63  }
64  }
65  if (!$parts[0]) {
66  unset($parts[0]);
67  }
68  }
69  return $parts;
70  }
71 
79  public function getSingleManual($table, $field)
80  {
81  $this->getLanguageService()->loadSingleTableDescription($table);
82  return $this->getItem($table, $field);
83  }
84 
91  public function getSections($mode)
92  {
93  // Initialize
94  $cshKeys = array_flip(array_keys($GLOBALS['TCA_DESCR']));
95  $tcaKeys = array_keys($GLOBALS['TCA']);
96  $outputSections = [];
97  $tocArray = [];
98  // TYPO3 Core Features
99  $lang = $this->getLanguageService();
100  $lang->loadSingleTableDescription('xMOD_csh_corebe');
101  $this->renderTableOfContentItem($mode, 'xMOD_csh_corebe', 'core', $outputSections, $tocArray, $cshKeys);
102  // Backend Modules
103  $loadModules = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
104  $loadModules->load($GLOBALS['TBE_MODULES']);
105  foreach ($loadModules->modules as $mainMod => $info) {
106  $cshKey = '_MOD_' . $mainMod;
107  if ($cshKeys[$cshKey]) {
108  $lang->loadSingleTableDescription($cshKey);
109  $this->renderTableOfContentItem($mode, $cshKey, 'modules', $outputSections, $tocArray, $cshKeys);
110  }
111  if (is_array($info['sub'])) {
112  foreach ($info['sub'] as $subMod => $subInfo) {
113  $cshKey = '_MOD_' . $mainMod . '_' . $subMod;
114  if ($cshKeys[$cshKey]) {
115  $lang->loadSingleTableDescription($cshKey);
116  $this->renderTableOfContentItem($mode, $cshKey, 'modules', $outputSections, $tocArray, $cshKeys);
117  }
118  }
119  }
120  }
121  // Database Tables
122  foreach ($tcaKeys as $table) {
123  // Load descriptions for table $table
124  $lang->loadSingleTableDescription($table);
125  if (is_array($GLOBALS['TCA_DESCR'][$table]['columns']) && $this->accessService->checkAccess('tables_select', $table)) {
126  $this->renderTableOfContentItem($mode, $table, 'tables', $outputSections, $tocArray, $cshKeys);
127  }
128  }
129  foreach ($cshKeys as $cshKey => $value) {
130  // Extensions
131  if (GeneralUtility::isFirstPartOfStr($cshKey, 'xEXT_') && !isset($GLOBALS['TCA'][$cshKey])) {
132  $lang->loadSingleTableDescription($cshKey);
133  $this->renderTableOfContentItem($mode, $cshKey, 'extensions', $outputSections, $tocArray, $cshKeys);
134  }
135  // Other
136  if (!GeneralUtility::isFirstPartOfStr($cshKey, '_MOD_') && !isset($GLOBALS['TCA'][$cshKey])) {
137  $lang->loadSingleTableDescription($cshKey);
138  $this->renderTableOfContentItem($mode, $cshKey, 'other', $outputSections, $tocArray, $cshKeys);
139  }
140  }
141 
142  if ($mode === \TYPO3\CMS\Cshmanual\Controller\HelpController::TOC_ONLY) {
143  return $tocArray;
144  }
145 
146  return [
147  'toc' => $tocArray,
148  'content' => $outputSections
149  ];
150  }
151 
162  protected function renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
163  {
164  $tocArray[$tocCat][$table] = $this->getTableFieldLabel($table);
165  if (!$mode) {
166  // Render full manual right here!
167  $outputSections[$table]['content'] = $this->getTableManual($table);
168  if (!$outputSections[$table]) {
169  unset($outputSections[$table]);
170  }
171  }
172 
173  // Unset CSH key
174  unset($CSHkeys[$table]);
175  }
176 
186  protected function getTableFieldLabel($key, $field = '', $mergeToken = ': ')
187  {
188  // Get table / field parts
189  list($tableName, $fieldName) = $this->getTableFieldNames($key, $field);
190  // Create label
191  return $this->getLanguageService()->sL($tableName) . ($field ? $mergeToken . rtrim(trim($this->getLanguageService()->sL($fieldName)), ':') : '');
192  }
193 
201  protected function getTableFieldNames($key, $field)
202  {
203  $this->getLanguageService()->loadSingleTableDescription($key);
204  // Define the label for the key
205  $keyName = $key;
206  if (!empty($GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'])) {
207  // If there's an alternative title, use it
208  $keyName = $GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'];
209  } elseif (isset($GLOBALS['TCA'][$key])) {
210  // Otherwise, if it's a table, use its title
211  $keyName = $GLOBALS['TCA'][$key]['ctrl']['title'];
212  } else {
213  // If no title was found, make sure to remove any "_MOD_"
214  $keyName = preg_replace('/^_MOD_/', '', $key);
215  }
216  // Define the label for the field
217  $fieldName = $field;
218  if (!empty($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'])) {
219  // If there's an alternative title, use it
220  $fieldName = $GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'];
221  } elseif (!empty($GLOBALS['TCA'][$key]['columns'][$field])) {
222  // Otherwise, if it's a table, use its title
223  $fieldName = $GLOBALS['TCA'][$key]['columns'][$field]['label'];
224  }
225  return [$keyName, $fieldName];
226  }
227 
237  protected function getItem($table, $field, $anchors = false)
238  {
239  if (!empty($table)) {
240  $field = !empty($field) ? $field : '';
241  $setup = $GLOBALS['TCA_DESCR'][$table]['columns'][$field];
242  return [
243  'table' => $table,
244  'field' => $field,
245  'configuration' => $setup,
246  'headerLine' => $this->getTableFieldLabel($table, $field),
247  'content' => !empty($setup['description']) ? $setup['description'] : '',
248  'images' => !empty($setup['image']) ? $this->getImages($setup['image'], $setup['image_descr']) : [],
249  'seeAlso' => !empty($setup['seeAlso']) ? $this->getSeeAlsoLinks($setup['seeAlso'], $anchors ? $table : '') : '',
250  ];
251  }
252  return [];
253  }
254 
262  protected function getSeeAlsoLinks($value, $anchorTable = '')
263  {
264  // Split references by comma or linebreak
265  $items = preg_split('/[,' . LF . ']/', $value);
266  $lines = [];
267  foreach ($items as $itemValue) {
268  $itemValue = trim($itemValue);
269  if ($itemValue) {
270  $reference = GeneralUtility::trimExplode(':', $itemValue);
271  $referenceUrl = GeneralUtility::trimExplode('|', $itemValue);
272  if (substr($referenceUrl[1], 0, 4) === 'http') {
273  // URL reference
274  $lines[] = [
275  'url' => $referenceUrl[1],
276  'title' => $referenceUrl[0],
277  'target' => '_blank'
278  ];
279  } elseif (substr($referenceUrl[1], 0, 5) === 'FILE:') {
280  // File reference
281  $fileName = GeneralUtility::getFileAbsFileName(substr($referenceUrl[1], 5));
282  if ($fileName && @is_file($fileName)) {
283  $fileName = '../' . PathUtility::stripPathSitePrefix($fileName);
284  $lines[] = [
285  'url' => $fileName,
286  'title' => $referenceUrl[0],
287  'target' => '_blank'
288  ];
289  }
290  } else {
291  // Table reference
292  $table = !empty($reference[0]) ? $reference[0] : '';
293  $field = !empty($reference[1]) ? $reference[1] : '';
294  $accessAllowed = true;
295  // Check if table exists and current user can access it
296  if (!empty($table)) {
297  $accessAllowed = !$this->getTableSetup($table) || $this->accessService->checkAccess('tables_select', $table);
298  }
299  // Check if field exists and is excludable or user can access it
300  if ($accessAllowed && !empty($field)) {
301  $accessAllowed = !$this->isExcludableField($table, $field) || $this->accessService->checkAccess('non_exclude_fields', $table . ':' . $field);
302  }
303  // Check read access
304  if ($accessAllowed && isset($GLOBALS['TCA_DESCR'][$table])) {
305  // Make see-also link
306  $label = $this->getTableFieldLabel($table, $field, ' / ');
307  if ($anchorTable && $table === $anchorTable) {
308  $lines[] = [
309  'url' => '#' . rawurlencode(implode('.', $reference)),
310  'title' => $label,
311  ];
312  } else {
313  $lines[] = [
314  'internal' => true,
315  'arguments' => [
316  'table' => $table,
317  'field' => $field
318  ],
319  'title' => $label
320  ];
321  }
322  }
323  }
324  }
325  }
326  return $lines;
327  }
328 
336  protected function isExcludableField($table, $field)
337  {
338  $fieldSetup = $this->getFieldSetup($table, $field);
339  if (!empty($fieldSetup)) {
340  return !empty($fieldSetup['exclude']);
341  }
342  return false;
343  }
344 
352  protected function getImages($images, $descriptions)
353  {
354  $imageData = [];
355  // Splitting
356  $imgArray = GeneralUtility::trimExplode(',', $images, true);
357  if (!empty($imgArray)) {
358  $descrArray = explode(LF, $descriptions, count($imgArray));
359  foreach ($imgArray as $k => $image) {
360  $descriptions = $descrArray[$k];
361  $absImagePath = GeneralUtility::getFileAbsFileName($image);
362  if ($absImagePath && @is_file($absImagePath)) {
363  $imgFile = PathUtility::stripPathSitePrefix($absImagePath);
364  $imgInfo = @getimagesize($absImagePath);
365  if (is_array($imgInfo)) {
366  $imageData[] = [
367  'image' => $imgFile,
368  'description' => $descriptions
369  ];
370  }
371  }
372  }
373  }
374  return $imageData;
375  }
376 
383  protected function getTableSetup($table)
384  {
385  if (!empty($table) && !empty($GLOBALS['TCA'][$table])) {
386  return $GLOBALS['TCA'][$table];
387  }
388  return [];
389  }
390 
399  protected function getFieldSetup($table, $field, $allowEmptyField = false)
400  {
401  $tableSetup = $this->getTableSetup($table);
402  if (!empty($tableSetup) && (!empty($field) || $allowEmptyField) && !empty($tableSetup['columns'][$field])) {
403  return $tableSetup['columns'][$field];
404  }
405  return [];
406  }
407 
413  protected function getLanguageService()
414  {
415  return $GLOBALS['LANG'];
416  }
417 }
static isFirstPartOfStr($str, $partStr)
static getFileAbsFileName($filename, $_=null, $_2=null)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static makeInstance($className,... $constructorArguments)
renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']