[TASK] Streamline BackendUtility::getPagesTSconfig
[Packages/TYPO3.CMS.git] / typo3 / sysext / info / Classes / Controller / InfoPageTyposcriptConfigController.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 TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
20 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
21 use TYPO3\CMS\Core\Imaging\Icon;
22 use TYPO3\CMS\Core\Imaging\IconFactory;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\CMS\Core\Utility\MathUtility;
25 use TYPO3\CMS\Fluid\View\StandaloneView;
26
27 /**
28 * Page TSconfig viewer
29 */
30 class InfoPageTyposcriptConfigController extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule
31 {
32 /**
33 * @var IconFactory
34 */
35 protected $iconFactory;
36
37 /**
38 * @var StandaloneView
39 */
40 protected $view;
41
42 /**
43 * Constructor
44 */
45 public function __construct()
46 {
47 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
48 $this->getLanguageService()->includeLLFile('EXT:info/Resources/Private/Language/InfoPageTsConfig.xlf');
49
50 $this->view = $this->getFluidTemplateObject();
51 }
52
53 /**
54 * Function menu initialization
55 *
56 * @return array Menu array
57 */
58 public function modMenu()
59 {
60 $lang = $this->getLanguageService();
61 $modMenuAdd = [
62 'tsconf_parts' => [
63 0 => $lang->getLL('tsconf_parts_0'),
64 1 => $lang->getLL('tsconf_parts_1'),
65 '1a' => $lang->getLL('tsconf_parts_1a'),
66 '1b' => $lang->getLL('tsconf_parts_1b'),
67 '1c' => $lang->getLL('tsconf_parts_1c'),
68 '1d' => $lang->getLL('tsconf_parts_1d'),
69 '1e' => $lang->getLL('tsconf_parts_1e'),
70 '1f' => $lang->getLL('tsconf_parts_1f'),
71 '1g' => $lang->getLL('tsconf_parts_1g'),
72 2 => 'RTE.',
73 5 => 'TCEFORM.',
74 6 => 'TCEMAIN.',
75 3 => 'TSFE.',
76 4 => 'user.',
77 99 => $lang->getLL('tsconf_configFields')
78 ],
79 'tsconf_alphaSort' => '1'
80 ];
81 if (!$this->getBackendUser()->isAdmin()) {
82 unset($modMenuAdd['tsconf_parts'][99]);
83 }
84 return $modMenuAdd;
85 }
86
87 /**
88 * Main function of class
89 *
90 * @return string HTML output
91 */
92 public function main()
93 {
94 $pageId = (int)(GeneralUtility::_GP('id'));
95
96 if ($pageId === 0) {
97 $this->view->assign('pageZero', 1);
98 $pagesUsingTSConfig = $this->getOverviewOfPagesUsingTSConfig();
99 if (count($pagesUsingTSConfig) > 0) {
100 $this->view->assign('overviewOfPagesUsingTSConfig', $pagesUsingTSConfig);
101 }
102 } else {
103 if ($this->pObj->MOD_SETTINGS['tsconf_parts'] == 99) {
104 $TSparts = BackendUtility::getRawPagesTSconfig($this->pObj->id);
105 $lines = [];
106 $pUids = [];
107
108 foreach ($TSparts as $k => $v) {
109 if ($k !== 'uid_0') {
110 $line = [];
111 if ($k === 'defaultPageTSconfig') {
112 $line['defaultPageTSconfig'] = 1;
113 } else {
114 $editIdList = substr($k, 4);
115 $pUids[] = $editIdList;
116 $row = BackendUtility::getRecordWSOL('pages', $editIdList);
117
118 $icon = $this->iconFactory->getIconForRecord('pages', $row, Icon::SIZE_SMALL);
119 $urlParameters = [
120 'edit' => [
121 'pages' => [
122 $editIdList => 'edit',
123 ]
124 ],
125 'columnsOnly' => 'TSconfig',
126 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
127 ];
128 $line['editIcon'] = BackendUtility::getModuleUrl('record_edit', $urlParameters);
129 $line['editTitle'] = 'editTSconfig';
130 $line['title'] = BackendUtility::wrapClickMenuOnIcon($icon, 'pages', $row['uid'])
131 . ' ' . htmlspecialchars(BackendUtility::getRecordTitle('pages', $row));
132 }
133 $tsparser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::class);
134 $tsparser->lineNumberOffset = 0;
135 $line['content'] = $tsparser->doSyntaxHighlight(trim($v) . LF);
136 $lines[] = $line;
137 }
138 }
139
140 if (!empty($pUids)) {
141 $urlParameters = [
142 'edit' => [
143 'pages' => [
144 implode(',', $pUids) => 'edit',
145 ]
146 ],
147 'columnsOnly' => 'TSconfig',
148 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
149 ];
150 $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
151 $editIcon = htmlspecialchars($url);
152 $editTitle = 'editTSconfig_all';
153 } else {
154 $editIcon = '';
155 $editTitle = '';
156 }
157
158 $this->view->assign('tsconfParts99', 1);
159 $this->view->assign('csh', BackendUtility::cshItem('_MOD_web_info', 'tsconfig_edit', null, '|'));
160 $this->view->assign('lines', $lines);
161 $this->view->assign('editIcon', $editIcon);
162 $this->view->assign('editTitle', $editTitle);
163 } else {
164 $this->view->assign('tsconfParts99', 0);
165 // Defined global here!
166 $tmpl = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\ExtendedTemplateService::class);
167 $tmpl->ext_expandAllNotes = 1;
168 $tmpl->ext_noPMicons = 1;
169
170 $beUser = $this->getBackendUser();
171 switch ($this->pObj->MOD_SETTINGS['tsconf_parts']) {
172 case '1':
173 $modTSconfig = BackendUtility::getModTSconfig($this->pObj->id, 'mod');
174 break;
175 case '1a':
176 $modTSconfig = $beUser->getTSConfig('mod.web_layout', BackendUtility::getPagesTSconfig($this->pObj->id));
177 break;
178 case '1b':
179 $modTSconfig = $beUser->getTSConfig('mod.web_view', BackendUtility::getPagesTSconfig($this->pObj->id));
180 break;
181 case '1c':
182 $modTSconfig = $beUser->getTSConfig('mod.web_modules', BackendUtility::getPagesTSconfig($this->pObj->id));
183 break;
184 case '1d':
185 $modTSconfig = $beUser->getTSConfig('mod.web_list', BackendUtility::getPagesTSconfig($this->pObj->id));
186 break;
187 case '1e':
188 $modTSconfig = $beUser->getTSConfig('mod.web_info', BackendUtility::getPagesTSconfig($this->pObj->id));
189 break;
190 case '1f':
191 $modTSconfig = $beUser->getTSConfig('mod.web_func', BackendUtility::getPagesTSconfig($this->pObj->id));
192 break;
193 case '1g':
194 $modTSconfig = $beUser->getTSConfig('mod.web_ts', BackendUtility::getPagesTSconfig($this->pObj->id));
195 break;
196 case '2':
197 $modTSconfig = $beUser->getTSConfig('RTE', BackendUtility::getPagesTSconfig($this->pObj->id));
198 break;
199 case '5':
200 $modTSconfig = $beUser->getTSConfig('TCEFORM', BackendUtility::getPagesTSconfig($this->pObj->id));
201 break;
202 case '6':
203 $modTSconfig = $beUser->getTSConfig('TCEMAIN', BackendUtility::getPagesTSconfig($this->pObj->id));
204 break;
205 case '3':
206 $modTSconfig = $beUser->getTSConfig('TSFE', BackendUtility::getPagesTSconfig($this->pObj->id));
207 break;
208 case '4':
209 $modTSconfig = $beUser->getTSConfig('user', BackendUtility::getPagesTSconfig($this->pObj->id));
210 break;
211 default:
212 $modTSconfig['properties'] = BackendUtility::getPagesTSconfig($this->pObj->id);
213 }
214
215 $modTSconfig = $modTSconfig['properties'];
216 if (!is_array($modTSconfig)) {
217 $modTSconfig = [];
218 }
219
220 $this->view->assign('csh', BackendUtility::cshItem('_MOD_web_info', 'tsconfig_hierarchy', null, '|'));
221 $this->view->assign('tree', $tmpl->ext_getObjTree($modTSconfig, '', '', '', '', $this->pObj->MOD_SETTINGS['tsconf_alphaSort']));
222 }
223 $this->view->assign('alphaSort', BackendUtility::getFuncCheck($this->pObj->id, 'SET[tsconf_alphaSort]', $this->pObj->MOD_SETTINGS['tsconf_alphaSort'], '', '', 'id="checkTsconf_alphaSort"'));
224 $this->view->assign('dropdownMenu', BackendUtility::getDropdownMenu($this->pObj->id, 'SET[tsconf_parts]', $this->pObj->MOD_SETTINGS['tsconf_parts'], $this->pObj->MOD_MENU['tsconf_parts']));
225 }
226 return $this->view->render();
227 }
228
229 /**
230 * Renders table rows of all pages containing TSConfig together with its rootline
231 *
232 * @return array
233 */
234 protected function getOverviewOfPagesUsingTSConfig()
235 {
236 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
237 $queryBuilder->getRestrictions()
238 ->removeAll()
239 ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
240 ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
241
242 $res = $queryBuilder
243 ->select('uid', 'TSconfig')
244 ->from('pages')
245 ->where(
246 $queryBuilder->expr()->neq(
247 'TSconfig',
248 $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
249 )
250 )
251 ->groupBy('uid')
252 ->execute();
253
254 $pageArray = [];
255
256 while ($row = $res->fetch()) {
257 $this->setInPageArray($pageArray, BackendUtility::BEgetRootLine($row['uid'], 'AND 1=1'), $row);
258 }
259 return $this->getList($pageArray);
260 }
261
262 /**
263 * Set page in array
264 * This function is called recursively and builds a multi-dimensional array that reflects the page
265 * hierarchy.
266 *
267 * @param array $hierarchicArray The hierarchic array (passed by reference)
268 * @param array $rootlineArray The rootline array
269 * @param array $row The row from the database containing the uid and TSConfig fields
270 */
271 protected function setInPageArray(&$hierarchicArray, $rootlineArray, $row)
272 {
273 ksort($rootlineArray);
274 reset($rootlineArray);
275 if (!$rootlineArray[0]['uid']) {
276 array_shift($rootlineArray);
277 }
278 $currentElement = current($rootlineArray);
279 $hierarchicArray[$currentElement['uid']] = htmlspecialchars($currentElement['title']);
280 array_shift($rootlineArray);
281 if (!empty($rootlineArray)) {
282 if (!isset($hierarchicArray[$currentElement['uid'] . '.'])) {
283 $hierarchicArray[$currentElement['uid'] . '.'] = [];
284 }
285 $this->setInPageArray($hierarchicArray[$currentElement['uid'] . '.'], $rootlineArray, $row);
286 } else {
287 $hierarchicArray[$currentElement['uid'] . '_'] = $this->extractLinesFromTSConfig($row);
288 }
289 }
290
291 /**
292 * Extract the lines of TSConfig from a given pages row
293 *
294 * @param array $row The row from the database containing the uid and TSConfig fields
295 * @return array
296 */
297 protected function extractLinesFromTSConfig(array $row)
298 {
299 $out = [];
300 $includeLines = 0;
301 $out['uid'] = $row['uid'];
302 $lines = GeneralUtility::trimExplode("\r\n", $row['TSconfig']);
303 foreach ($lines as $line) {
304 if (strpos($line, '<INCLUDE_TYPOSCRIPT:') !== false) {
305 $includeLines++;
306 }
307 }
308 $out['includeLines'] = $includeLines;
309 $out['writtenLines'] = (count($lines) - $includeLines);
310 return $out;
311 }
312
313 /**
314 * Get the list of pages to show.
315 * This function is called recursively
316 *
317 * @param array $pageArray The Page Array
318 * @param array $lines Lines that have been processed up to this point
319 * @param int $pageDepth The level of the current $pageArray being processed
320 * @return array
321 */
322 protected function getList($pageArray, $lines = [], $pageDepth = 0)
323 {
324 if (!is_array($pageArray)) {
325 return $lines;
326 }
327
328 foreach ($pageArray as $identifier => $_) {
329 if (!MathUtility::canBeInterpretedAsInteger($identifier)) {
330 continue;
331 }
332 $line = [];
333 $line['padding'] = ($pageDepth * 20) + 10;
334 if (isset($pageArray[$identifier . '_'])) {
335 $line['link'] = GeneralUtility::linkThisScript(['id' => $identifier]);
336 $line['icon'] = $this->iconFactory->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $identifier), Icon::SIZE_SMALL)->render();
337 $line['title'] = 'ID: ' . $identifier;
338 $line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pageArray[$identifier], 30);
339 $line['includedFiles'] = ($pageArray[$identifier . '_']['includeLines'] === 0 ? '' : $pageArray[($identifier . '_')]['includeLines']);
340 $line['lines'] = ($pageArray[$identifier . '_']['writtenLines'] === 0 ? '' : $pageArray[$identifier . '_']['writtenLines']);
341 } else {
342 $line['link'] = '';
343 $line['icon'] = $this->iconFactory->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $identifier), Icon::SIZE_SMALL)->render();
344 $line['title'] = '';
345 $line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pageArray[$identifier], 30);
346 $line['includedFiles'] = '';
347 $line['lines'] = '';
348 }
349 $lines[] = $line;
350 $lines = $this->getList($pageArray[$identifier . '.'], $lines, $pageDepth + 1);
351 }
352 return $lines;
353 }
354
355 /**
356 * Returns LanguageService
357 *
358 * @return \TYPO3\CMS\Core\Localization\LanguageService
359 */
360 protected function getLanguageService()
361 {
362 return $GLOBALS['LANG'];
363 }
364
365 /**
366 * Returns the current BE user.
367 *
368 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
369 */
370 protected function getBackendUser()
371 {
372 return $GLOBALS['BE_USER'];
373 }
374
375 /**
376 * returns a new standalone view, shorthand function
377 *
378 * @return StandaloneView
379 */
380 protected function getFluidTemplateObject()
381 {
382 /** @var StandaloneView $view */
383 $view = GeneralUtility::makeInstance(StandaloneView::class);
384 $view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Layouts')]);
385 $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Partials')]);
386 $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates')]);
387
388 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates/PageTsConfig.html'));
389
390 $view->getRequest()->setControllerExtensionName('info');
391 return $view;
392 }
393 }