Layout module */ class PageLayoutController { /** * Page Id for which to make the listing * * @var int */ public $id; /** * Pointer - for browsing list of records. * * @var int */ public $pointer; /** * Thumbnails or not * * @var string */ public $imagemode; /** * Search-fields * * @var string */ public $search_field; /** * Search-levels * * @var int */ public $search_levels; /** * Show-limit * * @var int */ public $showLimit; /** * Return URL * * @var string */ public $returnUrl; /** * Clear-cache flag - if set, clears page cache for current id. * * @var bool */ public $clear_cache; /** * PopView id - for opening a window with the page * * @var bool */ public $popView; /** * QuickEdit: Variable, that tells quick edit what to show/edit etc. * Format is [tablename]:[uid] with some exceptional values for both parameters (with special meanings). * * @var string */ public $edit_record; /** * QuickEdit: If set, this variable tells quick edit that the last edited record had * this value as UID and we should look up the new, real uid value in sys_log. * * @var string */ public $new_unique_uid; /** * Page select perms clause * * @var string */ public $perms_clause; /** * Module TSconfig * * @var array */ public $modTSconfig; /** * Module shared TSconfig * * @var array */ public $modSharedTSconfig; /** * Current ids page record * * @var array */ public $pageinfo; /** * Document template object * * @var \TYPO3\CMS\Backend\Template\DocumentTemplate */ public $doc; /** * "Pseudo" Description -table name * * @var string */ public $descrTable; /** * List of column-integers to edit. Is set from TSconfig, default is "1,0,2,3" * * @var string */ public $colPosList; /** * Flag: If content can be edited or not. * * @var bool */ public $EDIT_CONTENT; /** * Users permissions integer for this page. * * @var int */ public $CALC_PERMS; /** * Currently selected language for editing content elements * * @var int */ public $current_sys_language; /** * Module configuration * * @var array */ public $MCONF = array(); /** * Menu configuration * * @var array */ public $MOD_MENU = array(); /** * Module settings (session variable) * * @var array */ public $MOD_SETTINGS = array(); /** * Array of tables to be listed by the Web > Page module in addition to the default tables * * @var array */ public $externalTables = array(); /** * Module output accumulation * * @var string */ public $content; /** * Function menu temporary storage * * @var string */ public $topFuncMenu; /** * List of column-integers accessible to the current BE user. * Is set from TSconfig, default is $colPosList * * @var string */ public $activeColPosList; /** * Markers array * * @var array */ protected $markers = array(); /** * @var array */ protected $eRParts = array(); /** * @var string */ protected $editSelect; /** * @var bool */ protected $deleteButton; /** * @var bool */ protected $undoButton; /** * @var array */ protected $undoButtonR; /** * @var string */ protected $R_URI; /** * @var string */ protected $closeUrl; /** * Caches the available languages in a colPos * * @var array */ protected $languagesInColumnCache = array(); /** * Caches the amount of content elements as a matrix * * @var array * @internal */ public $contentElementCache = array(); /** * @var IconFactory */ protected $iconFactory; /** * Initializing the module * * @return void */ public function init() { $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); $this->getLanguageService()->includeLLFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf'); // Setting module configuration / page select clause $this->MCONF = $GLOBALS['MCONF']; $this->perms_clause = $this->getBackendUser()->getPagePermsClause(1); // Get session data $sessionData = $this->getBackendUser()->getSessionData(RecordList::class); $this->search_field = !empty($sessionData['search_field']) ? $sessionData['search_field'] : ''; // GPvars: $this->id = (int)GeneralUtility::_GP('id'); $this->pointer = GeneralUtility::_GP('pointer'); $this->imagemode = GeneralUtility::_GP('imagemode'); $this->clear_cache = GeneralUtility::_GP('clear_cache'); $this->popView = GeneralUtility::_GP('popView'); $this->edit_record = GeneralUtility::_GP('edit_record'); $this->new_unique_uid = GeneralUtility::_GP('new_unique_uid'); $this->search_field = GeneralUtility::_GP('search_field'); $this->search_levels = GeneralUtility::_GP('search_levels'); $this->showLimit = GeneralUtility::_GP('showLimit'); $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl')); $this->externalTables = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cms']['db_layout']['addTables']; $sessionData['search_field'] = $this->search_field; // Store session data $this->getBackendUser()->setAndSaveSessionData(RecordList::class, $sessionData); // Load page info array: $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause); // Initialize menu $this->menuConfig(); // Setting sys language from session var: $this->current_sys_language = (int)$this->MOD_SETTINGS['language']; // CSH / Descriptions: $this->descrTable = '_MOD_' . $this->MCONF['name']; $this->markers['SEARCHBOX'] = ''; $this->markers['BUTTONLIST_ADDITIONAL'] = ''; } /** * Initialize menu array * * @return void */ public function menuConfig() { $lang = $this->getLanguageService(); // MENU-ITEMS: $this->MOD_MENU = array( 'tt_content_showHidden' => '', 'function' => array( 0 => $lang->getLL('m_function_0'), 1 => $lang->getLL('m_function_1'), 2 => $lang->getLL('m_function_2') ), 'language' => array( 0 => $lang->getLL('m_default') ) ); // example settings: // $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cms']['db_layout']['addTables']['tx_myext'] = // array ('default' => array( // 'MENU' => 'LLL:EXT:tx_myext/locallang_db.xlf:menuDefault', // 'fList' => 'title,description,image', // 'icon' => TRUE)); if (is_array($this->externalTables)) { foreach ($this->externalTables as $table => $tableSettings) { // delete the default settings from above if (is_array($this->MOD_MENU[$table])) { unset($this->MOD_MENU[$table]); } if (is_array($tableSettings) && count($tableSettings) > 1) { foreach ($tableSettings as $key => $settings) { $this->MOD_MENU[$table][$key] = $lang->sL($settings['MENU']); } } } } // First, select all pages_language_overlay records on the current page. Each represents a possibility for a language on the page. Add these to language selector. $res = $this->exec_languageQuery($this->id); while ($lRow = $this->getDatabaseConnection()->sql_fetch_assoc($res)) { if ($this->getBackendUser()->checkLanguageAccess($lRow['uid'])) { $this->MOD_MENU['language'][$lRow['uid']] = $lRow['hidden'] ? '(' . $lRow['title'] . ')' : $lRow['title']; } } // Find if there are ANY languages at all (and if not, remove the language option from function menu). $count = $this->getDatabaseConnection()->exec_SELECTcountRows('uid', 'sys_language', $this->getBackendUser()->isAdmin() ? '' : 'hidden=0'); if (!$count) { unset($this->MOD_MENU['function']['2']); } // page/be_user TSconfig settings and blinding of menu-items $this->modSharedTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.SHARED'); $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->MCONF['name']); if ($this->modTSconfig['properties']['QEisDefault']) { ksort($this->MOD_MENU['function']); } $this->MOD_MENU['function'] = BackendUtility::unsetMenuItems($this->modTSconfig['properties'], $this->MOD_MENU['function'], 'menu.function'); // Remove QuickEdit as option if page type is not... if (!GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['FE']['content_doktypes'] . ',6', $this->pageinfo['doktype'])) { unset($this->MOD_MENU['function'][0]); } // Setting alternative default label: if (($this->modSharedTSconfig['properties']['defaultLanguageLabel'] || $this->modTSconfig['properties']['defaultLanguageLabel']) && isset($this->MOD_MENU['language'][0])) { $this->MOD_MENU['language'][0] = $this->modTSconfig['properties']['defaultLanguageLabel'] ? $this->modSharedTSconfig['properties']['defaultLanguageLabel'] : $this->modSharedTSconfig['properties']['defaultLanguageLabel']; } // Clean up settings $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_layout'); // For all elements to be shown in draft workspaces & to also show hidden elements by default if user hasn't disabled the option if ($this->getBackendUser()->workspace != 0 || $this->MOD_SETTINGS['tt_content_showHidden'] !== '0') { $this->MOD_SETTINGS['tt_content_showHidden'] = 1; } } /** * Clears page cache for the current id, $this->id * * @return void */ public function clearCache() { if ($this->clear_cache) { $tce = GeneralUtility::makeInstance(DataHandler::class); $tce->stripslashes_values = FALSE; $tce->start(array(), array()); $tce->clear_cacheCmd($this->id); } } /** * Generate the flashmessages for current pid * * @return string HTML content with flashmessages */ protected function getHeaderFlashMessagesForCurrentPid() { $content = ''; $lang = $this->getLanguageService(); // If page is a folder if ($this->pageinfo['doktype'] == PageRepository::DOKTYPE_SYSFOLDER) { // Access to list module $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); $moduleLoader->load($GLOBALS['TBE_MODULES']); $modules = $moduleLoader->modules; if (is_array($modules['web']['sub']['list'])) { $title = $lang->getLL('goToListModule'); $message = '
' . $lang->getLL('goToListModuleMessage') . '
'; $message .= '' . $lang->getLL('goToListModule') . ''; $view = GeneralUtility::makeInstance(StandaloneView::class); $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html')); $view->assignMultiple(array( 'title' => $title, 'message' => $message, 'state' => InfoboxViewHelper::STATE_INFO )); $content .= $view->render(); } } // If content from different pid is displayed if ($this->pageinfo['content_from_pid']) { $contentPage = BackendUtility::getRecord('pages', (int)$this->pageinfo['content_from_pid']); $title = BackendUtility::getRecordTitle('pages', $contentPage); $linkToPid = $this->local_linkThisScript(array('id' => $this->pageinfo['content_from_pid'])); $link = '' . htmlspecialchars($title) . ' (PID ' . (int)$this->pageinfo['content_from_pid'] . ')'; $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($lang->getLL('content_from_pid_title'), $link), '', FlashMessage::INFO); $content .= $flashMessage->render(); } return $content; } /** * * @return string $title */ protected function getLocalizedPageTitle() { if ($this->current_sys_language > 0) { $overlayRecord = $this->getDatabaseConnection()->exec_SELECTgetSingleRow( 'title', 'pages_language_overlay', 'pid = ' . (int)$this->id . ' AND sys_language_uid = ' . (int)$this->current_sys_language . BackendUtility::deleteClause('pages_language_overlay') . BackendUtility::versioningPlaceholderClause('pages_language_overlay'), '', '', '', 'sys_language_uid' ); return $overlayRecord['title']; } else { return $this->pageinfo['title']; } } /** * Main function. * Creates some general objects and calls other functions for the main rendering of module content. * * @return void */ public function main() { $lang = $this->getLanguageService(); // Access check... // The page will show only if there is a valid page and if this page may be viewed by the user $access = is_array($this->pageinfo) ? 1 : 0; if ($this->id && $access) { // Initialize permission settings: $this->CALC_PERMS = $this->getBackendUser()->calcPerms($this->pageinfo); $this->EDIT_CONTENT = $this->pageIsNotLockedForEditors(); // Start document template object: $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class); $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/db_layout.html'); // override the default jumpToUrl $this->doc->JScodeArray['jumpToUrl'] = ' function jumpToUrl(URL,formEl) { if (document.editform && TBE_EDITOR.isFormChanged) { // Check if the function exists... (works in all browsers?) if (!TBE_EDITOR.isFormChanged()) { window.location.href = URL; } else if (formEl) { if (formEl.type=="checkbox") formEl.checked = formEl.checked ? 0 : 1; } } else { window.location.href = URL; } } '; $this->doc->JScode .= $this->doc->wrapScriptTags(' if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . '; if (top.fsMod) top.fsMod.navFrameHighlightedID["web"] = "pages' . (int)$this->id . '_"+top.fsMod.currentBank; ' . (int)$this->id . '; ' . ($this->popView ? BackendUtility::viewOnClick($this->id, '', BackendUtility::BEgetRootLine($this->id)) : '') . ' function deleteRecord(table,id,url) { // if (confirm(' . GeneralUtility::quoteJSvalue($lang->getLL('deleteWarning')) . ')) { window.location.href = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('tce_db') . '&cmd[') . '+table+"]["+id+"][delete]=1&redirect="+escape(url)+"&vC=' . $this->getBackendUser()->veriCode() . '&prErr=1&uPT=1"; } return false; } '); $this->doc->JScode .= $this->doc->wrapScriptTags(' var DTM_array = []; var DTM_origClass = ""; // if tabs are used in a popup window the array might not exists if(!top.DTM_currentTabs) { top.DTM_currentTabs = []; } function DTM_activate(idBase,index,doToogle) { // // Hiding all: if (DTM_array[idBase]) { for(cnt = 0; cnt < DTM_array[idBase].length ; cnt++) { if (DTM_array[idBase][cnt] != idBase+"-"+index) { document.getElementById(DTM_array[idBase][cnt]+"-DIV").className = "tab-pane"; document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").value = "tab"; } } } // Showing one: if (document.getElementById(idBase+"-"+index+"-DIV")) { if (doToogle && document.getElementById(idBase+"-"+index+"-DIV").className === "tab-pane active") { document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane"; if(DTM_origClass=="") { document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab"; } else { DTM_origClass = "tab"; } top.DTM_currentTabs[idBase] = -1; } else { document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active"; if(DTM_origClass=="") { document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active"; } else { DTM_origClass = "active"; } top.DTM_currentTabs[idBase] = index; } } } function DTM_toggle(idBase,index,isInit) { // // Showing one: if (document.getElementById(idBase+"-"+index+"-DIV")) { if (document.getElementById(idBase+"-"+index+"-DIV").style.display == "block") { document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane"; if(isInit) { document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "tab"; } else { DTM_origClass = "tab"; } top.DTM_currentTabs[idBase+"-"+index] = 0; } else { document.getElementById(idBase+"-"+index+"-DIV").className = "tab-pane active"; if(isInit) { document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").value = "active"; } else { DTM_origClass = "active"; } top.DTM_currentTabs[idBase+"-"+index] = 1; } } } '); // Setting doc-header $this->doc->form = '