Total Complexity | 112 |
Total Lines | 1226 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like PageLayoutController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PageLayoutController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
46 | class PageLayoutController |
||
47 | { |
||
48 | /** |
||
49 | * Page Id for which to make the listing |
||
50 | * |
||
51 | * @var int |
||
52 | */ |
||
53 | public $id; |
||
54 | |||
55 | /** |
||
56 | * Pointer - for browsing list of records. |
||
57 | * |
||
58 | * @var int |
||
59 | */ |
||
60 | public $pointer; |
||
61 | |||
62 | /** |
||
63 | * Thumbnails or not |
||
64 | * |
||
65 | * @var string |
||
66 | */ |
||
67 | public $imagemode; |
||
68 | |||
69 | /** |
||
70 | * Search-fields |
||
71 | * |
||
72 | * @var string |
||
73 | */ |
||
74 | public $search_field; |
||
75 | |||
76 | /** |
||
77 | * Search-levels |
||
78 | * |
||
79 | * @var int |
||
80 | */ |
||
81 | public $search_levels; |
||
82 | |||
83 | /** |
||
84 | * Show-limit |
||
85 | * |
||
86 | * @var int |
||
87 | */ |
||
88 | public $showLimit; |
||
89 | |||
90 | /** |
||
91 | * Return URL |
||
92 | * |
||
93 | * @var string |
||
94 | */ |
||
95 | public $returnUrl; |
||
96 | |||
97 | /** |
||
98 | * Clear-cache flag - if set, clears page cache for current id. |
||
99 | * |
||
100 | * @var bool |
||
101 | */ |
||
102 | public $clear_cache; |
||
103 | |||
104 | /** |
||
105 | * PopView id - for opening a window with the page |
||
106 | * |
||
107 | * @var bool |
||
108 | */ |
||
109 | public $popView; |
||
110 | |||
111 | /** |
||
112 | * Page select perms clause |
||
113 | * |
||
114 | * @var string |
||
115 | */ |
||
116 | public $perms_clause; |
||
117 | |||
118 | /** |
||
119 | * Module TSconfig |
||
120 | * |
||
121 | * @var array |
||
122 | */ |
||
123 | public $modTSconfig; |
||
124 | |||
125 | /** |
||
126 | * Module shared TSconfig |
||
127 | * |
||
128 | * @var array |
||
129 | */ |
||
130 | public $modSharedTSconfig; |
||
131 | |||
132 | /** |
||
133 | * Current ids page record |
||
134 | * |
||
135 | * @var array |
||
136 | */ |
||
137 | public $pageinfo; |
||
138 | |||
139 | /** |
||
140 | * "Pseudo" Description -table name |
||
141 | * |
||
142 | * @var string |
||
143 | */ |
||
144 | public $descrTable; |
||
145 | |||
146 | /** |
||
147 | * List of column-integers to edit. Is set from TSconfig, default is "1,0,2,3" |
||
148 | * |
||
149 | * @var string |
||
150 | */ |
||
151 | public $colPosList; |
||
152 | |||
153 | /** |
||
154 | * Flag: If content can be edited or not. |
||
155 | * |
||
156 | * @var bool |
||
157 | */ |
||
158 | public $EDIT_CONTENT; |
||
159 | |||
160 | /** |
||
161 | * Users permissions integer for this page. |
||
162 | * |
||
163 | * @var int |
||
164 | */ |
||
165 | public $CALC_PERMS; |
||
166 | |||
167 | /** |
||
168 | * Currently selected language for editing content elements |
||
169 | * |
||
170 | * @var int |
||
171 | */ |
||
172 | public $current_sys_language; |
||
173 | |||
174 | /** |
||
175 | * Module configuration |
||
176 | * |
||
177 | * @var array |
||
178 | */ |
||
179 | public $MCONF = []; |
||
180 | |||
181 | /** |
||
182 | * Menu configuration |
||
183 | * |
||
184 | * @var array |
||
185 | */ |
||
186 | public $MOD_MENU = []; |
||
187 | |||
188 | /** |
||
189 | * Module settings (session variable) |
||
190 | * |
||
191 | * @var array |
||
192 | */ |
||
193 | public $MOD_SETTINGS = []; |
||
194 | |||
195 | /** |
||
196 | * Module output accumulation |
||
197 | * |
||
198 | * @var string |
||
199 | */ |
||
200 | public $content; |
||
201 | |||
202 | /** |
||
203 | * List of column-integers accessible to the current BE user. |
||
204 | * Is set from TSconfig, default is $colPosList |
||
205 | * |
||
206 | * @var string |
||
207 | */ |
||
208 | public $activeColPosList; |
||
209 | |||
210 | /** |
||
211 | * @var string |
||
212 | */ |
||
213 | protected $editSelect; |
||
214 | |||
215 | /** |
||
216 | * Caches the available languages in a colPos |
||
217 | * |
||
218 | * @var array |
||
219 | */ |
||
220 | protected $languagesInColumnCache = []; |
||
221 | |||
222 | /** |
||
223 | * @var IconFactory |
||
224 | */ |
||
225 | protected $iconFactory; |
||
226 | |||
227 | /** |
||
228 | * The name of the module |
||
229 | * |
||
230 | * @var string |
||
231 | */ |
||
232 | protected $moduleName = 'web_layout'; |
||
233 | |||
234 | /** |
||
235 | * @var ModuleTemplate |
||
236 | */ |
||
237 | protected $moduleTemplate; |
||
238 | |||
239 | /** |
||
240 | * @var ButtonBar |
||
241 | */ |
||
242 | protected $buttonBar; |
||
243 | |||
244 | /** |
||
245 | * @var string |
||
246 | */ |
||
247 | protected $searchContent; |
||
248 | |||
249 | /** |
||
250 | * Initializing the module |
||
251 | */ |
||
252 | public function init() |
||
253 | { |
||
254 | $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class); |
||
255 | $this->iconFactory = $this->moduleTemplate->getIconFactory(); |
||
256 | $this->buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); |
||
257 | $this->getLanguageService()->includeLLFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf'); |
||
258 | // Setting module configuration / page select clause |
||
259 | $this->MCONF['name'] = $this->moduleName; |
||
260 | $this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW); |
||
261 | // Get session data |
||
262 | $sessionData = $this->getBackendUser()->getSessionData(RecordList::class); |
||
263 | $this->search_field = !empty($sessionData['search_field']) ? $sessionData['search_field'] : ''; |
||
264 | // GPvars: |
||
265 | $this->id = (int)GeneralUtility::_GP('id'); |
||
266 | $this->pointer = GeneralUtility::_GP('pointer'); |
||
|
|||
267 | $this->imagemode = GeneralUtility::_GP('imagemode'); |
||
268 | $this->clear_cache = GeneralUtility::_GP('clear_cache'); |
||
269 | $this->popView = GeneralUtility::_GP('popView'); |
||
270 | $this->search_field = GeneralUtility::_GP('search_field'); |
||
271 | $this->search_levels = GeneralUtility::_GP('search_levels'); |
||
272 | $this->showLimit = GeneralUtility::_GP('showLimit'); |
||
273 | $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl')); |
||
274 | $sessionData['search_field'] = $this->search_field; |
||
275 | // Store session data |
||
276 | $this->getBackendUser()->setAndSaveSessionData(RecordList::class, $sessionData); |
||
277 | // Load page info array: |
||
278 | $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause); |
||
279 | // Initialize menu |
||
280 | $this->menuConfig(); |
||
281 | // Setting sys language from session var: |
||
282 | $this->current_sys_language = (int)$this->MOD_SETTINGS['language']; |
||
283 | // CSH / Descriptions: |
||
284 | $this->descrTable = '_MOD_' . $this->moduleName; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Initialize menu array |
||
289 | */ |
||
290 | public function menuConfig() |
||
291 | { |
||
292 | $lang = $this->getLanguageService(); |
||
293 | // MENU-ITEMS: |
||
294 | $this->MOD_MENU = [ |
||
295 | 'tt_content_showHidden' => '', |
||
296 | 'function' => [ |
||
297 | 1 => $lang->getLL('m_function_1'), |
||
298 | 2 => $lang->getLL('m_function_2') |
||
299 | ], |
||
300 | 'language' => [ |
||
301 | 0 => $lang->getLL('m_default') |
||
302 | ] |
||
303 | ]; |
||
304 | // initialize page/be_user TSconfig settings |
||
305 | $this->modSharedTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.SHARED'); |
||
306 | $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->moduleName); |
||
307 | |||
308 | // First, select all localized page records on the current page. Each represents a possibility for a language on the page. Add these to language selector. |
||
309 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language'); |
||
310 | $queryBuilder->getRestrictions()->removeAll(); |
||
311 | if ($this->id) { |
||
312 | $queryBuilder->select('sys_language.uid AS uid', 'sys_language.title AS title') |
||
313 | ->from('sys_language') |
||
314 | ->join( |
||
315 | 'sys_language', |
||
316 | 'pages', |
||
317 | 'pages', |
||
318 | $queryBuilder->expr()->eq( |
||
319 | 'sys_language.uid', |
||
320 | $queryBuilder->quoteIdentifier('pages.' . $GLOBALS['TCA']['pages']['ctrl']['languageField']) |
||
321 | ) |
||
322 | ) |
||
323 | ->where( |
||
324 | $queryBuilder->expr()->eq( |
||
325 | 'pages.deleted', |
||
326 | $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT) |
||
327 | ), |
||
328 | $queryBuilder->expr()->eq( |
||
329 | 'pages.' . $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'], |
||
330 | $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) |
||
331 | ), |
||
332 | $queryBuilder->expr()->orX( |
||
333 | $queryBuilder->expr()->gte( |
||
334 | 'pages.t3ver_state', |
||
335 | $queryBuilder->createNamedParameter( |
||
336 | (string)new VersionState(VersionState::DEFAULT_STATE), |
||
337 | \PDO::PARAM_INT |
||
338 | ) |
||
339 | ), |
||
340 | $queryBuilder->expr()->eq( |
||
341 | 'pages.t3ver_wsid', |
||
342 | $queryBuilder->createNamedParameter($this->getBackendUser()->workspace, \PDO::PARAM_INT) |
||
343 | ) |
||
344 | ) |
||
345 | ) |
||
346 | ->groupBy( |
||
347 | 'pages.' . $GLOBALS['TCA']['pages']['ctrl']['languageField'], |
||
348 | 'sys_language.uid', |
||
349 | 'sys_language.pid', |
||
350 | 'sys_language.tstamp', |
||
351 | 'sys_language.hidden', |
||
352 | 'sys_language.title', |
||
353 | 'sys_language.language_isocode', |
||
354 | 'sys_language.static_lang_isocode', |
||
355 | 'sys_language.flag', |
||
356 | 'sys_language.sorting' |
||
357 | ) |
||
358 | ->orderBy('sys_language.sorting'); |
||
359 | if (!$this->getBackendUser()->isAdmin()) { |
||
360 | $queryBuilder->andWhere( |
||
361 | $queryBuilder->expr()->eq( |
||
362 | 'sys_language.hidden', |
||
363 | $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT) |
||
364 | ) |
||
365 | ); |
||
366 | } |
||
367 | $statement = $queryBuilder->execute(); |
||
368 | } else { |
||
369 | $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(HiddenRestriction::class)); |
||
370 | $statement = $queryBuilder->select('uid', 'title') |
||
371 | ->from('sys_language') |
||
372 | ->orderBy('sorting') |
||
373 | ->execute(); |
||
374 | } |
||
375 | while ($lRow = $statement->fetch()) { |
||
376 | if ($this->getBackendUser()->checkLanguageAccess($lRow['uid'])) { |
||
377 | $this->MOD_MENU['language'][$lRow['uid']] = $lRow['title']; |
||
378 | } |
||
379 | } |
||
380 | // Setting alternative default label: |
||
381 | if (($this->modSharedTSconfig['properties']['defaultLanguageLabel'] || $this->modTSconfig['properties']['defaultLanguageLabel']) && isset($this->MOD_MENU['language'][0])) { |
||
382 | $this->MOD_MENU['language'][0] = $this->modTSconfig['properties']['defaultLanguageLabel'] ? $this->modTSconfig['properties']['defaultLanguageLabel'] : $this->modSharedTSconfig['properties']['defaultLanguageLabel']; |
||
383 | } |
||
384 | // Initialize the avaiable actions |
||
385 | $actions = $this->initActions(); |
||
386 | // Clean up settings |
||
387 | $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->moduleName); |
||
388 | // For all elements to be shown in draft workspaces & to also show hidden elements by default if user hasn't disabled the option |
||
389 | if ($this->getBackendUser()->workspace != 0 || $this->MOD_SETTINGS['tt_content_showHidden'] !== '0') { |
||
390 | $this->MOD_SETTINGS['tt_content_showHidden'] = 1; |
||
391 | } |
||
392 | // Make action menu from available actions |
||
393 | $this->makeActionMenu($actions); |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * Initializes the available actions this module provides |
||
398 | * |
||
399 | * @return array the available actions |
||
400 | */ |
||
401 | protected function initActions() |
||
402 | { |
||
403 | $actions = [ |
||
404 | 1 => $this->getLanguageService()->getLL('m_function_1'), |
||
405 | 2 => $this->getLanguageService()->getLL('m_function_2') |
||
406 | ]; |
||
407 | // Find if there are ANY languages at all (and if not, remove the language option from function menu). |
||
408 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language'); |
||
409 | if ($this->getBackendUser()->isAdmin()) { |
||
410 | $queryBuilder->getRestrictions()->removeAll(); |
||
411 | } |
||
412 | |||
413 | $count = $queryBuilder |
||
414 | ->count('uid') |
||
415 | ->from('sys_language') |
||
416 | ->execute() |
||
417 | ->fetchColumn(0); |
||
418 | |||
419 | if (!$count) { |
||
420 | unset($actions['2']); |
||
421 | } |
||
422 | // page/be_user TSconfig blinding of menu-items |
||
423 | $actions = BackendUtility::unsetMenuItems($this->modTSconfig['properties'], $actions, 'menu.function'); |
||
424 | |||
425 | return $actions; |
||
426 | } |
||
427 | |||
428 | /** |
||
429 | * This creates the dropdown menu with the different actions this module is able to provide. |
||
430 | * For now they are Columns, Quick Edit and Languages. |
||
431 | * |
||
432 | * @param array $actions array with the available actions |
||
433 | */ |
||
434 | protected function makeActionMenu(array $actions) |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Clears page cache for the current id, $this->id |
||
469 | */ |
||
470 | public function clearCache() |
||
471 | { |
||
472 | if ($this->clear_cache && !empty($this->pageinfo)) { |
||
473 | $dataHandler = GeneralUtility::makeInstance(DataHandler::class); |
||
474 | $dataHandler->start([], []); |
||
475 | $dataHandler->clear_cacheCmd($this->id); |
||
476 | } |
||
477 | } |
||
478 | |||
479 | /** |
||
480 | * Generate the flashmessages for current pid |
||
481 | * |
||
482 | * @return string HTML content with flashmessages |
||
483 | */ |
||
484 | protected function getHeaderFlashMessagesForCurrentPid() |
||
485 | { |
||
486 | $content = ''; |
||
487 | $lang = $this->getLanguageService(); |
||
488 | |||
489 | $view = GeneralUtility::makeInstance(StandaloneView::class); |
||
490 | $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html')); |
||
491 | |||
492 | // If page is a folder |
||
493 | if ($this->pageinfo['doktype'] == PageRepository::DOKTYPE_SYSFOLDER) { |
||
494 | $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); |
||
495 | $moduleLoader->load($GLOBALS['TBE_MODULES']); |
||
496 | $modules = $moduleLoader->modules; |
||
497 | if (is_array($modules['web']['sub']['list'])) { |
||
498 | $title = $lang->getLL('goToListModule'); |
||
499 | $message = '<p>' . $lang->getLL('goToListModuleMessage') . '</p>'; |
||
500 | $message .= '<a class="btn btn-info" href="javascript:top.goToModule(\'web_list\',1);">' . $lang->getLL('goToListModule') . '</a>'; |
||
501 | $view->assignMultiple([ |
||
502 | 'title' => $title, |
||
503 | 'message' => $message, |
||
504 | 'state' => InfoboxViewHelper::STATE_INFO |
||
505 | ]); |
||
506 | $content .= $view->render(); |
||
507 | } |
||
508 | } elseif ($this->pageinfo['doktype'] === PageRepository::DOKTYPE_SHORTCUT) { |
||
509 | $shortcutMode = (int)$this->pageinfo['shortcut_mode']; |
||
510 | $pageRepository = GeneralUtility::makeInstance(PageRepository::class); |
||
511 | $targetPage = []; |
||
512 | |||
513 | if ($this->pageinfo['shortcut'] || $shortcutMode) { |
||
514 | switch ($shortcutMode) { |
||
515 | case PageRepository::SHORTCUT_MODE_NONE: |
||
516 | $targetPage = $pageRepository->getPage($this->pageinfo['shortcut']); |
||
517 | break; |
||
518 | case PageRepository::SHORTCUT_MODE_FIRST_SUBPAGE: |
||
519 | $targetPage = reset($pageRepository->getMenu($this->pageinfo['shortcut'] ?: $this->pageinfo['uid'])); |
||
520 | break; |
||
521 | case PageRepository::SHORTCUT_MODE_PARENT_PAGE: |
||
522 | $targetPage = $pageRepository->getPage($this->pageinfo['pid']); |
||
523 | break; |
||
524 | } |
||
525 | |||
526 | $message = ''; |
||
527 | if ($shortcutMode === PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) { |
||
528 | $message .= sprintf($lang->getLL('pageIsRandomInternalLinkMessage')); |
||
529 | } else { |
||
530 | $linkToPid = $this->local_linkThisScript(['id' => $targetPage['uid']]); |
||
531 | $path = BackendUtility::getRecordPath($targetPage['uid'], $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW), 1000); |
||
532 | $linkedPath = '<a href="' . htmlspecialchars($linkToPid) . '">' . htmlspecialchars($path) . '</a>'; |
||
533 | $message .= sprintf($lang->getLL('pageIsInternalLinkMessage'), $linkedPath); |
||
534 | } |
||
535 | |||
536 | $message .= ' (' . htmlspecialchars($lang->sL(BackendUtility::getLabelFromItemlist('pages', 'shortcut_mode', $shortcutMode))) . ')'; |
||
537 | |||
538 | $view->assignMultiple([ |
||
539 | 'title' => $this->pageinfo['title'], |
||
540 | 'message' => $message, |
||
541 | 'state' => InfoboxViewHelper::STATE_INFO |
||
542 | ]); |
||
543 | $content .= $view->render(); |
||
544 | } else { |
||
545 | if (empty($targetPage) && $shortcutMode !== PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) { |
||
546 | $view->assignMultiple([ |
||
547 | 'title' => $this->pageinfo['title'], |
||
548 | 'message' => $lang->getLL('pageIsMisconfiguredInternalLinkMessage'), |
||
549 | 'state' => InfoboxViewHelper::STATE_ERROR |
||
550 | ]); |
||
551 | $content .= $view->render(); |
||
552 | } |
||
553 | } |
||
554 | } elseif ($this->pageinfo['doktype'] === PageRepository::DOKTYPE_LINK) { |
||
555 | if (empty($this->pageinfo['url'])) { |
||
556 | $view->assignMultiple([ |
||
557 | 'title' => $this->pageinfo['title'], |
||
558 | 'message' => $lang->getLL('pageIsMisconfiguredExternalLinkMessage'), |
||
559 | 'state' => InfoboxViewHelper::STATE_ERROR |
||
560 | ]); |
||
561 | $content .= $view->render(); |
||
562 | } else { |
||
563 | $externalUrl = htmlspecialchars(GeneralUtility::makeInstance(PageRepository::class)->getExtURL($this->pageinfo)); |
||
564 | if ($externalUrl !== false) { |
||
565 | $externalUrlHtml = '<a href="' . $externalUrl . '" target="_blank" rel="noopener">' . $externalUrl . '</a>'; |
||
566 | $view->assignMultiple([ |
||
567 | 'title' => $this->pageinfo['title'], |
||
568 | 'message' => sprintf($lang->getLL('pageIsExternalLinkMessage'), $externalUrlHtml), |
||
569 | 'state' => InfoboxViewHelper::STATE_INFO |
||
570 | ]); |
||
571 | $content .= $view->render(); |
||
572 | } |
||
573 | } |
||
574 | } |
||
575 | // If content from different pid is displayed |
||
576 | if ($this->pageinfo['content_from_pid']) { |
||
577 | $contentPage = BackendUtility::getRecord('pages', (int)$this->pageinfo['content_from_pid']); |
||
578 | $linkToPid = $this->local_linkThisScript(['id' => $this->pageinfo['content_from_pid']]); |
||
579 | $title = BackendUtility::getRecordTitle('pages', $contentPage); |
||
580 | $link = '<a href="' . htmlspecialchars($linkToPid) . '">' . htmlspecialchars($title) . ' (PID ' . (int)$this->pageinfo['content_from_pid'] . ')</a>'; |
||
581 | $message = sprintf($lang->getLL('content_from_pid_title'), $link); |
||
582 | $view->assignMultiple([ |
||
583 | 'title' => $title, |
||
584 | 'message' => $message, |
||
585 | 'state' => InfoboxViewHelper::STATE_INFO |
||
586 | ]); |
||
587 | $content .= $view->render(); |
||
588 | } else { |
||
589 | $links = $this->getPageLinksWhereContentIsAlsoShownOn($this->pageinfo['uid']); |
||
590 | if (!empty($links)) { |
||
591 | $message = sprintf($lang->getLL('content_on_pid_title'), $links); |
||
592 | $view->assignMultiple([ |
||
593 | 'title' => '', |
||
594 | 'message' => $message, |
||
595 | 'state' => InfoboxViewHelper::STATE_INFO |
||
596 | ]); |
||
597 | $content .= $view->render(); |
||
598 | } |
||
599 | } |
||
600 | return $content; |
||
601 | } |
||
602 | |||
603 | /** |
||
604 | * Get all pages with links where the content of a page $pageId is also shown on |
||
605 | * |
||
606 | * @param int $pageId |
||
607 | * @return string |
||
608 | */ |
||
609 | protected function getPageLinksWhereContentIsAlsoShownOn($pageId) |
||
610 | { |
||
611 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); |
||
612 | $queryBuilder->getRestrictions()->removeAll(); |
||
613 | $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class)); |
||
614 | $queryBuilder |
||
615 | ->select('*') |
||
616 | ->from('pages') |
||
617 | ->where($queryBuilder->expr()->eq('content_from_pid', $queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT))); |
||
618 | |||
619 | $links = []; |
||
620 | $rows = $queryBuilder->execute()->fetchAll(); |
||
621 | if (!empty($rows)) { |
||
622 | foreach ($rows as $row) { |
||
623 | $linkToPid = $this->local_linkThisScript(['id' => $row['uid']]); |
||
624 | $title = BackendUtility::getRecordTitle('pages', $row); |
||
625 | $link = '<a href="' . htmlspecialchars($linkToPid) . '">' . htmlspecialchars($title) . ' (PID ' . (int)$row['uid'] . ')</a>'; |
||
626 | $links[] = $link; |
||
627 | } |
||
628 | } |
||
629 | return implode(', ', $links); |
||
630 | } |
||
631 | |||
632 | /** |
||
633 | * @return string $title |
||
634 | */ |
||
635 | protected function getLocalizedPageTitle() |
||
636 | { |
||
637 | if ($this->current_sys_language > 0) { |
||
638 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) |
||
639 | ->getQueryBuilderForTable('pages'); |
||
640 | $queryBuilder->getRestrictions() |
||
641 | ->removeAll() |
||
642 | ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) |
||
643 | ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class)); |
||
644 | $localizedPage = $queryBuilder |
||
645 | ->select('*') |
||
646 | ->from('pages') |
||
647 | ->where( |
||
648 | $queryBuilder->expr()->eq( |
||
649 | $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'], |
||
650 | $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) |
||
651 | ), |
||
652 | $queryBuilder->expr()->eq( |
||
653 | $GLOBALS['TCA']['pages']['ctrl']['languageField'], |
||
654 | $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT) |
||
655 | ) |
||
656 | ) |
||
657 | ->setMaxResults(1) |
||
658 | ->execute() |
||
659 | ->fetch(); |
||
660 | BackendUtility::workspaceOL('pages', $localizedPage); |
||
661 | return $localizedPage['title']; |
||
662 | } |
||
663 | return $this->pageinfo['title']; |
||
664 | } |
||
665 | |||
666 | /** |
||
667 | * Injects the request object for the current request or subrequest |
||
668 | * As this controller goes only through the main() method, it is rather simple for now |
||
669 | * |
||
670 | * @param ServerRequestInterface $request the current request |
||
671 | * @param ResponseInterface $response |
||
672 | * @return ResponseInterface the response with the content |
||
673 | */ |
||
674 | public function mainAction(ServerRequestInterface $request, ResponseInterface $response) |
||
675 | { |
||
676 | $GLOBALS['SOBE'] = $this; |
||
677 | $this->init(); |
||
678 | $this->clearCache(); |
||
679 | $this->main(); |
||
680 | $response->getBody()->write($this->moduleTemplate->renderContent()); |
||
681 | return $response; |
||
682 | } |
||
683 | |||
684 | /** |
||
685 | * Main function. |
||
686 | * Creates some general objects and calls other functions for the main rendering of module content. |
||
687 | */ |
||
688 | public function main() |
||
689 | { |
||
690 | $lang = $this->getLanguageService(); |
||
691 | // Access check... |
||
692 | // The page will show only if there is a valid page and if this page may be viewed by the user |
||
693 | $access = is_array($this->pageinfo); |
||
694 | // Content |
||
695 | $content = ''; |
||
696 | if ($this->id && $access) { |
||
697 | // Initialize permission settings: |
||
698 | $this->CALC_PERMS = $this->getBackendUser()->calcPerms($this->pageinfo); |
||
699 | $this->EDIT_CONTENT = $this->contentIsNotLockedForEditors(); |
||
700 | |||
701 | $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo); |
||
702 | |||
703 | // override the default jumpToUrl |
||
704 | $this->moduleTemplate->addJavaScriptCode('jumpToUrl', ' |
||
705 | function jumpToUrl(URL,formEl) { |
||
706 | if (document.editform && TBE_EDITOR.isFormChanged) { // Check if the function exists... (works in all browsers?) |
||
707 | if (!TBE_EDITOR.isFormChanged()) { |
||
708 | window.location.href = URL; |
||
709 | } else if (formEl) { |
||
710 | if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1; |
||
711 | } |
||
712 | } else { |
||
713 | window.location.href = URL; |
||
714 | } |
||
715 | } |
||
716 | '); |
||
717 | |||
718 | /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ |
||
719 | $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); |
||
720 | |||
721 | $this->moduleTemplate->addJavaScriptCode('mainJsFunctions', ' |
||
722 | if (top.fsMod) { |
||
723 | top.fsMod.recentIds["web"] = ' . (int)$this->id . '; |
||
724 | top.fsMod.navFrameHighlightedID["web"] = "pages' . (int)$this->id . '_"+top.fsMod.currentBank; ' . (int)$this->id . '; |
||
725 | } |
||
726 | ' . ($this->popView ? BackendUtility::viewOnClick($this->id, '', BackendUtility::BEgetRootLine($this->id)) : '') . ' |
||
727 | function deleteRecord(table,id,url) { // |
||
728 | window.location.href = ' . GeneralUtility::quoteJSvalue((string)$uriBuilder->buildUriFromRoute('tce_db') . '&cmd[') |
||
729 | . ' + table + "][" + id + "][delete]=1&redirect=" + encodeURIComponent(url); |
||
730 | return false; |
||
731 | } |
||
732 | '); |
||
733 | |||
734 | // Find backend layout / columns |
||
735 | $backendLayout = GeneralUtility::callUserFunction(BackendLayoutView::class . '->getSelectedBackendLayout', $this->id, $this); |
||
736 | if (!empty($backendLayout['__colPosList'])) { |
||
737 | $this->colPosList = implode(',', $backendLayout['__colPosList']); |
||
738 | } |
||
739 | // Removing duplicates, if any |
||
740 | $this->colPosList = array_unique(GeneralUtility::intExplode(',', $this->colPosList)); |
||
741 | // Accessible columns |
||
742 | if (isset($this->modSharedTSconfig['properties']['colPos_list']) && trim($this->modSharedTSconfig['properties']['colPos_list']) !== '') { |
||
743 | $this->activeColPosList = array_unique(GeneralUtility::intExplode(',', trim($this->modSharedTSconfig['properties']['colPos_list']))); |
||
744 | // Match with the list which is present in the colPosList for the current page |
||
745 | if (!empty($this->colPosList) && !empty($this->activeColPosList)) { |
||
746 | $this->activeColPosList = array_unique(array_intersect( |
||
747 | $this->activeColPosList, |
||
748 | $this->colPosList |
||
749 | )); |
||
750 | } |
||
751 | } else { |
||
752 | $this->activeColPosList = $this->colPosList; |
||
753 | } |
||
754 | $this->activeColPosList = implode(',', $this->activeColPosList); |
||
755 | $this->colPosList = implode(',', $this->colPosList); |
||
756 | |||
757 | $content .= $this->getHeaderFlashMessagesForCurrentPid(); |
||
758 | |||
759 | // Render the primary module content: |
||
760 | if ($this->MOD_SETTINGS['function'] == 1 || $this->MOD_SETTINGS['function'] == 2) { |
||
761 | $content .= '<form action="' . htmlspecialchars((string)$uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->id, 'imagemode' => $this->imagemode])) . '" id="PageLayoutController" method="post">'; |
||
762 | // Page title |
||
763 | $content .= '<h1 class="t3js-title-inlineedit">' . htmlspecialchars($this->getLocalizedPageTitle()) . '</h1>'; |
||
764 | // All other listings |
||
765 | $content .= $this->renderContent(); |
||
766 | } |
||
767 | $content .= '</form>'; |
||
768 | $content .= $this->searchContent; |
||
769 | // Setting up the buttons for the docheader |
||
770 | $this->makeButtons(); |
||
771 | // @internal: This is an internal hook for compatibility7 only, this hook will be removed without further notice |
||
772 | if ($this->MOD_SETTINGS['function'] != 1 && $this->MOD_SETTINGS['function'] != 2) { |
||
773 | foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class]['renderActionHook'] ?? [] as $hook) { |
||
774 | $params = [ |
||
775 | 'deleteButton' => $this->deleteButton, |
||
776 | '' |
||
777 | ]; |
||
778 | $content .= GeneralUtility::callUserFunction($hook, $params, $this); |
||
779 | } |
||
780 | } |
||
781 | // Create LanguageMenu |
||
782 | $this->makeLanguageMenu(); |
||
783 | } else { |
||
784 | $this->moduleTemplate->addJavaScriptCode( |
||
785 | 'mainJsFunctions', |
||
786 | 'if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';' |
||
787 | ); |
||
788 | $content .= '<h1>' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '</h1>'; |
||
789 | $view = GeneralUtility::makeInstance(StandaloneView::class); |
||
790 | $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html')); |
||
791 | $view->assignMultiple([ |
||
792 | 'title' => $lang->getLL('clickAPage_header'), |
||
793 | 'message' => $lang->getLL('clickAPage_content'), |
||
794 | 'state' => InfoboxViewHelper::STATE_INFO |
||
795 | ]); |
||
796 | $content .= $view->render(); |
||
797 | } |
||
798 | // Set content |
||
799 | $this->moduleTemplate->setContent($content); |
||
800 | } |
||
801 | |||
802 | /** |
||
803 | * Rendering content |
||
804 | * |
||
805 | * @return string |
||
806 | */ |
||
807 | public function renderContent() |
||
808 | { |
||
809 | /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ |
||
810 | $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); |
||
811 | |||
812 | $this->moduleTemplate->getPageRenderer()->loadJquery(); |
||
813 | $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu'); |
||
814 | /** @var $dbList \TYPO3\CMS\Backend\View\PageLayoutView */ |
||
815 | $dbList = GeneralUtility::makeInstance(PageLayoutView::class); |
||
816 | $dbList->thumbs = $this->imagemode; |
||
817 | $dbList->no_noWrap = 1; |
||
818 | $dbList->descrTable = $this->descrTable; |
||
819 | $this->pointer = MathUtility::forceIntegerInRange($this->pointer, 0, 100000); |
||
820 | $dbList->script = (string)$uriBuilder->buildUriFromRoute($this->moduleName); |
||
821 | $dbList->showIcon = 0; |
||
822 | $dbList->setLMargin = 0; |
||
823 | $dbList->doEdit = $this->EDIT_CONTENT; |
||
824 | $dbList->ext_CALC_PERMS = $this->CALC_PERMS; |
||
825 | $dbList->agePrefixes = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears'); |
||
826 | $dbList->id = $this->id; |
||
827 | $dbList->nextThree = MathUtility::forceIntegerInRange($this->modTSconfig['properties']['editFieldsAtATime'], 0, 10); |
||
828 | $dbList->option_newWizard = empty($this->modTSconfig['properties']['disableNewContentElementWizard']); |
||
829 | $dbList->defLangBinding = !empty($this->modTSconfig['properties']['defLangBinding']); |
||
830 | if (!$dbList->nextThree) { |
||
831 | $dbList->nextThree = 1; |
||
832 | } |
||
833 | // Create menu for selecting a table to jump to (this is, if more than just pages/tt_content elements are found on the page!) |
||
834 | // also fills $dbList->activeTables |
||
835 | $dbList->getTableMenu($this->id); |
||
836 | // Initialize other variables: |
||
837 | $tableOutput = []; |
||
838 | $tableJSOutput = []; |
||
839 | $CMcounter = 0; |
||
840 | // Traverse the list of table names which has records on this page (that array is populated |
||
841 | // by the $dblist object during the function getTableMenu()): |
||
842 | foreach ($dbList->activeTables as $table => $value) { |
||
843 | $h_func = ''; |
||
844 | $h_func_b = ''; |
||
845 | if (!isset($dbList->externalTables[$table])) { |
||
846 | // Toggle hidden ContentElements |
||
847 | $numberOfHiddenElements = $this->getNumberOfHiddenElements(); |
||
848 | if ($numberOfHiddenElements > 0) { |
||
849 | $h_func_b = ' |
||
850 | <div class="checkbox"> |
||
851 | <label for="checkTt_content_showHidden"> |
||
852 | <input type="checkbox" id="checkTt_content_showHidden" class="checkbox" name="SET[tt_content_showHidden]" value="1" ' . ($this->MOD_SETTINGS['tt_content_showHidden'] ? 'checked="checked"' : '') . ' /> |
||
853 | ' . htmlspecialchars($this->getLanguageService()->getLL('hiddenCE')) . ' (<span class="t3js-hidden-counter">' . $numberOfHiddenElements . '</span>) |
||
854 | </label> |
||
855 | </div>'; |
||
856 | } |
||
857 | |||
858 | // Boolean: Display up/down arrows and edit icons for tt_content records |
||
859 | $dbList->tt_contentConfig['showCommands'] = 1; |
||
860 | // Boolean: Display info-marks or not |
||
861 | $dbList->tt_contentConfig['showInfo'] = 1; |
||
862 | // Setting up the tt_content columns to show: |
||
863 | if (is_array($GLOBALS['TCA']['tt_content']['columns']['colPos']['config']['items'])) { |
||
864 | $colList = []; |
||
865 | $tcaItems = GeneralUtility::callUserFunction(BackendLayoutView::class . '->getColPosListItemsParsed', $this->id, $this); |
||
866 | foreach ($tcaItems as $temp) { |
||
867 | $colList[] = $temp[1]; |
||
868 | } |
||
869 | } else { |
||
870 | // ... should be impossible that colPos has no array. But this is the fallback should it make any sense: |
||
871 | $colList = ['1', '0', '2', '3']; |
||
872 | } |
||
873 | if ($this->colPosList !== '') { |
||
874 | $colList = array_intersect(GeneralUtility::intExplode(',', $this->colPosList), $colList); |
||
875 | } |
||
876 | // The order of the rows: Default is left(1), Normal(0), right(2), margin(3) |
||
877 | $dbList->tt_contentConfig['cols'] = implode(',', $colList); |
||
878 | $dbList->tt_contentConfig['activeCols'] = $this->activeColPosList; |
||
879 | $dbList->tt_contentConfig['showHidden'] = $this->MOD_SETTINGS['tt_content_showHidden']; |
||
880 | $dbList->tt_contentConfig['sys_language_uid'] = (int)$this->current_sys_language; |
||
881 | // If the function menu is set to "Language": |
||
882 | if ($this->MOD_SETTINGS['function'] == 2) { |
||
883 | $dbList->tt_contentConfig['languageMode'] = 1; |
||
884 | $dbList->tt_contentConfig['languageCols'] = $this->MOD_MENU['language']; |
||
885 | $dbList->tt_contentConfig['languageColsPointer'] = $this->current_sys_language; |
||
886 | } |
||
887 | } else { |
||
888 | if (isset($this->MOD_SETTINGS) && isset($this->MOD_MENU)) { |
||
889 | $h_func = BackendUtility::getFuncMenu($this->id, 'SET[' . $table . ']', $this->MOD_SETTINGS[$table], $this->MOD_MENU[$table], '', ''); |
||
890 | } |
||
891 | } |
||
892 | // Start the dblist object: |
||
893 | $dbList->itemsLimitSingleTable = 1000; |
||
894 | $dbList->start($this->id, $table, $this->pointer, $this->search_field, $this->search_levels, $this->showLimit); |
||
895 | $dbList->counter = $CMcounter; |
||
896 | $dbList->ext_function = $this->MOD_SETTINGS['function']; |
||
897 | // Generate the list of elements here: |
||
898 | $dbList->generateList(); |
||
899 | // Adding the list content to the tableOutput variable: |
||
900 | $tableOutput[$table] = $h_func . $dbList->HTMLcode . $h_func_b; |
||
901 | // ... and any accumulated JavaScript goes the same way! |
||
902 | $tableJSOutput[$table] = $dbList->JScode; |
||
903 | // Increase global counter: |
||
904 | $CMcounter += $dbList->counter; |
||
905 | // Reset variables after operation: |
||
906 | $dbList->HTMLcode = ''; |
||
907 | $dbList->JScode = ''; |
||
908 | } |
||
909 | // END: traverse tables |
||
910 | // For Context Sensitive Menus: |
||
911 | // Init the content |
||
912 | $content = ''; |
||
913 | // Additional header content |
||
914 | foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawHeaderHook'] ?? [] as $hook) { |
||
915 | $params = []; |
||
916 | $content .= GeneralUtility::callUserFunction($hook, $params, $this); |
||
917 | } |
||
918 | // Add the content for each table we have rendered (traversing $tableOutput variable) |
||
919 | foreach ($tableOutput as $table => $output) { |
||
920 | $content .= $output; |
||
921 | } |
||
922 | // Making search form: |
||
923 | if (!$this->modTSconfig['properties']['disableSearchBox'] && ($dbList->counter > 0 || $this->currentPageHasSubPages())) { |
||
924 | $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ToggleSearchToolbox'); |
||
925 | $toggleSearchFormButton = $this->buttonBar->makeLinkButton() |
||
926 | ->setClasses('t3js-toggle-search-toolbox') |
||
927 | ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.title.searchIcon')) |
||
928 | ->setIcon($this->iconFactory->getIcon('actions-search', Icon::SIZE_SMALL)) |
||
929 | ->setHref('#'); |
||
930 | $this->buttonBar->addButton($toggleSearchFormButton, ButtonBar::BUTTON_POSITION_LEFT, 4); |
||
931 | $this->searchContent = $dbList->getSearchBox(); |
||
932 | } |
||
933 | // Additional footer content |
||
934 | foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawFooterHook'] ?? [] as $hook) { |
||
935 | $params = []; |
||
936 | $content .= GeneralUtility::callUserFunction($hook, $params, $this); |
||
937 | } |
||
938 | return $content; |
||
939 | } |
||
940 | |||
941 | /** |
||
942 | * @return ModuleTemplate |
||
943 | */ |
||
944 | public function getModuleTemplate() |
||
945 | { |
||
946 | return $this->moduleTemplate; |
||
947 | } |
||
948 | |||
949 | /*************************** |
||
950 | * |
||
951 | * Sub-content functions, rendering specific parts of the module content. |
||
952 | * |
||
953 | ***************************/ |
||
954 | /** |
||
955 | * This creates the buttons for the modules |
||
956 | */ |
||
957 | protected function makeButtons() |
||
958 | { |
||
959 | if ($this->MOD_SETTINGS['function'] == 1 || $this->MOD_SETTINGS['function'] == 2) { |
||
960 | // Add CSH (Context Sensitive Help) icon to tool bar |
||
961 | $contextSensitiveHelpButton = $this->buttonBar->makeHelpButton() |
||
962 | ->setModuleName($this->descrTable) |
||
963 | ->setFieldName('columns_' . $this->MOD_SETTINGS['function']); |
||
964 | $this->buttonBar->addButton($contextSensitiveHelpButton); |
||
965 | } |
||
966 | $lang = $this->getLanguageService(); |
||
967 | // View page |
||
968 | if (!VersionState::cast($this->pageinfo['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) { |
||
969 | $viewButton = $this->buttonBar->makeLinkButton() |
||
970 | ->setOnClick(BackendUtility::viewOnClick($this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid']))) |
||
971 | ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.showPage')) |
||
972 | ->setIcon($this->iconFactory->getIcon('actions-view-page', Icon::SIZE_SMALL)) |
||
973 | ->setHref('#'); |
||
974 | |||
975 | $this->buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 3); |
||
976 | } |
||
977 | // Shortcut |
||
978 | $shortcutButton = $this->buttonBar->makeShortcutButton() |
||
979 | ->setModuleName($this->moduleName) |
||
980 | ->setGetVariables([ |
||
981 | 'id', |
||
982 | 'route', |
||
983 | 'edit_record', |
||
984 | 'pointer', |
||
985 | 'new_unique_uid', |
||
986 | 'search_field', |
||
987 | 'search_levels', |
||
988 | 'showLimit' |
||
989 | ]) |
||
990 | ->setSetVariables(array_keys($this->MOD_MENU)); |
||
991 | $this->buttonBar->addButton($shortcutButton); |
||
992 | |||
993 | /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ |
||
994 | $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); |
||
995 | // Cache |
||
996 | if (empty($this->modTSconfig['properties']['disableAdvanced'])) { |
||
997 | $clearCacheButton = $this->buttonBar->makeLinkButton() |
||
998 | ->setHref((string)$uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->pageinfo['uid'], 'clear_cache' => '1'])) |
||
999 | ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.clear_cache')) |
||
1000 | ->setIcon($this->iconFactory->getIcon('actions-system-cache-clear', Icon::SIZE_SMALL)); |
||
1001 | $this->buttonBar->addButton($clearCacheButton, ButtonBar::BUTTON_POSITION_RIGHT, 1); |
||
1002 | } |
||
1003 | if (empty($this->modTSconfig['properties']['disableIconToolbar'])) { |
||
1004 | // Edit page properties and page language overlay icons |
||
1005 | if ($this->pageIsNotLockedForEditors() && $this->getBackendUser()->checkLanguageAccess(0)) { |
||
1006 | // Edit localized pages only when one specific language is selected |
||
1007 | if ($this->MOD_SETTINGS['function'] == 1 && $this->current_sys_language > 0) { |
||
1008 | $localizationParentField = $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']; |
||
1009 | $languageField = $GLOBALS['TCA']['pages']['ctrl']['languageField']; |
||
1010 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) |
||
1011 | ->getQueryBuilderForTable('pages'); |
||
1012 | $queryBuilder->getRestrictions() |
||
1013 | ->removeAll() |
||
1014 | ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) |
||
1015 | ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class)); |
||
1016 | $overlayRecord = $queryBuilder |
||
1017 | ->select('uid') |
||
1018 | ->from('pages') |
||
1019 | ->where( |
||
1020 | $queryBuilder->expr()->eq( |
||
1021 | $localizationParentField, |
||
1022 | $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) |
||
1023 | ), |
||
1024 | $queryBuilder->expr()->eq( |
||
1025 | $languageField, |
||
1026 | $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT) |
||
1027 | ) |
||
1028 | ) |
||
1029 | ->setMaxResults(1) |
||
1030 | ->execute() |
||
1031 | ->fetch(); |
||
1032 | // Edit button |
||
1033 | $urlParameters = [ |
||
1034 | 'edit' => [ |
||
1035 | 'pages' => [ |
||
1036 | $overlayRecord['uid'] => 'edit' |
||
1037 | ] |
||
1038 | ], |
||
1039 | 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') |
||
1040 | ]; |
||
1041 | |||
1042 | $url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters); |
||
1043 | $editLanguageButton = $this->buttonBar->makeLinkButton() |
||
1044 | ->setHref($url) |
||
1045 | ->setTitle($lang->getLL('editPageLanguageOverlayProperties')) |
||
1046 | ->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', Icon::SIZE_SMALL)); |
||
1047 | $this->buttonBar->addButton($editLanguageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); |
||
1048 | } |
||
1049 | $urlParameters = [ |
||
1050 | 'edit' => [ |
||
1051 | 'pages' => [ |
||
1052 | $this->id => 'edit' |
||
1053 | ] |
||
1054 | ], |
||
1055 | 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') |
||
1056 | ]; |
||
1057 | $url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters); |
||
1058 | $editPageButton = $this->buttonBar->makeLinkButton() |
||
1059 | ->setHref($url) |
||
1060 | ->setTitle($lang->getLL('editPageProperties')) |
||
1061 | ->setIcon($this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)); |
||
1062 | $this->buttonBar->addButton($editPageButton, ButtonBar::BUTTON_POSITION_LEFT, 3); |
||
1063 | } |
||
1064 | } |
||
1065 | } |
||
1066 | |||
1067 | /******************************* |
||
1068 | * |
||
1069 | * Other functions |
||
1070 | * |
||
1071 | ******************************/ |
||
1072 | /** |
||
1073 | * Returns the number of hidden elements (including those hidden by start/end times) |
||
1074 | * on the current page (for the current sys_language) |
||
1075 | * |
||
1076 | * @return int |
||
1077 | */ |
||
1078 | public function getNumberOfHiddenElements() |
||
1079 | { |
||
1080 | /** @var QueryBuilder $queryBuilder */ |
||
1081 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); |
||
1082 | $queryBuilder->getRestrictions() |
||
1083 | ->removeAll() |
||
1084 | ->add(GeneralUtility::makeInstance(DeletedRestriction::class)) |
||
1085 | ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class)); |
||
1086 | |||
1087 | $queryBuilder |
||
1088 | ->count('uid') |
||
1089 | ->from('tt_content') |
||
1090 | ->where( |
||
1091 | $queryBuilder->expr()->eq( |
||
1092 | 'pid', |
||
1093 | $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) |
||
1094 | ), |
||
1095 | $queryBuilder->expr()->eq( |
||
1096 | 'sys_language_uid', |
||
1097 | $queryBuilder->createNamedParameter($this->current_sys_language, \PDO::PARAM_INT) |
||
1098 | ) |
||
1099 | ); |
||
1100 | |||
1101 | if (!empty($GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'])) { |
||
1102 | $andWhere[] = $queryBuilder->expr()->neq( |
||
1103 | 'hidden', |
||
1104 | $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT) |
||
1105 | ); |
||
1106 | } |
||
1107 | |||
1108 | if (!empty($GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['starttime'])) { |
||
1109 | $andWhere[] = $queryBuilder->expr()->andX( |
||
1110 | $queryBuilder->expr()->neq( |
||
1111 | 'starttime', |
||
1112 | $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT) |
||
1113 | ), |
||
1114 | $queryBuilder->expr()->gt( |
||
1115 | 'starttime', |
||
1116 | $queryBuilder->createNamedParameter($GLOBALS['SIM_ACCESS_TIME'], \PDO::PARAM_INT) |
||
1117 | ) |
||
1118 | ); |
||
1119 | } |
||
1120 | |||
1121 | if (!empty($GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['endtime'])) { |
||
1122 | $andWhere[] = $queryBuilder->expr()->andX( |
||
1123 | $queryBuilder->expr()->neq( |
||
1124 | 'endtime', |
||
1125 | $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT) |
||
1126 | ), |
||
1127 | $queryBuilder->expr()->lte( |
||
1128 | 'endtime', |
||
1129 | $queryBuilder->createNamedParameter($GLOBALS['SIM_ACCESS_TIME'], \PDO::PARAM_INT) |
||
1130 | ) |
||
1131 | ); |
||
1132 | } |
||
1133 | |||
1134 | if (!empty($andWhere)) { |
||
1135 | $queryBuilder->andWhere( |
||
1136 | $queryBuilder->expr()->orX(...$andWhere) |
||
1137 | ); |
||
1138 | } |
||
1139 | |||
1140 | $count = $queryBuilder |
||
1141 | ->execute() |
||
1142 | ->fetchColumn(0); |
||
1143 | |||
1144 | return (int)$count; |
||
1145 | } |
||
1146 | |||
1147 | /** |
||
1148 | * Returns URL to the current script. |
||
1149 | * In particular the "popView" and "new_unique_uid" Get vars are unset. |
||
1150 | * |
||
1151 | * @param array $params Parameters array, merged with global GET vars. |
||
1152 | * @return string URL |
||
1153 | */ |
||
1154 | public function local_linkThisScript($params) |
||
1155 | { |
||
1156 | $params['popView'] = ''; |
||
1157 | $params['new_unique_uid'] = ''; |
||
1158 | return GeneralUtility::linkThisScript($params); |
||
1159 | } |
||
1160 | |||
1161 | /** |
||
1162 | * Check if page can be edited by current user |
||
1163 | * |
||
1164 | * @return bool |
||
1165 | */ |
||
1166 | public function pageIsNotLockedForEditors() |
||
1167 | { |
||
1168 | return $this->getBackendUser()->isAdmin() || ($this->CALC_PERMS & Permission::PAGE_EDIT) === Permission::PAGE_EDIT && !$this->pageinfo['editlock']; |
||
1169 | } |
||
1170 | |||
1171 | /** |
||
1172 | * Check if content can be edited by current user |
||
1173 | * |
||
1174 | * @return bool |
||
1175 | */ |
||
1176 | public function contentIsNotLockedForEditors() |
||
1177 | { |
||
1178 | return $this->getBackendUser()->isAdmin() || ($this->CALC_PERMS & Permission::CONTENT_EDIT) === Permission::CONTENT_EDIT && !$this->pageinfo['editlock']; |
||
1179 | } |
||
1180 | |||
1181 | /** |
||
1182 | * Returns LanguageService |
||
1183 | * |
||
1184 | * @return \TYPO3\CMS\Core\Localization\LanguageService |
||
1185 | */ |
||
1186 | protected function getLanguageService() |
||
1187 | { |
||
1188 | return $GLOBALS['LANG']; |
||
1189 | } |
||
1190 | |||
1191 | /** |
||
1192 | * Returns the current BE user. |
||
1193 | * |
||
1194 | * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication |
||
1195 | */ |
||
1196 | protected function getBackendUser() |
||
1197 | { |
||
1198 | return $GLOBALS['BE_USER']; |
||
1199 | } |
||
1200 | |||
1201 | /** |
||
1202 | * Returns current PageRenderer |
||
1203 | * |
||
1204 | * @return PageRenderer |
||
1205 | */ |
||
1206 | protected function getPageRenderer() |
||
1207 | { |
||
1208 | return GeneralUtility::makeInstance(PageRenderer::class); |
||
1209 | } |
||
1210 | |||
1211 | /** |
||
1212 | * Make the LanguageMenu |
||
1213 | */ |
||
1214 | protected function makeLanguageMenu() |
||
1233 | } |
||
1234 | } |
||
1235 | |||
1236 | /** |
||
1237 | * Checks whether the current page has sub pages |
||
1238 | * |
||
1239 | * @return bool |
||
1240 | */ |
||
1241 | protected function currentPageHasSubPages() |
||
1242 | { |
||
1243 | /** @var QueryBuilder $queryBuilder */ |
||
1244 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); |
||
1245 | $queryBuilder->getRestrictions() |
||
1272 | } |
||
1273 | } |
||
1274 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.