how to generate Frontend URI in Scheduler Command (TYPO3 9)

Viewed 2046

What is the best way to generate frontend URIs in a scheduler command in TYPO3 v9.

I have seen attempts by initializing the TSFE manually, but for me this seems fishy. Are there any other ways?

2 Answers

The proper way to create links in any context (FE/BE/CLI) is by using the PageRouter. This router is always attached to a site, so you will need to retrieve the correct site first, e.g. by using the SiteFinder. After that you can use PageRouter::generateUri().

Complete example:

use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;

$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageUid);
$arguments = [
    'foo' => 1,
];

// E.g.: "https://example.org/slug-of-page/?foo=1"
$uri = (string)$site->getRouter()->generateUri((string)$pageUid, $arguments);

Notice that this API knows nothing about Extbase and passes through $arguments to the URI so if you need to mimic the behavior of the Extbase UriBuilder you'll need to do that yourself:

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Service\ExtensionService;

$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$extensionService = $objectManager->get(ExtensionService::class);
// E.g. "tx_acme_test"
$argumentsPrefix = $extensionService->getPluginNamespace($extensionName, $pluginName);
$arguments = [
    $argumentsPrefix => [
      'action' => $actionName, // E.g. "bar"
      'controller' => $controllerName, // E.g. "Foo"
      'foo' => 42,
    ],
];

// E.g.: "https://example.org/slug-of-page/?tx_acme_test[action]=bar&tx_acme_test[controller]=Foo&tx_acme_test[foo]=42"
// Or with a route enhancer: "https://example.org/slug-of-page/detail/slug-of-foo"
$uri = (string)$site->getRouter()->generateUri((string)$pageUid, $arguments);

Depending on your needs, the native way described by @mathias-brodala might not be sufficient. In those cases you will need a proper TSFE otherwise you do not have all the TypoScript settings that might influence link generation.

For these cases you basically need to create an instance of the TypoScriptFrontendController yourself, call setup methods and inject real or mocked dependencies like FrontendUserAuthentication depending on your usecase.

A working solution for TYPO3v9, for instance, can be found in the rx_scheduled_social extension.

Related