Skip to content

Commit aa1404e

Browse files
committed
Refactor the language bootstrapping
1 parent 1db67a4 commit aa1404e

File tree

1 file changed

+112
-46
lines changed

1 file changed

+112
-46
lines changed

Classes/Bootstrap.php

Lines changed: 112 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
1515
use TYPO3\CMS\Frontend\Utility\EidUtility;
1616
use TYPO3\CMS\Lang\LanguageService;
17+
use function class_exists;
18+
use function intval;
19+
use function is_int;
20+
use function is_string;
1721

1822

1923
/**
@@ -26,6 +30,8 @@ class Bootstrap
2630
*
2731
* @param TypoScriptFrontendController|null $frontendController
2832
* @return TypoScriptFrontendController
33+
* @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException
34+
* @throws \TYPO3\CMS\Core\Http\ImmediateResponseException
2935
*/
3036
public function init(TypoScriptFrontendController $frontendController = null)
3137
{
@@ -57,9 +63,6 @@ public function initializeLanguageObject()
5763
}
5864
}
5965

60-
/**
61-
*
62-
*/
6366
private function initializeTimeTracker()
6467
{
6568
if (!isset($GLOBALS['TT']) || !is_object($GLOBALS['TT'])) {
@@ -82,7 +85,7 @@ private function buildFrontendController(int $pageUid): TypoScriptFrontendContro
8285

8386
return $objectManager->get(
8487
TypoScriptFrontendController::class,
85-
$GLOBALS['TYPO3_CONF_VARS'], // can be removed in TYPO3 v8
88+
null, // previously TYPO3_CONF_VARS
8689
$pageUid,
8790
0, // Type
8891
0, // no_cache
@@ -117,6 +120,8 @@ private function getFrontendControllerIsInitialized(): bool
117120
* Configure the given frontend controller
118121
*
119122
* @param TypoScriptFrontendController $frontendController
123+
* @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException
124+
* @throws \TYPO3\CMS\Core\Http\ImmediateResponseException
120125
*/
121126
private function configureFrontendController(TypoScriptFrontendController $frontendController)
122127
{
@@ -135,8 +140,11 @@ private function configureFrontendController(TypoScriptFrontendController $front
135140
$frontendController->determineId();
136141
$frontendController->getConfigArray();
137142

138-
$this->setRequestedLanguage($frontendController);
139-
$frontendController->settingLanguage();
143+
$this->detectAndSetRequestedLanguage($frontendController);
144+
//try {
145+
// $frontendController->settingLanguage();
146+
//} catch (\RuntimeException $exception) {
147+
//}
140148
$frontendController->settingLocale();
141149
}
142150

@@ -145,40 +153,57 @@ private function configureFrontendController(TypoScriptFrontendController $front
145153
*
146154
* @param TypoScriptFrontendController $frontendController
147155
*/
148-
private function setRequestedLanguage(TypoScriptFrontendController $frontendController)
156+
private function detectAndSetRequestedLanguage(TypoScriptFrontendController $frontendController)
149157
{
158+
if (!isset($GLOBALS['TYPO3_REQUEST']) || !class_exists(SiteMatcher::class)) {
159+
$this->setRequestedLanguage($frontendController, $this->getRequestedLanguageUid($frontendController));
160+
161+
return;
162+
}
163+
150164
// support new TYPO3 v9.2 Site Handling until middleware concept is implemented
151165
// see https://github.com/cundd/rest/issues/59
152-
if (isset($GLOBALS['TYPO3_REQUEST']) && class_exists(SiteMatcher::class)) {
153-
/** @var ServerRequestInterface $request */
154-
$request = $GLOBALS['TYPO3_REQUEST'];
166+
/** @var ServerRequestInterface $request */
167+
$request = $GLOBALS['TYPO3_REQUEST'];
155168

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

159-
$language = $routeResult->getLanguage();
160179

161-
$request = $request->withAttribute('site', $routeResult->getSite());
162-
$request = $request->withAttribute('language', $language);
163-
$request = $request->withAttribute('routing', $routeResult);
180+
/** @var SiteRouteResult $routeResult */
181+
$routeResult = GeneralUtility::makeInstance(SiteMatcher::class)->matchRequest($request);
164182

165-
$GLOBALS['TYPO3_REQUEST'] = $request;
166183

167-
// Set language if defined
168-
$requestedLanguageUid = ($language && $language->getLanguageId() !== null)
169-
? $language->getLanguageId()
170-
: $this->getRequestedLanguageUid($frontendController);
171-
} else {
172-
$requestedLanguageUid = GeneralUtility::_GP('L') !== null
173-
? intval(GeneralUtility::_GP('L'))
174-
: $this->getRequestedLanguageUid($frontendController);
184+
$site = $routeResult->getSite();
185+
$language = $routeResult->getLanguage();
186+
187+
// If TYPO3 could not determine the language for the request use the detected fallback
188+
if (!$language && $fallbackLanguageId !== null) {
189+
$language = $site->getLanguageById($fallbackLanguageId);
175190
}
176191

177-
if (null !== $requestedLanguageUid) {
178-
$frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid;
179-
// Add LinkVars and language to work with correct localized labels
180-
$frontendController->config['config']['linkVars'] = 'L(int)';
181-
$frontendController->config['config']['language'] = $this->getRequestedLanguageCode();
192+
$request = $request->withAttribute('site', $site);
193+
$request = $request->withAttribute('language', $language);
194+
$request = $request->withAttribute('routing', $routeResult);
195+
196+
// Patch the original Request so that at least `site` and `routing` are defined
197+
$GLOBALS['TYPO3_REQUEST'] = $request
198+
->withAttribute('site', $site)
199+
->withAttribute('language', $language)
200+
->withAttribute('routing', $routeResult);
201+
202+
// Set language if defined
203+
if ($language && $language->getLanguageId() !== null) {
204+
$this->setRequestedLanguage($frontendController, $language->getLanguageId());
205+
} else {
206+
$this->setRequestedLanguage($frontendController, $fallbackLanguageId);
182207
}
183208
}
184209

@@ -190,33 +215,38 @@ private function setRequestedLanguage(TypoScriptFrontendController $frontendCont
190215
*/
191216
private function getRequestedLanguageUid(TypoScriptFrontendController $frontendController): ?int
192217
{
218+
if (GeneralUtility::_GP('L') !== null) {
219+
return (int)GeneralUtility::_GP('L');
220+
}
221+
if (GeneralUtility::_GP('locale') !== null) {
222+
$languageId = $this->getLanguageIdForCode($frontendController, GeneralUtility::_GP('locale'));
223+
if ($languageId !== null) {
224+
return $languageId;
225+
}
226+
}
227+
193228
// Test the full HTTP_ACCEPT_LANGUAGE header
194229
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
195-
$typoscriptValue = $this->readConfigurationFromTyposcript(
196-
'plugin.tx_rest.settings.languages.' . $_SERVER['HTTP_ACCEPT_LANGUAGE'],
197-
$frontendController
230+
$languageId = $this->getLanguageIdForCode(
231+
$frontendController,
232+
(string)$_SERVER['HTTP_ACCEPT_LANGUAGE']
198233
);
199234

200-
if ($typoscriptValue !== null) {
201-
return intval($typoscriptValue);
235+
if ($languageId !== null) {
236+
return $languageId;
202237
}
203238
}
204239

205240
// Retrieve and test the parsed header
206241
$languageCode = $this->getRequestedLanguageCode();
207-
if ($languageCode === null) {
208-
return null;
209-
}
210-
$typoscriptValue = $this->readConfigurationFromTyposcript(
211-
'plugin.tx_rest.settings.languages.' . $languageCode,
212-
$frontendController
213-
);
214-
215-
if ($typoscriptValue === null) {
216-
return null;
242+
if ($languageCode !== null) {
243+
$languageId = $this->getLanguageIdForCode($frontendController, $languageCode);
244+
if ($languageId !== null) {
245+
return $languageId;
246+
}
217247
}
218248

219-
return intval($typoscriptValue);
249+
return null;
220250
}
221251

222252
/**
@@ -260,4 +290,40 @@ private function getRequestedLanguageCode(): ?string
260290

261291
return null;
262292
}
293+
294+
/**
295+
* @param TypoScriptFrontendController $frontendController
296+
* @param string $languageCode
297+
* @return int
298+
*/
299+
private function getLanguageIdForCode(TypoScriptFrontendController $frontendController, string $languageCode): ?int
300+
{
301+
$value = $this->readConfigurationFromTyposcript(
302+
'plugin.tx_rest.settings.languages.' . $languageCode,
303+
$frontendController
304+
);
305+
if (is_int($value)) {
306+
return $value;
307+
} elseif (is_string($value)) {
308+
return trim($value) === '' ? null : (int)$value;
309+
} else {
310+
return null;
311+
}
312+
}
313+
314+
/**
315+
* @param TypoScriptFrontendController $frontendController
316+
* @param int|null $requestedLanguageUid
317+
*/
318+
private function setRequestedLanguage(
319+
TypoScriptFrontendController $frontendController,
320+
?int $requestedLanguageUid
321+
): void {
322+
if (null !== $requestedLanguageUid) {
323+
$frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid;
324+
// Add LinkVars and language to work with correct localized labels
325+
$frontendController->config['config']['linkVars'] = 'L(int)';
326+
$frontendController->config['config']['language'] = $this->getRequestedLanguageCode();
327+
}
328+
}
263329
}

0 commit comments

Comments
 (0)