Skip to content

Commit

Permalink
Refactor the language bootstrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
cundd committed May 17, 2019
1 parent 1db67a4 commit aa1404e
Showing 1 changed file with 112 additions and 46 deletions.
158 changes: 112 additions & 46 deletions Classes/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Frontend\Utility\EidUtility;
use TYPO3\CMS\Lang\LanguageService;
use function class_exists;
use function intval;
use function is_int;
use function is_string;


/**
Expand All @@ -26,6 +30,8 @@ class Bootstrap
*
* @param TypoScriptFrontendController|null $frontendController
* @return TypoScriptFrontendController
* @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException
* @throws \TYPO3\CMS\Core\Http\ImmediateResponseException
*/
public function init(TypoScriptFrontendController $frontendController = null)
{
Expand Down Expand Up @@ -57,9 +63,6 @@ public function initializeLanguageObject()
}
}

/**
*
*/
private function initializeTimeTracker()
{
if (!isset($GLOBALS['TT']) || !is_object($GLOBALS['TT'])) {
Expand All @@ -82,7 +85,7 @@ private function buildFrontendController(int $pageUid): TypoScriptFrontendContro

return $objectManager->get(
TypoScriptFrontendController::class,
$GLOBALS['TYPO3_CONF_VARS'], // can be removed in TYPO3 v8
null, // previously TYPO3_CONF_VARS
$pageUid,
0, // Type
0, // no_cache
Expand Down Expand Up @@ -117,6 +120,8 @@ private function getFrontendControllerIsInitialized(): bool
* Configure the given frontend controller
*
* @param TypoScriptFrontendController $frontendController
* @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException
* @throws \TYPO3\CMS\Core\Http\ImmediateResponseException
*/
private function configureFrontendController(TypoScriptFrontendController $frontendController)
{
Expand All @@ -135,8 +140,11 @@ private function configureFrontendController(TypoScriptFrontendController $front
$frontendController->determineId();
$frontendController->getConfigArray();

$this->setRequestedLanguage($frontendController);
$frontendController->settingLanguage();
$this->detectAndSetRequestedLanguage($frontendController);
//try {
// $frontendController->settingLanguage();
//} catch (\RuntimeException $exception) {
//}
$frontendController->settingLocale();
}

Expand All @@ -145,40 +153,57 @@ private function configureFrontendController(TypoScriptFrontendController $front
*
* @param TypoScriptFrontendController $frontendController
*/
private function setRequestedLanguage(TypoScriptFrontendController $frontendController)
private function detectAndSetRequestedLanguage(TypoScriptFrontendController $frontendController)
{
if (!isset($GLOBALS['TYPO3_REQUEST']) || !class_exists(SiteMatcher::class)) {
$this->setRequestedLanguage($frontendController, $this->getRequestedLanguageUid($frontendController));

return;
}

// support new TYPO3 v9.2 Site Handling until middleware concept is implemented
// see https://github.com/cundd/rest/issues/59
if (isset($GLOBALS['TYPO3_REQUEST']) && class_exists(SiteMatcher::class)) {
/** @var ServerRequestInterface $request */
$request = $GLOBALS['TYPO3_REQUEST'];
/** @var ServerRequestInterface $request */
$request = $GLOBALS['TYPO3_REQUEST'];

/** @var SiteRouteResult $routeResult */
$routeResult = GeneralUtility::makeInstance(SiteMatcher::class)->matchRequest($request);
/**
* Try to detect the language ID from request parameters or headers. If the SiteMatcher detects a language this
* fallback will **not** be used
*
* @var int|null $fallbackLanguageId
*/
$fallbackLanguageId = (int)($request->getQueryParams()['L']
?? $request->getParsedBody()['L']
?? $this->getRequestedLanguageUid($frontendController));

$language = $routeResult->getLanguage();

$request = $request->withAttribute('site', $routeResult->getSite());
$request = $request->withAttribute('language', $language);
$request = $request->withAttribute('routing', $routeResult);
/** @var SiteRouteResult $routeResult */
$routeResult = GeneralUtility::makeInstance(SiteMatcher::class)->matchRequest($request);

$GLOBALS['TYPO3_REQUEST'] = $request;

// Set language if defined
$requestedLanguageUid = ($language && $language->getLanguageId() !== null)
? $language->getLanguageId()
: $this->getRequestedLanguageUid($frontendController);
} else {
$requestedLanguageUid = GeneralUtility::_GP('L') !== null
? intval(GeneralUtility::_GP('L'))
: $this->getRequestedLanguageUid($frontendController);
$site = $routeResult->getSite();
$language = $routeResult->getLanguage();

// If TYPO3 could not determine the language for the request use the detected fallback
if (!$language && $fallbackLanguageId !== null) {
$language = $site->getLanguageById($fallbackLanguageId);
}

if (null !== $requestedLanguageUid) {
$frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid;
// Add LinkVars and language to work with correct localized labels
$frontendController->config['config']['linkVars'] = 'L(int)';
$frontendController->config['config']['language'] = $this->getRequestedLanguageCode();
$request = $request->withAttribute('site', $site);
$request = $request->withAttribute('language', $language);
$request = $request->withAttribute('routing', $routeResult);

// Patch the original Request so that at least `site` and `routing` are defined
$GLOBALS['TYPO3_REQUEST'] = $request
->withAttribute('site', $site)
->withAttribute('language', $language)
->withAttribute('routing', $routeResult);

// Set language if defined
if ($language && $language->getLanguageId() !== null) {
$this->setRequestedLanguage($frontendController, $language->getLanguageId());
} else {
$this->setRequestedLanguage($frontendController, $fallbackLanguageId);
}
}

Expand All @@ -190,33 +215,38 @@ private function setRequestedLanguage(TypoScriptFrontendController $frontendCont
*/
private function getRequestedLanguageUid(TypoScriptFrontendController $frontendController): ?int
{
if (GeneralUtility::_GP('L') !== null) {
return (int)GeneralUtility::_GP('L');
}
if (GeneralUtility::_GP('locale') !== null) {
$languageId = $this->getLanguageIdForCode($frontendController, GeneralUtility::_GP('locale'));
if ($languageId !== null) {
return $languageId;
}
}

// Test the full HTTP_ACCEPT_LANGUAGE header
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$typoscriptValue = $this->readConfigurationFromTyposcript(
'plugin.tx_rest.settings.languages.' . $_SERVER['HTTP_ACCEPT_LANGUAGE'],
$frontendController
$languageId = $this->getLanguageIdForCode(
$frontendController,
(string)$_SERVER['HTTP_ACCEPT_LANGUAGE']
);

if ($typoscriptValue !== null) {
return intval($typoscriptValue);
if ($languageId !== null) {
return $languageId;
}
}

// Retrieve and test the parsed header
$languageCode = $this->getRequestedLanguageCode();
if ($languageCode === null) {
return null;
}
$typoscriptValue = $this->readConfigurationFromTyposcript(
'plugin.tx_rest.settings.languages.' . $languageCode,
$frontendController
);

if ($typoscriptValue === null) {
return null;
if ($languageCode !== null) {
$languageId = $this->getLanguageIdForCode($frontendController, $languageCode);
if ($languageId !== null) {
return $languageId;
}
}

return intval($typoscriptValue);
return null;
}

/**
Expand Down Expand Up @@ -260,4 +290,40 @@ private function getRequestedLanguageCode(): ?string

return null;
}

/**
* @param TypoScriptFrontendController $frontendController
* @param string $languageCode
* @return int
*/
private function getLanguageIdForCode(TypoScriptFrontendController $frontendController, string $languageCode): ?int
{
$value = $this->readConfigurationFromTyposcript(
'plugin.tx_rest.settings.languages.' . $languageCode,
$frontendController
);
if (is_int($value)) {
return $value;
} elseif (is_string($value)) {
return trim($value) === '' ? null : (int)$value;
} else {
return null;
}
}

/**
* @param TypoScriptFrontendController $frontendController
* @param int|null $requestedLanguageUid
*/
private function setRequestedLanguage(
TypoScriptFrontendController $frontendController,
?int $requestedLanguageUid
): void {
if (null !== $requestedLanguageUid) {
$frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid;
// Add LinkVars and language to work with correct localized labels
$frontendController->config['config']['linkVars'] = 'L(int)';
$frontendController->config['config']['language'] = $this->getRequestedLanguageCode();
}
}
}

0 comments on commit aa1404e

Please sign in to comment.