Skip to content
Snippets Groups Projects
Commit 9a912800 authored by Benni Mack's avatar Benni Mack Committed by Georg Ringer
Browse files

[TASK] Use ModuleTemplate in BackendController

The main entry point for the TYPO3 backend is the BackendController.

Some changes are made:
- Only instantiate necessary code
- Use $uriBuilder as property
- Use ModuleTemplate's view to not instantiate a Fluid view multiple times

This eases the way to lower the usage of DocumentTemplate again.

Resolves: #90282
Releases: master
Change-Id: I7ebc0f564f898f7451a5821ec357d05bda5bbda4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63109


Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
parent 1e2f5733
Branches
Tags
No related merge requests found
......@@ -16,16 +16,17 @@ namespace TYPO3\CMS\Backend\Controller;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository;
use TYPO3\CMS\Backend\Module\ModuleLoader;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Type\File\ImageInfo;
......@@ -39,11 +40,6 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
*/
class BackendController
{
/**
* @var string
*/
protected $content = '';
/**
* @var string
*/
......@@ -54,11 +50,6 @@ class BackendController
*/
protected $toolbarItems = [];
/**
* @var bool
*/
protected $debug;
/**
* @var string
*/
......@@ -74,11 +65,6 @@ class BackendController
*/
protected $backendModuleRepository;
/**
* @var ModuleLoader Object for loading backend modules
*/
protected $moduleLoader;
/**
* @var PageRenderer
*/
......@@ -94,52 +80,38 @@ class BackendController
*/
protected $typo3Version;
/**
* @var UriBuilder
*/
protected $uriBuilder;
/**
* Constructor
*/
public function __construct()
{
$this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
$this->backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$this->uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$this->typo3Version = GeneralUtility::makeInstance(Typo3Version::class);
// Set debug flag for BE development only
$this->debug = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] === 1;
// Initializes the backend modules structure for use later.
$this->moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
$this->moduleLoader->load($GLOBALS['TBE_MODULES']);
$this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
// Add default BE javascript
$this->pageRenderer->addJsFile('EXT:backend/Resources/Public/JavaScript/md5.js');
$this->pageRenderer->addJsFile('EXT:backend/Resources/Public/JavaScript/backend.js');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LoginRefresh', 'function(LoginRefresh) {
LoginRefresh.setIntervalTime(' . MathUtility::forceIntegerInRange((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'] - 60, 60) . ');
LoginRefresh.setLoginFramesetUrl(' . GeneralUtility::quoteJSvalue((string)$uriBuilder->buildUriFromRoute('login_frameset')) . ');
LoginRefresh.setLogoutUrl(' . GeneralUtility::quoteJSvalue((string)$uriBuilder->buildUriFromRoute('logout')) . ');
LoginRefresh.setLoginFramesetUrl(' . GeneralUtility::quoteJSvalue((string)$this->uriBuilder->buildUriFromRoute('login_frameset')) . ');
LoginRefresh.setLogoutUrl(' . GeneralUtility::quoteJSvalue((string)$this->uriBuilder->buildUriFromRoute('logout')) . ');
LoginRefresh.initialize();
}');
// load BroadcastService
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/BroadcastService', 'function(service) { service.listen(); }');
// load module menu
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ModuleMenu');
// load Toolbar class
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar');
// load Notification functionality
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Notification');
// load Modals
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
// load InfoWindow
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/InfoWindow');
// load ContextMenu
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
// load the storage API and fill the UC into the PersistentStorage, so no additional AJAX call is needed
......@@ -147,24 +119,22 @@ class BackendController
PersistentStorage.load(' . json_encode($this->getBackendUser()->uc) . ');
}');
// load debug console
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DebugConsole');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/debugger.xlf');
$this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/wizard.xlf');
$this->pageRenderer->addInlineSetting('ShowItem', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('show_item'));
$this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_history'));
$this->pageRenderer->addInlineSetting('NewRecord', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('db_new'));
$this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('record_edit'));
$this->pageRenderer->addInlineSetting('RecordCommit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('tce_db'));
$this->pageRenderer->addInlineSetting('FileCommit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('tce_file'));
$this->pageRenderer->addInlineSetting('WebLayout', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('web_layout'));
$this->pageRenderer->addInlineSetting('ShowItem', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('show_item'));
$this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_history'));
$this->pageRenderer->addInlineSetting('NewRecord', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('db_new'));
$this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('record_edit'));
$this->pageRenderer->addInlineSetting('RecordCommit', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('tce_db'));
$this->pageRenderer->addInlineSetting('FileCommit', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('tce_file'));
$this->pageRenderer->addInlineSetting('WebLayout', 'moduleUrl', (string)$this->uriBuilder->buildUriFromRoute('web_layout'));
$this->initializeToolbarItems();
$this->executeHook('constructPostProcess');
......@@ -214,8 +184,10 @@ class BackendController
$this->executeHook('renderPreProcess');
// Prepare the scaffolding, at this point extension may still add javascript and css
$view = $this->getFluidTemplateObject($this->templatePath . 'Backend/Main.html');
$moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
$view = $moduleTemplate->getView();
$view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($this->templatePath . 'Backend/Main.html'));
$view->assign('moduleMenuCollapsed', $this->getCollapseStateOfMenu());
$view->assign('moduleMenu', $this->generateModuleMenu());
$view->assign('topbar', $this->renderTopbar());
......@@ -225,14 +197,15 @@ class BackendController
}
$this->generateJavascript();
// Set document title:
// Set document title
$typo3Version = 'TYPO3 CMS ' . $this->typo3Version->getVersion();
$title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [' . $typo3Version . ']' : $typo3Version;
// Renders the module page
$this->content = GeneralUtility::makeInstance(DocumentTemplate::class)->render($title, $view->render());
$hookConfiguration = ['content' => &$this->content];
$this->executeHook('renderPostProcess', $hookConfiguration);
return new HtmlResponse($this->content);
$moduleTemplate->setTitle($title);
// Renders the backend scaffolding
$content = $moduleTemplate->renderContent();
$this->executeHook('renderPostProcess', ['content' => &$content]);
return new HtmlResponse($content);
}
/**
......@@ -290,7 +263,7 @@ class BackendController
{
$toolbar = [];
foreach ($this->toolbarItems as $toolbarItem) {
/** @var \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface $toolbarItem */
/** @var ToolbarItemInterface $toolbarItem */
if ($toolbarItem->checkAccess()) {
$hasDropDown = (bool)$toolbarItem->hasDropDown();
$additionalAttributes = (array)$toolbarItem->getAdditionalAttributes();
......@@ -360,7 +333,7 @@ class BackendController
if (!$beUser->check('modules', $pageModule)) {
$pageModule = '';
} else {
$pageModuleUrl = (string)GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute($pageModule);
$pageModuleUrl = (string)$this->uriBuilder->buildUriFromRoute($pageModule);
}
$t3Configuration = [
'username' => htmlspecialchars($beUser->user['username']),
......@@ -582,7 +555,7 @@ class BackendController
/**
* Returns LanguageService
*
* @return \TYPO3\CMS\Core\Localization\LanguageService
* @return LanguageService
*/
protected function getLanguageService()
{
......@@ -592,7 +565,7 @@ class BackendController
/**
* Returns the current BE user.
*
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
* @return BackendUserAuthentication
*/
protected function getBackendUser()
{
......
......@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
......@@ -27,6 +28,7 @@ use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException;
......@@ -331,6 +333,7 @@ class ModuleTemplate
$this->pageRenderer->setCharSet('utf-8');
$this->pageRenderer->setLanguage($this->getLanguageService()->lang);
$this->pageRenderer->setMetaTag('name', 'viewport', 'width=device-width, initial-scale=1');
$this->pageRenderer->setFavIcon($this->getBackendFavicon());
$this->pageRenderer->enableConcatenateCss();
$this->pageRenderer->enableConcatenateJavascript();
$this->pageRenderer->enableCompressCss();
......@@ -613,6 +616,48 @@ class ModuleTemplate
return HttpUtility::buildQueryString($storeArray, '&');
}
/**
* Retrieves configured favicon for backend (with fallback)
*
* @return string
*/
protected function getBackendFavicon()
{
$backendFavicon = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('backend', 'backendFavicon');
if (!empty($backendFavicon)) {
$path = $this->getUriForFileName($backendFavicon);
} else {
$path = ExtensionManagementUtility::extPath('backend') . 'Resources/Public/Icons/favicon.ico';
}
return PathUtility::getAbsoluteWebPath($path);
}
/**
* Returns the uri of a relative reference, resolves the "EXT:" prefix
* (way of referring to files inside extensions) and checks that the file is inside
* the project root of the TYPO3 installation
*
* @param string $filename The input filename/filepath to evaluate
* @return string Returns the filename of $filename if valid, otherwise blank string.
*/
protected function getUriForFileName($filename)
{
if (strpos($filename, '://')) {
return $filename;
}
$urlPrefix = '';
if (strpos($filename, 'EXT:') === 0) {
$absoluteFilename = GeneralUtility::getFileAbsFileName($filename);
$filename = '';
if ($absoluteFilename !== '') {
$filename = PathUtility::getAbsoluteWebPath($absoluteFilename);
}
} elseif (strpos($filename, '/') !== 0) {
$urlPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
}
return $urlPrefix . $filename;
}
/**
* Returns the BE USER Object
*
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment