Closed thomaszbz closed 9 years ago
The reason for this to happen is that
TypoScriptFrontendController->initPageRenderer()
is somehow executed. This function makes a
protected function initPageRenderer() {
//...
$this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
//...
$this->pageRenderer->setBackPath(TYPO3_mainDir);
}
with constant TYPO3_mainDir = 'typo3/'. So it sets a Frontend Backpath typo3/
which actually is responsible for this bug. A workaround would be to setBackPath(NULL), then everything works. But we can't do that of course in TYPO3's TypoScriptFrontendController.
When I throw an exception here (for a test):
protected function initPageRenderer() {
$this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
if ((TYPO3_MODE == 'BE')) {
throw new \Exception("You should not prefix assets with 'typo3/' in the Backend");
}else{
$this->pageRenderer->setBackPath(TYPO3_mainDir);
}
}
then the exception gets thrown for the reproduction steps and I get the following stacktrace:
Exception: 'You should not prefix assets with 'typo3/' in the Backend'
Exception thrown in file
/var/webadmin/typo3_src/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php in line 913.
28 TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::initPageRenderer()
/var/webadmin/typo3_src/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php:
00889: $this->uniqueString = md5(microtime());
00890: $this->csConvObj = GeneralUtility::makeInstance(CharsetConverter::class);
> 00891: $this->initPageRenderer();
00892: // Call post processing function for constructor:
00893: if (is_array($this->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['tslib_fe-PostProc'])) {
27 TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::__construct(array, "1", 0, "", "", "", "", "")
/var/webadmin/typo3_src/typo3/sysext/core/Classes/Utility/GeneralUtility.php:
04351: break;
04352: case 9:
> 04353: $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
04354: break;
04355: default:
26 TYPO3\CMS\Core\Utility\GeneralUtility::instantiateClass("TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController", array)
/var/webadmin/typo3_src/typo3/sysext/core/Classes/Utility/GeneralUtility.php:
04309: }
04310: // Create new instance and call constructor with parameters
> 04311: $instance = static::instantiateClass($finalClassName, func_get_args());
04312: // Register new singleton instance
04313: if ($instance instanceof SingletonInterface) {
25 TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController", array, "1", 0, "", "", "", "", "")
24 call_user_func_array(array, array)
/var/webadmin/typo3_src/typo3/sysext/extbase/Classes/Object/Container/Container.php:
00199: $constructorArguments = $this->getConstructorArguments($className, $classInfo, $givenConstructorArguments);
00200: array_unshift($constructorArguments, $className);
> 00201: $instance = call_user_func_array(array(\TYPO3\CMS\Core\Utility\GeneralUtility::class, 'makeInstance'), $constructorArguments);
00202: if ($classIsSingleton) {
00203: $this->singletonInstances[$className] = $instance;
23 TYPO3\CMS\Extbase\Object\Container\Container::instanciateObject(TYPO3\CMS\Extbase\Object\Container\ClassInfo, array)
/var/webadmin/typo3_src/typo3/sysext/extbase/Classes/Object/Container/Container.php:
00172: $this->prototypeObjectsWhichAreCurrentlyInstanciated[$className] = TRUE;
00173: }
> 00174: $instance = $this->instanciateObject($classInfo, $givenConstructorArguments);
00175: $this->injectDependencies($instance, $classInfo);
00176: $this->initializeObject($instance, $classInfo);
22 TYPO3\CMS\Extbase\Object\Container\Container::getInstanceInternal("TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController", array)
/var/webadmin/typo3_src/typo3/sysext/extbase/Classes/Object/Container/Container.php:
00119: public function getInstance($className, $givenConstructorArguments = array()) {
00120: $this->prototypeObjectsWhichAreCurrentlyInstanciated = array();
> 00121: return $this->getInstanceInternal($className, $givenConstructorArguments);
00122: }
00123:
21 TYPO3\CMS\Extbase\Object\Container\Container::getInstance("TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController", array)
/var/webadmin/typo3_src/typo3/sysext/extbase/Classes/Object/ObjectManager.php:
00092: $instance = call_user_func_array(array(\TYPO3\CMS\Core\Utility\GeneralUtility::class, 'makeInstance'), $arguments);
00093: } else {
> 00094: $instance = $this->objectContainer->getInstance($objectName, $arguments);
00095: }
00096: return $instance;
20 TYPO3\CMS\Extbase\Object\ObjectManager::get("TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController", array, "1", 0)
/var/www/typo3/typo3conf/ext/metaseo/Classes/Hook/TCA/RobotsTxtDefault.php:
00100: $rootPageId,
00101: 0
> 00102: );
00103:
00104: $GLOBALS['TSFE'] = $tsfeController;
19 Metaseo\Metaseo\Hook\TCA\RobotsTxtDefault::main(array, TYPO3\CMS\Backend\Form\FormEngine)
18 call_user_func_array(array, array)
/var/webadmin/typo3_src/typo3/sysext/core/Classes/Utility/GeneralUtility.php:
04172: }
04173: // Call method:
> 04174: $content = call_user_func_array(array(&$classObj, $parts[1]), array(&$params, &$ref));
04175: } else {
04176: $errorMsg = 'No method name \'' . $parts[1] . '\' in class ' . $parts[0];
17 TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction("Metaseo\Metaseo\Hook\TCA\RobotsTxtDefault->main", array, TYPO3\CMS\Backend\Form\FormEngine)
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Element/UserElement.php:
00044: $parameterArray,
00045: $dummyFormEngine
> 00046: );
00047: return $resultArray;
00048: }
16 TYPO3\CMS\Backend\Form\Element\UserElement::render()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php:
00180: /** @var NodeFactory $nodeFactory */
00181: $nodeFactory = $this->globalOptions['nodeFactory'];
> 00182: $resultArray = $nodeFactory->create($options)->render();
00183: $html = $resultArray['html'];
00184:
15 TYPO3\CMS\Backend\Form\Container\SingleFieldContainer::render()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Container/PaletteAndSingleContainer.php:
00218: /** @var NodeFactory $nodeFactory */
00219: $nodeFactory = $this->globalOptions['nodeFactory'];
> 00220: $singleFieldContentArray = $nodeFactory->create($options)->render();
00221:
00222: if (!empty($singleFieldContentArray['html'])) {
14 TYPO3\CMS\Backend\Form\Container\PaletteAndSingleContainer::createPaletteContentArray("pallette_robotstxt")
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Container/PaletteAndSingleContainer.php:
00117: $fieldName = $fieldConfiguration['fieldName'];
00118: if ($fieldName === '--palette--') {
> 00119: $paletteElementArray = $this->createPaletteContentArray($fieldConfiguration['paletteName']);
00120: if (!empty($paletteElementArray)) {
00121: $mainStructureCounter ++;
13 TYPO3\CMS\Backend\Form\Container\PaletteAndSingleContainer::render()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Container/TabsContainer.php:
00090: /** @var NodeFactory $nodeFactory */
00091: $nodeFactory = $this->globalOptions['nodeFactory'];
> 00092: $childArray = $nodeFactory->create($options)->render();
00093:
00094: $tabsContent[] = array(
12 TYPO3\CMS\Backend\Form\Container\TabsContainer::render()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/Container/FullRecordContainer.php:
00109: /** @var NodeFactory $nodeFactory */
00110: $nodeFactory = $this->globalOptions['nodeFactory'];
> 00111: $resultArray = $nodeFactory->create($options)->render();
00112: } else {
00113: $options['renderType'] = 'noTabsContainer';
11 TYPO3\CMS\Backend\Form\Container\FullRecordContainer::render()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Form/FormEngine.php:
00276: $options = $this->getConfigurationOptionsForChildElements();
00277: $options['renderType'] = 'fullRecordContainer';
> 00278: $resultArray = $this->nodeFactory->create($options)->render();
00279:
00280: $content = $resultArray['html'];
10 TYPO3\CMS\Backend\Form\FormEngine::getMainFields("tx_metaseo_setting_root", array)
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Controller/EditDocumentController.php:
01073: }
01074: } else {
> 01075: $panel .= $this->tceforms->getMainFields($table, $rec);
01076: }
01077: $panel = $this->tceforms->wrapTotal($panel, $rec, $table);
9 TYPO3\CMS\Backend\Controller\EditDocumentController::makeEditForm()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Controller/EditDocumentController.php:
00873: }
00874: // Creating the editing form, wrap it with buttons, document selector etc.
> 00875: $editForm = $this->makeEditForm();
00876: if ($editForm) {
00877: $this->firstEl = reset($this->elementsData);
8 TYPO3\CMS\Backend\Controller\EditDocumentController::main()
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Controller/EditDocumentController.php:
01663:
> 01664: $this->init();
01665: $this->main();
01666:
01667: /** @var Response $response */
7 TYPO3\CMS\Backend\Controller\EditDocumentController::processRequest(TYPO3\CMS\Core\Http\ServerRequest)
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Http/RequestHandler.php:
00185: throw new \RuntimeException('Requested controller "' . $className . '" does not implement the ControllerInterface', 1425389452);
00186: }
> 00187: return $controller->processRequest($request);
00188: }
00189: }
6 TYPO3\CMS\Backend\Http\RequestHandler::dispatch(TYPO3\CMS\Core\Http\ServerRequest)
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Http/RequestHandler.php:
00090: // Check if the router has the available route and dispatch.
00091: if ($routingEnabled) {
> 00092: return $this->dispatch($request);
00093: }
00094:
5 TYPO3\CMS\Backend\Http\RequestHandler::handleRequest(TYPO3\CMS\Core\Http\ServerRequest)
/var/webadmin/typo3_src/typo3/sysext/core/Classes/Core/Bootstrap.php:
00286:
00287: // Execute the command which returns a Response object or NULL
> 00288: $this->response = $requestHandler->handleRequest($request);
00289: return $this;
00290: }
4 TYPO3\CMS\Core\Core\Bootstrap::handleRequest(TYPO3\CMS\Core\Http\ServerRequest)
/var/webadmin/typo3_src/typo3/sysext/backend/Classes/Http/Application.php:
00090: */
00091: public function run(callable $execute = NULL) {
> 00092: $this->bootstrap->handleRequest($this->request);
00093:
00094: if ($execute !== NULL) {
3 TYPO3\CMS\Backend\Http\Application::run()
/var/webadmin/typo3_src/typo3/index.php:
00018: call_user_func(function() {
00019: $classLoader = require __DIR__ . '/../vendor/autoload.php';
> 00020: (new \TYPO3\CMS\Backend\Http\Application($classLoader))->run();
00021: });
2 {closure}()
1 call_user_func(Closure)
/var/webadmin/typo3_src/typo3/index.php:
00019: $classLoader = require __DIR__ . '/../vendor/autoload.php';
00020: (new \TYPO3\CMS\Backend\Http\Application($classLoader))->run();
> 00021: });
According to the Stacktrace, the instanciation of TypoScriptFrontendcontroller is triggered by
Metaseo\Metaseo\Hook\TCA\RobotsTxtDefault::main(array, TYPO3\CMS\Backend\Form\FormEngine)
For instance, I'll reset the backPath to null after the use of TSFE has finished. That fixes it. This is a workaround for the regression in TYPO3 CMS.
/**
* Sets backPath of PageRenderer back to null (for Backend)
*/
protected function cleanUpPageRendererBackPath()
{
$pageRenderer = $this->getPageRenderer();
$pageRenderer->setBackPath(null);
}
Tested with:
Reproduce with:
Instead, prefix typo3/ is wrong here, as it's a relative path and the URL of the page which initiates the request of assets already has prefix http(s)://typo3/. Adding another prefix typo3/ results in http(s):typo3/typo3/ which will be 404'd by the web server.
Javascript console output:
Investigation
Summary: Whenever TypoScriptFrontendController is instanciated it also instanciates PageRenderer (which is a Singleton!) and sets the backPath to
typo3/
which is a change in behaviour which also affects URL creation of Backend Assets.Affected Versions
This is a regression in TYPO3 CMS 7.4.0 introduced with commit 43ab6508e7eb01a5b9cca294257349d3e4a53995 https://review.typo3.org/#/c/41239/ https://review.typo3.org/#/c/41239/5/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
Deprecation message does not include the breaking change we are faced with here. https://docs.typo3.org/typo3cms/extensions/core/latest/Changelog/7.4/Deprecation-68074-DeprecateGetPageRenderer.html
Forge issue
https://forge.typo3.org/issues/69319