diff --git a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LiveSearch.ts b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/Toolbar/LiveSearch.ts similarity index 97% rename from Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LiveSearch.ts rename to Build/Sources/TypeScript/backend/Resources/Public/TypeScript/Toolbar/LiveSearch.ts index d8418014351769e574ac29db2c4147a4563df933..ba653ebe4beeb851e2db8d631830c68375384fb8 100644 --- a/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LiveSearch.ts +++ b/Build/Sources/TypeScript/backend/Resources/Public/TypeScript/Toolbar/LiveSearch.ts @@ -12,10 +12,10 @@ */ import $ from 'jquery'; -import Viewport = require('./Viewport'); -import Icons = require('./Icons'); +import Viewport = require('../Viewport'); +import Icons = require('../Icons'); import 'jquery/autocomplete'; -import './Input/Clearable'; +import '../Input/Clearable'; import {html, render, TemplateResult} from 'lit'; import {unsafeHTML} from 'lit/directives/unsafe-html'; import {renderHTML} from 'TYPO3/CMS/Core/lit-helper'; @@ -44,9 +44,9 @@ interface Suggestion { } /** - * Module: TYPO3/CMS/Backend/LiveSearch + * Module: TYPO3/CMS/Backend/Toolbar/LiveSearch * Global search to deal with everything in the backend that is search-related - * @exports TYPO3/CMS/Backend/LiveSearch + * @exports TYPO3/CMS/Backend/Toolbar/LiveSearch */ class LiveSearch { private url: string = TYPO3.settings.ajaxUrls.livesearch; diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ClearCacheToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ClearCacheToolbarItem.php index 5014d6b1e80b98bb2580b3ee75a76222157ff343..fa36606bc07367b35dd4ab3656b2324757fb2861 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ClearCacheToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ClearCacheToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -20,37 +22,23 @@ use TYPO3\CMS\Backend\Backend\Event\ModifyClearCacheActionsEvent; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; -use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * Render cache clearing toolbar item - * Adds a dropdown if there are more than one item to clear (usually for admins to render the flush all caches) - * - * The dropdown items can be extended via a hook named "cacheActions". + * Render cache clearing toolbar item. + * Adds a dropdown if there are more than one item to clear (usually for admins to render the flush all caches). + * The dropdown items can be manipulated using ModifyClearCacheActionsEvent. */ class ClearCacheToolbarItem implements ToolbarItemInterface { - /** - * @var array - */ - protected $cacheActions = []; - - /** - * @var array - */ - protected $optionValues = []; + protected array $cacheActions = []; + protected array $optionValues = []; - /** - * @throws \UnexpectedValueException - */ public function __construct( - PageRenderer $pageRenderer, UriBuilder $uriBuilder, EventDispatcherInterface $eventDispatcher ) { - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/ClearCacheMenu'); $isAdmin = $this->getBackendUser()->isAdmin(); $userTsConfig = $this->getBackendUser()->getTSConfig(); @@ -89,11 +77,9 @@ class ClearCacheToolbarItem implements ToolbarItemInterface } /** - * Checks whether the user has access to this toolbar item - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. */ - public function checkAccess() + public function checkAccess(): bool { $backendUser = $this->getBackendUser(); if ($backendUser->isAdmin()) { @@ -109,92 +95,66 @@ class ClearCacheToolbarItem implements ToolbarItemInterface /** * Render clear cache icon, based on the option if there is more than one icon or just one. - * - * @return string Icon HTML */ - public function getItem() + public function getItem(): string { if ($this->hasDropDown()) { - return $this->getFluidTemplateObject('ClearCacheToolbarItem.html')->render(); + return $this->getFluidTemplateObject()->render('ToolbarItems/ClearCacheToolbarItem'); } - $view = $this->getFluidTemplateObject('ClearCacheToolbarItemSingle.html'); + $view = $this->getFluidTemplateObject(); $cacheAction = end($this->cacheActions); $view->assignMultiple([ 'link' => $cacheAction['href'], 'title' => $cacheAction['title'], 'iconIdentifier' => $cacheAction['iconIdentifier'], ]); - return $view->render(); + return $view->render('ToolbarItems/ClearCacheToolbarItemSingle'); } /** - * Render drop down - * - * @return string Drop down HTML + * Render drop-down. */ - public function getDropDown() + public function getDropDown(): string { - $view = $this->getFluidTemplateObject('ClearCacheToolbarItemDropDown.html'); + $view = $this->getFluidTemplateObject(); $view->assign('cacheActions', $this->cacheActions); - return $view->render(); + return $view->render('ToolbarItems/ClearCacheToolbarItemDropDown'); } /** * No additional attributes needed. - * - * @return array */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** - * This item has a drop down if there is more than one cache action available for the current Backend user. - * - * @return bool + * This item has a drop-down, if there is more than one cache action available for the current Backend user. */ - public function hasDropDown() + public function hasDropDown(): bool { return count($this->cacheActions) > 1; } /** * Position relative to others - * - * @return int */ - public function getIndex() + public function getIndex(): int { return 25; } - /** - * Returns the current BE user. - * - * @return BackendUserAuthentication - */ - protected function getBackendUser() + protected function getFluidTemplateObject(): BackendTemplateView { - return $GLOBALS['BE_USER']; + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); + return $view; } - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView + protected function getBackendUser(): BackendUserAuthentication { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']); - - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Backend'); - return $view; + return $GLOBALS['BE_USER']; } } diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php index 21f5fd723b86e24c3f57a9d5a515fa79980ee5a9..d0d5403f0722122f7e787185471166a8d623200d 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -19,24 +21,18 @@ use TYPO3\CMS\Backend\Domain\Model\Module\BackendModule; use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * Help toolbar item + * Help toolbar item - The question mark icon in toolbar */ class HelpToolbarItem implements ToolbarItemInterface { - /** - * @var BackendModule - */ - protected $helpModuleMenu; + protected ?BackendModule $helpModuleMenu = null; - /** - * Constructor - */ - public function __construct() - { - $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class); + public function __construct( + BackendModuleRepository $backendModuleRepository + ) { $helpModuleMenu = $backendModuleRepository->findByModuleName('help'); if ($helpModuleMenu && $helpModuleMenu->getChildren()->count() > 0) { $this->helpModuleMenu = $helpModuleMenu; @@ -45,81 +41,63 @@ class HelpToolbarItem implements ToolbarItemInterface /** * Users see this if a module is available - * - * @return bool TRUE */ - public function checkAccess() + public function checkAccess(): bool { return (bool)$this->helpModuleMenu; } /** * Render help icon - * - * @return string toolbar item for the help icon */ - public function getItem() + public function getItem(): string { - return $this->getFluidTemplateObject('HelpToolbarItem.html')->render(); + return $this->getFluidTemplateObject()->render('ToolbarItems/HelpToolbarItem'); } /** * Render drop down - * - * @return string */ - public function getDropDown() + public function getDropDown(): string { - $view = $this->getFluidTemplateObject('HelpToolbarItemDropDown.html'); + if (!$this->helpModuleMenu instanceof BackendModule) { + // checkAccess() is called before and prevents call to getDropDown() if there is no help. + throw new \RuntimeException('No HelpModuleMenu found.', 1641993564); + } + $view = $this->getFluidTemplateObject(); $view->assign('modules', $this->helpModuleMenu->getChildren()); - return $view->render(); + return $view->render('ToolbarItems/HelpToolbarItemDropDown'); } /** * No additional attributes needed. - * - * @return array */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down */ - public function hasDropDown() + public function hasDropDown(): bool { return true; } /** * Position relative to others - * - * @return int */ - public function getIndex() + public function getIndex(): int { return 70; } - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView + protected function getFluidTemplateObject(): BackendTemplateView { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']); - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Backend'); + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); return $view; } } diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/LiveSearchToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/LiveSearchToolbarItem.php index 65fa3062e5debb6c7a85d020bcb565d623b5ae71..260bf1a0dcf317f74916e8f08494e8ca949b9eab 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/LiveSearchToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/LiveSearchToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -17,113 +19,71 @@ namespace TYPO3\CMS\Backend\Backend\ToolbarItems; use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; -use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** * Adds backend live search to the toolbar by adding JavaScript and adding an input search field */ class LiveSearchToolbarItem implements ToolbarItemInterface { - /** - * Loads the needed JavaScript file, ands includes it to the page renderer - */ - public function __construct() - { - $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/LiveSearch'); + protected BackendModuleRepository $backendModuleRepository; + + public function __construct( + BackendModuleRepository $backendModuleRepository + ) { + $this->backendModuleRepository = $backendModuleRepository; } /** - * Checks whether the user has access to this toolbar item, - * only allowed when the list module is available. - * Live search is heavily dependent on the list module and only available when that module is. - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. + * Live search depends on the list module and only available when that module is allowed. */ - public function checkAccess() + public function checkAccess(): bool { - $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class); - $listModule = $backendModuleRepository->findByModuleName('web_list'); + $listModule = $this->backendModuleRepository->findByModuleName('web_list'); return $listModule !== null && $listModule !== false; } /** - * Render search field - * - * @return string Live search form HTML + * Render search field. */ - public function getItem() + public function getItem(): string { - return $this->getFluidTemplateObject('LiveSearchToolbarItem.html')->render(); + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); + return $view->render('ToolbarItems/LiveSearchToolbarItem'); } /** - * This item needs to additional attributes - * - * @return array + * This item needs additional attributes. */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return ['class' => 'toolbar-item-search t3js-toolbar-item-search']; } /** - * This item has no drop down - * - * @return bool + * This item has no drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return false; } /** - * No drop down here - * - * @return string + * No drop-down here. */ - public function getDropDown() + public function getDropDown(): string { return ''; } /** - * Position relative to others, live search should be very right - * - * @return int + * Position relative to others, live search should be very right. */ - public function getIndex() + public function getIndex(): int { return 90; } - - /** - * Returns current PageRenderer - * - * @return PageRenderer - */ - protected function getPageRenderer() - { - return GeneralUtility::makeInstance(PageRenderer::class); - } - - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView - { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']); - - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Backend'); - return $view; - } } diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php index df49a0b0f4a5fdcaf520312084cab21471a9c032..6eda674fa7827972cfb894d33eb0b0fd67d10d5d 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -17,85 +19,57 @@ namespace TYPO3\CMS\Backend\Backend\ToolbarItems; use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; -use TYPO3\CMS\Core\Page\PageRenderer; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * Class to render the shortcut menu + * Class to render the shortcut menu toolbar. * * @internal This class is a specific Backend implementation and is not considered part of the Public TYPO3 API. */ class ShortcutToolbarItem implements ToolbarItemInterface { - /** - * @var ShortcutRepository - */ - protected $shortcutRepository; - - /** - * Constructor - */ - public function __construct() - { - $this->shortcutRepository = GeneralUtility::makeInstance(ShortcutRepository::class); + protected ShortcutRepository $shortcutRepository; - $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/ShortcutMenu'); - $languageService = $this->getLanguageService(); - $languageFile = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf'; - $pageRenderer->addInlineLanguageLabelArray([ - 'bookmark.delete' => $languageService->sL($languageFile . ':toolbarItems.bookmarksDelete'), - 'bookmark.confirmDelete' => $languageService->sL($languageFile . ':toolbarItems.confirmBookmarksDelete'), - 'bookmark.create' => $languageService->sL($languageFile . ':toolbarItems.createBookmark'), - 'bookmark.savedTitle' => $languageService->sL($languageFile . ':toolbarItems.bookmarkSavedTitle'), - 'bookmark.savedMessage' => $languageService->sL($languageFile . ':toolbarItems.bookmarkSavedMessage'), - ]); + public function __construct( + ShortcutRepository $shortcutRepository + ) { + $this->shortcutRepository = $shortcutRepository; } /** - * Checks whether the user has access to this toolbar item - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. */ - public function checkAccess() + public function checkAccess(): bool { return (bool)($this->getBackendUser()->getTSConfig()['options.']['enableBookmarks'] ?? false); } /** - * Render shortcut icon - * - * @return string HTML - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException - * @throws \InvalidArgumentException + * Render shortcut icon. */ - public function getItem() + public function getItem(): string { - return $this->getFluidTemplateObject('Item.html')->render(); + return $this->getFluidTemplateObject()->render('ToolbarItems/ShortcutToolbarItemItem'); } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return true; } /** - * Render drop down content - * - * @return string HTML + * Render drop-down content */ - public function getDropDown() + public function getDropDown(): string { $shortcutMenu = []; $groups = $this->shortcutRepository->getGroupsFromShortcuts(); arsort($groups, SORT_NUMERIC); - foreach ($groups as $groupId => $groupLabel) { $shortcutMenu[] = [ 'id' => (int)$groupId, @@ -103,69 +77,36 @@ class ShortcutToolbarItem implements ToolbarItemInterface 'shortcuts' => $this->shortcutRepository->getShortcutsByGroup($groupId), ]; } - - $dropDownView = $this->getFluidTemplateObject('DropDown.html'); + $dropDownView = $this->getFluidTemplateObject(); $dropDownView->assign('shortcutMenu', $shortcutMenu); - - return $dropDownView->render(); + return $dropDownView->render('ToolbarItems/ShortcutToolbarItemDropDown'); } /** - * This toolbar item needs no additional attributes - * - * @return array + * This toolbar item needs no additional attributes. */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** - * Position relative to others, live search should be very right - * - * @return int + * Position relative to others. */ - public function getIndex() + public function getIndex(): int { return 20; } - /** - * returns a new standalone view, shorthand function - * - * @param string $templateFilename - * @return StandaloneView - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException - * @throws \InvalidArgumentException - * @internal param string $templateFile - */ - protected function getFluidTemplateObject(string $templateFilename): StandaloneView + protected function getFluidTemplateObject(): BackendTemplateView { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ShortcutToolbarItem']); - $view->setTemplate($templateFilename); - $view->getRequest()->setControllerExtensionName('Backend'); - + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); return $view; } - /** - * Returns the current BE user. - * - * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication - */ - protected function getBackendUser() + protected function getBackendUser(): BackendUserAuthentication { return $GLOBALS['BE_USER']; } - - /** - * @return \TYPO3\CMS\Core\Localization\LanguageService - */ - protected function getLanguageService() - { - return $GLOBALS['LANG']; - } } diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/SystemInformationToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/SystemInformationToolbarItem.php index 6de73fb57c85c2539aaf3cd7740c265be354f1b4..b28b7835e5636642454e6fdb379cf1bfcc626605 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/SystemInformationToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/SystemInformationToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -20,72 +22,40 @@ use TYPO3\CMS\Backend\Backend\Event\SystemInformationToolbarCollectorEvent; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Localization\LanguageService; -use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Routing\RouteNotFoundException; use TYPO3\CMS\Core\Utility\CommandUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * Render system info toolbar item + * Render system information toolbar item and drop-down. + * Provides some events for other extensions to add information. */ class SystemInformationToolbarItem implements ToolbarItemInterface { - /** - * Number displayed as badge on the dropdown trigger - * - * @var int - */ - protected $totalCount = 0; - - /** - * Holds the highest severity - * - * @var InformationStatus - */ - protected $highestSeverity; - - /** - * The CSS class for the badge - * - * @var string - */ - protected $severityBadgeClass = ''; - - /** - * @var array - */ - protected $systemInformation = []; - - /** - * @var array - */ - protected $systemMessages = []; - - /** - * @var EventDispatcherInterface - */ - protected $eventDispatcher; - - /** - * @var int - */ - protected $maximumCountInBadge = 99; - - /** - * @var Typo3Version - */ - protected $typo3Version; - - public function __construct(EventDispatcherInterface $eventDispatcher = null) - { - $this->eventDispatcher = $eventDispatcher ?? GeneralUtility::getContainer()->get(EventDispatcherInterface::class); - $this->typo3Version = GeneralUtility::makeInstance(Typo3Version::class); - $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/SystemInformationMenu'); + protected array $systemInformation = []; + protected InformationStatus $highestSeverity; + protected string $severityBadgeClass = ''; + protected array $systemMessages = []; + protected int $systemMessageTotalCount = 0; + + protected EventDispatcherInterface $eventDispatcher; + protected Typo3Version $typo3Version; + protected UriBuilder $uriBuilder; + + public function __construct( + EventDispatcherInterface $eventDispatcher, + Typo3Version $typo3Version, + UriBuilder $uriBuilder + ) { + $this->eventDispatcher = $eventDispatcher; + $this->typo3Version = $typo3Version; + $this->uriBuilder = $uriBuilder; $this->highestSeverity = InformationStatus::cast(InformationStatus::STATUS_INFO); } @@ -99,17 +69,15 @@ class SystemInformationToolbarItem implements ToolbarItemInterface * @param string $module The associated module * @param string $params Query string with additional parameters */ - public function addSystemMessage($text, $status = InformationStatus::STATUS_OK, $count = 0, $module = '', $params = '') + public function addSystemMessage($text, $status = InformationStatus::STATUS_OK, $count = 0, $module = '', $params = ''): void { - $this->totalCount += (int)$count; - + $this->systemMessageTotalCount += (int)$count; /** @var InformationStatus $messageSeverity */ $messageSeverity = InformationStatus::cast($status); // define the severity for the badge if ($messageSeverity->isGreaterThan($this->highestSeverity)) { $this->highestSeverity = $messageSeverity; } - $this->systemMessages[] = [ 'module' => $module, 'params' => $params, @@ -123,12 +91,12 @@ class SystemInformationToolbarItem implements ToolbarItemInterface * Add a system information. * This is a callback method for signal receivers. * - * @param string $title The title of this system information + * @param string $title The title of this system information, typically a LLL:EXT:... label string * @param string $value The associated value * @param string $iconIdentifier The icon identifier * @param string $status The status of this system information */ - public function addSystemInformation($title, $value, $iconIdentifier, $status = InformationStatus::STATUS_NOTICE) + public function addSystemInformation($title, $value, $iconIdentifier, $status = InformationStatus::STATUS_NOTICE): void { $this->systemInformation[] = [ 'title' => $title, @@ -139,111 +107,89 @@ class SystemInformationToolbarItem implements ToolbarItemInterface } /** - * Checks whether the user has access to this toolbar item - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. */ - public function checkAccess() + public function checkAccess(): bool { return $this->getBackendUserAuthentication()->isAdmin(); } /** - * Render system information dropdown - * - * @return string Icon HTML + * Render system information dropdown. */ - public function getItem() + public function getItem(): string { - return $this->getFluidTemplateObject('SystemInformationToolbarItem.html')->render(); + return $this->getFluidTemplateObject()->render('ToolbarItems/SystemInformationToolbarItem'); } /** - * Render drop down - * - * @return string Drop down HTML + * Render drop-down */ - public function getDropDown() + public function getDropDown(): string { if (!$this->checkAccess()) { return ''; } - $this->collectInformation(); - - $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - $view = $this->getFluidTemplateObject('SystemInformationDropDown.html'); - try { - $environmentToolUrl = (string)$uriBuilder->buildUriFromRoute('tools_toolsenvironment'); + $environmentToolUrl = (string)$this->uriBuilder->buildUriFromRoute('tools_toolsenvironment'); } catch (RouteNotFoundException $e) { $environmentToolUrl = ''; } - + $view = $this->getFluidTemplateObject(); $view->assignMultiple([ 'environmentToolUrl' => $environmentToolUrl, 'messages' => $this->systemMessages, - 'count' => $this->totalCount > $this->maximumCountInBadge ? $this->maximumCountInBadge . '+' : $this->totalCount, + 'count' => $this->systemMessageTotalCount > 99 ? '99+' : $this->systemMessageTotalCount, 'severityBadgeClass' => $this->severityBadgeClass, 'systemInformation' => $this->systemInformation, ]); - return $view->render(); + return $view->render('ToolbarItems/SystemInformationDropDown'); } /** * No additional attributes needed. - * - * @return array */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return true; } /** * Position relative to others - * - * @return int */ - public function getIndex() + public function getIndex(): int { return 75; } /** - * Collect the information for the menu + * Collect the information for the drop-down. */ - protected function collectInformation() + protected function collectInformation(): void { - $this->getTypo3Version(); - $this->getWebServer(); - $this->getPhpVersion(); - $this->getDebugger(); - $this->getDatabase(); - $this->getApplicationContext(); - $this->getComposerMode(); - $this->getGitRevision(); - $this->getOperatingSystem(); - + $this->addTypo3Version(); + $this->addWebServer(); + $this->addPhpVersion(); + $this->addDebugger(); + $this->addDatabase(); + $this->addApplicationContext(); + $this->addComposerMode(); + $this->addGitRevision(); + $this->addOperatingSystem(); $this->eventDispatcher->dispatch(new SystemInformationToolbarCollectorEvent($this)); - $this->severityBadgeClass = !$this->highestSeverity->equals(InformationStatus::STATUS_NOTICE) ? 'badge-' . (string)$this->highestSeverity : ''; } - /** - * Gets the TYPO3 version - */ - protected function getTypo3Version() + protected function addTypo3Version(): void { $this->systemInformation[] = [ 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.typo3-version', @@ -252,22 +198,16 @@ class SystemInformationToolbarItem implements ToolbarItemInterface ]; } - /** - * Gets the webserver software - */ - protected function getWebServer() + protected function addWebServer(): void { $this->systemInformation[] = [ 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.webserver', - 'value' => $_SERVER['SERVER_SOFTWARE'], + 'value' => $_SERVER['SERVER_SOFTWARE'] ?? '', 'iconIdentifier' => 'information-webserver', ]; } - /** - * Gets the PHP version - */ - protected function getPhpVersion() + protected function addPhpVersion(): void { $this->systemInformation[] = [ 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.phpversion', @@ -276,7 +216,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface ]; } - protected function getDebugger(): void + protected function addDebugger(): void { $knownDebuggers = ['xdebug', 'Zend Debugger']; foreach ($knownDebuggers as $debugger) { @@ -291,10 +231,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface } } - /** - * Get the database info - */ - protected function getDatabase() + protected function addDatabase(): void { foreach (GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionNames() as $connectionName) { $serverVersion = '[' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.database.offline') . ']'; @@ -316,10 +253,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface } } - /** - * Gets the application context - */ - protected function getApplicationContext() + protected function addApplicationContext(): void { $applicationContext = Environment::getContext(); $this->systemInformation[] = [ @@ -333,12 +267,11 @@ class SystemInformationToolbarItem implements ToolbarItemInterface /** * Adds the information if the Composer mode is enabled or disabled to the displayed system information */ - protected function getComposerMode() + protected function addComposerMode(): void { if (!Environment::isComposerMode()) { return; } - $this->systemInformation[] = [ 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.composerMode', 'value' => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.enabled'), @@ -349,7 +282,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface /** * Gets the current GIT revision and branch */ - protected function getGitRevision() + protected function addGitRevision(): void { if (!str_ends_with($this->typo3Version->getVersion(), '-dev') || $this->isFunctionDisabled('exec')) { return; @@ -375,7 +308,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface /** * Gets the system kernel and version */ - protected function getOperatingSystem() + protected function addOperatingSystem(): void { switch (PHP_OS_FAMILY) { case 'Linux': @@ -398,29 +331,7 @@ class SystemInformationToolbarItem implements ToolbarItemInterface } /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView - { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']); - - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Backend'); - return $view; - } - - /** - * Check if the given PHP function is disabled in the system - * - * @param string $functionName - * @return bool + * Check if the given PHP function is disabled in the system. */ protected function isFunctionDisabled(string $functionName): bool { @@ -431,31 +342,22 @@ class SystemInformationToolbarItem implements ToolbarItemInterface return false; } - /** - * Returns the current BE user. - * - * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication - */ - protected function getBackendUserAuthentication() + protected function getFluidTemplateObject(): BackendTemplateView { - return $GLOBALS['BE_USER']; + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); + $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); + return $view; } - /** - * @return LanguageService|null - */ - protected function getLanguageService(): ?LanguageService + protected function getBackendUserAuthentication(): BackendUserAuthentication { - return $GLOBALS['LANG'] ?? null; + return $GLOBALS['BE_USER']; } - /** - * Returns current PageRenderer - * - * @return PageRenderer - */ - protected function getPageRenderer() + protected function getLanguageService(): LanguageService { - return GeneralUtility::makeInstance(PageRenderer::class); + return $GLOBALS['LANG']; } } diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/UserToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/UserToolbarItem.php index 7935648692b5f5086e01e04d1a0cadc110ddefd5..dfb22917506475132ca2e88accbb1ef781c4caac 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/UserToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/UserToolbarItem.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -16,60 +18,56 @@ namespace TYPO3\CMS\Backend\Backend\ToolbarItems; use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository; -use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; -use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * User toolbar item + * User toolbar item and drop-down. * * @internal This class is a specific Backend implementation and is not considered part of the Public TYPO3 API. */ class UserToolbarItem implements ToolbarItemInterface { + protected BackendModuleRepository $backendModuleRepository; + + public function __construct(BackendModuleRepository $backendModuleRepository) + { + $this->backendModuleRepository = $backendModuleRepository; + } + /** - * Item is always enabled - * - * @return bool TRUE + * Item is always enabled. */ - public function checkAccess() + public function checkAccess(): bool { return true; } /** - * Render username and an icon - * - * @return string HTML + * Render username and an icon. */ - public function getItem() + public function getItem(): string { $backendUser = $this->getBackendUser(); - $view = $this->getFluidTemplateObject('UserToolbarItem.html'); + $view = $this->getFluidTemplateObject(); $view->assignMultiple([ 'currentUser' => $backendUser->user, 'switchUserMode' => (int)$backendUser->getOriginalUserIdWhenInSwitchUserMode(), ]); - return $view->render(); + return $view->render('ToolbarItems/UserToolbarItem'); } /** - * Render drop down - * - * @return string HTML + * Render drop-down content. */ - public function getDropDown() + public function getDropDown(): string { $backendUser = $this->getBackendUser(); - /** @var BackendModuleRepository $backendModuleRepository */ - $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class); - $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - $mostRecentUsers = []; if ($backendUser->isAdmin() && $backendUser->getOriginalUserIdWhenInSwitchUserMode() === null @@ -103,29 +101,23 @@ class UserToolbarItem implements ToolbarItemInterface } } - GeneralUtility::makeInstance(PageRenderer::class) - ->loadRequireJsModule('TYPO3/CMS/Backend/SwitchUser'); - $modules = null; - if ($userModule = $backendModuleRepository->findByModuleName('user')) { + if ($userModule = $this->backendModuleRepository->findByModuleName('user')) { $modules = $userModule->getChildren(); } - $view = $this->getFluidTemplateObject('UserToolbarItemDropDown.html'); + $view = $this->getFluidTemplateObject(); $view->assignMultiple([ 'modules' => $modules, - 'logoutUrl' => (string)$uriBuilder->buildUriFromRoute('logout'), 'switchUserMode' => $this->getBackendUser()->getOriginalUserIdWhenInSwitchUserMode() !== null, 'recentUsers' => $mostRecentUsers, ]); - return $view->render(); + return $view->render('ToolbarItems/UserToolbarItemDropDown'); } /** - * Returns an additional class if user is in "switch user" mode - * - * @return array + * Returns an additional class if user is in "switch user" mode. */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { $result = [ 'class' => 'toolbar-item-user', @@ -137,52 +129,30 @@ class UserToolbarItem implements ToolbarItemInterface } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return true; } /** - * Position relative to others - * - * @return int + * Position relative to others. */ - public function getIndex() + public function getIndex(): int { return 80; } - /** - * Returns the current BE user. - * - * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication - */ - protected function getBackendUser() + protected function getBackendUser(): BackendUserAuthentication { return $GLOBALS['BE_USER']; } - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView + protected function getFluidTemplateObject(): BackendTemplateView { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); - $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/ToolbarItems']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ToolbarItems']); - - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Backend'); + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); return $view; } } diff --git a/typo3/sysext/backend/Classes/Controller/ShortcutController.php b/typo3/sysext/backend/Classes/Controller/ShortcutController.php index a2956f310e53b83d42da163825bf6c9ac365a271..fbdbf603382a5d23455f7bfa3da522c0aba420eb 100644 --- a/typo3/sysext/backend/Classes/Controller/ShortcutController.php +++ b/typo3/sysext/backend/Classes/Controller/ShortcutController.php @@ -25,47 +25,34 @@ use TYPO3\CMS\Backend\Module\ModuleLoader; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\JsonResponse; -use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; /** - * Controller for shortcut processing + * Controller for shortcut processing. + * * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API. */ class ShortcutController { - /** - * @var ShortcutToolbarItem - */ - protected $shortcutToolbarItem; - - /** - * @var ShortcutRepository - */ - protected $shortcutRepository; - - /** - * @var ModuleLoader - */ - protected $moduleLoader; - - /** - * Set up dependencies - */ - public function __construct() - { - $this->shortcutToolbarItem = GeneralUtility::makeInstance(ShortcutToolbarItem::class); - $this->shortcutRepository = GeneralUtility::makeInstance(ShortcutRepository::class); + protected ShortcutToolbarItem $shortcutToolbarItem; + protected ShortcutRepository $shortcutRepository; + protected ModuleLoader $moduleLoader; + + public function __construct( + ShortcutToolbarItem $shortcutToolbarItem, + ShortcutRepository $shortcutRepository, + ModuleLoader $moduleLoader + ) { + $this->shortcutToolbarItem = $shortcutToolbarItem; + $this->shortcutRepository = $shortcutRepository; // Needed to get the correct icons when reloading the menu after saving it - $this->moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); - $this->moduleLoader->load($GLOBALS['TBE_MODULES']); + $moduleLoader->load($GLOBALS['TBE_MODULES']); + $this->moduleLoader = $moduleLoader; } /** - * Renders the menu so that it can be returned as response to an AJAX call - * - * @return ResponseInterface + * Renders the menu so that it can be returned as response to an AJAX call. */ public function menuAction(): ResponseInterface { @@ -73,19 +60,14 @@ class ShortcutController } /** - * Creates a shortcut through an AJAX call - * - * @param ServerRequestInterface $request - * @return ResponseInterface + * Creates a shortcut through an AJAX call. */ public function addAction(ServerRequestInterface $request): ResponseInterface { $result = 'success'; $parsedBody = $request->getParsedBody(); - $queryParams = $request->getQueryParams(); - $routeIdentifier = $parsedBody['routeIdentifier'] ?? $queryParams['routeIdentifier'] ?? ''; - $arguments = $parsedBody['arguments'] ?? $queryParams['arguments'] ?? ''; - + $routeIdentifier = $parsedBody['routeIdentifier'] ?? ''; + $arguments = $parsedBody['arguments'] ?? ''; if ($routeIdentifier === '') { $result = 'missingRoute'; } elseif ($this->shortcutRepository->shortcutExists($routeIdentifier, $arguments)) { @@ -97,105 +79,63 @@ class ShortcutController $result = 'failed'; } } - return new HtmlResponse($result); } /** - * Fetches the available shortcut groups, renders a form so it can be saved later on, called via AJAX - * - * @param ServerRequestInterface $request - * @return ResponseInterface the full HTML for the form + * Fetches the available shortcut groups, renders a form so it can be saved later on, called via AJAX. */ public function showEditFormAction(ServerRequestInterface $request): ResponseInterface { - $parsedBody = $request->getParsedBody(); $queryParams = $request->getQueryParams(); - - $selectedShortcutId = (int)($parsedBody['shortcutId'] ?? $queryParams['shortcutId']); - $selectedShortcutGroupId = (int)($parsedBody['shortcutGroup'] ?? $queryParams['shortcutGroup']); + $selectedShortcutId = (int)($queryParams['shortcutId'] ?? 0); + $selectedShortcutGroupId = (int)($queryParams['shortcutGroup'] ?? ''); $selectedShortcut = $this->shortcutRepository->getShortcutById($selectedShortcutId); $shortcutGroups = $this->shortcutRepository->getShortcutGroups(); - - $editFormView = $this->getFluidTemplateObject('EditForm.html'); - $editFormView->assign('selectedShortcutId', $selectedShortcutId); - $editFormView->assign('selectedShortcutGroupId', $selectedShortcutGroupId); - $editFormView->assign('selectedShortcut', $selectedShortcut); - $editFormView->assign('shortcutGroups', $shortcutGroups); - - return new HtmlResponse($editFormView->render()); + $editFormView = $this->getFluidTemplateObject(); + $editFormView->assignMultiple([ + 'selectedShortcutId' => $selectedShortcutId, + 'selectedShortcutGroupId' => $selectedShortcutGroupId, + 'selectedShortcut' => $selectedShortcut, + 'shortcutGroups' => $shortcutGroups, + ]); + return new HtmlResponse($editFormView->render('ToolbarItems/ShortcutToolbarItemEditForm')); } /** * Gets called when a shortcut is changed, checks whether the user has - * permissions to do so and saves the changes if everything is ok - * - * @param ServerRequestInterface $request - * @return ResponseInterface + * permissions to do so and saves the changes if everything is ok. */ public function updateAction(ServerRequestInterface $request): ResponseInterface { $parsedBody = $request->getParsedBody(); - $queryParams = $request->getQueryParams(); - $shortcutId = (int)($parsedBody['shortcutId'] ?? $queryParams['shortcutId'] ?? 0); - $shortcutTitle = strip_tags($parsedBody['shortcutTitle'] ?? $queryParams['shortcutTitle'] ?? ''); - $shortcutGroupId = (int)($parsedBody['shortcutGroup'] ?? $queryParams['shortcutGroup'] ?? 0); - + $shortcutId = (int)($parsedBody['shortcutId'] ?? 0); + $shortcutTitle = strip_tags($parsedBody['shortcutTitle'] ?? ''); + $shortcutGroupId = (int)($parsedBody['shortcutGroup'] ?? 0); $success = $this->shortcutRepository->updateShortcut($shortcutId, $shortcutTitle, $shortcutGroupId); - return new HtmlResponse($success ? $shortcutTitle : 'failed'); } /** - * Deletes a shortcut through an AJAX call - * - * @param ServerRequestInterface $request - * @return ResponseInterface + * Deletes a shortcut through an AJAX call. */ public function removeAction(ServerRequestInterface $request): ResponseInterface { - $parsedBody = $request->getParsedBody(); - $queryParams = $request->getQueryParams(); - $shortcutId = (int)($parsedBody['shortcutId'] ?? $queryParams['shortcutId'] ?? 0); - $success = $this->shortcutRepository->removeShortcut($shortcutId); - + $success = $this->shortcutRepository->removeShortcut((int)($request->getParsedBody()['shortcutId'] ?? 0)); return new JsonResponse(['success' => $success]); } - /** - * returns a new standalone view, shorthand function - * - * @param string $templateFilename - * @return StandaloneView - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException - * @throws \InvalidArgumentException - * @internal param string $templateFile - */ - protected function getFluidTemplateObject(string $templateFilename): StandaloneView + protected function getFluidTemplateObject(): BackendTemplateView { - $view = GeneralUtility::makeInstance(StandaloneView::class); + $view = GeneralUtility::makeInstance(BackendTemplateView::class); $view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']); $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); - $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates/ShortcutToolbarItem']); - $view->setTemplate($templateFilename); - $view->getRequest()->setControllerExtensionName('Backend'); - + $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); return $view; } - /** - * @return BackendUserAuthentication - */ protected function getBackendUser(): BackendUserAuthentication { return $GLOBALS['BE_USER']; } - - /** - * @return LanguageService - */ - protected function getLanguageService(): LanguageService - { - return $GLOBALS['LANG']; - } } diff --git a/typo3/sysext/backend/Classes/Controller/SystemInformationController.php b/typo3/sysext/backend/Classes/Controller/SystemInformationController.php index 9953cac874dc359f4eb4e9bc01c341b9f7bd105c..c268293606adf95e1a51b932760bdafe7b983468 100644 --- a/typo3/sysext/backend/Classes/Controller/SystemInformationController.php +++ b/typo3/sysext/backend/Classes/Controller/SystemInformationController.php @@ -20,22 +20,27 @@ namespace TYPO3\CMS\Backend\Controller; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Backend\Backend\ToolbarItems\SystemInformationToolbarItem; use TYPO3\CMS\Core\Http\HtmlResponse; -use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * Controller for system information processing + * Controller for system information processing. Used as ajax end point to update drop down + * * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API. */ class SystemInformationController { + protected SystemInformationToolbarItem $systemInformationToolbarItem; + + public function __construct( + SystemInformationToolbarItem $systemInformationToolbarItem + ) { + $this->systemInformationToolbarItem = $systemInformationToolbarItem; + } + /** * Renders the menu for AJAX calls - * - * @return ResponseInterface */ public function renderMenuAction(): ResponseInterface { - $toolbarItem = GeneralUtility::makeInstance(SystemInformationToolbarItem::class); - return new HtmlResponse($toolbarItem->getDropDown()); + return new HtmlResponse($this->systemInformationToolbarItem->getDropDown()); } } diff --git a/typo3/sysext/backend/Configuration/Services.yaml b/typo3/sysext/backend/Configuration/Services.yaml index 76eec43cec4ea631b449a349f6d7ef589718d4dc..9d65a530a3d1486a21c54afd93676c1055f1cfab 100644 --- a/typo3/sysext/backend/Configuration/Services.yaml +++ b/typo3/sysext/backend/Configuration/Services.yaml @@ -34,6 +34,9 @@ services: arguments: - !tagged_iterator backend.contextmenu.itemprovider + TYPO3\CMS\Backend\Module\ModuleLoader: + public: true + TYPO3\CMS\Backend\Template\ModuleTemplate: shared: false public: true @@ -108,9 +111,15 @@ services: TYPO3\CMS\Backend\Controller\SiteConfigurationController: tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\ShortcutController: + tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\SwitchUserController: tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\SystemInformationController: + tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\ColumnSelectorController: tags: ['backend.controller'] @@ -151,6 +160,12 @@ services: TYPO3\CMS\Backend\Backend\ToolbarItems\ClearCacheToolbarItem: public: true + TYPO3\CMS\Backend\Backend\ToolbarItems\ShortcutToolbarItem: + public: true + + TYPO3\CMS\Backend\Backend\ToolbarItems\SystemInformationToolbarItem: + public: true + TYPO3\CMS\Backend\Tree\View\ContentCreationPagePositionMap: public: true diff --git a/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html b/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html deleted file mode 100644 index 0d129901c8d8c7d37237496a616b8fa45f23aef3..0000000000000000000000000000000000000000 --- a/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html +++ /dev/null @@ -1,28 +0,0 @@ -<div class="dropdown-table-row t3js-topbar-shortcut" data-shortcutid="{shortcut.raw.uid}" data-shortcutgroup="{group.id}"> - <div class="dropdown-table-column dropdown-table-title"> - <a href="{shortcut.href}" class="dropdown-table-title-ellipsis t3js-shortcut-jump" data-module="{shortcut.module}" data-route="{shortcut.route}" data-pageid="{shortcut.pageId}"> - <span title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.shortcut')}"> - <f:format.raw>{shortcut.icon}</f:format.raw> - </span> - {shortcut.label} - </a> - </div> - <div class="dropdown-table-column dropdown-table-actions"> - <f:render section="Edit"/> - <f:render section="Delete"/> - </div> -</div> - -<f:section name="Edit"> - <a href="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-edit t3js-shortcut-edit" - title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')}"> - <core:icon identifier="actions-open" alternativeMarkupIdentifier="inline"/> - </a> -</f:section> - -<f:section name="Delete"> - <a href="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-delete t3js-shortcut-delete" - title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksDelete')}"> - <core:icon identifier="actions-delete" alternativeMarkupIdentifier="inline"/> - </a> -</f:section> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html deleted file mode 100644 index 751da5fdf42495b4e7fea43bf40201c83791b189..0000000000000000000000000000000000000000 --- a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html +++ /dev/null @@ -1,32 +0,0 @@ -<h3 class="dropdown-headline"> - {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')} -</h3> -<hr> -<f:if condition="{f:count(subject: '{shortcutMenu}')} == 0"> - <f:then> - <f:render section="helpMessage"/> - </f:then> - <f:else> - <f:for each="{shortcutMenu}" as="group" iteration="iterator"> - <f:if condition="!{iterator.isFirst}"> - <hr> - </f:if> - <f:if condition="{group.title}"> - <h3 class="dropdown-headline" id="shortcut-group-{group.id}">{group.title}</h3> - </f:if> - <div class="dropdown-table" data-shortcutgroup="{group.id}"> - <f:for each="{group.shortcuts}" as="shortcut"> - <f:render partial="ShortcutToolbarItem/Shortcut" arguments="{group : group, shortcut : shortcut}" /> - </f:for> - </div> - </f:for> - </f:else> -</f:if> - -<f:section name="helpMessage"> - <f:comment>No shortcuts added yet, show a small help message how to add shortcuts</f:comment> - <f:alias - map="{inlineIcon: '{core:icon(identifier: \'actions-system-shortcut-new\', alternativeMarkupIdentifier: \'inline\')}', inlineIconTitle: '{f:translate(key: \'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks\')}'}"> - <p>{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:bookmark_description', arguments:'{0: \'<span title="{inlineIconTitle}">{inlineIcon -> f:format.raw()}</span>\'}') -> f:format.raw()}</p> - </f:alias> -</f:section> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html deleted file mode 100644 index e6d46c3fcb701aef1b8d9386428ac3631e567735..0000000000000000000000000000000000000000 --- a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html +++ /dev/null @@ -1,6 +0,0 @@ -<span class="toolbar-item-icon" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')}"> - <core:icon identifier="apps-toolbar-menu-shortcut" alternativeMarkupIdentifier="inline" /> -</span> -<span class="toolbar-item-title"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks"/> -</span> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItem.html index 8fe0135c35c2b747c92fca198c0f4e36b79c99de..8b307db9fa0968c7a91a9efadc9529b0b8355f63 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItem.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItem.html @@ -1,5 +1,10 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<f:render partial="ToolbarItem" arguments="{ +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/Toolbar/ClearCacheMenu' + }" +/> +<f:render partial="ToolbarItems/ToolbarItem" arguments="{ title: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.clearCache_clearCache', icon: '{core:icon(identifier: \'apps-toolbar-menu-cache\', size: \'small\', alternativeMarkupIdentifier: \'inline\')}' }" /> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItemSingle.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItemSingle.html index c107e85a0a88a434c9e3131609af814aab47cc6f..40242667e832018ad506e4400011728c747a1f5d 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItemSingle.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ClearCacheToolbarItemSingle.html @@ -1,5 +1,10 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/Toolbar/ClearCacheMenu' + }" +/> <a href="{link}" class="toolbar-cache-flush-action toolbar-item-link" title="{f:translate(key: title, default: title)}"> - <f:render partial="ToolbarItem" arguments="{title: title, icon: '{core:icon(identifier: iconIdentifier, size: \'small\')}'}"/> + <f:render partial="ToolbarItems/ToolbarItem" arguments="{title: title, icon: '{core:icon(identifier: iconIdentifier, size: \'small\')}'}"/> </a> </html> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItem.html index d2c928de0c68f17e194b6a0c0ece1acb1c1eb321..9b022209f0f79c510e608c092ffe67ebd823385c 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItem.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItem.html @@ -1,5 +1,5 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<f:render partial="ToolbarItem" arguments="{ +<f:render partial="ToolbarItems/ToolbarItem" arguments="{ title: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.help', icon: '{core:icon(identifier: \'apps-toolbar-menu-help\', size: \'small\', alternativeMarkupIdentifier: \'inline\')}' }" /> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItemDropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItemDropDown.html index 4376cdfa7e37b95c985c892162a48081d942eb39..575025ec078a31447449a863dae583f103a9671b 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItemDropDown.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItemDropDown.html @@ -1,6 +1,6 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <h3 class="dropdown-headline" id="help-dropdown-headline"> - {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.help') -> f:format.raw()} + {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.help')} </h3> <f:if condition="{modules}"> <hr aria-hidden="true"> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/LiveSearchToolbarItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/LiveSearchToolbarItem.html index 441c735f0c9ff56d1ceaa8e17ffb3870a7f10dd0..beb67058b3f1c1b5d1c22269b60c41d40d15347f 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/LiveSearchToolbarItem.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/LiveSearchToolbarItem.html @@ -1,13 +1,24 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/Toolbar/LiveSearch' + }" +/> <form class="t3js-topbar-navigation-search toolbar-item-search-form live-search-wrapper" role="search"> <div class="form-control-holder"> <div class="form-control-icon"> <core:icon identifier="apps-toolbar-menu-search" size="small" alternativeMarkupIdentifier="inline"/> </div> - <input type="search" class="form-control toolbar-item-search-field t3js-topbar-navigation-search-field" - placeholder="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.search') -> f:format.htmlspecialchars()}" - id="live-search-box" aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.searchLabel')}" - autocomplete="off" spellcheck="off" autocapitalize="none"/> + <input + type="search" + class="form-control toolbar-item-search-field t3js-topbar-navigation-search-field" + placeholder="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.search') -> f:format.htmlspecialchars()}" + id="live-search-box" + aria-label="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.searchLabel')}" + autocomplete="off" + spellcheck="off" + autocapitalize="none" + /> </div> </form> <a href="#" class="dropdown-toggle float-lg-end t3js-toolbar-search-dropdowntoggle" data-bs-toggle="dropdown" data-bs-offset="0,-2" aria-expanded="false"></a> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemDropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemDropDown.html new file mode 100644 index 0000000000000000000000000000000000000000..747c8417002bc534cbff727e668dfecd0187da96 --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemDropDown.html @@ -0,0 +1,59 @@ +<h3 class="dropdown-headline"> + {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')} +</h3> +<hr> +<f:if condition="{f:count(subject: '{shortcutMenu}')} == 0"> + <f:then> + <f:comment>No shortcuts added yet, show a small help message how to add shortcuts</f:comment> + <f:alias + map="{inlineIcon: '{core:icon(identifier: \'actions-share-alt\', alternativeMarkupIdentifier: \'inline\')}', inlineIconTitle: '{f:translate(key: \'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks\')}'}"> + <p>{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:bookmark_description', arguments:'{0: \'<span title="{inlineIconTitle}">{inlineIcon -> f:format.raw()}</span>\'}') -> f:format.raw()}</p> + </f:alias> + </f:then> + <f:else> + <f:for each="{shortcutMenu}" as="group" iteration="iterator"> + <f:if condition="!{iterator.isFirst}"> + <hr> + </f:if> + <f:if condition="{group.title}"> + <h3 class="dropdown-headline" id="shortcut-group-{group.id}">{group.title}</h3> + </f:if> + <div class="dropdown-table" data-shortcutgroup="{group.id}"> + <f:for each="{group.shortcuts}" as="shortcut"> + <div class="dropdown-table-row t3js-topbar-shortcut" data-shortcutid="{shortcut.raw.uid}" data-shortcutgroup="{group.id}"> + <div class="dropdown-table-column dropdown-table-title"> + <a + href="{shortcut.href}" + class="dropdown-table-title-ellipsis t3js-shortcut-jump" + data-module="{shortcut.module}" + data-route="{shortcut.route}" + data-pageid="{shortcut.pageId}" + > + <span title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.shortcut')}"> + <f:format.raw>{shortcut.icon}</f:format.raw> + </span> + {shortcut.label} + </a> + </div> + <div class="dropdown-table-column dropdown-table-actions"> + <a + href="#" + class="dropdown-table-actions-btn dropdown-table-actions-btn-edit t3js-shortcut-edit" + title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')}" + > + <core:icon identifier="actions-open" alternativeMarkupIdentifier="inline"/> + </a> + <a + href="#" + class="dropdown-table-actions-btn dropdown-table-actions-btn-delete t3js-shortcut-delete" + title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksDelete')}" + > + <core:icon identifier="actions-delete" alternativeMarkupIdentifier="inline"/> + </a> + </div> + </div> + </f:for> + </div> + </f:for> + </f:else> +</f:if> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemEditForm.html similarity index 100% rename from typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html rename to typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemEditForm.html diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemItem.html new file mode 100644 index 0000000000000000000000000000000000000000..f746bf345ead9c0f1a5d84a6476d3ad0f9831940 --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/ShortcutToolbarItemItem.html @@ -0,0 +1,20 @@ +<html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/Toolbar/ShortcutMenu' + }" + addJsInlineLabels="{ + 'bookmark.delete': 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksDelete', + 'bookmark.confirmDelete': 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.confirmBookmarksDelete', + 'bookmark.create': 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.createBookmark', + 'bookmark.savedTitle': 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarkSavedTitle', + 'bookmark.savedMessage': 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarkSavedMessage' + }" +/> +<span class="toolbar-item-icon" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')}"> + <core:icon identifier="apps-toolbar-menu-shortcut" alternativeMarkupIdentifier="inline" /> +</span> +<span class="toolbar-item-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks"/> +</span> +</html> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationDropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationDropDown.html index 2177ed3bf37555a96f746ece13b9ff755a21b7f7..8613c54ae4ca64fd815fd6377492d7a916f2fd4d 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationDropDown.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationDropDown.html @@ -1,14 +1,16 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<span class="systeminformationtoolbaritem-container t3js-systeminformation-container" data-count="{count}" - data-severityclass="{severityBadgeClass}"></span> +<span + class="systeminformationtoolbaritem-container t3js-systeminformation-container" + data-count="{count}" + data-severityclass="{severityBadgeClass}"></span> <h3 class="dropdown-headline"> - <f:translate key="systemmessage.header"/> + <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang.xlf:systemmessage.header"/> </h3> <f:if condition="{environmentToolUrl}"> <p class="dropdown-text typo3-module-menu-item submodule mod-tools_toolsenvironment" data-modulename="tools_toolsenvironment"> <f:format.raw> - <f:translate key="systemmessage.intro" arguments="{0: environmentToolUrl}"/> + <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang.xlf:systemmessage.intro" arguments="{0: environmentToolUrl}"/> </f:format.raw> </p> </f:if> @@ -63,7 +65,7 @@ <f:else> <p class="dropdown-text text-success"> <f:format.nl2br> - <f:translate key="systemmessage.allgood"/> + <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang.xlf:systemmessage.allgood"/> </f:format.nl2br> </p> </f:else> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationToolbarItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationToolbarItem.html index 82c841e7f50f1a9f094a24e2648384443cb3a060..e4204fce9b57fb78b48a6225a24a3371fe0dfd82 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationToolbarItem.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/SystemInformationToolbarItem.html @@ -1,5 +1,10 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<f:render partial="ToolbarItem" arguments="{ +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/Toolbar/SystemInformationMenu' + }" +/> +<f:render partial="ToolbarItems/ToolbarItem" arguments="{ title: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo', icon: '{core:icon(identifier: \'actions-system-list-open\', size: \'small\', alternativeMarkupIdentifier: \'inline\')}' }" /> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItem.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItem.html index b818cc090d8320f22818876aaed59d1252ec2572..d04bb9e555aacc04a4e3264471a727997dfdb48a 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItem.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItem.html @@ -1,11 +1,12 @@ <html xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers" data-namespace-typo3-fluid="true"> - <span class="toolbar-item-avatar"><be:avatar backendUser="{currentUser.uid}"/></span> <f:if condition="{switchUserMode}"> <f:then> - <span class="toolbar-item-name" - title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:switchtouser')} {currentUser.username}"> - {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:switchtousershort') -> f:format.raw()} + <span + class="toolbar-item-name" + title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:switchtouser')} {currentUser.username}" + > + {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:switchtousershort')} {f:if(condition: '{currentUser.realName}', then: '{currentUser.realName} ({currentUser.username})', else: '{currentUser.username}')} </span> </f:then> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItemDropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItemDropDown.html index a9be67fc2c769a4341d05ee1bfe413e15220bcc1..a66a7769cd21a4f1e4a0d40848e5838e9deecfdb 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItemDropDown.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/UserToolbarItemDropDown.html @@ -1,4 +1,13 @@ -<html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers" data-namespace-typo3-fluid="true"> +<html + xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" + xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers" + data-namespace-typo3-fluid="true" +> +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Backend/SwitchUser' + }" +/> <h3 class="dropdown-headline"> {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.user')} </h3> @@ -26,13 +35,17 @@ <hr> </f:if> <f:if condition="{f:count(subject: recentUsers)} > 0"> - <h3 class="dropdown-headline"><f:translate key="usermodule.su.list" /></h3> + <h3 class="dropdown-headline"><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang.xlf:usermodule.su.list" /></h3> <div class="dropdown-table"> <f:for each="{recentUsers}" as="user"> <div class="dropdown-table-row"> <div class="dropdown-table-column dropdown-table-title"> <typo3-backend-switch-user mode="switch" targetUser="{user.uid}"> - <button type="button" class="modulemenu-action" title="{f:translate(key: 'usermodule.su.tooltip', arguments: '{0: user.username}')}"> + <button + type="button" + class="modulemenu-action" + title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang.xlf:usermodule.su.tooltip', arguments: '{0: user.username}')}" + > <be:avatar backendUser="{user.uid}" size="32" /> {f:if(condition: user.realName, then: user.realName, else: user.username)} </button> </typo3-backend-switch-user> @@ -52,10 +65,10 @@ </typo3-backend-switch-user> </f:then> <f:else> - <a href="{logoutUrl}" class="btn btn-danger pull-left" target="_top"> + <f:be.link route="logout" class="btn btn-danger pull-left" target="_top"> <core:icon identifier="actions-logout" size="small" alternativeMarkupIdentifier="inline"/> {f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:buttons.logout')} - </a> + </f:be.link> </f:else> </f:if> </html> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/LiveSearch.js similarity index 65% rename from typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js rename to typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/LiveSearch.js index 96cb0d0506ae966e57b6c025af4049ca77e50fbd..d4e2d4913eec2fb3453649e87e1c7f42672339b2 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/LiveSearch.js @@ -10,7 +10,7 @@ * * The TYPO3 project - inspiring people to share! */ -var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery","./Viewport","./Icons","lit","lit/directives/unsafe-html","TYPO3/CMS/Core/lit-helper","TYPO3/CMS/Backend/Storage/ModuleStateStorage","jquery/autocomplete","./Input/Clearable"],(function(e,t,l,o,a,r,s,n,i){"use strict";var d;l=__importDefault(l),function(e){e.containerSelector="#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem",e.toolbarItem=".t3js-toolbar-item-search",e.dropdownToggle=".t3js-toolbar-search-dropdowntoggle",e.searchFieldSelector=".t3js-topbar-navigation-search-field",e.formSelector=".t3js-topbar-navigation-search"}(d||(d={}));return new class{constructor(){this.url=TYPO3.settings.ajaxUrls.livesearch,o.Topbar.Toolbar.registerEvent(()=>{let e;this.registerAutocomplete(),this.registerEvents(),(0,l.default)(d.toolbarItem).removeAttr("style"),null!==(e=document.querySelector(d.searchFieldSelector))&&e.clearable({onClear:()=>{(0,l.default)(d.dropdownToggle).hasClass("show")&&(0,l.default)(d.dropdownToggle).dropdown("toggle")}})})}registerAutocomplete(){(0,l.default)(d.searchFieldSelector).autocomplete({serviceUrl:this.url,paramName:"q",dataType:"json",minChars:2,width:"100%",groupBy:"typeLabel",noCache:!0,containerClass:d.toolbarItem.substr(1,d.toolbarItem.length),appendTo:d.containerSelector+" .dropdown-menu",forceFixPosition:!1,preserveInput:!0,showNoSuggestionNotice:!0,triggerSelectOnValidInput:!1,preventBadQueries:!1,noSuggestionNotice:'<h3 class="dropdown-headline">'+TYPO3.lang.liveSearch_listEmptyText+"</h3><p>"+TYPO3.lang.liveSearch_helpTitle+"</p><hr><p>"+TYPO3.lang.liveSearch_helpDescription+"<br>"+TYPO3.lang.liveSearch_helpDescriptionPages+"</p>",transformResult:e=>({suggestions:l.default.map(e,e=>({value:e.title,data:e}))}),formatGroup:(e,t,l)=>(0,n.renderHTML)(r.html` +var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};define(["require","exports","jquery","../Viewport","../Icons","lit","lit/directives/unsafe-html","TYPO3/CMS/Core/lit-helper","TYPO3/CMS/Backend/Storage/ModuleStateStorage","jquery/autocomplete","../Input/Clearable"],(function(e,t,l,o,a,r,s,n,i){"use strict";var d;l=__importDefault(l),function(e){e.containerSelector="#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem",e.toolbarItem=".t3js-toolbar-item-search",e.dropdownToggle=".t3js-toolbar-search-dropdowntoggle",e.searchFieldSelector=".t3js-topbar-navigation-search-field",e.formSelector=".t3js-topbar-navigation-search"}(d||(d={}));return new class{constructor(){this.url=TYPO3.settings.ajaxUrls.livesearch,o.Topbar.Toolbar.registerEvent(()=>{let e;this.registerAutocomplete(),this.registerEvents(),(0,l.default)(d.toolbarItem).removeAttr("style"),null!==(e=document.querySelector(d.searchFieldSelector))&&e.clearable({onClear:()=>{(0,l.default)(d.dropdownToggle).hasClass("show")&&(0,l.default)(d.dropdownToggle).dropdown("toggle")}})})}registerAutocomplete(){(0,l.default)(d.searchFieldSelector).autocomplete({serviceUrl:this.url,paramName:"q",dataType:"json",minChars:2,width:"100%",groupBy:"typeLabel",noCache:!0,containerClass:d.toolbarItem.substr(1,d.toolbarItem.length),appendTo:d.containerSelector+" .dropdown-menu",forceFixPosition:!1,preserveInput:!0,showNoSuggestionNotice:!0,triggerSelectOnValidInput:!1,preventBadQueries:!1,noSuggestionNotice:'<h3 class="dropdown-headline">'+TYPO3.lang.liveSearch_listEmptyText+"</h3><p>"+TYPO3.lang.liveSearch_helpTitle+"</p><hr><p>"+TYPO3.lang.liveSearch_helpDescription+"<br>"+TYPO3.lang.liveSearch_helpDescriptionPages+"</p>",transformResult:e=>({suggestions:l.default.map(e,e=>({value:e.title,data:e}))}),formatGroup:(e,t,l)=>(0,n.renderHTML)(r.html` ${l>0?r.html`<hr>`:""} <h3 class="dropdown-headline">${t}</h3> `),formatResult:e=>(0,n.renderHTML)(r.html` diff --git a/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php index 3ac620928b249f3eadd0576c47b2b6795d76fa12..46152c1ff4d42e8305647399ed80778860797293 100644 --- a/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php +++ b/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php @@ -17,7 +17,10 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\Tests\Functional\Controller; +use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository; +use TYPO3\CMS\Backend\Backend\ToolbarItems\ShortcutToolbarItem; use TYPO3\CMS\Backend\Controller\ShortcutController; +use TYPO3\CMS\Backend\Module\ModuleLoader; use TYPO3\CMS\Core\Core\Bootstrap; use TYPO3\CMS\Core\Http\NormalizedParams; use TYPO3\CMS\Core\Http\ServerRequest; @@ -37,41 +40,31 @@ class ShortcutControllerTest extends FunctionalTestCase $this->setUpBackendUserFromFixture(1); Bootstrap::initializeLanguageObject(); - $this->subject = new ShortcutController(); + $this->subject = new ShortcutController( + $this->getContainer()->get(ShortcutToolbarItem::class), + $this->getContainer()->get(ShortcutRepository::class), + $this->getContainer()->get(ModuleLoader::class) + ); $this->request = (new ServerRequest())->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } /** * @dataProvider addShortcutTestDataProvide * @test - * - * @param array $parsedBody - * @param array $queryParams - * @param string $expectedResponseBody */ - public function addShortcutTest(array $parsedBody, array $queryParams, string $expectedResponseBody): void + public function addShortcutTest(array $parsedBody, string $expectedResponseBody): void { - $request = $this->request->withParsedBody($parsedBody)->withQueryParams($queryParams); + $request = $this->request->withParsedBody($parsedBody); self::assertEquals($expectedResponseBody, $this->subject->addAction($request)->getBody()); } public function addShortcutTestDataProvide(): \Generator { yield 'No route defined' => [ - [], [], 'missingRoute', ]; yield 'Existing data as parsed body' => [ - [ - 'routeIdentifier' => 'web_layout', - 'arguments' => '{"id":"123"}', - ], - [], - 'alreadyExists', - ]; - yield 'Existing data as query parameters' => [ - [], [ 'routeIdentifier' => 'web_layout', 'arguments' => '{"id":"123"}', @@ -79,7 +72,6 @@ class ShortcutControllerTest extends FunctionalTestCase 'alreadyExists', ]; yield 'Invalid route identifier' => [ - [], [ 'routeIdentifier' => 'invalid_route_identifier', ], @@ -90,15 +82,6 @@ class ShortcutControllerTest extends FunctionalTestCase 'routeIdentifier' => 'web_list', 'arguments' => '{"id":"123","GET":{"clipBoard":"1"}}', ], - [], - 'success', - ]; - yield 'New data as query parameters' => [ - [], - [ - 'routeIdentifier' => 'web_list', - 'arguments' => '{"id":"321","GET":{"clipBoard":"1"}}', - ], 'success', ]; } diff --git a/typo3/sysext/belog/Classes/Controller/SystemInformationController.php b/typo3/sysext/belog/Classes/Controller/SystemInformationController.php index 4e70a74e6b0e24c34a8a5b690ad63549d62e9c23..bbd7025564b3a639d7f86114083d5a3c948d2c5c 100644 --- a/typo3/sysext/belog/Classes/Controller/SystemInformationController.php +++ b/typo3/sysext/belog/Classes/Controller/SystemInformationController.php @@ -22,8 +22,8 @@ use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Utility\LocalizationUtility; /** * Count latest exceptions for the system information menu. @@ -71,7 +71,7 @@ final class SystemInformationController $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); $systemInformationToolbarItem->addSystemMessage( sprintf( - LocalizationUtility::translate('systemmessage.errorsInPeriod', 'belog') ?? '', + $this->getLanguageService()->sL('LLL:EXT:belog/Resources/Private/Language/locallang.xlf:systemmessage.errorsInPeriod'), $count, (string)$uriBuilder->buildUriFromRoute( 'system_BelogLog', @@ -98,4 +98,9 @@ final class SystemInformationController return (int)$systemInformationUc['system_BelogLog']['lastAccess']; } + + private function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } } diff --git a/typo3/sysext/core/Resources/Private/Language/locallang_misc.xlf b/typo3/sysext/core/Resources/Private/Language/locallang_misc.xlf index 0dadeeadcca163dead4e2fae69f7a56ae5c9805b..1ec4bb0401e5a345a0b9ed20a262a1a90e371f77 100644 --- a/typo3/sysext/core/Resources/Private/Language/locallang_misc.xlf +++ b/typo3/sysext/core/Resources/Private/Language/locallang_misc.xlf @@ -3,9 +3,6 @@ <file source-language="en" datatype="plaintext" original="EXT:core/Resources/Private/Language/locallang_misc.xlf" date="2011-10-17T20:22:34Z" product-name="lang"> <header/> <body> - <trans-unit id="shortcutDescription" resname="shortcutDescription"> - <source>This is the shortcuts menu. You do not have any shortcuts added yet, you can do so by clicking the shortcut icon %icon%, which you can find on each page in the backend.</source> - </trans-unit> <trans-unit id="shortcut_edit" resname="shortcut_edit"> <source>Edit</source> </trans-unit> @@ -88,7 +85,7 @@ <source>Go to Workspace Module</source> </trans-unit> <trans-unit id="bookmark_description" resname="bookmark_description"> - <source>This is the bookmarks menu. You do not have any bookmarks added yet, you can do so by clicking the bookmark icon %s, which you can find on each page in the backend.</source> + <source>This is the bookmarks menu. You do not have any bookmarks added yet. You can add one by clicking the bookmark icon %s, which you can find on all pages in the backend.</source> </trans-unit> <trans-unit id="bookmark_edit" resname="bookmark_edit"> <source>Edit</source> diff --git a/typo3/sysext/opendocs/Classes/Backend/ToolbarItems/OpendocsToolbarItem.php b/typo3/sysext/opendocs/Classes/Backend/ToolbarItems/OpendocsToolbarItem.php index 40ae5768988a894dc456ba5073eee025ed784925..a83c54cbbea2f4a29dbd4c26df8f7d20e5f1dea4 100644 --- a/typo3/sysext/opendocs/Classes/Backend/ToolbarItems/OpendocsToolbarItem.php +++ b/typo3/sysext/opendocs/Classes/Backend/ToolbarItems/OpendocsToolbarItem.php @@ -23,34 +23,29 @@ use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; use TYPO3\CMS\Opendocs\Service\OpenDocumentService; /** - * Main functionality to render a list of all open documents in the top bar of the TYPO3 Backend + * Main functionality to render a list of all open documents in the top bar of the Backend. + * * @internal This class is a specific hook implementation and is not part of the TYPO3's Core API. */ class OpendocsToolbarItem implements ToolbarItemInterface { - /** - * @var OpenDocumentService - */ - protected $documentService; - - /** - * Set up dependencies - * - * @param OpenDocumentService|null $documentService - */ - public function __construct(OpenDocumentService $documentService = null) - { - $this->documentService = $documentService ?: GeneralUtility::makeInstance(OpenDocumentService::class); + protected OpenDocumentService $documentService; + protected UriBuilder $uriBuilder; + + public function __construct( + OpenDocumentService $documentService, + UriBuilder $uriBuilder + ) { + $this->documentService = $documentService; + $this->uriBuilder = $uriBuilder; } /** - * Checks whether the user has access to this toolbar item - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. */ public function checkAccess(): bool { @@ -59,70 +54,56 @@ class OpendocsToolbarItem implements ToolbarItemInterface /** * Render toolbar icon via Fluid - * - * @return string HTML */ - public function getItem() + public function getItem(): string { - $view = $this->getFluidTemplateObject('ToolbarItem.html'); - - return $view->render(); + $view = $this->getFluidTemplateObject(); + return $view->render('ToolbarItems/ToolbarItem'); } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return true; } /** - * Render drop down via Fluid - * - * @return string HTML + * Render drop-down. */ - public function getDropDown() + public function getDropDown(): string { - $view = $this->getFluidTemplateObject('DropDown.html'); + $view = $this->getFluidTemplateObject(); $view->assignMultiple([ 'openDocuments' => $this->getMenuEntries($this->documentService->getOpenDocuments()), // If there are "recent documents" in the list, add them 'recentDocuments' => $this->getMenuEntries($this->documentService->getRecentDocuments()), ]); - - return $view->render(); + return $view->render('ToolbarItems/DropDown'); } /** * No additional attributes - * - * @return array List of attributes */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** * Position relative to others - * - * @return int */ - public function getIndex() + public function getIndex(): int { return 30; } /** - * Called as a hook in \TYPO3\CMS\Backend\Utility\BackendUtility::getUpdateSignalCode, calls a JS function to change - * the number of opened documents - * - * @param array $params + * Called as a hook in \TYPO3\CMS\Backend\Utility\BackendUtility::getUpdateSignalCode, calls a JS function + * to change the number of opened documents. */ - public function updateNumberOfOpenDocsHook(array &$params) + public function updateNumberOfOpenDocsHook(array &$params): void { $params['html'] = ImmediateActionElement::dispatchCustomEvent( 'typo3:opendocs:updateRequested', @@ -132,23 +113,17 @@ class OpendocsToolbarItem implements ToolbarItemInterface } /** - * Get menu entries for all eligible records - * - * @param array $documents - * @return array + * Get menu entries for all eligible records. */ protected function getMenuEntries(array $documents): array { $entries = []; - foreach ($documents as $identifier => $document) { $menuEntry = $this->getMenuEntry($document, $identifier); - if (!empty($menuEntry)) { $entries[] = $menuEntry; } } - return $entries; } @@ -174,9 +149,7 @@ class OpendocsToolbarItem implements ToolbarItemInterface $result['table'] = $table; $result['record'] = $record; $result['label'] = strip_tags(htmlspecialchars_decode($document[0])); - /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ - $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - $uri = (string)$uriBuilder->buildUriFromRoute('record_edit') . '&' . $document[2]; + $uri = (string)$this->uriBuilder->buildUriFromRoute('record_edit') . '&' . $document[2]; $pid = (int)$document[3]['pid']; if ($document[3]['table'] === 'pages') { @@ -190,30 +163,13 @@ class OpendocsToolbarItem implements ToolbarItemInterface return $result; } - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView + protected function getFluidTemplateObject(): BackendTemplateView { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:opendocs/Resources/Private/Layouts']); - $view->setPartialRootPaths([ - 'EXT:backend/Resources/Private/Partials/ToolbarItems', - 'EXT:opendocs/Resources/Private/Partials/ToolbarItems', - ]); - $view->setTemplateRootPaths(['EXT:opendocs/Resources/Private/Templates/ToolbarItems']); - $view->setTemplate($filename); - $view->getRequest()->setControllerExtensionName('Opendocs'); - + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setTemplateRootPaths(['EXT:opendocs/Resources/Private/Templates']); return $view; } - /** - * @return BackendUserAuthentication - */ protected function getBackendUser(): BackendUserAuthentication { return $GLOBALS['BE_USER']; diff --git a/typo3/sysext/opendocs/Classes/Controller/OpenDocumentController.php b/typo3/sysext/opendocs/Classes/Controller/OpenDocumentController.php index 889f57fb3df4f2e6bf8f6e1ac444d920b6503946..4d15075790d1bb80ced313ec9a514f6c91500221 100644 --- a/typo3/sysext/opendocs/Classes/Controller/OpenDocumentController.php +++ b/typo3/sysext/opendocs/Classes/Controller/OpenDocumentController.php @@ -20,41 +20,30 @@ namespace TYPO3\CMS\Opendocs\Controller; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Http\HtmlResponse; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Opendocs\Backend\ToolbarItems\OpendocsToolbarItem; use TYPO3\CMS\Opendocs\Service\OpenDocumentService; /** - * Controller for documents processing + * Controller for documents processing. + * Contains AJAX endpoints of the open docs toolbar item click actions. * - * Contains AJAX endpoints of the open docs toolbar item click actions * @internal This class is a specific Backend controller implementation and is not part of the TYPO3's Core API. */ class OpenDocumentController { - /** - * @var OpenDocumentService - */ - protected $documents; - - /** - * @var OpendocsToolbarItem - */ - protected $toolbarItem; + protected OpenDocumentService $documents; + protected OpendocsToolbarItem $toolbarItem; - /** - * Set up dependencies - */ - public function __construct() - { - $this->documents = GeneralUtility::makeInstance(OpenDocumentService::class); - $this->toolbarItem = GeneralUtility::makeInstance(OpendocsToolbarItem::class); + public function __construct( + OpenDocumentService $documents, + OpendocsToolbarItem $toolbarItem + ) { + $this->documents = $documents; + $this->toolbarItem = $toolbarItem; } /** - * Renders the menu so that it can be returned as response to an AJAX call - * - * @return ResponseInterface + * Renders the menu so that it can be returned as response to an AJAX call. */ public function renderMenu(): ResponseInterface { @@ -62,21 +51,16 @@ class OpenDocumentController } /** - * Closes a document and returns the updated menu - * - * @param ServerRequestInterface $request - * @return ResponseInterface + * Closes a document and returns the updated menu. */ public function closeDocument(ServerRequestInterface $request): ResponseInterface { $identifier = $request->getParsedBody()['md5sum'] ?? $request->getQueryParams()['md5sum'] ?? null; - if ($identifier) { $this->documents->closeDocument($identifier); } else { $this->documents->closeAllDocuments(); } - return $this->renderMenu(); } } diff --git a/typo3/sysext/opendocs/Configuration/Services.yaml b/typo3/sysext/opendocs/Configuration/Services.yaml index 5e278e80398ddccbf3171dc8af6abfc94cd47f43..c434e41bc61f6fb23f2ef73770459feb3aa86be6 100644 --- a/typo3/sysext/opendocs/Configuration/Services.yaml +++ b/typo3/sysext/opendocs/Configuration/Services.yaml @@ -6,3 +6,9 @@ services: TYPO3\CMS\Opendocs\: resource: '../Classes/*' + + TYPO3\CMS\Opendocs\Backend\ToolbarItems\OpendocsToolbarItem: + public: true + + TYPO3\CMS\Opendocs\Controller\OpenDocumentController: + tags: ['backend.controller'] diff --git a/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/DropDown.html b/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/DropDown.html index 1d8835e993c60bc969467248055ddf61dfcb180f..45cb150b77d606f0649e1a8aeb70935af7fc358a 100644 --- a/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/DropDown.html +++ b/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/DropDown.html @@ -1,21 +1,24 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<f:be.pageRenderer includeRequireJsModules="{0:'TYPO3/CMS/Opendocs/Toolbar/OpendocsMenu'}"/> - +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Opendocs/Toolbar/OpendocsMenu' + }" +/> <h3 class="dropdown-headline"> - {f:translate(key: 'toolbaritem', extensionName: 'opendocs')} + {f:translate(key: 'LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:toolbaritem')} </h3> <hr> <f:if condition="{noDocs}"> <f:then> <p> - <f:translate key="no_docs" extensionName="opendocs"/> + <f:translate key="LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:no_docs" /> </p> </f:then> <f:else> <f:if condition="{openDocuments}"> <h3 class="dropdown-headline"> - <f:translate key="open_docs" extensionName="opendocs"/> + <f:translate key="LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:open_docs" /> <a href="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-close t3js-topbar-opendocs-close pull-right" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.closeAllDocs')}"> <core:icon identifier="actions-close" alternativeMarkupIdentifier="inline"/> @@ -44,7 +47,7 @@ </f:if> <f:if condition="{recentDocuments}"> <h3 class="dropdown-headline"> - <f:translate key="recent_docs" extensionName="opendocs"/> + <f:translate key="LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:recent_docs" /> </h3> <div class="dropdown-table"> <f:for each="{recentDocuments}" as="recentDocument"> diff --git a/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/ToolbarItem.html b/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/ToolbarItem.html index ccdf7cc3c04a3267d87bc7bbe61149d35e774a72..b034e4a52c830857034df9567677b4a92f0cdb23 100644 --- a/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/ToolbarItem.html +++ b/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarItems/ToolbarItem.html @@ -1,7 +1,7 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<span class="toolbar-item-icon" title="{f:translate(key: 'toolbaritem', extensionName: 'opendocs')}"> +<span class="toolbar-item-icon" title="{f:translate(key: 'LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:toolbaritem')}"> <core:icon identifier="apps-toolbar-menu-opendocs" alternativeMarkupIdentifier="inline"/> </span> -<span class="toolbar-item-title">{f:translate(key: 'toolbaritem', extensionName: 'opendocs')}</span> +<span class="toolbar-item-title">{f:translate(key: 'LLL:EXT:opendocs/Resources/Private/Language/locallang.xlf:toolbaritem')}</span> <span class="toolbar-item-badge badge rounded-pill bg-primary" id="tx-opendocs-counter"></span> </html> diff --git a/typo3/sysext/workspaces/Classes/Backend/ToolbarItems/WorkspaceSelectorToolbarItem.php b/typo3/sysext/workspaces/Classes/Backend/ToolbarItems/WorkspaceSelectorToolbarItem.php index b3e33825cba4ed1bb215798220143a4cccd19728..65ac7d85371ca3c195d2ef2a4ee723a49e8bccc5 100644 --- a/typo3/sysext/workspaces/Classes/Backend/ToolbarItems/WorkspaceSelectorToolbarItem.php +++ b/typo3/sysext/workspaces/Classes/Backend/ToolbarItems/WorkspaceSelectorToolbarItem.php @@ -17,9 +17,9 @@ namespace TYPO3\CMS\Workspaces\Backend\ToolbarItems; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface; -use TYPO3\CMS\Core\Page\PageRenderer; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Fluid\View\StandaloneView; +use TYPO3\CMS\Fluid\View\BackendTemplateView; use TYPO3\CMS\Workspaces\Service\WorkspaceService; /** @@ -29,59 +29,45 @@ use TYPO3\CMS\Workspaces\Service\WorkspaceService; */ class WorkspaceSelectorToolbarItem implements ToolbarItemInterface { - /** - * @var array - */ - protected $availableWorkspaces; - - /** - * Constructor - */ - public function __construct() - { - $currentWorkspace = $this->getBackendUser()->workspace; - $this->availableWorkspaces = GeneralUtility::makeInstance(WorkspaceService::class) - ->getAvailableWorkspaces(); + protected array $availableWorkspaces; - $pageRenderer = $this->getPageRenderer(); - $pageRenderer->addInlineLanguageLabel('Workspaces.workspaceTitle', $currentWorkspace !== -99 ? WorkspaceService::getWorkspaceTitle($currentWorkspace) : ''); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Workspaces/Toolbar/WorkspacesMenu'); + public function __construct( + WorkspaceService $workspaceService + ) { + $this->availableWorkspaces = $workspaceService->getAvailableWorkspaces(); } /** - * Checks whether the user has access to this toolbar item - * - * @return bool TRUE if user has access, FALSE if not + * Checks whether the user has access to this toolbar item. */ - public function checkAccess() + public function checkAccess(): bool { return count($this->availableWorkspaces) > 1; } /** - * Render item - * - * @return string HTML + * Render item. */ - public function getItem() + public function getItem(): string { if (empty($this->availableWorkspaces)) { return ''; } - return $this->getFluidTemplateObject('ToolbarItem.html')->render(); + $currentWorkspace = $this->getBackendUser()->workspace; + $view = $this->getFluidTemplateObject(); + $view->assign('workspaceTitle', $currentWorkspace !== -99 ? WorkspaceService::getWorkspaceTitle($currentWorkspace) : ''); + return $this->getFluidTemplateObject()->render('ToolbarItems/ToolbarItem'); } /** - * Get drop down - * - * @return string + * Render drop-down. */ - public function getDropDown() + public function getDropDown(): string { $topItem = null; $additionalItems = []; $backendUser = $this->getBackendUser(); - $view = $this->getFluidTemplateObject('DropDown.html'); + $view = $this->getFluidTemplateObject(); $activeWorkspace = (int)$backendUser->workspace; $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); foreach ($this->availableWorkspaces as $workspaceId => $label) { @@ -98,86 +84,49 @@ class WorkspaceSelectorToolbarItem implements ToolbarItemInterface $additionalItems[] = $item; } } - - // Add the "Go to workspace module" link - // if there is at least one icon on top and if the access rights are there + // Add the "Go to workspace module" link if there is at least one icon on top and if the access rights are there if ($topItem !== null && $backendUser->check('modules', 'web_WorkspacesWorkspaces')) { $view->assign('showLinkToModule', true); } $view->assign('topItem', $topItem); $view->assign('additionalItems', $additionalItems); - return $view->render(); + return $view->render('ToolbarItems/DropDown'); } /** - * This toolbar needs no additional attributes - * - * @return array + * This toolbar needs no additional attributes. */ - public function getAdditionalAttributes() + public function getAdditionalAttributes(): array { return []; } /** - * This item has a drop down - * - * @return bool + * This item has a drop-down. */ - public function hasDropDown() + public function hasDropDown(): bool { return !empty($this->availableWorkspaces); } /** * Position relative to others - * - * @return int */ - public function getIndex() + public function getIndex(): int { return 40; } - /** - * Returns the current BE user. - * - * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication - */ - protected function getBackendUser() - { - return $GLOBALS['BE_USER']; - } - - /** - * Returns current PageRenderer - * - * @return PageRenderer - */ - protected function getPageRenderer() + protected function getFluidTemplateObject(): BackendTemplateView { - return GeneralUtility::makeInstance(PageRenderer::class); + $view = GeneralUtility::makeInstance(BackendTemplateView::class); + $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']); + $view->setTemplateRootPaths(['EXT:workspaces/Resources/Private/Templates']); + return $view; } - /** - * Returns a new standalone view, shorthand function - * - * @param string $filename Which templateFile should be used. - * @return StandaloneView - */ - protected function getFluidTemplateObject(string $filename): StandaloneView + protected function getBackendUser(): BackendUserAuthentication { - $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->setLayoutRootPaths(['EXT:workspaces/Resources/Private/Layouts']); - $view->setPartialRootPaths([ - 'EXT:backend/Resources/Private/Partials/ToolbarItems', - 'EXT:workspaces/Resources/Private/Partials/ToolbarItems', - ]); - $view->setTemplateRootPaths(['EXT:workspaces/Resources/Private/Templates/ToolbarItems']); - - $view->setTemplate($filename); - - $view->getRequest()->setControllerExtensionName('Workspaces'); - return $view; + return $GLOBALS['BE_USER']; } } diff --git a/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/DropDown.html b/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/DropDown.html index 32f8fae633034a8eda85d344602d1b6adab24cd8..b9d646c46ff5e5d642baffcf0037fc46fe44208c 100644 --- a/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/DropDown.html +++ b/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/DropDown.html @@ -37,9 +37,7 @@ </div> <f:if condition="{additionalItems}"> - <hr> - <div class="dropdown-table"> <f:for each="{additionalItems}" as="item"> <f:render section="workspaceItem" arguments="{item: item}" /> diff --git a/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/ToolbarItem.html b/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/ToolbarItem.html index 3742ed55cfab3c7c38da72ba9a22c6bf7982c8b9..d0b0ae4cc3df45e48526cedd97a6f42643035dc3 100644 --- a/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/ToolbarItem.html +++ b/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarItems/ToolbarItem.html @@ -1,5 +1,13 @@ <html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" data-namespace-typo3-fluid="true"> -<f:render partial="ToolbarItem" arguments="{ +<f:be.pageRenderer + includeRequireJsModules="{ + 0: 'TYPO3/CMS/Workspaces/Toolbar/WorkspacesMenu' + }" + addJsInlineLabels="{ + 'Workspaces.workspaceTitle': workspaceTitle + }" +/> +<f:render partial="ToolbarItems/ToolbarItem" arguments="{ title: 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.workspace', icon: '{core:icon(identifier: \'apps-toolbar-menu-workspace\', size: \'small\', alternativeMarkupIdentifier: \'inline\')}' }" />