first commit

This commit is contained in:
salam committed 2026-10-19 08:18:39 +02:00
commit 1218dd1517
12716 files changed
+989233

No files matched your search

@@ -0,0 +1,208 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Toolbar\ClearCacheActionsHookInterface;
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;
/**
* 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".
*/
class ClearCacheToolbarItem implements ToolbarItemInterface
{
/**
* @var array
*/
protected $cacheActions = [];
/**
* @var array
*/
protected $optionValues = [];
/**
* @throws \UnexpectedValueException
*/
public function __construct()
{
$this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/ClearCacheMenu');
$isAdmin = $this->getBackendUser()->isAdmin();
$userTsConfig = $this->getBackendUser()->getTSConfig();
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
// Clear all page-related caches
if ($isAdmin || $userTsConfig['options.']['clearCache.']['pages'] ?? false) {
$this->cacheActions[] = [
'id' => 'pages',
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:flushPageCachesTitle',
'description' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:flushPageCachesDescription',
'href' => (string)$uriBuilder->buildUriFromRoute('tce_db', ['cacheCmd' => 'pages']),
'iconIdentifier' => 'actions-system-cache-clear-impact-low'
];
$this->optionValues[] = 'pages';
}
// Clearing of all caches is only shown if explicitly enabled via TSConfig
// or if BE-User is admin and the TSconfig explicitly disables the possibility for admins.
// This is useful for big production systems where admins accidentally could slow down the system.
if (($userTsConfig['options.']['clearCache.']['all'] ?? false)
|| ($isAdmin && (bool)($userTsConfig['options.']['clearCache.']['all'] ?? true))
) {
$this->cacheActions[] = [
'id' => 'all',
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:flushAllCachesTitle2',
'description' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:flushAllCachesDescription2',
'href' => (string)$uriBuilder->buildUriFromRoute('tce_db', ['cacheCmd' => 'all']),
'iconIdentifier' => 'actions-system-cache-clear-impact-high'
];
$this->optionValues[] = 'all';
}
// Hook for manipulating cacheActions
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['additionalBackendItems']['cacheActions'] ?? [] as $cacheAction) {
$hookObject = GeneralUtility::makeInstance($cacheAction);
if (!$hookObject instanceof ClearCacheActionsHookInterface) {
throw new \UnexpectedValueException($cacheAction . ' must implement interface ' . ClearCacheActionsHookInterface::class, 1228262000);
}
$hookObject->manipulateCacheActions($this->cacheActions, $this->optionValues);
}
}
/**
* Checks whether the user has access to this toolbar item
*
* @return bool TRUE if user has access, FALSE if not
*/
public function checkAccess()
{
$backendUser = $this->getBackendUser();
if ($backendUser->isAdmin()) {
return true;
}
foreach ($this->optionValues as $value) {
if ($backendUser->getTSConfig()['options.']['clearCache.'][$value] ?? false) {
return true;
}
}
return false;
}
/**
* 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()
{
if ($this->hasDropDown()) {
return $this->getFluidTemplateObject('ClearCacheToolbarItem.html')->render();
}
$view = $this->getFluidTemplateObject('ClearCacheToolbarItemSingle.html');
$cacheAction = end($this->cacheActions);
$view->assignMultiple([
'link' => $cacheAction['href'],
'title' => $cacheAction['title'],
'iconIdentifier' => $cacheAction['iconIdentifier'],
]);
return $view->render();
}
/**
* Render drop down
*
* @return string Drop down HTML
*/
public function getDropDown()
{
$view = $this->getFluidTemplateObject('ClearCacheToolbarItemDropDown.html');
$view->assign('cacheActions', $this->cacheActions);
return $view->render();
}
/**
* No additional attributes needed.
*
* @return array
*/
public function getAdditionalAttributes()
{
return [];
}
/**
* This item has a drop down if there is more than one cache action available for the current Backend user.
*
* @return bool
*/
public function hasDropDown()
{
return count($this->cacheActions) > 1;
}
/**
* Position relative to others
*
* @return int
*/
public function getIndex()
{
return 25;
}
/**
* Returns the current BE user.
*
* @return BackendUserAuthentication
*/
protected function getBackendUser()
{
return $GLOBALS['BE_USER'];
}
/**
* @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;
}
}
@@ -0,0 +1,124 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
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;
/**
* Help toolbar item
*/
class HelpToolbarItem implements ToolbarItemInterface
{
/**
* @var BackendModule
*/
protected $helpModuleMenu;
/**
* Constructor
*/
public function __construct()
{
$backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
$helpModuleMenu = $backendModuleRepository->findByModuleName('help');
if ($helpModuleMenu && $helpModuleMenu->getChildren()->count() > 0) {
$this->helpModuleMenu = $helpModuleMenu;
}
}
/**
* Users see this if a module is available
*
* @return bool TRUE
*/
public function checkAccess()
{
return (bool)$this->helpModuleMenu;
}
/**
* Render help icon
*
* @return string toolbar item for the help icon
*/
public function getItem()
{
return $this->getFluidTemplateObject('HelpToolbarItem.html')->render();
}
/**
* Render drop down
*
* @return string
*/
public function getDropDown()
{
$view = $this->getFluidTemplateObject('HelpToolbarItemDropDown.html');
$view->assign('modules', $this->helpModuleMenu->getChildren());
return $view->render();
}
/**
* No additional attributes needed.
*
* @return array
*/
public function getAdditionalAttributes()
{
return [];
}
/**
* This item has a drop down
*
* @return bool
*/
public function hasDropDown()
{
return true;
}
/**
* Position relative to others
*
* @return int
*/
public function getIndex()
{
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
{
$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;
}
}
@@ -0,0 +1,128 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
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;
/**
* 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');
}
/**
* 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
*/
public function checkAccess()
{
$backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
$listModule = $backendModuleRepository->findByModuleName('web_list');
return $listModule !== null && $listModule !== false;
}
/**
* Render search field
*
* @return string Live search form HTML
*/
public function getItem()
{
return $this->getFluidTemplateObject('LiveSearchToolbarItem.html')->render();
}
/**
* This item needs to additional attributes
*
* @return array
*/
public function getAdditionalAttributes()
{
return ['class' => 'toolbar-item-search t3js-toolbar-item-search'];
}
/**
* This item has no drop down
*
* @return bool
*/
public function hasDropDown()
{
return false;
}
/**
* No drop down here
*
* @return string
*/
public function getDropDown()
{
return '';
}
/**
* Position relative to others, live search should be very right
*
* @return int
*/
public function getIndex()
{
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;
}
}
@@ -0,0 +1,170 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Class to render the shortcut menu
*
* @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);
$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'),
]);
}
/**
* Checks whether the user has access to this toolbar item
*
* @return bool TRUE if user has access, FALSE if not
*/
public function checkAccess()
{
return (bool)($this->getBackendUser()->getTSConfig()['options.']['enableBookmarks'] ?? false);
}
/**
* Render shortcut icon
*
* @return string HTML
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException
* @throws \InvalidArgumentException
*/
public function getItem()
{
return $this->getFluidTemplateObject('Item.html')->render();
}
/**
* This item has a drop down
*
* @return bool
*/
public function hasDropDown()
{
return true;
}
/**
* Render drop down content
*
* @return string HTML
*/
public function getDropDown()
{
$shortcutMenu = [];
$groups = $this->shortcutRepository->getGroupsFromShortcuts();
arsort($groups, SORT_NUMERIC);
foreach ($groups as $groupId => $groupLabel) {
$shortcutMenu[] = [
'id' => (int)$groupId,
'title' => $groupLabel,
'shortcuts' => $this->shortcutRepository->getShortcutsByGroup($groupId),
];
}
$dropDownView = $this->getFluidTemplateObject('DropDown.html');
$dropDownView->assign('shortcutMenu', $shortcutMenu);
return $dropDownView->render();
}
/**
* This toolbar item needs no additional attributes
*
* @return array
*/
public function getAdditionalAttributes()
{
return [];
}
/**
* Position relative to others, live search should be very right
*
* @return int
*/
public function getIndex()
{
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
{
$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');
return $view;
}
/**
* Returns the current BE user.
*
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
*/
protected function getBackendUser()
{
return $GLOBALS['BE_USER'];
}
/**
* @return \TYPO3\CMS\Core\Localization\LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,440 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus;
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
use TYPO3\CMS\Core\Database\ConnectionPool;
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\Core\Utility\StringUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Render system info toolbar item
*/
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 Dispatcher
*/
protected $signalSlotDispatcher;
/**
* @var int
*/
protected $maximumCountInBadge = 99;
/**
* Constructor
*/
public function __construct()
{
$this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/SystemInformationMenu');
$this->highestSeverity = InformationStatus::cast(InformationStatus::STATUS_INFO);
}
/**
* Add a system message.
* This is a callback method for signal receivers.
*
* @param string $text The text to be displayed
* @param string $status The status of this system message
* @param int $count Will be added to the total count
* @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 = '')
{
$this->totalCount += (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,
'count' => (int)$count,
'status' => $messageSeverity,
'text' => $text
];
}
/**
* Add a system information.
* This is a callback method for signal receivers.
*
* @param string $title The title of this system information
* @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)
{
$this->systemInformation[] = [
'title' => $title,
'value' => $value,
'iconIdentifier' => $iconIdentifier,
'status' => $status
];
}
/**
* Checks whether the user has access to this toolbar item
*
* @return bool TRUE if user has access, FALSE if not
*/
public function checkAccess()
{
return $this->getBackendUserAuthentication()->isAdmin();
}
/**
* Render system information dropdown
*
* @return string Icon HTML
*/
public function getItem()
{
return $this->getFluidTemplateObject('SystemInformationToolbarItem.html')->render();
}
/**
* Render drop down
*
* @return string Drop down HTML
*/
public function getDropDown()
{
if (!$this->checkAccess()) {
return '';
}
$this->collectInformation();
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$view = $this->getFluidTemplateObject('SystemInformationDropDown.html');
try {
$environmentToolUrl = (string)$uriBuilder->buildUriFromRoute('tools_toolsenvironment');
} catch (RouteNotFoundException $e) {
$environmentToolUrl = '';
}
$view->assignMultiple([
'environmentToolUrl' => $environmentToolUrl,
'messages' => $this->systemMessages,
'count' => $this->totalCount > $this->maximumCountInBadge ? $this->maximumCountInBadge . '+' : $this->totalCount,
'severityBadgeClass' => $this->severityBadgeClass,
'systemInformation' => $this->systemInformation
]);
return $view->render();
}
/**
* No additional attributes needed.
*
* @return array
*/
public function getAdditionalAttributes()
{
return [];
}
/**
* This item has a drop down
*
* @return bool
*/
public function hasDropDown()
{
return true;
}
/**
* Position relative to others
*
* @return int
*/
public function getIndex()
{
return 75;
}
/**
* Collect the information for the menu
*/
protected function collectInformation()
{
$this->getTypo3Version();
$this->getWebServer();
$this->getPhpVersion();
$this->getDatabase();
$this->getApplicationContext();
$this->getComposerMode();
$this->getGitRevision();
$this->getOperatingSystem();
$this->emitGetSystemInformation();
$this->emitLoadMessages();
$this->severityBadgeClass = !$this->highestSeverity->equals(InformationStatus::STATUS_NOTICE) ? 'badge-' . (string)$this->highestSeverity : '';
}
/**
* Gets the TYPO3 version
*/
protected function getTypo3Version()
{
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.typo3-version',
'value' => VersionNumberUtility::getCurrentTypo3Version(),
'iconIdentifier' => 'information-typo3-version'
];
}
/**
* Gets the webserver software
*/
protected function getWebServer()
{
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.webserver',
'value' => $_SERVER['SERVER_SOFTWARE'],
'iconIdentifier' => 'information-webserver'
];
}
/**
* Gets the PHP version
*/
protected function getPhpVersion()
{
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.phpversion',
'value' => PHP_VERSION,
'iconIdentifier' => 'information-php-version'
];
}
/**
* Get the database info
*/
protected function getDatabase()
{
foreach (GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionNames() as $connectionName) {
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.database',
'titleAddition' => $connectionName,
'value' => GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionByName($connectionName)
->getServerVersion(),
'iconIdentifier' => 'information-database'
];
}
}
/**
* Gets the application context
*/
protected function getApplicationContext()
{
$applicationContext = GeneralUtility::getApplicationContext();
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.applicationcontext',
'value' => (string)$applicationContext,
'status' => $applicationContext->isProduction() ? InformationStatus::STATUS_OK : InformationStatus::STATUS_WARNING,
'iconIdentifier' => 'information-application-context'
];
}
/**
* Adds the information if the Composer mode is enabled or disabled to the displayed system information
*/
protected function getComposerMode()
{
if (!Environment::isComposerMode()) {
return;
}
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.composerMode',
'value' => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.enabled'),
'iconIdentifier' => 'information-composer-mode'
];
}
/**
* Gets the current GIT revision and branch
*/
protected function getGitRevision()
{
if (!StringUtility::endsWith(TYPO3_version, '-dev') || SystemEnvironmentBuilder::isFunctionDisabled('exec')) {
return;
}
// check if git exists
CommandUtility::exec('git --version', $_, $returnCode);
if ((int)$returnCode !== 0) {
// git is not available
return;
}
$revision = trim(CommandUtility::exec('git rev-parse --short HEAD'));
$branch = trim(CommandUtility::exec('git rev-parse --abbrev-ref HEAD'));
if (!empty($revision) && !empty($branch)) {
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.gitrevision',
'value' => sprintf('%s [%s]', $revision, $branch),
'iconIdentifier' => 'information-git'
];
}
}
/**
* Gets the system kernel and version
*/
protected function getOperatingSystem()
{
switch (PHP_OS_FAMILY) {
case 'Linux':
$icon = 'linux';
break;
case 'Darwin':
$icon = 'apple';
break;
case 'Windows':
$icon = 'windows';
break;
default:
$icon = 'unknown';
}
$this->systemInformation[] = [
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:toolbarItems.sysinfo.operatingsystem',
'value' => PHP_OS . ' ' . php_uname('r'),
'iconIdentifier' => 'information-os-' . $icon
];
}
/**
* Emits the "getSystemInformation" signal
*/
protected function emitGetSystemInformation()
{
$this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'getSystemInformation', [$this]);
}
/**
* Emits the "loadMessages" signal
*/
protected function emitLoadMessages()
{
$this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'loadMessages', [$this]);
}
/**
* 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;
}
/**
* Returns the current BE user.
*
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
*/
protected function getBackendUserAuthentication()
{
return $GLOBALS['BE_USER'];
}
/**
* Returns current PageRenderer
*
* @return PageRenderer
*/
protected function getPageRenderer()
{
return GeneralUtility::makeInstance(PageRenderer::class);
}
/**
* Get the SignalSlot dispatcher
*
* @return Dispatcher
*/
protected function getSignalSlotDispatcher()
{
if (!isset($this->signalSlotDispatcher)) {
$this->signalSlotDispatcher = GeneralUtility::makeInstance(ObjectManager::class)->get(Dispatcher::class);
}
return $this->signalSlotDispatcher;
}
}
@@ -0,0 +1,188 @@
<?php
namespace TYPO3\CMS\Backend\Backend\ToolbarItems;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* User toolbar item
*
* @internal This class is a specific Backend implementation and is not considered part of the Public TYPO3 API.
*/
class UserToolbarItem implements ToolbarItemInterface
{
/**
* Item is always enabled
*
* @return bool TRUE
*/
public function checkAccess()
{
return true;
}
/**
* Render username and an icon
*
* @return string HTML
*/
public function getItem()
{
$backendUser = $this->getBackendUser();
$view = $this->getFluidTemplateObject('UserToolbarItem.html');
$view->assignMultiple([
'currentUser' => $backendUser->user,
'switchUserMode' => $backendUser->user['ses_backuserid'],
]);
return $view->render();
}
/**
* Render drop down
*
* @return string HTML
*/
public function getDropDown()
{
$backendUser = $this->getBackendUser();
/** @var BackendModuleRepository $backendModuleRepository */
$backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$mostRecentUsers = [];
if (ExtensionManagementUtility::isLoaded('beuser')
&& $backendUser->isAdmin()
&& (int)$backendUser->user['ses_backuserid'] === 0
&& isset($backendUser->uc['recentSwitchedToUsers'])
&& is_array($backendUser->uc['recentSwitchedToUsers'])
) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
$result = $queryBuilder
->select('uid', 'username', 'realName')
->from('be_users')
->where(
$queryBuilder->expr()->in('uid', $queryBuilder->createNamedParameter($backendUser->uc['recentSwitchedToUsers'], Connection::PARAM_INT_ARRAY))
)->execute();
// Flip the array to have a "sorted" list of items
$mostRecentUsers = array_flip($backendUser->uc['recentSwitchedToUsers']);
while ($row = $result->fetch()) {
$row['switchUserLink'] = (string)$uriBuilder->buildUriFromRoute(
'system_BeuserTxBeuser',
[
'SwitchUser' => $row['uid']
]
);
$mostRecentUsers[$row['uid']] = $row;
}
// Remove any item that is not an array (means, the stored uid is not available anymore)
$mostRecentUsers = array_filter($mostRecentUsers, function ($record) {
return is_array($record);
});
$availableUsers = array_keys($mostRecentUsers);
if (!empty(array_diff($backendUser->uc['recentSwitchedToUsers'], $availableUsers))) {
$backendUser->uc['recentSwitchedToUsers'] = $availableUsers;
$backendUser->writeUC();
}
}
$view = $this->getFluidTemplateObject('UserToolbarItemDropDown.html');
$view->assignMultiple([
'modules' => $backendModuleRepository->findByModuleName('user')->getChildren(),
'logoutUrl' => (string)$uriBuilder->buildUriFromRoute('logout'),
'switchUserMode' => $this->getBackendUser()->user['ses_backuserid'],
'recentUsers' => $mostRecentUsers,
]);
return $view->render();
}
/**
* Returns an additional class if user is in "switch user" mode
*
* @return array
*/
public function getAdditionalAttributes()
{
$result = [
'class' => 'toolbar-item-user'
];
if ($this->getBackendUser()->user['ses_backuserid']) {
$result['class'] .= ' su-user';
}
return $result;
}
/**
* This item has a drop down
*
* @return bool
*/
public function hasDropDown()
{
return true;
}
/**
* Position relative to others
*
* @return int
*/
public function getIndex()
{
return 80;
}
/**
* Returns the current BE user.
*
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
*/
protected function getBackendUser()
{
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
{
$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;
}
}