TYPO3 CMS  TYPO3_7-6
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 
163  protected function renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
164  {
165  $tocArray[$tocCat][$table] = $this->getTableFieldLabel($table);
166  if (!$mode) {
167  // Render full manual right here!
168  $outputSections[$table]['content'] = $this->getTableManual($table);
169  if (!$outputSections[$table]) {
170  unset($outputSections[$table]);
171  }
172  }
173 
174  // Unset CSH key
175  unset($CSHkeys[$table]);
176  }
177 
187  protected function getTableFieldLabel($key, $field = '', $mergeToken = ': ')
188  {
189  // Get table / field parts
190  list($tableName, $fieldName) = $this->getTableFieldNames($key, $field);
191  // Create label
192  return $this->getLanguageService()->sL($tableName) . ($field ? $mergeToken . rtrim(trim($this->getLanguageService()->sL($fieldName)), ':') : '');
193  }
194 
202  protected function getTableFieldNames($key, $field)
203  {
204  $this->getLanguageService()->loadSingleTableDescription($key);
205  // Define the label for the key
206  $keyName = $key;
207  if (!empty($GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'])) {
208  // If there's an alternative title, use it
209  $keyName = $GLOBALS['TCA_DESCR'][$key]['columns']['']['alttitle'];
210  } elseif (isset($GLOBALS['TCA'][$key])) {
211  // Otherwise, if it's a table, use its title
212  $keyName = $GLOBALS['TCA'][$key]['ctrl']['title'];
213  } else {
214  // If no title was found, make sure to remove any "_MOD_"
215  $keyName = preg_replace('/^_MOD_/', '', $key);
216  }
217  // Define the label for the field
218  $fieldName = $field;
219  if (!empty($GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'])) {
220  // If there's an alternative title, use it
221  $fieldName = $GLOBALS['TCA_DESCR'][$key]['columns'][$field]['alttitle'];
222  } elseif (!empty($GLOBALS['TCA'][$key]['columns'][$field])) {
223  // Otherwise, if it's a table, use its title
224  $fieldName = $GLOBALS['TCA'][$key]['columns'][$field]['label'];
225  }
226  return [$keyName, $fieldName];
227  }
228 
238  protected function getItem($table, $field, $anchors = false)
239  {
240  if (!empty($table)) {
241  $field = !empty($field) ? $field : '';
242  $setup = $GLOBALS['TCA_DESCR'][$table]['columns'][$field];
243  return [
244  'table' => $table,
245  'field' => $field,
246  'configuration' => $setup,
247  'headerLine' => $this->getTableFieldLabel($table, $field),
248  'content' => !empty($setup['description']) ? $setup['description'] : '',
249  'images' => !empty($setup['image']) ? $this->getImages($setup['image'], $setup['image_descr']) : [],
250  'seeAlso' => !empty($setup['seeAlso']) ? $this->getSeeAlsoLinks($setup['seeAlso'], $anchors ? $table : '') : '',
251  ];
252  }
253  return [];
254  }
255 
263  protected function getSeeAlsoLinks($value, $anchorTable = '')
264  {
265  // Split references by comma or linebreak
266  $items = preg_split('/[,' . LF . ']/', $value);
267  $lines = [];
268  foreach ($items as $itemValue) {
269  $itemValue = trim($itemValue);
270  if ($itemValue) {
271  $reference = GeneralUtility::trimExplode(':', $itemValue);
272  $referenceUrl = GeneralUtility::trimExplode('|', $itemValue);
273  if (substr($referenceUrl[1], 0, 4) === 'http') {
274  // URL reference
275  $lines[] = [
276  'url' => $referenceUrl[1],
277  'title' => $referenceUrl[0],
278  'target' => '_blank'
279  ];
280  } elseif (substr($referenceUrl[1], 0, 5) === 'FILE:') {
281  // File reference
282  $fileName = GeneralUtility::getFileAbsFileName(substr($referenceUrl[1], 5), 1, 1);
283  if ($fileName && @is_file($fileName)) {
284  $fileName = '../' . PathUtility::stripPathSitePrefix($fileName);
285  $lines[] = [
286  'url' => $fileName,
287  'title' => $referenceUrl[0],
288  'target' => '_blank'
289  ];
290  }
291  } else {
292  // Table reference
293  $table = !empty($reference[0]) ? $reference[0] : '';
294  $field = !empty($reference[1]) ? $reference[1] : '';
295  $accessAllowed = true;
296  // Check if table exists and current user can access it
297  if (!empty($table)) {
298  $accessAllowed = !$this->getTableSetup($table) || $this->accessService->checkAccess('tables_select', $table);
299  }
300  // Check if field exists and is excludable or user can access it
301  if ($accessAllowed && !empty($field)) {
302  $accessAllowed = !$this->isExcludableField($table, $field) || $this->accessService->checkAccess('non_exclude_fields', $table . ':' . $field);
303  }
304  // Check read access
305  if ($accessAllowed && isset($GLOBALS['TCA_DESCR'][$table])) {
306  // Make see-also link
307  $label = $this->getTableFieldLabel($table, $field, ' / ');
308  if ($anchorTable && $table === $anchorTable) {
309  $lines[] = [
310  'url' => '#' . rawurlencode(implode('.', $reference)),
311  'title' => $label,
312  ];
313  } else {
314  $lines[] = [
315  'internal' => true,
316  'arguments' => [
317  'table' => $table,
318  'field' => $field
319  ],
320  'title' => $label
321  ];
322  }
323  }
324  }
325  }
326  }
327  return $lines;
328  }
329 
337  protected function isExcludableField($table, $field)
338  {
339  $fieldSetup = $this->getFieldSetup($table, $field);
340  if (!empty($fieldSetup)) {
341  return !empty($fieldSetup['exclude']);
342  }
343  return false;
344  }
345 
353  protected function getImages($images, $descriptions)
354  {
355  $imageData = [];
356  // Splitting
357  $imgArray = GeneralUtility::trimExplode(',', $images, true);
358  if (!empty($imgArray)) {
359  $descrArray = explode(LF, $descriptions, count($imgArray));
360  foreach ($imgArray as $k => $image) {
361  $descriptions = $descrArray[$k];
362  $absImagePath = GeneralUtility::getFileAbsFileName($image, true, true);
363  if ($absImagePath && @is_file($absImagePath)) {
364  $imgFile = PathUtility::stripPathSitePrefix($absImagePath);
365  $imgInfo = @getimagesize($absImagePath);
366  if (is_array($imgInfo)) {
367  $imageData[] = [
368  'image' => $imgFile,
369  'description' => $descriptions
370  ];
371  }
372  }
373  }
374  }
375  return $imageData;
376  }
377 
384  protected function getTableSetup($table)
385  {
386  if (!empty($table) && !empty($GLOBALS['TCA'][$table])) {
387  return $GLOBALS['TCA'][$table];
388  }
389  return [];
390  }
391 
400  protected function getFieldSetup($table, $field, $allowEmptyField = false)
401  {
402  $tableSetup = $this->getTableSetup($table);
403  if (!empty($tableSetup) && (!empty($field) || $allowEmptyField) && !empty($tableSetup['columns'][$field])) {
404  return $tableSetup['columns'][$field];
405  }
406  return [];
407  }
408 
414  protected function getLanguageService()
415  {
416  return $GLOBALS['LANG'];
417  }
418 }
static isFirstPartOfStr($str, $partStr)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static getFileAbsFileName($filename, $onlyRelative=true, $relToTYPO3_mainDir=false)
renderTableOfContentItem($mode, $table, $tocCat, &$outputSections, &$tocArray, &$CSHkeys)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']