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,594 @@
<?php
namespace TYPO3\CMS\Info\Controller;
/*
* 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 Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Script Class for the Web > Info module
* This class creates the framework to which other extensions can connect their sub-modules
* @internal This class is a specific Backend controller implementation and is not part of the TYPO3's Core API.
*/
class InfoModuleController
{
use PublicPropertyDeprecationTrait;
use PublicMethodDeprecationTrait;
/**
* @var array
*/
private $deprecatedPublicProperties = [
'perms_clause' => 'Using InfoModuleController::$perms_clause is deprecated and will not be possible anymore in TYPO3 v10.0.',
'modTSconfig' => 'Using InfoModuleController::$modTSconfig is deprecated and will not be possible anymore in TYPO3 v10.0.',
'modMenu_setDefaultList' => 'Using InfoModuleController::$modMenu_setDefaultList is deprecated and will not be possible anymore in TYPO3 v10.0.',
'modMenu_dontValidateList' => 'Using InfoModuleController::$modMenu_dontValidateList is deprecated and will not be possible anymore in TYPO3 v10.0.',
'modMenu_type' => 'Using InfoModuleController::$modMenu_type$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extClassConf' => 'Using InfoModuleController::extClassConf$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObj' => 'Using InfoModuleController::$extObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
'content' => 'Using InfoModuleController::$content is deprecated and will not be possible anymore in TYPO3 v10.0.',
'pObj' => 'Using InfoModuleController::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
'id' => 'Using InfoModuleController::id$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
'CMD' => 'Using InfoModuleController::$CMD is deprecated, property will be removed in TYPO3 v10.0.',
'doc' => 'Using InfoModuleController::$doc is deprecated, property will be removed in TYPO3 v10.0.',
'MCONF' => 'Using InfoModuleController::$MCONF is deprecated, property will be removed in TYPO3 v10.0.',
];
/**
* @var array
*/
private $deprecatedPublicMethods = [
'main' => 'Using InfoModuleController::main() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'init' => 'Using InfoModuleController::init() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'getModuleTemplate' => 'Using InfoModuleController::getModuleTemplate() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'menuConfig' => 'Using InfoModuleController::menuConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'handleExternalFunctionValue' => 'Using InfoModuleController::handleExternalFunctionValue() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'mergeExternalItems' => 'Using InfoModuleController::mergeExternalItems() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'getExternalItemConfig' => 'Using InfoModuleController::getExternalItemConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObjContent' => 'Using InfoModuleController::extObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'getExtObjContent' => 'Using InfoModuleController::getExtObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'checkExtObj' => 'Using InfoModuleController::checkExtObj() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObjHeader' => 'Using InfoModuleController::extObjHeader() is deprecated, method will be removed in TYPO3 v10.0.',
'checkSubExtObj' => 'Using InfoModuleController::checkSubExtObj() is deprecated, method will be removed in TYPO3 v10.0.',
];
/**
* @var array Used by client classes.
*/
public $pageinfo;
/**
* The name of the module
*
* @var string
*/
protected $moduleName = 'web_info';
/**
* ModuleTemplate Container
*
* @var ModuleTemplate
*/
protected $moduleTemplate;
/**
* @var StandaloneView
*/
protected $view;
/**
* Loaded with the global array $MCONF which holds some module configuration from the conf.php file of backend modules.
*
* @var array
*/
protected $MCONF = [];
/**
* @var int Value of the GET/POST var 'id'
*/
protected $id;
/**
* The value of GET/POST var, 'CMD'
*
* @var mixed
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $CMD;
/**
* A WHERE clause for selection records from the pages table based on read-permissions of the current backend user.
*
* @var string
*/
protected $perms_clause;
/**
* The module menu items array. Each key represents a key for which values can range between the items in the array of that key.
* Written by client classes.
*
* @var array
*/
public $MOD_MENU = [
'function' => []
];
/**
* Current settings for the keys of the MOD_MENU array
* Written by client classes.
*
* @var array
*/
public $MOD_SETTINGS = [];
/**
* Module TSconfig based on PAGE TSconfig / USER TSconfig
*
* @var array
*/
protected $modTSconfig;
/**
* If type is 'ses' then the data is stored as session-lasting data. This means that it'll be wiped out the next time the user logs in.
* Can be set from extension classes of this class before the init() function is called.
*
* @var string
*/
protected $modMenu_type = '';
/**
* dontValidateList can be used to list variables that should not be checked if their value is found in the MOD_MENU array. Used for dynamically generated menus.
* Can be set from extension classes of this class before the init() function is called.
*
* @var string
*/
protected $modMenu_dontValidateList = '';
/**
* List of default values from $MOD_MENU to set in the output array (only if the values from MOD_MENU are not arrays)
* Can be set from extension classes of this class before the init() function is called.
*
* @var string
*/
protected $modMenu_setDefaultList = '';
/**
* @var array Contains module configuration parts from TBE_MODULES_EXT if found
*/
protected $extClassConf;
/**
* Generally used for accumulating the output content of backend modules
*
* @var string
*/
protected $content = '';
/**
* @var DocumentTemplate
*/
protected $doc;
/**
* May contain an instance of a 'Function menu module' which connects to this backend module.
*
* @var \object
*/
protected $extObj;
/**
* Constructor
*/
public function __construct()
{
$this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
$languageService = $this->getLanguageService();
$languageService->includeLLFile('EXT:info/Resources/Private/Language/locallang_mod_web_info.xlf');
// @deprecated and will be removed in TYPO3 v10.0.
$this->MCONF = [
'name' => $this->moduleName,
];
}
/**
* Initializes the backend module by setting internal variables, initializing the menu.
*/
protected function init()
{
$this->id = (int)GeneralUtility::_GP('id');
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
$this->CMD = GeneralUtility::_GP('CMD');
$this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
$this->menuConfig();
$this->handleExternalFunctionValue();
}
/**
* Initialize module header etc and call extObjContent function
*/
protected function main()
{
// since TYPO3 v9, will be removed in TYPO3 v10.0.
$this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
$languageService = $this->getLanguageService();
$backendUser = $this->getBackendUser();
// The page will show only if there is a valid page and if this page
// may be viewed by the user
$this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
if ($this->pageinfo) {
$this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
}
$access = is_array($this->pageinfo);
if ($this->id && $access || $backendUser->isAdmin() && !$this->id) {
if ($backendUser->isAdmin() && !$this->id) {
$this->pageinfo = ['title' => '[root-level]', 'uid' => 0, 'pid' => 0];
}
// JavaScript
$this->moduleTemplate->addJavaScriptCode(
'WebFuncInLineJS',
'if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
function jumpToUrl(URL) {
window.location.href = URL;
return false;
}
'
);
// Setting up the context sensitive menu:
$this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
$this->view = $this->getFluidTemplateObject();
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$this->view->assign('moduleName', (string)$uriBuilder->buildUriFromRoute($this->moduleName));
$this->view->assign('functionMenuModuleContent', $this->getExtObjContent());
// Setting up the buttons and markers for doc header
$this->getButtons();
$this->generateMenu();
$this->content .= $this->view->render();
} else {
// If no access or if ID == zero
$this->content = $this->moduleTemplate->header($languageService->getLL('title'));
}
}
/**
* Injects the request object for the current request or subrequest
* Then checks for module functions that have hooked in, and renders menu etc.
*
* @param ServerRequestInterface $request the current request
* @return ResponseInterface the response with the content
*/
public function mainAction(ServerRequestInterface $request): ResponseInterface
{
// @deprecated and will be removed in TYPO3 v10.0.
$GLOBALS['SOBE'] = $this;
$this->init();
// Checking for first level external objects
$this->checkExtObj();
// Checking second level external objects
// @deprecated and will be removed in TYPO3 v10.0.
$this->checkSubExtObj();
$this->main();
$this->moduleTemplate->setContent($this->content);
return new HtmlResponse($this->moduleTemplate->renderContent());
}
/**
* Create the panel of buttons for submitting the form or otherwise perform operations.
*/
protected function getButtons()
{
$languageService = $this->getLanguageService();
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
// View page
$viewButton = $buttonBar->makeLinkButton()
->setHref('#')
->setOnClick(BackendUtility::viewOnClick(
$this->pageinfo['uid'],
'',
BackendUtility::BEgetRootLine($this->pageinfo['uid'])
))
->setTitle($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-page', Icon::SIZE_SMALL));
$buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
// Shortcut
$shortCutButton = $buttonBar->makeShortcutButton()
->setModuleName($this->moduleName)
->setDisplayName($this->MOD_MENU['function'][$this->MOD_SETTINGS['function']])
->setGetVariables([
'route',
'id',
'edit_record',
'pointer',
'new_unique_uid',
'search_field',
'search_levels',
'showLimit'
])
->setSetVariables(array_keys($this->MOD_MENU));
$buttonBar->addButton($shortCutButton, ButtonBar::BUTTON_POSITION_RIGHT);
// CSH
$cshButton = $buttonBar->makeHelpButton()
->setModuleName('xMOD_csh_corebe')
->setFieldName('pagetree_overview');
$buttonBar->addButton($cshButton);
}
/**
* Generate the ModuleMenu
*/
protected function generateMenu()
{
$menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
$menu->setIdentifier('WebInfoJumpMenu');
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
foreach ($this->MOD_MENU['function'] as $controller => $title) {
$item = $menu
->makeMenuItem()
->setHref(
(string)$uriBuilder->buildUriFromRoute(
$this->moduleName,
[
'id' => $this->id,
'SET' => [
'function' => $controller
]
]
)
)
->setTitle($title);
if ($controller === $this->MOD_SETTINGS['function']) {
$item->setActive(true);
}
$menu->addMenuItem($item);
}
$this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
}
/**
* Returns the ModuleTemplate container
* This is used by PageLayoutView.php
*
* @return ModuleTemplate
*/
protected function getModuleTemplate()
{
return $this->moduleTemplate;
}
/**
* returns a new standalone view, shorthand function
*
* @return StandaloneView
*/
protected function getFluidTemplateObject()
{
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Layouts')]);
$view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Partials')]);
$view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates')]);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates/Main.html'));
$view->getRequest()->setControllerExtensionName('info');
return $view;
}
/**
* Initializes the internal MOD_MENU array setting and unsetting items based on various conditions. It also merges in external menu items from the global array TBE_MODULES_EXT (see mergeExternalItems())
* Then MOD_SETTINGS array is cleaned up (see \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()) so it contains only valid values. It's also updated with any SET[] values submitted.
* Also loads the modTSconfig internal variable.
*/
protected function menuConfig()
{
// Page / user TSconfig settings and blinding of menu-items
$this->modTSconfig['properties'] = BackendUtility::getPagesTSconfig($this->id)['mod.']['web_info.'] ?? [];
$this->MOD_MENU['function'] = $this->mergeExternalItems('web_info', 'function', $this->MOD_MENU['function']);
$blindActions = $this->modTSconfig['properties']['menu.']['function.'] ?? [];
foreach ($blindActions as $key => $value) {
if (!$value && array_key_exists($key, $this->MOD_MENU['function'])) {
unset($this->MOD_MENU['function'][$key]);
}
}
$this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
}
/**
* Merges menu items from global array $TBE_MODULES_EXT
*
* @param string $modName Module name for which to find value
* @param string $menuKey Menu key, eg. 'function' for the function menu.
* @param array $menuArr The part of a MOD_MENU array to work on.
* @return array Modified array part.
* @internal
*/
protected function mergeExternalItems($modName, $menuKey, $menuArr)
{
$mergeArray = $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
if (is_array($mergeArray)) {
$backendUser = $this->getBackendUser();
foreach ($mergeArray as $k => $v) {
if (((string)$v['ws'] === '' || $backendUser->workspace === 0 && GeneralUtility::inList($v['ws'], 'online'))
|| $backendUser->workspace === -1 && GeneralUtility::inList($v['ws'], 'offline')
|| $backendUser->workspace > 0 && GeneralUtility::inList($v['ws'], 'custom')
) {
$menuArr[$k] = $this->getLanguageService()->sL($v['title']);
}
}
}
return $menuArr;
}
/**
* Loads $this->extClassConf with the configuration for the CURRENT function of the menu.
*
* @param string $MM_key The key to MOD_MENU for which to fetch configuration. 'function' is default since it is first and foremost used to get information per "extension object" (I think that is what its called)
* @param string $MS_value The value-key to fetch from the config array. If NULL (default) MOD_SETTINGS[$MM_key] will be used. This is useful if you want to force another function than the one defined in MOD_SETTINGS[function]. Call this in init() function of your Script Class: handleExternalFunctionValue('function', $forcedSubModKey)
*/
protected function handleExternalFunctionValue($MM_key = 'function', $MS_value = null)
{
if ($MS_value === null) {
$MS_value = $this->MOD_SETTINGS[$MM_key];
}
$this->extClassConf = $this->getExternalItemConfig('web_info', $MM_key, $MS_value);
}
/**
* Returns configuration values from the global variable $TBE_MODULES_EXT for the module given.
* For example if the module is named "web_info" and the "function" key ($menuKey) of MOD_SETTINGS is "stat" ($value) then you will have the values
* of $TBE_MODULES_EXT['webinfo']['MOD_MENU']['function']['stat'] returned.
*
* @param string $modName Module name
* @param string $menuKey Menu key, eg. "function" for the function menu. See $this->MOD_MENU
* @param string $value Optionally the value-key to fetch from the array that would otherwise have been returned if this value was not set. Look source...
* @return mixed The value from the TBE_MODULES_EXT array.
*/
protected function getExternalItemConfig($modName, $menuKey, $value = '')
{
if (isset($GLOBALS['TBE_MODULES_EXT'][$modName])) {
return (string)$value !== ''
? $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey][$value]
: $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
}
return null;
}
/**
* Creates an instance of the class found in $this->extClassConf['name'] in $this->extObj if any (this should hold three keys, "name", "path" and "title" if a "Function menu module" tries to connect...)
* This value in extClassConf might be set by an extension (in an ext_tables/ext_localconf file) which thus "connects" to a module.
* The array $this->extClassConf is set in handleExternalFunctionValue() based on the value of MOD_SETTINGS[function]
* If an instance is created it is initiated with $this passed as value and $this->extClassConf as second argument. Further the $this->MOD_SETTING is cleaned up again after calling the init function.
*/
protected function checkExtObj()
{
if (is_array($this->extClassConf) && $this->extClassConf['name']) {
$this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
if (is_callable([$this->extObj, 'init'])) {
$this->extObj->init($this);
}
// Re-write:
$this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
}
}
/**
* Calls the checkExtObj function in sub module if present.
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected function checkSubExtObj()
{
if (is_object($this->extObj) && is_callable([$this->extObj, 'checkExtObj'])) {
$this->extObj->checkExtObj();
}
}
/**
* Calls the 'header' function inside the "Function menu module" if present.
* A header function might be needed to add JavaScript or other stuff in the head. This can't be done in the main function because the head is already written.
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected function extObjHeader()
{
if (is_callable([$this->extObj, 'head'])) {
$this->extObj->head();
}
}
/**
* Calls the 'main' function inside the "Function menu module" if present
*/
protected function extObjContent()
{
if ($this->extObj === null) {
$languageService = $this->getLanguageService();
$flashMessage = GeneralUtility::makeInstance(
FlashMessage::class,
$languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:no_modules_registered'),
$languageService->getLL('title'),
FlashMessage::ERROR
);
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
/** @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue $defaultFlashMessageQueue */
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
$defaultFlashMessageQueue->enqueue($flashMessage);
} else {
if (is_callable([$this->extObj, 'main'])) {
$main = $this->extObj->main();
if ($main instanceof ResponseInterface) {
$stream = $main->getBody();
$stream->rewind();
$main = $stream->getContents();
}
$this->content .= $main;
}
}
}
/**
* Return the content of the 'main' function inside the "Function menu module" if present
*
* @return string
*/
protected function getExtObjContent()
{
$savedContent = $this->content;
$this->content = '';
$this->extObjContent();
$newContent = $this->content;
$this->content = $savedContent;
return $newContent;
}
/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
/**
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}
@@ -0,0 +1,485 @@
<?php
namespace TYPO3\CMS\Info\Controller;
/*
* 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\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\TypoScript\ExtendedTemplateService;
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
/**
* Page TSconfig viewer in Web -> Info
* @internal This class is a specific Backend controller implementation and is not part of the TYPO3's Core API.
*/
class InfoPageTyposcriptConfigController
{
use PublicPropertyDeprecationTrait;
use PublicMethodDeprecationTrait;
/**
* @var array
*/
private $deprecatedPublicProperties = [
'pObj' => 'Using InfoPageTyposcriptConfigController::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
'function_key' => 'Using InfoPageTyposcriptConfigController::$function_key is deprecated, property will be removed in TYPO3 v10.0.',
'extClassConf' => 'Using InfoPageTyposcriptConfigController::$extClassConf is deprecated, property will be removed in TYPO3 v10.0.',
'localLangFile' => 'Using InfoPageTyposcriptConfigController::$localLangFile is deprecated, property will be removed in TYPO3 v10.0.',
'extObj' => 'Using InfoPageTyposcriptConfigController::$extObj is deprecated, property will be removed in TYPO3 v10.0.',
];
/**
* @var array
*/
private $deprecatedPublicMethods = [
'modMenu' => 'Using InfoPageTyposcriptConfigController::modMenu() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObjContent' => 'Using InfoPageTyposcriptConfigController::extObjContent() is deprecated, method will be removed in TYPO3 v10.0.',
];
/**
* @var IconFactory
*/
protected $iconFactory;
/**
* @var StandaloneView
*/
protected $view;
/**
* @var InfoModuleController Contains a reference to the parent calling object
*/
protected $pObj;
/**
* @var int Value of the GET/POST var 'id'
*/
protected $id;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extObj;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $localLangFile = '';
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extClassConf;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $function_key = '';
/**
* Init, called from parent object
*
* @param InfoModuleController $pObj A reference to the parent (calling) object
*/
public function init($pObj)
{
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$languageService = $this->getLanguageService();
$languageService->includeLLFile('EXT:info/Resources/Private/Language/InfoPageTsConfig.xlf');
$this->view = $this->getFluidTemplateObject();
$this->pObj = $pObj;
// Local lang:
if (!empty($this->localLangFile)) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
$languageService->includeLLFile($this->localLangFile);
}
$this->id = (int)GeneralUtility::_GP('id');
// Setting MOD_MENU items as we need them for logging:
$this->pObj->MOD_MENU = array_merge($this->pObj->MOD_MENU, $this->modMenu());
}
/**
* Main, called from parent object
*
* @return string HTML output
*/
public function main()
{
$pageId = (int)GeneralUtility::_GP('id');
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
if ($pageId === 0) {
$this->view->assign('pageZero', 1);
$pagesUsingTSConfig = $this->getOverviewOfPagesUsingTSConfig();
if (count($pagesUsingTSConfig) > 0) {
$this->view->assign('overviewOfPagesUsingTSConfig', $pagesUsingTSConfig);
}
} else {
if ($this->pObj->MOD_SETTINGS['tsconf_parts'] == 99) {
$TSparts = BackendUtility::getRawPagesTSconfig($this->id);
$lines = [];
$pUids = [];
foreach ($TSparts as $k => $v) {
if ($k !== 'uid_0') {
$line = [];
if ($k === 'defaultPageTSconfig') {
$line['defaultPageTSconfig'] = 1;
} else {
$editIdList = substr($k, 4);
$pUids[] = $editIdList;
$row = BackendUtility::getRecordWSOL('pages', $editIdList);
$icon = $this->iconFactory->getIconForRecord('pages', $row, Icon::SIZE_SMALL);
$urlParameters = [
'edit' => [
'pages' => [
$editIdList => 'edit',
]
],
'columnsOnly' => 'TSconfig',
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
];
$line['editIcon'] = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
$line['editTitle'] = 'editTSconfig';
$line['title'] = BackendUtility::wrapClickMenuOnIcon($icon, 'pages', $row['uid'])
. ' ' . htmlspecialchars(BackendUtility::getRecordTitle('pages', $row));
}
$tsparser = GeneralUtility::makeInstance(TypoScriptParser::class);
$tsparser->lineNumberOffset = 0;
$line['content'] = $tsparser->doSyntaxHighlight(trim($v) . LF);
$lines[] = $line;
}
}
if (!empty($pUids)) {
$urlParameters = [
'edit' => [
'pages' => [
implode(',', $pUids) => 'edit',
]
],
'columnsOnly' => 'TSconfig',
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
];
$url = (string)$uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
$editIcon = htmlspecialchars($url);
$editTitle = 'editTSconfig_all';
} else {
$editIcon = '';
$editTitle = '';
}
$this->view->assign('tsconfParts99', 1);
$this->view->assign('csh', BackendUtility::cshItem('_MOD_web_info', 'tsconfig_edit', null, '|'));
$this->view->assign('lines', $lines);
$this->view->assign('editIcon', $editIcon);
$this->view->assign('editTitle', $editTitle);
} else {
$this->view->assign('tsconfParts99', 0);
// Defined global here!
$tmpl = GeneralUtility::makeInstance(ExtendedTemplateService::class);
$tmpl->ext_expandAllNotes = 1;
$tmpl->ext_noPMicons = 1;
$pageTsConfig = BackendUtility::getPagesTSconfig($this->id);
switch ($this->pObj->MOD_SETTINGS['tsconf_parts']) {
case '1':
$pageTsConfig = $pageTsConfig['mod.'] ?? [];
break;
case '1a':
$pageTsConfig = $pageTsConfig['mod.']['web_layout.'] ?? [];
break;
case '1b':
$pageTsConfig = $pageTsConfig['mod.']['web_view.'] ?? [];
break;
case '1c':
$pageTsConfig = $pageTsConfig['mod.']['web_modules.'] ?? [];
break;
case '1d':
$pageTsConfig = $pageTsConfig['mod.']['web_list.'] ?? [];
break;
case '1e':
$pageTsConfig = $pageTsConfig['mod.']['web_info.'] ?? [];
break;
case '1f':
$pageTsConfig = $pageTsConfig['mod.']['web_func.'] ?? [];
break;
case '1g':
$pageTsConfig = $pageTsConfig['mod.']['web_ts.'] ?? [];
break;
case '2':
$pageTsConfig = $pageTsConfig['RTE.'] ?? [];
break;
case '5':
$pageTsConfig = $pageTsConfig['TCEFORM.'] ?? [];
break;
case '6':
$pageTsConfig = $pageTsConfig['TCEMAIN.'] ?? [];
break;
case '3':
$pageTsConfig = $pageTsConfig['TSFE.'] ?? [];
break;
case '7':
$pageTsConfig = $pageTsConfig['TCAdefaults.'] ?? [];
break;
case '4':
$pageTsConfig = $pageTsConfig['user.'] ?? [];
break;
default:
// Entire array
}
$this->view->assign('csh', BackendUtility::cshItem('_MOD_web_info', 'tsconfig_hierarchy', null, '|'));
$this->view->assign('tree', $tmpl->ext_getObjTree($pageTsConfig, '', '', '', '', $this->pObj->MOD_SETTINGS['tsconf_alphaSort']));
}
$this->view->assign('alphaSort', BackendUtility::getFuncCheck($this->id, 'SET[tsconf_alphaSort]', $this->pObj->MOD_SETTINGS['tsconf_alphaSort'], '', '', 'id="checkTsconf_alphaSort"'));
$this->view->assign('dropdownMenu', BackendUtility::getDropdownMenu($this->id, 'SET[tsconf_parts]', $this->pObj->MOD_SETTINGS['tsconf_parts'], $this->pObj->MOD_MENU['tsconf_parts']));
}
return $this->view->render();
}
/**
* Function menu initialization
*
* @return array Menu array
*/
protected function modMenu()
{
$lang = $this->getLanguageService();
$modMenuAdd = [
'tsconf_parts' => [
0 => $lang->getLL('tsconf_parts_0'),
1 => $lang->getLL('tsconf_parts_1'),
'1a' => $lang->getLL('tsconf_parts_1a'),
'1b' => $lang->getLL('tsconf_parts_1b'),
'1c' => $lang->getLL('tsconf_parts_1c'),
'1d' => $lang->getLL('tsconf_parts_1d'),
'1e' => $lang->getLL('tsconf_parts_1e'),
'1f' => $lang->getLL('tsconf_parts_1f'),
'1g' => $lang->getLL('tsconf_parts_1g'),
2 => 'RTE.',
7 => 'TCAdefaults.',
5 => 'TCEFORM.',
6 => 'TCEMAIN.',
3 => 'TSFE.',
4 => 'user.',
99 => $lang->getLL('tsconf_configFields')
],
'tsconf_alphaSort' => '1'
];
if (!$this->getBackendUser()->isAdmin()) {
unset($modMenuAdd['tsconf_parts'][99]);
}
return $modMenuAdd;
}
/**
* Renders table rows of all pages containing TSConfig together with its rootline
*
* @return array
*/
protected function getOverviewOfPagesUsingTSConfig()
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$res = $queryBuilder
->select('uid', 'TSconfig')
->from('pages')
->where(
$queryBuilder->expr()->neq(
'TSconfig',
$queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
)
)
->execute();
$pageArray = [];
while ($row = $res->fetch()) {
$this->setInPageArray($pageArray, BackendUtility::BEgetRootLine($row['uid'], 'AND 1=1'), $row);
}
return $this->getList($pageArray);
}
/**
* Set page in array
* This function is called recursively and builds a multi-dimensional array that reflects the page
* hierarchy.
*
* @param array $hierarchicArray The hierarchic array (passed by reference)
* @param array $rootlineArray The rootline array
* @param array $row The row from the database containing the uid and TSConfig fields
*/
protected function setInPageArray(&$hierarchicArray, $rootlineArray, $row)
{
ksort($rootlineArray);
reset($rootlineArray);
if (!$rootlineArray[0]['uid']) {
array_shift($rootlineArray);
}
$currentElement = current($rootlineArray);
$hierarchicArray[$currentElement['uid']] = htmlspecialchars($currentElement['title']);
array_shift($rootlineArray);
if (!empty($rootlineArray)) {
if (!isset($hierarchicArray[$currentElement['uid'] . '.'])) {
$hierarchicArray[$currentElement['uid'] . '.'] = [];
}
$this->setInPageArray($hierarchicArray[$currentElement['uid'] . '.'], $rootlineArray, $row);
} else {
$hierarchicArray[$currentElement['uid'] . '_'] = $this->extractLinesFromTSConfig($row);
}
}
/**
* Extract the lines of TSConfig from a given pages row
*
* @param array $row The row from the database containing the uid and TSConfig fields
* @return array
*/
protected function extractLinesFromTSConfig(array $row)
{
$out = [];
$includeLines = 0;
$out['uid'] = $row['uid'];
$lines = GeneralUtility::trimExplode("\r\n", $row['TSconfig']);
foreach ($lines as $line) {
if (strpos($line, '<INCLUDE_TYPOSCRIPT:') !== false) {
$includeLines++;
}
}
$out['includeLines'] = $includeLines;
$out['writtenLines'] = (count($lines) - $includeLines);
return $out;
}
/**
* Get the list of pages to show.
* This function is called recursively
*
* @param array $pageArray The Page Array
* @param array $lines Lines that have been processed up to this point
* @param int $pageDepth The level of the current $pageArray being processed
* @return array
*/
protected function getList($pageArray, $lines = [], $pageDepth = 0)
{
if (!is_array($pageArray)) {
return $lines;
}
foreach ($pageArray as $identifier => $_) {
if (!MathUtility::canBeInterpretedAsInteger($identifier)) {
continue;
}
$line = [];
$line['padding'] = ($pageDepth * 20) + 10;
if (isset($pageArray[$identifier . '_'])) {
$line['link'] = GeneralUtility::linkThisScript(['id' => $identifier]);
$line['icon'] = $this->iconFactory->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $identifier), Icon::SIZE_SMALL)->render();
$line['title'] = 'ID: ' . $identifier;
$line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pageArray[$identifier], 30);
$line['includedFiles'] = ($pageArray[$identifier . '_']['includeLines'] === 0 ? '' : $pageArray[$identifier . '_']['includeLines']);
$line['lines'] = ($pageArray[$identifier . '_']['writtenLines'] === 0 ? '' : $pageArray[$identifier . '_']['writtenLines']);
} else {
$line['link'] = '';
$line['icon'] = $this->iconFactory->getIconForRecord('pages', BackendUtility::getRecordWSOL('pages', $identifier), Icon::SIZE_SMALL)->render();
$line['title'] = '';
$line['pageTitle'] = GeneralUtility::fixed_lgd_cs($pageArray[$identifier], 30);
$line['includedFiles'] = '';
$line['lines'] = '';
}
$lines[] = $line;
$lines = $this->getList($pageArray[$identifier . '.'], $lines, $pageDepth + 1);
}
return $lines;
}
/**
* returns a new standalone view, shorthand function
*
* @return StandaloneView
*/
protected function getFluidTemplateObject()
{
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Layouts')]);
$view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Partials')]);
$view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates')]);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates/PageTsConfig.html'));
$view->getRequest()->setControllerExtensionName('info');
return $view;
}
/**
* Called from InfoModuleController until deprecation removal in TYPO3 v10.0
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
public function checkExtObj()
{
if (is_array($this->extClassConf) && $this->extClassConf['name']) {
$this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
$this->extObj->init($this->pObj, $this->extClassConf);
// Re-write:
$this->pObj->MOD_SETTINGS = BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info');
}
}
/**
* Calls the main function inside ANOTHER sub-submodule which might exist.
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected function extObjContent()
{
if (is_object($this->extObj)) {
return $this->extObj->main();
}
}
/**
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,292 @@
<?php
namespace TYPO3\CMS\Info\Controller;
/*
* 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 Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\PageLayoutView;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Site\Entity\NullSite;
use TYPO3\CMS\Core\Site\Entity\PseudoSite;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class for displaying page information (records, page record properties) in Web -> Info
* @internal This class is a specific Backend controller implementation and is not part of the TYPO3's Core API.
*/
class PageInformationController
{
use PublicPropertyDeprecationTrait;
use PublicMethodDeprecationTrait;
/**
* @var array
*/
private $deprecatedPublicProperties = [
'pObj' => 'Using PageInformationController::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
'function_key' => 'Using PageInformationController::$function_key is deprecated, property will be removed in TYPO3 v10.0.',
'extClassConf' => 'Using PageInformationController::$extClassConf is deprecated, property will be removed in TYPO3 v10.0.',
'localLangFile' => 'Using PageInformationController::$localLangFile is deprecated, property will be removed in TYPO3 v10.0.',
'extObj' => 'Using PageInformationController::$extObj is deprecated, property will be removed in TYPO3 v10.0.',
];
/**
* @var array
*/
private $deprecatedPublicMethods = [
'modMenu' => 'Using PageInformationController::modMenu() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObjContent' => 'Using PageInformationController::extObjContent() is deprecated, method will be removed in TYPO3 v10.0.',
];
/**
* @var array
*/
protected $fieldConfiguration = [];
/**
* @var int Value of the GET/POST var 'id'
*/
protected $id;
/**
* @var InfoModuleController Contains a reference to the parent calling object
*/
protected $pObj;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extObj;
/**
* Can be hardcoded to the name of a locallang.xlf file (from the same directory as the class file) to use/load
* and is included / added to $GLOBALS['LOCAL_LANG']
*
* @var string
*/
protected $localLangFile = '';
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extClassConf;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $function_key = '';
/**
* Init, called from parent object
*
* @param InfoModuleController $pObj A reference to the parent (calling) object
*/
public function init($pObj)
{
$this->pObj = $pObj;
// Local lang:
if (!empty($this->localLangFile)) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
$this->getLanguageService()->includeLLFile($this->localLangFile);
}
$this->id = (int)GeneralUtility::_GP('id');
// Setting MOD_MENU items as we need them for logging:
$this->pObj->MOD_MENU = array_merge($this->pObj->MOD_MENU, $this->modMenu());
}
/**
* Main, called from parent object
*
* @return string Output HTML for the module.
*/
public function main()
{
$languageService = $this->getLanguageService();
$theOutput = '<h1>' . htmlspecialchars($languageService->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:page_title')) . '</h1>';
$dblist = GeneralUtility::makeInstance(PageLayoutView::class);
$dblist->descrTable = '_MOD_web_info';
$dblist->thumbs = 0;
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
$dblist->script = (string)$uriBuilder->buildUriFromRoute('web_info');
$dblist->showIcon = 0;
$dblist->setLMargin = 0;
$dblist->agePrefixes = $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.minutesHoursDaysYears');
$dblist->pI_showUser = true;
if (isset($this->fieldConfiguration[$this->pObj->MOD_SETTINGS['pages']])) {
$dblist->fieldArray = $this->fieldConfiguration[$this->pObj->MOD_SETTINGS['pages']]['fields'];
}
// PAGES:
$this->pObj->MOD_SETTINGS['pages_levels'] = $this->pObj->MOD_SETTINGS['depth'];
// ONLY for the sake of dblist module which uses this value.
$h_func = BackendUtility::getDropdownMenu($this->id, 'SET[depth]', $this->pObj->MOD_SETTINGS['depth'], $this->pObj->MOD_MENU['depth']);
$h_func .= BackendUtility::getDropdownMenu($this->id, 'SET[pages]', $this->pObj->MOD_SETTINGS['pages'], $this->pObj->MOD_MENU['pages']);
$dblist->start($this->id, 'pages', 0);
$dblist->generateList();
$theOutput .= '<div class="form-inline form-inline-spaced">'
. $h_func
. '<div class="form-group">'
. BackendUtility::cshItem($dblist->descrTable, 'func_' . $this->pObj->MOD_SETTINGS['pages'], null, '<span class="btn btn-default btn-sm">|</span>')
. '</div>'
. '</div>'
. $dblist->HTMLcode;
// Additional footer content
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/web_info/class.tx_cms_webinfo.php']['drawFooterHook'] ?? [] as $hook) {
// @todo: request object should be submitted here as soon as it is available in TYPO3 v10.0.
$params = [];
$theOutput .= GeneralUtility::callUserFunction($hook, $params, $this);
}
return $theOutput;
}
/**
* Returns the menu array
*
* @return array
*/
protected function modMenu()
{
$menu = [
'pages' => [],
'depth' => [
0 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
1 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
2 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
3 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
4 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
999 => $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
]
];
// Using $GLOBALS['TYPO3_REQUEST'] since $request is not available at this point
// @todo: Refactor mess and have $request available
$this->fillFieldConfiguration($this->id, $GLOBALS['TYPO3_REQUEST']);
foreach ($this->fieldConfiguration as $key => $item) {
$menu['pages'][$key] = $item['label'];
}
return $menu;
}
/**
* Function, which returns all tables to
* which the user has access. Also a set of standard tables (pages, sys_filemounts, etc...)
* are filtered out. So what is left is basically all tables which makes sense to list content from.
*
* @return string
*/
protected function cleanTableNames(): string
{
// Get all table names:
$tableNames = array_flip(array_keys($GLOBALS['TCA']));
// Unset common names:
unset($tableNames['pages']);
unset($tableNames['sys_filemounts']);
unset($tableNames['sys_action']);
unset($tableNames['sys_workflows']);
unset($tableNames['be_users']);
unset($tableNames['be_groups']);
$allowedTableNames = [];
// Traverse table names and set them in allowedTableNames array IF they can be read-accessed by the user.
if (is_array($tableNames)) {
foreach ($tableNames as $k => $v) {
if (!$GLOBALS['TCA'][$k]['ctrl']['hideTable'] && $this->getBackendUser()->check('tables_select', $k)) {
$allowedTableNames['table_' . $k] = $k;
}
}
}
return implode(',', array_keys($allowedTableNames));
}
/**
* Generate configuration for field selection
*
* @param int $pageId current page id
* @param ServerRequestInterface $request
*/
protected function fillFieldConfiguration(int $pageId, ServerRequestInterface $request)
{
$modTSconfig = BackendUtility::getPagesTSconfig($pageId)['mod.']['web_info.']['fieldDefinitions.'] ?? [];
foreach ($modTSconfig as $key => $item) {
$fieldList = str_replace('###ALL_TABLES###', $this->cleanTableNames(), $item['fields']);
$fields = GeneralUtility::trimExplode(',', $fieldList, true);
if ((int)$key === 0) {
// If "Basic settings" is rendered, hide the alias field on trees that have a site configuration
// and hide the slug field on PseudoSites. On NullSites (pid 0), show both.
$site = $request->getAttribute('site');
if ($site instanceof PseudoSite) {
$fields = array_diff($fields, ['slug']);
} elseif ($site instanceof Site && !$site instanceof NullSite) {
$fields = array_diff($fields, ['alias']);
}
}
$key = trim($key, '.');
$this->fieldConfiguration[$key] = [
'label' => $item['label'] ? $GLOBALS['LANG']->sL($item['label']) : $key,
'fields' => $fields
];
}
}
/**
* Called from InfoModuleController until deprecation removal in TYPO3 v10.0
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
public function checkExtObj()
{
if (is_array($this->extClassConf) && $this->extClassConf['name']) {
$this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
$this->extObj->init($this->pObj, $this->extClassConf);
// Re-write:
$this->pObj->MOD_SETTINGS = BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info');
}
}
/**
* Calls the main function inside ANOTHER sub-submodule which might exist.
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected function extObjContent()
{
if (is_object($this->extObj)) {
return $this->extObj->main();
}
}
/**
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
@@ -0,0 +1,609 @@
<?php
namespace TYPO3\CMS\Info\Controller;
/*
* 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\Tree\View\PageTreeView;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class for displaying translation status of pages in the tree in Web -> Info
* @internal This class is a specific Backend controller implementation and is not part of the TYPO3's Core API.
*/
class TranslationStatusController
{
use PublicPropertyDeprecationTrait;
use PublicMethodDeprecationTrait;
/**
* @var array
*/
private $deprecatedPublicProperties = [
'pObj' => 'Using TranslationStatusController::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
'function_key' => 'Using TranslationStatusController::function_key$ is deprecated, property will be removed in TYPO3 v10.0.',
'extClassConf' => 'Using TranslationStatusController::$extClassConf is deprecated, property will be removed in TYPO3 v10.0.',
'localLangFile' => 'Using TranslationStatusController::$localLangFile is deprecated, property will be removed in TYPO3 v10.0.',
'extObj' => 'Using TranslationStatusController::$extObj is deprecated, property will be removed in TYPO3 v10.0.',
];
/**
* @var array
*/
private $deprecatedPublicMethods = [
'getContentElementCount' => 'Using TranslationStatusController::getContentElementCount() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'getLangStatus' => 'Using TranslationStatusController::getLangStatus() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'renderL10nTable' => 'Using TranslationStatusController::renderL10nTable() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'modMenu' => 'Using TranslationStatusController::modMenu() is deprecated and will not be possible anymore in TYPO3 v10.0.',
'extObjContent' => 'Using TranslationStatusController::extObjContent() is deprecated, method will be removed in TYPO3 v10.0.',
];
/**
* @var IconFactory
*/
protected $iconFactory;
/**
* @var SiteLanguage[]
*/
protected $siteLanguages;
/**
* @var InfoModuleController Contains a reference to the parent calling object
*/
protected $pObj;
/**
* @var int Value of the GET/POST var 'id'
*/
protected $id;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extObj;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $localLangFile = '';
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $extClassConf;
/**
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected $function_key = '';
/**
* Init, called from parent object
*
* @param InfoModuleController $pObj A reference to the parent (calling) object
*/
public function init($pObj)
{
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$this->id = (int)GeneralUtility::_GP('id');
$this->initializeSiteLanguages();
$this->pObj = $pObj;
// Local lang:
if (!empty($this->localLangFile)) {
// @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
$this->getLanguageService()->includeLLFile($this->localLangFile);
}
// Setting MOD_MENU items as we need them for logging:
$this->pObj->MOD_MENU = array_merge($this->pObj->MOD_MENU, $this->modMenu());
}
/**
* Main, called from parent object
*
* @return string Output HTML for the module.
*/
public function main()
{
$theOutput = '<h1>' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_title')) . '</h1>';
if ($this->id) {
$this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Info/TranslationStatus');
// Depth selector:
$theOutput .= '<div class="form-inline form-inline-spaced">';
$h_func = BackendUtility::getDropdownMenu($this->id, 'SET[depth]', $this->pObj->MOD_SETTINGS['depth'], $this->pObj->MOD_MENU['depth']);
$h_func .= BackendUtility::getDropdownMenu($this->id, 'SET[lang]', $this->pObj->MOD_SETTINGS['lang'], $this->pObj->MOD_MENU['lang']);
$theOutput .= $h_func;
// Add CSH:
$theOutput .= BackendUtility::cshItem('_MOD_web_info', 'lang', null, '<div class="form-group"><span class="btn btn-default btn-sm">|</span></div><br />');
$theOutput .= '</div>';
// Showing the tree:
// Initialize starting point of page tree:
$treeStartingPoint = (int)$this->id;
$treeStartingRecord = BackendUtility::getRecordWSOL('pages', $treeStartingPoint);
$depth = $this->pObj->MOD_SETTINGS['depth'];
// Initialize tree object:
$tree = GeneralUtility::makeInstance(PageTreeView::class);
$tree->init('AND ' . $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW));
$tree->addField('l18n_cfg');
// Creating top icon; the current page
$HTML = $this->iconFactory->getIconForRecord('pages', $treeStartingRecord, Icon::SIZE_SMALL)->render();
$tree->tree[] = [
'row' => $treeStartingRecord,
'HTML' => $HTML
];
// Create the tree from starting point:
if ($depth) {
$tree->getTree($treeStartingPoint, $depth, '');
}
// Render information table:
$theOutput .= $this->renderL10nTable($tree);
}
return $theOutput;
}
/**
* Returns the menu array
*
* @return array
*/
protected function modMenu()
{
$lang = $this->getLanguageService();
$menuArray = [
'depth' => [
0 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
1 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
2 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
3 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
4 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
999 => $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
]
];
// Languages:
$menuArray['lang'] = [];
foreach ($this->siteLanguages as $language) {
if ($language->getLanguageId() === 0) {
$menuArray['lang'][0] = '[All]';
} else {
$menuArray['lang'][$language->getLanguageId()] = $language->getTitle();
}
}
return $menuArray;
}
/**
* Rendering the localization information table.
*
* @param array $tree The Page tree data
* @return string HTML for the localization information table.
*/
protected function renderL10nTable(&$tree)
{
$lang = $this->getLanguageService();
// Title length:
$titleLen = $this->getBackendUser()->uc['titleLen'];
// Put together the TREE:
$output = '';
$newOL_js = [];
$langRecUids = [];
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$userTsConfig = $this->getBackendUser()->getTSConfig();
$showPageId = !empty($userTsConfig['options.']['pageTree.']['showPageIdWithTitle']);
foreach ($tree->tree as $data) {
$tCells = [];
$langRecUids[0][] = $data['row']['uid'];
$pageTitle = ($showPageId ? '[' . (int)$data['row']['uid'] . '] ' : '') . GeneralUtility::fixed_lgd_cs($data['row']['title'], $titleLen);
// Page icons / titles etc.
$tCells[] = '<td' . ($data['row']['_CSSCLASS'] ? ' class="' . $data['row']['_CSSCLASS'] . '"' : '') . '>' .
($data['depthData'] ?: '') .
BackendUtility::wrapClickMenuOnIcon($data['HTML'], 'pages', $data['row']['uid']) .
'<a href="#" onclick="' . htmlspecialchars(
'top.loadEditId(' . (int)$data['row']['uid'] . ',"&SET[language]=0"); return false;'
) . '" title="' . $lang->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPage') . '">' .
htmlspecialchars($pageTitle) .
'</a>' .
((string)$data['row']['nav_title'] !== '' ? ' [Nav: <em>' . htmlspecialchars(GeneralUtility::fixed_lgd_cs($data['row']['nav_title'], $titleLen)) . '</em>]' : '') .
'</td>';
// DEFAULT language:
// "View page" link is created:
$viewPageLink = '<a href="#" onclick="' . htmlspecialchars(
BackendUtility::viewOnClick(
$data['row']['uid'],
'',
null,
'',
'',
'&L=###LANG_UID###'
)
) . '" class="btn btn-default" title="' . $lang->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_viewPage') . '">' .
$this->iconFactory->getIcon('actions-view', Icon::SIZE_SMALL)->render() . '</a>';
$status = GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : 'success';
// Create links:
$editUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [
'edit' => [
'pages' => [
$data['row']['uid'] => 'edit'
]
],
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
]);
$info = '<a href="#" onclick="' . htmlspecialchars(
BackendUtility::viewOnClick(
$data['row']['uid'],
'',
null,
'',
'',
''
)
) . '" class="btn btn-default" title="' . $lang->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_viewPage') . '">' .
$this->iconFactory->getIcon('actions-view-page', Icon::SIZE_SMALL)->render() . '</a>';
$info .= '<a href="' . htmlspecialchars($editUrl)
. '" class="btn btn-default" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editDefaultLanguagePage'
) . '">' . $this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)->render() . '</a>';
$info .= '&nbsp;';
$info .= GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? '<span title="' . htmlspecialchars($lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.l18n_cfg.I.1')) . '">D</span>' : '&nbsp;';
$info .= GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) ? '<span title="' . htmlspecialchars($lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.l18n_cfg.I.2')) . '">N</span>' : '&nbsp;';
// Put into cell:
$tCells[] = '<td class="' . $status . ' col-border-left"><div class="btn-group">' . $info . '</div></td>';
$tCells[] = '<td class="' . $status . '" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_CEcount'
) . '" align="center">' . $this->getContentElementCount($data['row']['uid'], 0) . '</td>';
// Traverse system languages:
foreach ($this->siteLanguages as $siteLanguage) {
$languageId = $siteLanguage->getLanguageId();
if ($languageId === 0) {
continue;
}
if ($this->pObj->MOD_SETTINGS['lang'] == 0 || (int)$this->pObj->MOD_SETTINGS['lang'] === $languageId) {
$row = $this->getLangStatus($data['row']['uid'], $languageId);
if (is_array($row)) {
$langRecUids[$languageId][] = $row['uid'];
$status = $row['_HIDDEN'] ? (GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) || GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : '') : 'success';
$icon = $this->iconFactory->getIconForRecord('pages', $row, Icon::SIZE_SMALL)->render();
$info = $icon . ($showPageId ? ' [' . (int)$row['uid'] . ']' : '') . ' ' . htmlspecialchars(
GeneralUtility::fixed_lgd_cs($row['title'], $titleLen)
) . ((string)$row['nav_title'] !== '' ? ' [Nav: <em>' . htmlspecialchars(
GeneralUtility::fixed_lgd_cs($row['nav_title'], $titleLen)
) . '</em>]' : '') . ($row['_COUNT'] > 1 ? '<div>' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_badThingThereAre'
) . '</div>' : '');
$tCells[] = '<td class="' . $status . ' col-border-left">' .
'<a href="#" onclick="' . htmlspecialchars(
'top.loadEditId(' . (int)$data['row']['uid'] . ',"&SET[language]=' . $languageId . '"); return false;'
) . '" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPageLang'
) . '">' . $info . '</a></td>';
// Edit whole record:
// Create links:
$editUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [
'edit' => [
'pages' => [
$row['uid'] => 'edit'
]
],
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
]);
$info = str_replace('###LANG_UID###', $languageId, $viewPageLink);
$info .= '<a href="' . htmlspecialchars($editUrl)
. '" class="btn btn-default" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editLanguageOverlayRecord'
) . '">' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . '</a>';
$tCells[] = '<td class="' . $status . '"><div class="btn-group">' . $info . '</div></td>';
$tCells[] = '<td class="' . $status . '" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_CEcount'
) . '" align="center">' . $this->getContentElementCount($data['row']['uid'], $languageId) . '</td>';
} else {
$status = GeneralUtility::hideIfNotTranslated($data['row']['l18n_cfg']) || GeneralUtility::hideIfDefaultLanguage($data['row']['l18n_cfg']) ? 'danger' : '';
$info = '<div class="btn-group"><label class="btn btn-default btn-checkbox">';
$info .= '<input type="checkbox" data-lang="' . $languageId . '" data-uid="' . (int)$data['row']['uid'] . '" name="newOL[' . $languageId . '][' . $data['row']['uid'] . ']" value="1" />';
$info .= '<span class="t3-icon fa"></span></label></div>';
$newOL_js[$languageId] .=
' +(document.webinfoForm['
. GeneralUtility::quoteJSvalue('newOL[' . $languageId . '][' . $data['row']['uid'] . ']')
. '].checked ? '
. GeneralUtility::quoteJSvalue('&edit[pages][' . $data['row']['uid'] . ']=new')
. ' : \'\')'
;
$tCells[] = '<td class="' . $status . ' col-border-left">&nbsp;</td>';
$tCells[] = '<td class="' . $status . '">&nbsp;</td>';
$tCells[] = '<td class="' . $status . '">' . $info . '</td>';
}
}
}
$output .= '
<tr>
' . implode('
', $tCells) . '
</tr>';
}
// Put together HEADER:
$tCells = [];
$tCells[] = '<td>' . $lang->sL('LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_page') . '</td>';
if (is_array($langRecUids[0])) {
$editUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [
'edit' => [
'pages' => [
implode(',', $langRecUids[0]) => 'edit'
]
],
'columnsOnly' => 'title,nav_title,l18n_cfg,hidden',
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
]);
$editIco = '<a href="' . htmlspecialchars($editUrl)
. '" class="btn btn-default" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPageProperties'
) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
} else {
$editIco = '';
}
$tCells[] = '<td class="col-border-left" colspan="2">' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_default'
) . '&nbsp;' . $editIco . '</td>';
foreach ($this->siteLanguages as $siteLanguage) {
$languageId = $siteLanguage->getLanguageId();
if ($languageId === 0) {
continue;
}
if ($this->pObj->MOD_SETTINGS['lang'] == 0 || (int)$this->pObj->MOD_SETTINGS['lang'] === $languageId) {
// Title:
$tCells[] = '<td class="col-border-left">' . htmlspecialchars($siteLanguage->getTitle()) . '</td>';
// Edit language overlay records:
if (is_array($langRecUids[$languageId])) {
$editUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [
'edit' => [
'pages' => [
implode(',', $langRecUids[$languageId]) => 'edit'
]
],
'columnsOnly' => 'title,nav_title,hidden',
'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
]);
$editButton = '<a href="' . htmlspecialchars($editUrl)
. '" class="btn btn-default" title="' . $lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editLangOverlays'
) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
} else {
$editButton = '';
}
// Create new overlay records:
$createLink = (string)$uriBuilder->buildUriFromRoute('tce_db', [
'redirect' => GeneralUtility::getIndpEnv('REQUEST_URI')
]);
$newButton = '<a href="' .
htmlspecialchars($createLink) .
'" data-edit-url="' .
htmlspecialchars($createLink) .
'" class="btn btn-default disabled t3js-language-new-' .
$languageId .
'" title="' .
$lang->sL(
'LLL:EXT:info/Resources/Private/Language/locallang_webinfo.xlf:lang_getlangsta_createNewTranslationHeaders'
) .
'">' .
$this->iconFactory->getIcon('actions-document-new', Icon::SIZE_SMALL)->render() .
'</a>';
$tCells[] = '<td class="btn-group">' . $editButton . $newButton . '</td>';
$tCells[] = '<td>&nbsp;</td>';
}
}
$output =
'<div class="table-fit">' .
'<table class="table table-striped table-hover" id="langTable">' .
'<thead>' .
'<tr>' .
implode('', $tCells) .
'</tr>' .
'</thead>' .
'<tbody>' .
$output .
'</tbody>' .
'</table>' .
'</div>';
return $output;
}
/**
* Selects all system languages (from sys_language)
*
* @return array System language records in an array.
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0
*/
public function getSystemLanguages()
{
trigger_error('This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
if (!$this->getBackendUser()->isAdmin() && $this->getBackendUser()->groupData['allowed_languages'] !== '') {
$allowed_languages = array_flip(explode(',', $this->getBackendUser()->groupData['allowed_languages']));
}
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_language')
->select('*')
->from('sys_language')
->orderBy('sorting');
$res = $queryBuilder->execute();
$outputArray = [];
if (is_array($allowed_languages) && !empty($allowed_languages)) {
while ($output = $res->fetch()) {
if (isset($allowed_languages[$output['uid']])) {
$outputArray[] = $output;
}
}
} else {
$outputArray = $res->fetchAll();
}
return $outputArray;
}
/**
* Get an alternative language record for a specific page / language
*
* @param int $pageId Page ID to look up for.
* @param int $langId Language UID to select for.
* @return array translated pages record
*/
protected function getLangStatus($pageId, $langId)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
$queryBuilder
->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class))
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$result = $queryBuilder
->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq(
$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
)
)
->andWhere(
$queryBuilder->expr()->eq(
$GLOBALS['TCA']['pages']['ctrl']['languageField'],
$queryBuilder->createNamedParameter($langId, \PDO::PARAM_INT)
)
)
->execute();
$row = $result->fetch();
BackendUtility::workspaceOL('pages', $row);
if (is_array($row)) {
$row['_COUNT'] = $queryBuilder->count('uid')->execute()->fetchColumn(0);
$row['_HIDDEN'] = $row['hidden'] || (int)$row['endtime'] > 0 && (int)$row['endtime'] < $GLOBALS['EXEC_TIME'] || $GLOBALS['EXEC_TIME'] < (int)$row['starttime'];
}
$result->closeCursor();
return $row;
}
/**
* Counting content elements for a single language on a page.
*
* @param int $pageId Page id to select for.
* @param int $sysLang Sys language uid
* @return int Number of content elements from the PID where the language is set to a certain value.
*/
protected function getContentElementCount($pageId, $sysLang)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$count = $queryBuilder
->count('uid')
->from('tt_content')
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
)
)
->andWhere(
$queryBuilder->expr()->eq(
'sys_language_uid',
$queryBuilder->createNamedParameter($sysLang, \PDO::PARAM_INT)
)
)
->execute()
->fetchColumn(0);
return $count ?: '-';
}
/**
* Since the AbstractFunctionModule cannot access the current request yet, we'll do it "old school"
* to fetch the Site based on the current ID.
*/
protected function initializeSiteLanguages()
{
/** @var SiteInterface $currentSite */
$currentSite = $GLOBALS['TYPO3_REQUEST']->getAttribute('site');
$this->siteLanguages = $currentSite->getAvailableLanguages($this->getBackendUser(), false, (int)$this->id);
}
/**
* Called from InfoModuleController until deprecation removal in TYPO3 v10.0
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
public function checkExtObj()
{
if (is_array($this->extClassConf) && $this->extClassConf['name']) {
$this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
$this->extObj->init($this->pObj, $this->extClassConf);
// Re-write:
$this->pObj->MOD_SETTINGS = BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info');
}
}
/**
* Calls the main function inside ANOTHER sub-submodule which might exist.
*
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
*/
protected function extObjContent()
{
if (is_object($this->extObj)) {
return $this->extObj->main();
}
}
/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
/**
* Returns the current BE user.
*
* @return BackendUserAuthentication
*/
protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
/**
* @return PageRenderer
*/
protected function getPageRenderer(): PageRenderer
{
return GeneralUtility::makeInstance(PageRenderer::class);
}
}