Bug #67355
closedManually instantiated objects in 6.2 are incomplete
Added by Aimeos no-lastname-given over 9 years ago. Updated over 8 years ago.
0%
Description
When trying to instantiate the UriBuilder object in a scheduler task using the object manager, the resulting object is incomplete, esp. the ContentObjectRenderer instance is missing. This results in a fatal error when trying to generate a link.
Example code in scheduler task:
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( \TYPO3\CMS\Extbase\Object\ObjectManager::class );
$uriBuilder = $objectManager->get( \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class );
$uriBuilder->setTargetPageUid( $pageid )->setArguments( array() );
$url = $uriBuilder->buildFrontendUri();
This works in TYPO3 7.0+ but not in 6.2.12
Updated by Markus Klein over 9 years ago
Please post the fatal error and a stack trace, thanks.
Updated by Aimeos no-lastname-given over 9 years ago
Sorry, forgot the most important part:
PHP Fatal error: Call to a member function typoLink_URL() on a non-object in .../typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php on line 640, referer: http://localhost/typo3/mod.php?M=system_txschedulerM1&moduleToken=ba6d0897b460583aa3c2983f86412b5bfa071ae3&CMD=edit&tx_scheduler[uid]=2
This is the code that causes the problem:
public function buildFrontendUri() { // ... $uri = $this->contentObject->typoLink_URL($typolinkConfiguration); // $this->contentObject is null! return $uri; }
Before, the TSFE was set up like in this post: https://forum.typo3.org/index.php/m/733676/
Updated by Markus Klein over 9 years ago
This seems to be a very rough edge case.
You're faking a FE to work with UriBuilder. I do a pretty similar thing, but only on CMS 7, so no clue whether this works on 6.2.
https://gist.github.com/liayn/b09fa61878244f273493
Updated by Aimeos no-lastname-given over 9 years ago
Markus Klein wrote:
You're faking a FE to work with UriBuilder. I do a pretty similar thing, but only on CMS 7, so no clue whether this works on 6.2.
https://gist.github.com/liayn/b09fa61878244f273493
CMS 7 works but 6.2 does not. It's not related to faking the FE environment because we've implemented a command controller doing the same things with the same code but using the injected object manager. There it works without problems so I assume that there must be a difference in manually vs. injected object managers.
In standard setup task (fatal error):
Base::initFrontend( $pageid ); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( \TYPO3\CMS\Extbase\Object\ObjectManager::class ); $uriBuilder = $objectManager->get( \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class ); $uriBuilder->setTargetPageUid( $pageid )->setArguments( array() ); $url = $uriBuilder->buildFrontendUri();
In Extbase setup task (works):
Base::initFrontend( $pageid ); $uriBuilder = $this->objectManager->get( \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class ); $uriBuilder->setTargetPageUid( $pageid )->setArguments( array() ); $url = $uriBuilder->buildFrontendUri();
Faking the environment:
public static function initFrontend( $pageid ) { $type = 0; $name = 'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController'; if( !is_object( $GLOBALS['TT'] ) ) { $GLOBALS['TT'] = new \TYPO3\CMS\Core\TimeTracker\TimeTracker(); $GLOBALS['TT']->start(); } $GLOBALS['TSFE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( $name, $GLOBALS['TYPO3_CONF_VARS'], $pageid, $type ); $GLOBALS['TSFE']->connectToDB(); $GLOBALS['TSFE']->initFEuser(); $GLOBALS['TSFE']->determineId(); $GLOBALS['TSFE']->initTemplate(); $GLOBALS['TSFE']->getConfigArray(); if( \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded( 'realurl' ) ) { $rootline = \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine( $pageid ); $host = \TYPO3\CMS\Backend\Utility\BackendUtility::firstDomainRecord( $rootline ); $_SERVER['HTTP_HOST'] = $host; } }
The whole thing about faking the FE environment seems to be the only way to generated FE links in a setup task or a backend module. Hopefully, this will be easier one day.
Updated by Christian Kuhn over 9 years ago
Without digging into this too much: The extbase bootstrap does quite some stuff to prepare the environment. This issue has nothing todo with makeInstance vs. injection of object manager, but with the different scopes they are executed in (once in a "safe" extbase environment, once from within "native" core). So the reason for the UriBuilder behaving differently is located in this. The details of this issue are probably located deep in the system, and I tend to rather reject the issue as 'won't fix' in 6.2 and don't dig into this as long as it is not nailed that it worked in other 6.2 releases already and broke later in 6.2. I'm sorry, but I'd tend to say "for 6.2 you're up on your own, and enjoy it is working in 7".
Updated by Alexander Opitz over 9 years ago
- Target version changed from 6.2.13 to 6.2.14
Updated by Alexander Opitz over 9 years ago
- Status changed from New to Needs Feedback
- Target version changed from 6.2.14 to 6.2.15
Hi,
is it ok for you, that we close this issue as it is working in TYPO3 CMS 7?
Updated by Bernhard Berger over 9 years ago
I may be wrong here, but isn't the whole purpose of an LTS version that bugs get fixed until the support runs out? If that isn't how Long Term Support works then I'm not sure what they're good for.
Imho you can't just tell people (especially web agencies and bigger customers) to use an unproven TYPO3 7 version that doesn't have LTS, causes additional costs in maintaining and developing etc.
I sencierly think that closing bug issues just because it's inconvinient to fix is the wrong approach here.
Updated by Christian Kuhn over 9 years ago
- Status changed from Needs Feedback to Rejected
- Priority changed from Must have to Won't have this time
A change in the bootstrap in 6.2 jeopardizes the stability of this branch and is very unlikely to happen.
Updated by Philipp Rönsch about 9 years ago
This problem reappeared in 7.4 for me. Same picture instancing the UriBuilder even in FE context. I do the following in a service: (wich in turn is called by a custom PostProcessor for tx_form)
$targetPid = $GLOBALS['TSFE']->id;
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
$uriBuilder = $objectManager->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
$link = $uriBuilder->setTargetPageUid($targetPid)->setArguments(array())->buildFrontendUri();
Result:
Fatal error: Call to a member function typoLink_URL() on null in C:\dev\xampp\htdocs\typo3_src-7.4.0\typo3\sysext\extbase\Classes\Mvc\Web\Routing\UriBuilder.php on line 669
Updated by Markus Klein about 9 years ago
@Philipp: This can not work if the ConfigurationManager has no ContentObjectRenderer assigned. If you bootstrap your own extbase environment you have to look at the Core implementation how this is done.
Why do you use the UriBuilder for a simple link? What about $GLOBALS['TSFE']->cObj->typolink()
?
UriBuilder is just a convenience wrapper around this Core API.
Updated by Aimeos no-lastname-given almost 9 years ago
The problem is in 7.6 LTS too.
This means it's impossible to create FE URLs from command line tasks using the UriBuilder because the object manager creates incomplete objects.
Updated by Daniel Dorndorf over 8 years ago
I wrote myself a service that instanciates the uribuilder always correcty
(rel: https://github.com/featdd/dpn_glossary/blob/master/Classes/Service/LinkService.php)
use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManager; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; class PageService implements SingletonInterface { /** * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder */ protected $uriBuilder; /** * @return PageService */ public function __construct() { /** @var ObjectManager $objectManager */ $objectManager = GeneralUtility::makeInstance(ObjectManager::class); /** @var ConfigurationManager $configurationManager */ $configurationManager = $objectManager->get(ConfigurationManager::class); /** @var ContentObjectRenderer $contentObjectRenderer */ $contentObjectRenderer = $objectManager->get(ContentObjectRenderer::class); $configurationManager->setContentObject($contentObjectRenderer); $this->uriBuilder = $objectManager->get(UriBuilder::class); $this->uriBuilder->injectConfigurationManager($configurationManager); } /** * Creates a link to a single page * * @param int $pageId * @param int $sysLanguageUid * @return string */ public function getPageLink($pageId, $sysLanguageUid = 0) { return $this->uriBuilder ->reset() ->setTargetPageUid($pageId) ->setArguments( 0 < $sysLanguageUid ? array('L' => $sysLanguageUid) : array() ) ->buildFrontendUri(); } }