38f1bd6234fc8f1ff1ce9ea06fbf4bddba0b6c12
[Packages/TYPO3.CMS.git] / typo3 / sysext / info / Classes / Controller / PageInformationController.php
1 <?php
2 namespace TYPO3\CMS\Info\Controller;
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
17 use Psr\Http\Message\ServerRequestInterface;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Backend\View\PageLayoutView;
20 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
21 use TYPO3\CMS\Core\Site\Entity\NullSite;
22 use TYPO3\CMS\Core\Site\Entity\PseudoSite;
23 use TYPO3\CMS\Core\Site\Entity\Site;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Class for displaying page information (records, page record properties)
28 */
29 class PageInformationController extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule
30 {
31
32 /** @var array */
33 protected $fieldConfiguration = [];
34
35 /**
36 * Returns the menu array
37 *
38 * @return array
39 */
40 public function modMenu()
41 {
42 $menu = [
43 'pages' => [],
44 'depth' => [
45 0 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
46 1 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
47 2 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
48 3 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
49 4 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
50 999 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
51 ]
52 ];
53
54 // Using $GLOBALS['TYPO3_REQUEST'] since $request is not available at this point
55 // @todo: Refactor AbstractFunctionModule mess and have $request available
56 $this->fillFieldConfiguration($this->pObj->id, $GLOBALS['TYPO3_REQUEST']);
57 foreach ($this->fieldConfiguration as $key => $item) {
58 $menu['pages'][$key] = $item['label'];
59 }
60 return $menu;
61 }
62
63 /**
64 * MAIN function for page information display
65 *
66 * @return string Output HTML for the module.
67 */
68 public function main()
69 {
70 $theOutput = '<h1>' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:page_title')) . '</h1>';
71 $dblist = GeneralUtility::makeInstance(PageLayoutView::class);
72 $dblist->descrTable = '_MOD_web_info';
73 $dblist->thumbs = 0;
74 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
75 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
76 $dblist->script = (string)$uriBuilder->buildUriFromRoute('web_info');
77 $dblist->showIcon = 0;
78 $dblist->setLMargin = 0;
79 $dblist->agePrefixes = $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears');
80 $dblist->pI_showUser = true;
81
82 if (isset($this->fieldConfiguration[$this->pObj->MOD_SETTINGS['pages']])) {
83 $dblist->fieldArray = $this->fieldConfiguration[$this->pObj->MOD_SETTINGS['pages']]['fields'];
84 }
85
86 // PAGES:
87 $this->pObj->MOD_SETTINGS['pages_levels'] = $this->pObj->MOD_SETTINGS['depth'];
88 // ONLY for the sake of dblist module which uses this value.
89 $h_func = BackendUtility::getDropdownMenu($this->pObj->id, 'SET[depth]', $this->pObj->MOD_SETTINGS['depth'], $this->pObj->MOD_MENU['depth']);
90 $h_func .= BackendUtility::getDropdownMenu($this->pObj->id, 'SET[pages]', $this->pObj->MOD_SETTINGS['pages'], $this->pObj->MOD_MENU['pages']);
91 $dblist->start($this->pObj->id, 'pages', 0);
92 $dblist->generateList();
93
94 $theOutput .= '<div class="form-inline form-inline-spaced">'
95 . $h_func
96 . '<div class="form-group">'
97 . BackendUtility::cshItem($dblist->descrTable, 'func_' . $this->pObj->MOD_SETTINGS['pages'], null, '<span class="btn btn-default btn-sm">|</span>')
98 . '</div>'
99 . '</div>'
100 . $dblist->HTMLcode;
101
102 // Additional footer content
103 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/web_info/class.tx_cms_webinfo.php']['drawFooterHook'] ?? [] as $hook) {
104 $params = [];
105 $theOutput .= GeneralUtility::callUserFunction($hook, $params, $this);
106 }
107 return $theOutput;
108 }
109
110 /**
111 * Function, which returns all tables to
112 * which the user has access. Also a set of standard tables (pages, sys_filemounts, etc...)
113 * are filtered out. So what is left is basically all tables which makes sense to list content from.
114 *
115 * @return string
116 */
117 protected function cleanTableNames(): string
118 {
119 // Get all table names:
120 $tableNames = array_flip(array_keys($GLOBALS['TCA']));
121 // Unset common names:
122 unset($tableNames['pages']);
123 unset($tableNames['sys_filemounts']);
124 unset($tableNames['sys_action']);
125 unset($tableNames['sys_workflows']);
126 unset($tableNames['be_users']);
127 unset($tableNames['be_groups']);
128 $allowedTableNames = [];
129 // Traverse table names and set them in allowedTableNames array IF they can be read-accessed by the user.
130 if (is_array($tableNames)) {
131 foreach ($tableNames as $k => $v) {
132 if (!$GLOBALS['TCA'][$k]['ctrl']['hideTable'] && $this->getBackendUser()->check('tables_select', $k)) {
133 $allowedTableNames['table_' . $k] = $k;
134 }
135 }
136 }
137 return implode(',', array_keys($allowedTableNames));
138 }
139
140 /**
141 * Generate configuration for field selection
142 *
143 * @param int $pageId current page id
144 * @param ServerRequestInterface $request
145 */
146 protected function fillFieldConfiguration(int $pageId, ServerRequestInterface $request)
147 {
148 $modTSconfig = BackendUtility::getPagesTSconfig($pageId)['mod.']['web_info.']['fieldDefinitions.'] ?? [];
149 foreach ($modTSconfig as $key => $item) {
150 $fieldList = str_replace('###ALL_TABLES###', $this->cleanTableNames(), $item['fields']);
151 $fields = GeneralUtility::trimExplode(',', $fieldList, true);
152 if ((int)$key === 0) {
153 // If "Basic settings" is rendered, hide the alias field on trees that have a site configuration
154 // and hide the slug field on PseudoSites. On NullSites (pid 0), show both.
155 $site = $request->getAttribute('site');
156 if ($site instanceof PseudoSite) {
157 $fields = array_diff($fields, ['slug']);
158 } elseif ($site instanceof Site && !$site instanceof NullSite) {
159 $fields = array_diff($fields, ['alias']);
160 }
161 }
162 $key = trim($key, '.');
163 $this->fieldConfiguration[$key] = [
164 'label' => $item['label'] ? $GLOBALS['LANG']->sL($item['label']) : $key,
165 'fields' => $fields
166 ];
167 }
168 }
169
170 /**
171 * @return BackendUserAuthentication
172 */
173 protected function getBackendUser()
174 {
175 return $GLOBALS['BE_USER'];
176 }
177 }