diff --git a/Classes/Backend/Form/FormBuilder.php b/Classes/Backend/Form/FormBuilder.php index 706b9de1..d0cb44e7 100644 --- a/Classes/Backend/Form/FormBuilder.php +++ b/Classes/Backend/Form/FormBuilder.php @@ -2,13 +2,15 @@ namespace Sys25\RnBase\Backend\Form; +use Sys25\RnBase\Backend\Module\IModule; use Sys25\RnBase\Utility\TYPO3; use tx_rnbase; +use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord; /*************************************************************** * Copyright notice * - * (c) 2016-2021 Rene Nitzsche (rene@system25.de) + * (c) 2016-2025 Rene Nitzsche (rene@system25.de) * All rights reserved * * This library is free software; you can redistribute it and/or @@ -49,6 +51,11 @@ class FormBuilder */ private $formResultCompiler; + /** + * @var IModule + */ + private $module; + /** * @var array */ @@ -57,7 +64,7 @@ class FormBuilder public function __construct() { /** - * @var \TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord + * @var TcaDatabaseRecord */ $formDataGroup = tx_rnbase::makeInstance('TYPO3\\CMS\\Backend\\Form\\FormDataGroup\\TcaDatabaseRecord'); $this->formDataCompiler = tx_rnbase::makeInstance('TYPO3\\CMS\\Backend\\Form\\FormDataCompiler', $formDataGroup); @@ -65,8 +72,9 @@ public function __construct() $this->formResultCompiler = tx_rnbase::makeInstance('TYPO3\\CMS\\Backend\\Form\\FormResultCompiler'); } - public function initDefaultBEmode() + public function setModule(IModule $module) { + $this->module = $module; } /** @@ -128,7 +136,13 @@ protected function compileFormData($table, $uid, $record) 'returnUrl' => '', ]; } - $this->formDataCache[$cacheKey] = $this->formDataCompiler->compile($formDataCompilerInput); + $formDataCompilerInput['request'] = $this->module->getRequest(); + + if (TYPO3::isTYPO130OrHigher()) { + $this->formDataCache[$cacheKey] = $this->formDataCompiler->compile($formDataCompilerInput, tx_rnbase::makeInstance(TcaDatabaseRecord::class)); + } else { + $this->formDataCache[$cacheKey] = $this->formDataCompiler->compile($formDataCompilerInput); + } if ($this->isNEWRecord($uid)) { // Override generated with given uid $this->formDataCache[$cacheKey]['databaseRow']['uid'] = $uid; @@ -171,11 +185,7 @@ public function getSoloField($table, $row, $fieldName) */ public function printNeededJSFunctions_top() { - if (TYPO3::isTYPO90OrHigher()) { - $result = $this->formResultCompiler->addCssFiles(); - } else { - $result = $this->formResultCompiler->JStop(); - } + $result = $this->formResultCompiler->addCssFiles(); return $result; } diff --git a/Classes/Backend/Form/ToolBox.php b/Classes/Backend/Form/ToolBox.php index d7d4979c..28e80c59 100644 --- a/Classes/Backend/Form/ToolBox.php +++ b/Classes/Backend/Form/ToolBox.php @@ -10,6 +10,7 @@ use Sys25\RnBase\Backend\Utility\Icons; use Sys25\RnBase\Backend\Utility\TCA; use Sys25\RnBase\Frontend\Request\Parameters; +use Sys25\RnBase\Utility\LanguageTool; use Sys25\RnBase\Utility\Link; use Sys25\RnBase\Utility\Math; use Sys25\RnBase\Utility\Misc; @@ -107,7 +108,7 @@ public function init(DocumentTemplate $doc, IModule $module) // TCEform für das Formular erstellen $this->form = tx_rnbase::makeInstance(FormBuilder::class); - $this->form->initDefaultBEmode(); + $this->form->setModule($module); } /** @@ -1150,7 +1151,7 @@ public function showTabMenu($pid, $name, $modName, $entries) ]; $SETTINGS = BackendUtility::getModuleData( $MENU, - T3General::_GP('SET'), + Parameters::_GP('SET'), $modName ); $menuItems = []; @@ -1351,7 +1352,7 @@ protected function buildDataHandlerUri(string $params, $redirect) } /** - * @return LanguageService|\TYPO3\CMS\Lang\LanguageService + * @return LanguageTool */ public function getLanguageService() { diff --git a/Classes/Backend/Module/BaseModFunc.php b/Classes/Backend/Module/BaseModFunc.php index 369ac10b..f9f5338e 100644 --- a/Classes/Backend/Module/BaseModFunc.php +++ b/Classes/Backend/Module/BaseModFunc.php @@ -41,7 +41,7 @@ abstract class BaseModFunc implements IModFunc /* @var $mod IModule */ protected $mod; - public function init(IModule $module, $conf) + private function init(IModule $module, $conf) { $this->mod = $module; } @@ -64,7 +64,9 @@ public function getModule() public function main(?ServerRequestInterface $request = null) { if (TYPO3::isTYPO121OrHigher()) { + /** @var IModule $modFuncFrame */ $modFuncFrame = tx_rnbase::makeInstance(ModFuncFrame::class); + $this->init($modFuncFrame, []); return $modFuncFrame->render($this, function () { return $this->renderOutput(); }, $request); } diff --git a/Classes/Backend/Module/BaseModule.php b/Classes/Backend/Module/BaseModule.php index a3e6b589..942075f0 100644 --- a/Classes/Backend/Module/BaseModule.php +++ b/Classes/Backend/Module/BaseModule.php @@ -159,7 +159,7 @@ protected function prepareModuleParts($parts) $parts->setContent($this->moduleContent()); $parts->setButtons($this->getButtons()); - $parts->setTitle($GLOBALS['LANG']->getLL('title')); + $parts->setTitle($this->getFormTool()->getLL('title')); $parts->setFuncMenu($this->getFuncMenu()); // if we got no array the user got no permissions for the // selected page or no page is selected @@ -625,6 +625,6 @@ public function getRouteIdentifier() public function getLanguageService() { - return $GLOBALS['LANG']; + return $this->getFormTool()->getLanguageService() } } diff --git a/Classes/Backend/Module/BaseScriptClass.php b/Classes/Backend/Module/BaseScriptClass.php index 83bad2dd..c0a9afac 100644 --- a/Classes/Backend/Module/BaseScriptClass.php +++ b/Classes/Backend/Module/BaseScriptClass.php @@ -72,6 +72,8 @@ * $GLOBALS['SOBE']->main(); * * TODO: check TYPO3 versions used. + * + * @deprecated */ abstract class BaseScriptClass { diff --git a/Classes/Backend/Module/IModFunc.php b/Classes/Backend/Module/IModFunc.php index 5b18f3f4..5bee6c62 100644 --- a/Classes/Backend/Module/IModFunc.php +++ b/Classes/Backend/Module/IModFunc.php @@ -37,7 +37,7 @@ interface IModFunc public const ICON_FATAL = 3; - public function init(IModule $module, $conf); + // public function init(IModule $module, $conf); /** * Module identifier for ts_config. diff --git a/Classes/Backend/Module/IModule.php b/Classes/Backend/Module/IModule.php index aa543617..601b785f 100644 --- a/Classes/Backend/Module/IModule.php +++ b/Classes/Backend/Module/IModule.php @@ -2,9 +2,11 @@ namespace Sys25\RnBase\Backend\Module; +use Psr\Http\Message\ServerRequestInterface; use Sys25\RnBase\Backend\Form\ToolBox; use Sys25\RnBase\Backend\Template\Override\DocumentTemplate; use Sys25\RnBase\Configuration\ConfigurationInterface; +use Sys25\RnBase\Utility\LanguageTool; /*************************************************************** * Copyright notice @@ -36,6 +38,8 @@ interface IModule */ public function getDoc(); + public function getRequest(): ?ServerRequestInterface; + /** * Returns the form tool. * @@ -76,6 +80,8 @@ public function getRouteIdentifier(); */ public function getPid(); + public function render(IModFunc $modFunc, callable $renderFunc, ServerRequestInterface $request); + /** * Submenu String for the marker ###TABS###. * @@ -105,7 +111,7 @@ public function setSelector($selectorString); public function addMessage($message, $title = '', $severity = 0, $storeInSession = false); /** - * @return \TYPO3\CMS\Core\Localization\LanguageService + * @return LanguageTool */ public function getLanguageService(); } diff --git a/Classes/Backend/Module/ModFuncFrame.php b/Classes/Backend/Module/ModFuncFrame.php index e6b4c34a..8c171892 100644 --- a/Classes/Backend/Module/ModFuncFrame.php +++ b/Classes/Backend/Module/ModFuncFrame.php @@ -56,6 +56,8 @@ class ModFuncFrame implements IModule protected $doc; protected $tabs; + private ?ServerRequestInterface $request = null; + /** * @var array */ @@ -74,8 +76,14 @@ public function __construct( $this->pageRenderer = $pageRenderer; } + public function getRequest(): ?ServerRequestInterface + { + return $this->request; + } + public function render(IModFunc $modFunc, callable $renderFunc, ServerRequestInterface $request) { + $this->request = $request; $this->modFunc = $modFunc; $this->moduleIdentifier = $modFunc->getModuleIdentifier(); $this->id = (int) ($request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? 0); @@ -88,11 +96,11 @@ public function render(IModFunc $modFunc, callable $renderFunc, ServerRequestInt } $this->getLanguageService()->registerLangFile('EXT:rn_base/Resources/Private/Language/locallang.xlf'); - $this->modFunc->init($this, [ - // 'form' => $this->getFormTag(), - // 'docstyles' => $this->getDocStyles(), - // 'template' => $this->getModuleTemplateFilename(), - ]); + // $this->modFunc->init($this, [ + // // 'form' => $this->getFormTag(), + // // 'docstyles' => $this->getDocStyles(), + // // 'template' => $this->getModuleTemplateFilename(), + // ]); // Rahmen rendern $this->moduleTemplate = $this->createModuleTemplate($request); // Die Variable muss gesetzt sein. diff --git a/Classes/Backend/Template/ModuleTemplate.php b/Classes/Backend/Template/ModuleTemplate.php index c6e30787..7eb3d539 100644 --- a/Classes/Backend/Template/ModuleTemplate.php +++ b/Classes/Backend/Template/ModuleTemplate.php @@ -85,15 +85,15 @@ protected function renderContent12(ModuleParts $parts) { /** @var ModuleTemplateFactory $factory */ $factory = tx_rnbase::makeInstance(ModuleTemplateFactory::class); - $view = $factory->create($this->options['request']); + $moduleTemplate = $factory->create($this->options['request']); $content = ''; // $moduleTemplate->getPageRenderer()->loadJquery(); - $view->getDocHeaderComponent()->setMetaInformation($parts->getPageInfo()); - $this->registerMenu($view, $parts); + $moduleTemplate->getDocHeaderComponent()->setMetaInformation($parts->getPageInfo()); + $this->registerMenu($moduleTemplate, $parts); $content .= $this->options['form'] ?? $this->module->buildFormTag(); - $view->makeDocHeaderModuleMenu(['id' => $this->module->getPid()]); + $moduleTemplate->makeDocHeaderModuleMenu(['id' => $this->module->getPid()]); if (is_string($parts->getFuncMenu())) { // Fallback für Module, die das FuncMenu selbst als String generieren @@ -106,7 +106,7 @@ protected function renderContent12(ModuleParts $parts) $content .= ''; // Es ist sinnvoll, die Buttons nach der Generierung des Content zu generieren - $this->generateButtons($view, $parts); + $this->generateButtons($moduleTemplate, $parts); // Workaround: jumpUrl wieder einfügen // @TODO Weg finden dass ohne das DocumentTemplate zu machen @@ -115,9 +115,12 @@ protected function renderContent12(ModuleParts $parts) // @TODO haupttemplate eines BE moduls enthält evtl. JS/CSS etc. // das wurde bisher über das DocumentTemplate eingefügt, was jetzt // nicht mehr geht. Dafür muss ein Weg gefunden werden. - $view->setContent($content); + // $moduleTemplate->setContent($content); + $moduleTemplate->assign('content', $content); - return $view->renderContent(); + return $moduleTemplate->render('ModuleTemplate/Module.html'); + + return $moduleTemplate->renderContent(); } /** diff --git a/Classes/Backend/Template/Override/DocumentTemplate.php b/Classes/Backend/Template/Override/DocumentTemplate.php index a6c3fc25..1dc32482 100644 --- a/Classes/Backend/Template/Override/DocumentTemplate.php +++ b/Classes/Backend/Template/Override/DocumentTemplate.php @@ -4,10 +4,13 @@ use Sys25\RnBase\Backend\Utility\Icons; use Sys25\RnBase\Utility\Files; +use Sys25\RnBase\Utility\LanguageTool; use Sys25\RnBase\Utility\Strings; use Sys25\RnBase\Utility\T3General; use Sys25\RnBase\Utility\TYPO3; +use tx_rnbase; use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Localization\Locale; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -97,17 +100,22 @@ function jumpToUrl(URL) { /** @var LanguageService */ private $lang; + /** @var LanguageTool */ + private $languageTool; /** * Constructor. */ - public function __construct() - { + public function __construct( + ?LanguageTool $languageTool = null, + ?\TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService = null + ) { + $this->languageTool = $languageTool ?? tx_rnbase::makeInstance(LanguageTool::class); + $this->lang = $this->languageTool->getLanguageService(); // Initializes the page rendering object: $this->initPageRenderer(); - $this->flashMessageService = T3General::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class); - $this->lang = $GLOBALS['LANG']; + $this->flashMessageService = $flashMessageService ?? tx_rnbase::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class); } /** @@ -429,8 +437,13 @@ protected function initPageRenderer() if (null !== $this->pageRenderer) { return; } + $lang = $this->getLangSrv()->lang; + if (TYPO3::isTYPO121OrHigher()) { + $lang = new Locale($lang); + } + $this->pageRenderer = T3General::makeInstance(PageRenderer::class); - $this->pageRenderer->setLanguage($GLOBALS['LANG']->lang); + $this->pageRenderer->setLanguage($lang); $this->pageRenderer->enableConcatenateCss(); $this->pageRenderer->enableConcatenateJavascript(); $this->pageRenderer->enableCompressCss(); diff --git a/Classes/Backend/Utility/BackendUtility.php b/Classes/Backend/Utility/BackendUtility.php index 104f99a5..dc5fd24a 100644 --- a/Classes/Backend/Utility/BackendUtility.php +++ b/Classes/Backend/Utility/BackendUtility.php @@ -3,10 +3,15 @@ namespace Sys25\RnBase\Backend\Utility; use InvalidArgumentException; +use Psr\Http\Message\ServerRequestInterface; use Sys25\RnBase\Utility\T3General; use Sys25\RnBase\Utility\TYPO3; use tx_rnbase; +use TYPO3\CMS\Backend\Routing\Route; use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Core\Environment; +use TYPO3\CMS\Core\Utility\HttpUtility; +use TYPO3\CMS\Core\Utility\PathUtility; /*************************************************************** * Copyright notice @@ -224,4 +229,92 @@ public static function editOnClick($params) return 'window.location.href='.T3General::quoteJSvalue((string) $uri.'&returnUrl=').'+'.$returnUrl.'; return false;'; } + + /** + * Returns a selector box to switch the view + * Based on BackendUtility::getFuncMenu() but done as new function because it has another purpose. + * Mingling with getFuncMenu would harm the docHeader Menu. + * + * @param mixed $mainParams The "&id=" parameter value to be sent to the module, but it can be also a parameter array which will be passed instead of the &id=... + * @param string $elementName The form elements name, probably something like "SET[...] + * @param string|int $currentValue the value to be selected currently + * @param array $menuItems An array with the menu items for the selector box + * @param string $script The script to send the &id to, if empty it's automatically found + * @param string $addParams additional parameters to pass to the script + * @param array $additionalAttributes Additional attributes for the select element + * @return string HTML code for selector box + * + * @deprecated since TYPO3 v12.2. will be removed in TYPO3 v13.0. + */ + public static function getDropdownMenu( + $mainParams, + $elementName, + $currentValue, + $menuItems, + $script = '', + $addParams = '', + array $additionalAttributes = [] + ) { + if (!is_array($menuItems) || count($menuItems) <= 1) { + return ''; + } + $scriptUrl = self::buildScriptUrl($mainParams, $addParams, $script); + $options = []; + foreach ($menuItems as $value => $label) { + $options[] = ''; + } + $dataMenuIdentifier = str_replace(['SET[', ']'], '', $elementName); + $dataMenuIdentifier = T3General::camelCaseToLowerCaseUnderscored($dataMenuIdentifier); + $dataMenuIdentifier = str_replace('_', '-', $dataMenuIdentifier); + // relies on module 'TYPO3/CMS/Backend/ActionDispatcher' + $attributes = T3General::implodeAttributes(array_merge([ + 'name' => $elementName, + 'data-menu-identifier' => $dataMenuIdentifier, + 'data-global-event' => 'change', + 'data-action-navigate' => '$data=~s/$value/', + 'data-navigate-value' => $scriptUrl.'&'.$elementName.'=${value}', + ], $additionalAttributes), true); + + return ' +