'Using TypoScriptTemplateModuleController::$textExtensions is deprecated and will not be possible anymore in TYPO3 v10.0.', 'pageinfo' => 'Using TypoScriptTemplateModuleController::$pageinfo is deprecated and will not be possible anymore in TYPO3 v10.0.', 'id' => 'Using TypoScriptTemplateModuleController::$id is deprecated and will not be possible anymore in TYPO3 v10.0.', 'modTSconfig' => 'Using TypoScriptTemplateModuleController::$modTSconfig is deprecated and will not be possible anymore in TYPO3 v10.0.', 'content' => 'Using TypoScriptTemplateModuleController::$content is deprecated and will not be possible anymore in TYPO3 v10.0.', 'extObj' => 'Using TypoScriptTemplateModuleController::$extObj is deprecated and will not be possible anymore in TYPO3 v10.0.', 'access' => 'Using TypoScriptTemplateModuleController::$access is deprecated and will not be possible anymore in TYPO3 v10.0.', 'perms_clause' => 'Using TypoScriptTemplateModuleController::$perms_clause is deprecated and will not be possible anymore in TYPO3 v10.0.', 'extClassConf' => 'Using TypoScriptTemplateModuleController::$extClassConf is deprecated and will not be possible anymore in TYPO3 v10.0.', 'edit' => 'Using TypoScriptTemplateModuleController::$edit is deprecated, property will be removed in TYPO3 v10.0.', 'modMenu_type' => 'Using TypoScriptTemplateModuleController::$modMenu_type is deprecated, property will be removed in TYPO3 v10.0.', 'MCONF' => 'Using TypoScriptTemplateModuleController::$MCONF is deprecated, property will be removed in TYPO3 v10.0.', 'CMD' => 'Using TypoScriptTemplateModuleController::$CMD is deprecated, property will be removed in TYPO3 v10.0.', 'sObj' => 'Using TypoScriptTemplateModuleController::$sObj is deprecated, property will be removed in TYPO3 v10.0.', ]; /** * @var array */ private $deprecatedPublicMethods = [ 'getExternalItemConfig' => 'Using TypoScriptTemplateModuleController::getExternalItemConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'init' => 'Using TypoScriptTemplateModuleController::init() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'clearCache' => 'Using TypoScriptTemplateModuleController::clearCache() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'main' => 'Using TypoScriptTemplateModuleController::main() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'setInPageArray' => 'Using TypoScriptTemplateModuleController::setInPageArray() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'menuConfig' => 'Using TypoScriptTemplateModuleController::menuConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'mergeExternalItems' => 'Using TypoScriptTemplateModuleController::mergeExternalItems() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'handleExternalFunctionValue' => 'Using TypoScriptTemplateModuleController::handleExternalFunctionValue() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'checkExtObj' => 'Using TypoScriptTemplateModuleController::checkExtObj() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'extObjContent' => 'Using TypoScriptTemplateModuleController::extObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'getExtObjContent' => 'Using TypoScriptTemplateModuleController::getExtObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.', 'checkSubExtObj' => 'Using TypoScriptTemplateModuleController::checkSubExtObj() is deprecated, method will be removed in TYPO3 v10.0.', 'extObjHeader' => 'Using TypoScriptTemplateModuleController::extObjHeader() is deprecated, method will be removed in TYPO3 v10.0.', ]; /** * @var string */ protected $perms_clause; /** * @var string * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected $sObj; /** * @var string * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected $edit; /** * @var string * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected $textExtensions = 'html,htm,txt,css,tmpl,inc,js'; /** * @var string Written by client classes. * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. Remove last usages, too. */ protected $modMenu_type = ''; /** * @var string */ public $modMenu_dontValidateList = ''; /** * @var string Written by client classes */ public $modMenu_setDefaultList = ''; /** * @var array */ protected $pageinfo = []; /** * @var bool */ protected $access = false; /** * The name of the module * * @var string */ protected $moduleName = 'web_ts'; /** * ModuleTemplate Container * * @var ModuleTemplate */ protected $moduleTemplate; /** * @var ExtendedTemplateService */ protected $templateService; /** * Loaded with the global array $MCONF which holds some module configuration from the conf.php file of backend modules. * * @var array * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected $MCONF = []; /** * @var int GET/POST var 'id' */ protected $id; /** * The value of GET/POST var, 'CMD' * * @var mixed * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected $CMD; /** * The module menu items array. Each key represents a key for which values can range between the items in the array of that key. * Written by client classes. * * @var array */ public $MOD_MENU = [ 'function' => [] ]; /** * Current settings for the keys of the MOD_MENU array, used in client classes * * @see $MOD_MENU * @var array */ public $MOD_SETTINGS = []; /** * Module TSconfig based on PAGE TSconfig / USER TSconfig * * @var array */ protected $modTSconfig; /** * Contains module configuration parts from TBE_MODULES_EXT if found * * @see handleExternalFunctionValue() * @var array */ protected $extClassConf; /** * Generally used for accumulating the output content of backend modules * * @var string */ protected $content = ''; /** * May contain an instance of a 'Function menu module' which connects to this backend module. * * @see checkExtObj() * @var \object */ protected $extObj; /** * Constructor */ public function __construct() { $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class); $this->getLanguageService()->includeLLFile('EXT:tstemplate/Resources/Private/Language/locallang.xlf'); // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. $this->MCONF = [ 'name' => $this->moduleName ]; $this->moduleTemplate->addJavaScriptCode( 'jumpToUrl', ' function jumpToUrl(URL) { window.location.href = URL; return false; } ' ); } /** * Init */ protected function init() { // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. $this->CMD = GeneralUtility::_GP('CMD'); $this->id = (int)GeneralUtility::_GP('id'); $this->menuConfig(); $this->handleExternalFunctionValue(); // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. $this->sObj = GeneralUtility::_GP('sObj'); // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. $this->edit = GeneralUtility::_GP('edit'); $this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW); } /** * Clear cache */ protected function clearCache() { if (GeneralUtility::_GP('clear_all_cache')) { $tce = GeneralUtility::makeInstance(DataHandler::class); $tce->start([], []); $tce->clear_cacheCmd('all'); } } /** * Main */ protected function main() { // Access check... // The page will show only if there is a valid page and if this page may be viewed by the user $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause); $this->access = is_array($this->pageinfo); $view = $this->getFluidTemplateObject('tstemplate'); $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); if ($this->id && $this->access) { $urlParameters = [ 'id' => $this->id, 'template' => 'all' ]; $aHref = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters); // JavaScript $this->moduleTemplate->addJavaScriptCode( 'TSTemplateInlineJS', 'function uFormUrl(aname) { document.forms[0].action = ' . GeneralUtility::quoteJSvalue($aHref . '#') . '+aname; } function brPoint(lnumber,t) { window.location.href = ' . GeneralUtility::quoteJSvalue( $aHref . '&SET[function]=TYPO3\\CMS\\Tstemplate\\Controller\\' . 'TypoScriptTemplateObjectBrowserModuleFunctionController&SET[ts_browser_type]=' ) . '+(t?"setup":"const")+"&breakPointLN="+lnumber; return false; } if (top.fsMod) top.fsMod.recentIds["web"] = ' . $this->id . ';' ); $this->moduleTemplate->getPageRenderer()->addCssInlineBlock( 'TSTemplateInlineStyle', 'TABLE#typo3-objectBrowser { width: 100%; margin-bottom: 24px; } TABLE#typo3-objectBrowser A { text-decoration: none; } TABLE#typo3-objectBrowser .comment { color: maroon; font-weight: bold; } .ts-typoscript { width: 100%; } .tsob-search-submit {margin-left: 3px; margin-right: 3px;} .tst-analyzer-options { margin:5px 0; }' ); // Setting up the context sensitive menu: $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu'); // Build the module content $view->assign('actionName', $aHref); $view->assign('typoscriptTemplateModuleContent', $this->getExtObjContent()); // Setting up the buttons and markers for docheader $this->getButtons(); $this->generateMenu(); } else { $workspaceId = $this->getBackendUser()->workspace; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_template'); $queryBuilder->getRestrictions() ->removeAll() ->add(GeneralUtility::makeInstance(DeletedRestriction::class)); $this->applyWorkspaceConstraint( $queryBuilder, 'sys_template', $workspaceId ); $result = $queryBuilder ->select( 'uid', 'pid', 'title', 'sitetitle', 'root', 'hidden', 'starttime', 'endtime', 't3ver_oid', 't3ver_wsid', 't3ver_state', 't3ver_move_id' ) ->from('sys_template') ->orderBy('sys_template.pid') ->addOrderBy('sys_template.sorting') ->execute(); $pArray = []; while ($record = $result->fetch()) { BackendUtility::workspaceOL('sys_template', $record, $workspaceId, true); if (empty($record) || VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) { continue; } $additionalFieldsForRootline = ['sorting', 'shortcut']; $rootline = BackendUtility::BEgetRootLine($record['pid'], '', true, $additionalFieldsForRootline); $this->setInPageArray($pArray, $rootline, $record); } $view->getRenderingContext()->setControllerAction('PageZero'); $view->assign('pageTree', $pArray); // RENDER LIST of pages with templates, END // Setting up the buttons and markers for docheader $this->getButtons(); } $this->content = $view->render(); } /** * Generates the menu based on $this->MOD_MENU * * @throws \InvalidArgumentException */ protected function generateMenu() { $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu(); $menu->setIdentifier('WebFuncJumpMenu'); $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); foreach ($this->MOD_MENU['function'] as $controller => $title) { $item = $menu ->makeMenuItem() ->setHref( (string)$uriBuilder->buildUriFromRoute( $this->moduleName, [ 'id' => $this->id, 'SET' => [ 'function' => $controller ] ] ) ) ->setTitle($title); if ($controller === $this->MOD_SETTINGS['function']) { $item->setActive(true); } $menu->addMenuItem($item); } $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu); } /** * Injects the request object for the current request or subrequest * Then checks for module functions that have hooked in, and renders menu etc. * * @param ServerRequestInterface $request the current request * @return ResponseInterface the response with the content */ public function mainAction(ServerRequestInterface $request): ResponseInterface { // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. $GLOBALS['SOBE'] = $this; $this->init(); // Checking for first level external objects $this->checkExtObj(); $this->clearCache(); $this->main(); $this->moduleTemplate->setContent($this->content); return new HtmlResponse($this->moduleTemplate->renderContent()); } /** * Create the panel of buttons for submitting the form or otherwise perform operations. */ protected function getButtons() { $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); $lang = $this->getLanguageService(); if ($this->id && $this->access) { // View page $viewButton = $buttonBar->makeLinkButton() ->setHref('#') ->setOnClick(BackendUtility::viewOnClick( $this->pageinfo['uid'], '', BackendUtility::BEgetRootLine($this->pageinfo['uid']) )) ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage')) ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-page', Icon::SIZE_SMALL)); $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 99); if ($this->extClassConf['name'] === TypoScriptTemplateInformationModuleFunctionController::class) { // NEW button $urlParameters = [ 'id' => $this->id, 'template' => 'all', 'createExtension' => 'new' ]; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); $newButton = $buttonBar->makeLinkButton() ->setHref((string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters)) ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:db_new.php.pagetitle')) ->setIcon($this->moduleTemplate->getIconFactory()->getIcon( 'actions-add', Icon::SIZE_SMALL )); $buttonBar->addButton($newButton); } elseif ($this->extClassConf['name'] === TypoScriptTemplateConstantEditorModuleFunctionController::class && !empty($this->MOD_MENU['constant_editor_cat'])) { // SAVE button $saveButton = $buttonBar->makeInputButton() ->setName('_savedok') ->setValue('1') ->setForm('TypoScriptTemplateModuleController') ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.saveDoc')) ->setIcon($this->moduleTemplate->getIconFactory()->getIcon( 'actions-document-save', Icon::SIZE_SMALL )) ->setShowLabelText(true); $buttonBar->addButton($saveButton); } elseif ($this->extClassConf['name'] === TypoScriptTemplateObjectBrowserModuleFunctionController::class && !empty(GeneralUtility::_GP('sObj')) ) { // back button in edit mode of object browser. "sObj" is set by ExtendedTemplateService $urlParameters = [ 'id' => $this->id ]; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); $backButton = $buttonBar->makeLinkButton() ->setHref((string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters)) ->setClasses('typo3-goBack') ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack')) ->setIcon($this->moduleTemplate->getIconFactory()->getIcon( 'actions-view-go-back', Icon::SIZE_SMALL )); $buttonBar->addButton($backButton); } } // Shortcut $shortcutButton = $buttonBar->makeShortcutButton() ->setModuleName('web_ts') ->setGetVariables(['id', 'route']); $buttonBar->addButton($shortcutButton); } /** * Wrap title for link in template, called from client classes. * * @param string $title * @param string $onlyKey * @return string */ public function linkWrapTemplateTitle($title, $onlyKey = '') { $urlParameters = [ 'id' => $this->id ]; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); $aHref = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters); if ($onlyKey) { $title = '' . htmlspecialchars($title) . ''; } else { $title = '' . htmlspecialchars($title) . ''; } return $title; } /** * No template, called from client classes. * * @param int $newStandardTemplate * @return string */ public function noTemplate($newStandardTemplate = 0) { $this->templateService = GeneralUtility::makeInstance(ExtendedTemplateService::class); $moduleContent['state'] = InfoboxViewHelper::STATE_INFO; // New standard? if ($newStandardTemplate) { $selector = ''; $staticsText = ''; // Hook to change output, implemented for statictemplates $hookObject = $this->getHookObjectForAction('newStandardTemplateView'); if (!empty($hookObject)) { $reference = [ 'selectorHtml' => &$selector, 'staticsText' => &$staticsText ]; GeneralUtility::callUserFunction( $hookObject, $reference, $this ); $selector = $reference['selectorHtml']; $staticsText = $reference['staticsText']; } // Extension? $moduleContent['staticsText'] = $staticsText; $moduleContent['selector'] = $selector; } // Go to previous Page with Template... $previousPage = $this->templateService->ext_prevPageWithTemplate($this->id, $this->perms_clause); if ($previousPage) { $urlParameters = [ 'id' => $previousPage['uid'] ]; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); $previousPage['aHref'] = (string)$uriBuilder->buildUriFromRoute('web_ts', $urlParameters); $moduleContent['previousPage'] = $previousPage; } $view = $this->getFluidTemplateObject('tstemplate', 'NoTemplate'); $view->assign('content', $moduleContent); return $view->render(); } /** * Render template menu, called from client classes. * * @return string */ public function templateMenu() { $this->templateService = GeneralUtility::makeInstance(ExtendedTemplateService::class); $all = $this->templateService->ext_getAllTemplates($this->id); if (count($all) > 1) { $this->MOD_MENU['templatesOnPage'] = []; foreach ($all as $d) { $this->MOD_MENU['templatesOnPage'][$d['uid']] = $d['title']; } } $this->MOD_SETTINGS = BackendUtility::getModuleData( $this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_ts', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList ); return BackendUtility::getFuncMenu( $this->id, 'SET[templatesOnPage]', $this->MOD_SETTINGS['templatesOnPage'], $this->MOD_MENU['templatesOnPage'] ); } /** * Create template, called from client classes. * * @param int $id * @param int $actTemplateId * @return string */ public function createTemplate($id, $actTemplateId = 0) { $recData = []; $tce = GeneralUtility::makeInstance(DataHandler::class); if (GeneralUtility::_GP('createExtension')) { $recData['sys_template']['NEW'] = [ 'pid' => $actTemplateId ? -1 * $actTemplateId : $id, 'title' => '+ext' ]; $tce->start($recData, []); $tce->process_datamap(); } elseif (GeneralUtility::_GP('newWebsite')) { // Hook to handle row data, implemented for statictemplates $hookObject = $this->getHookObjectForAction('newStandardTemplateHandler'); if (!empty($hookObject)) { $reference = [ 'recData' => &$recData, 'id' => $id, ]; GeneralUtility::callUserFunction( $hookObject, $reference, $this ); $recData = $reference['recData']; } else { $recData['sys_template']['NEW'] = [ 'pid' => $id, 'title' => $this->getLanguageService()->getLL('titleNewSite'), 'sorting' => 0, 'root' => 1, 'clear' => 3, 'config' => ' # Default PAGE object: page = PAGE page.10 = TEXT page.10.value = HELLO WORLD! ' ]; } $tce->start($recData, []); $tce->process_datamap(); $tce->clear_cacheCmd('all'); } return $tce->substNEWwithIDs['NEW']; } /** * Set page in array * To render list of page tree with templates * * @param array $pArray Multidimensional array of page tree with template records * @param array $rlArr Rootline array * @param array $row Record of sys_template */ protected function setInPageArray(&$pArray, $rlArr, $row) { ksort($rlArr); reset($rlArr); if (!$rlArr[0]['uid']) { array_shift($rlArr); } $cEl = current($rlArr); if (empty($pArray[$cEl['uid']])) { $pArray[$cEl['uid']] = $cEl; } array_shift($rlArr); if (!empty($rlArr)) { if (empty($pArray[$cEl['uid']]['_nodes'])) { $pArray[$cEl['uid']]['_nodes'] = []; } $this->setInPageArray($pArray[$cEl['uid']]['_nodes'], $rlArr, $row); } else { $pArray[$cEl['uid']]['_templates'][] = $row; } uasort($pArray, function ($a, $b) { return $a['sorting'] - $b['sorting']; }); } /** * Get the list * * @param array $pArray * @param array $lines * @param int $c * @return array * @deprecated since TYPO3 v9.4, will be removed in TYPO3 v10.0 */ public function renderList($pArray, $lines = [], $c = 0) { trigger_error( 'The method `TYPO3\CMS\Tstemplate\Controller\TypoScriptTemplateModuleController::renderList` has been deprecated and should not be used any longer, this method will be removed in TYPO3 v10.0', E_USER_DEPRECATED ); if (!is_array($pArray)) { return $lines; } $statusCheckedIcon = $this->moduleTemplate->getIconFactory() ->getIcon('status-status-checked', Icon::SIZE_SMALL)->render(); foreach ($pArray as $k => $v) { if (MathUtility::canBeInterpretedAsInteger($k)) { $line = []; $key = $k . '_'; $line['marginLeft'] = $c * 20; $line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pArray[$k], 30); $line['icon'] = $this->moduleTemplate->getIconFactory() ->getIconForRecord( 'pages', BackendUtility::getRecordWSOL('pages', $k), Icon::SIZE_SMALL )->render(); if (!empty($pArray[$key])) { $line['href'] = GeneralUtility::linkThisScript(['id' => (int)$k]); $line['title'] = 'ID: ' . (int)$k; $line['count'] = $pArray[$k . '_']['count']; $line['root_max_val'] = ($pArray[$key]['root_max_val'] > 0 ? $statusCheckedIcon : ' '); $line['root_min_val'] = ($pArray[$key]['root_min_val'] === 0 ? $statusCheckedIcon : ' '); } else { $line['href'] = ''; $line['title'] = ''; $line['count'] = ''; $line['root_max_val'] = ''; $line['root_min_val'] = ''; } $lines[] = $line; $lines = $this->renderList($pArray[$k . '.'], $lines, $c + 1); } } return $lines; } /** * Returns a new standalone view, shorthand function * * @param string $extensionName * @param string $templateName * @return StandaloneView */ protected function getFluidTemplateObject($extensionName, $templateName = 'Main') { $view = GeneralUtility::makeInstance(StandaloneView::class); $view->getRenderingContext()->getTemplatePaths()->fillDefaultsByPackageName($extensionName); $view->getRenderingContext()->setControllerAction($templateName); $view->getRequest()->setControllerExtensionName('tstemplate'); return $view; } /** * @param QueryBuilder $queryBuilder * @param string $tableName * @param int $workspaceId */ protected function applyWorkspaceConstraint( QueryBuilder $queryBuilder, string $tableName, int $workspaceId ) { if (empty($GLOBALS['TCA'][$tableName]['ctrl']['versioningWS'])) { return; } $workspaceIds = [0]; if ($workspaceId > 0) { $workspaceIds[] = $workspaceId; } $queryBuilder->andWhere( $queryBuilder->expr()->in( 't3ver_wsid', $queryBuilder->createNamedParameter($workspaceIds, Connection::PARAM_INT_ARRAY) ), $queryBuilder->expr()->neq( 'pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT) ) ); } /** * @param string $action * @return string */ protected function getHookObjectForAction($action) { if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class][$action])) { return $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][self::class][$action]; } return null; } /** * Initializes the internal MOD_MENU array setting and unsetting items based on various conditions. It also merges in external menu items from the global array TBE_MODULES_EXT (see mergeExternalItems()) * Then MOD_SETTINGS array is cleaned up (see \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()) so it contains only valid values. It's also updated with any SET[] values submitted. * Also loads the modTSconfig internal variable. * * @see init(), $MOD_MENU, $MOD_SETTINGS, \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData(), mergeExternalItems() */ protected function menuConfig() { // Page / user TSconfig settings and blinding of menu-items $this->modTSconfig['properties'] = BackendUtility::getPagesTSconfig($this->id)['mod.']['web_ts.'] ?? []; $this->MOD_MENU['function'] = $this->mergeExternalItems('web_ts', 'function', $this->MOD_MENU['function']); $blindActions = $this->modTSconfig['properties']['menu.']['function.'] ?? []; foreach ($blindActions as $key => $value) { if (!$value && array_key_exists($key, $this->MOD_MENU['function'])) { unset($this->MOD_MENU['function'][$key]); } } $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_ts', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList); } /** * Merges menu items from global array $TBE_MODULES_EXT * * @param string $modName Module name for which to find value * @param string $menuKey Menu key, eg. 'function' for the function menu. * @param array $menuArr The part of a MOD_MENU array to work on. * @return array Modified array part. * @internal * @see \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(), menuConfig() */ protected function mergeExternalItems($modName, $menuKey, $menuArr) { $mergeArray = $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey]; if (is_array($mergeArray)) { foreach ($mergeArray as $k => $v) { if (((string)$v['ws'] === '' || $this->getBackendUser()->workspace === 0 && GeneralUtility::inList($v['ws'], 'online')) || $this->getBackendUser()->workspace === -1 && GeneralUtility::inList($v['ws'], 'offline') || $this->getBackendUser()->workspace > 0 && GeneralUtility::inList($v['ws'], 'custom')) { $menuArr[$k] = $this->getLanguageService()->sL($v['title']); } } } return $menuArr; } /** * Loads $this->extClassConf with the configuration for the CURRENT function of the menu. * * @param string $MM_key The key to MOD_MENU for which to fetch configuration. 'function' is default since it is first and foremost used to get information per "extension object" (I think that is what its called) * @param string $MS_value The value-key to fetch from the config array. If NULL (default) MOD_SETTINGS[$MM_key] will be used. This is useful if you want to force another function than the one defined in MOD_SETTINGS[function]. Call this in init() function of your Script Class: handleExternalFunctionValue('function', $forcedSubModKey) * @see getExternalItemConfig(), init() */ protected function handleExternalFunctionValue($MM_key = 'function', $MS_value = null) { if ($MS_value === null) { $MS_value = $this->MOD_SETTINGS[$MM_key]; } $this->extClassConf = $this->getExternalItemConfig('web_ts', $MM_key, $MS_value); } /** * Returns configuration values from the global variable $TBE_MODULES_EXT for the module given. * For example if the module is named "web_info" and the "function" key ($menuKey) of MOD_SETTINGS is "stat" ($value) then you will have the values of $TBE_MODULES_EXT['webinfo']['MOD_MENU']['function']['stat'] returned. * * @param string $modName Module name * @param string $menuKey Menu key, eg. "function" for the function menu. See $this->MOD_MENU * @param string $value Optionally the value-key to fetch from the array that would otherwise have been returned if this value was not set. Look source... * @return mixed The value from the TBE_MODULES_EXT array. * @see handleExternalFunctionValue() */ protected function getExternalItemConfig($modName, $menuKey, $value = '') { if (isset($GLOBALS['TBE_MODULES_EXT'][$modName])) { return (string)$value !== '' ? $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey][$value] : $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey]; } return null; } /** * Creates an instance of the class found in $this->extClassConf['name'] in $this->extObj if any (this should hold three keys, "name", "path" and "title" if a "Function menu module" tries to connect...) * This value in extClassConf might be set by an extension (in an ext_tables/ext_localconf file) which thus "connects" to a module. * The array $this->extClassConf is set in handleExternalFunctionValue() based on the value of MOD_SETTINGS[function] * If an instance is created it is initiated with $this passed as value and $this->extClassConf as second argument. Further the $this->MOD_SETTING is cleaned up again after calling the init function. * * @see handleExternalFunctionValue(), \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(), $extObj */ protected function checkExtObj() { if (is_array($this->extClassConf) && $this->extClassConf['name']) { $this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']); $this->extObj->init($this); // Re-write: $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_ts', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList); } } /** * Calls the checkExtObj function in sub module if present. * * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected function checkSubExtObj() { if (is_object($this->extObj) && is_callable([$this->extObj, 'checkExtObj'])) { $this->extObj->checkExtObj(); } } /** * Calls the 'header' function inside the "Function menu module" if present. * A header function might be needed to add JavaScript or other stuff in the head. * This can't be done in the main function because the head is already written. * * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. */ protected function extObjHeader() { if (is_callable([$this->extObj, 'head'])) { $this->extObj->head(); } } /** * Calls the 'main' function inside the "Function menu module" if present */ protected function extObjContent() { if ($this->extObj === null) { $flashMessage = GeneralUtility::makeInstance( FlashMessage::class, $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:no_modules_registered'), $this->getLanguageService()->getLL('title'), FlashMessage::ERROR ); $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); /** @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue $defaultFlashMessageQueue */ $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(); $defaultFlashMessageQueue->enqueue($flashMessage); } else { if (is_callable([$this->extObj, 'main'])) { $this->content .= $this->extObj->main(); } } } /** * Return the content of the 'main' function inside the "Function menu module" if present * * @return string */ protected function getExtObjContent() { $savedContent = $this->content; $this->content = ''; $this->extObjContent(); $newContent = $this->content; $this->content = $savedContent; return $newContent; } /** * Returns the Language Service * @return LanguageService */ protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; } /** * Returns the Backend User * @return BackendUserAuthentication */ protected function getBackendUser(): BackendUserAuthentication { return $GLOBALS['BE_USER']; } /** * @return PageRenderer */ protected function getPageRenderer(): PageRenderer { return GeneralUtility::makeInstance(PageRenderer::class); } }