Skip to content

Commit 6848078

Browse files
committed
Breaking changes: Languages are used for Domain Models and must be mapped in TypoScript
- A mapping for each used language must be defined in `plugin.tx_rest.settings.languages` - System language is respected for Extbase Domain Models
1 parent 94780af commit 6848078

5 files changed

Lines changed: 162 additions & 51 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Cundd\Rest\Bootstrap\Language\Exception;
5+
6+
use RuntimeException;
7+
8+
class InvalidLanguageException extends RuntimeException
9+
{
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Cundd\Rest\Bootstrap\Language\Exception;
5+
6+
class MissingLanguageCodeException extends InvalidLanguageException
7+
{
8+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Cundd\Rest\Bootstrap\Language;
5+
6+
use Cundd\Rest\Bootstrap\Language\Exception\MissingLanguageCodeException;
7+
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
8+
9+
class LanguageInformation
10+
{
11+
/**
12+
* @var int
13+
*/
14+
private $uid;
15+
16+
/**
17+
* @var string
18+
*/
19+
private $code;
20+
21+
/**
22+
* LanguageInformation constructor.
23+
*
24+
* @param int $uid
25+
* @param string $code
26+
*/
27+
public function __construct(int $uid, ?string $code)
28+
{
29+
$this->uid = $uid;
30+
if (!$code) {
31+
throw new MissingLanguageCodeException('Two Letter ISO Code must be given');
32+
}
33+
$this->code = $code;
34+
}
35+
36+
public static function fromSiteLanguage(SiteLanguage $siteLanguage): self
37+
{
38+
return new static($siteLanguage->getLanguageId(), $siteLanguage->getTwoLetterIsoCode());
39+
}
40+
41+
/**
42+
* @return int
43+
*/
44+
public function getUid(): int
45+
{
46+
return $this->uid;
47+
}
48+
49+
/**
50+
* @return string
51+
*/
52+
public function getCode(): string
53+
{
54+
return $this->code;
55+
}
56+
}

Classes/Bootstrap/LanguageBootstrap.php

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace Cundd\Rest\Bootstrap;
55

6+
use Cundd\Rest\Bootstrap\Language\LanguageInformation;
67
use Cundd\Rest\Exception\InvalidLanguageException;
78
use Cundd\Rest\ObjectManagerInterface;
89
use Psr\Http\Message\ServerRequestInterface;
@@ -29,6 +30,20 @@ public function __construct(ObjectManagerInterface $objectManager)
2930
$this->objectManager = $objectManager;
3031
}
3132

33+
/**
34+
* Initialize language object
35+
*
36+
* @param ServerRequestInterface $request
37+
*/
38+
public function initializeLanguageObject(ServerRequestInterface $request)
39+
{
40+
if (!isset($GLOBALS['LANG']) || !is_object($GLOBALS['LANG'])) {
41+
/** @var LanguageService $GLOBALS ['LANG'] */
42+
$GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class);
43+
$GLOBALS['LANG']->init($this->getRequestedPrimaryLanguageCode($request));
44+
}
45+
}
46+
3247
/**
3348
* Initialize the language settings
3449
*
@@ -40,30 +55,36 @@ public function initializeFrontendController(
4055
TypoScriptFrontendController $frontendController,
4156
ServerRequestInterface $request
4257
) {
43-
$this->detectAndSetRequestedLanguage($frontendController, $request);
58+
$requestedLanguage = $this->detectRequestedLanguage($frontendController, $request);
59+
60+
$this->setRequestedLanguage($frontendController, $requestedLanguage);
4461

4562
return $frontendController;
4663
}
4764

4865
/**
49-
* Configure the system to use the requested language
66+
* Detect the requested language
5067
*
5168
* @param TypoScriptFrontendController $frontendController
5269
* @param ServerRequestInterface $request
70+
* @return LanguageInformation
5371
*/
54-
private function detectAndSetRequestedLanguage(
72+
private function detectRequestedLanguage(
5573
TypoScriptFrontendController $frontendController,
5674
ServerRequestInterface $request
57-
) {
75+
): ?LanguageInformation {
5876
$requestedLanguageUid = $this->getRequestedLanguageUid($frontendController, $request);
59-
if (!class_exists(SiteMatcher::class)) {
60-
$this->setRequestedLanguage(
61-
$frontendController,
62-
$requestedLanguageUid,
63-
null
64-
);
6577

66-
return;
78+
// TYPO3 v8
79+
if (!class_exists(SiteMatcher::class)) {
80+
if ($requestedLanguageUid) {
81+
return new LanguageInformation(
82+
$requestedLanguageUid,
83+
$this->getLanguageCodeForId($frontendController, $requestedLanguageUid)
84+
);
85+
} else {
86+
return null;
87+
}
6788
}
6889

6990
// support new TYPO3 v9.2 Site Handling until middleware concept is implemented
@@ -89,17 +110,14 @@ private function detectAndSetRequestedLanguage(
89110

90111
// Set language if defined
91112
if ($language && $language->getLanguageId() !== null) {
92-
$this->setRequestedLanguage(
93-
$frontendController,
94-
$language->getLanguageId(),
95-
$language->getTwoLetterIsoCode()
96-
);
97-
} else {
98-
$this->setRequestedLanguage(
99-
$frontendController,
113+
return LanguageInformation::fromSiteLanguage($language);
114+
} elseif ($requestedLanguageUid) {
115+
return new LanguageInformation(
100116
$requestedLanguageUid,
101-
$this->getRequestedPrimaryLanguageCode($patchedRequest)
117+
$this->getLanguageCodeForId($frontendController, $requestedLanguageUid)
102118
);
119+
} else {
120+
return null;
103121
}
104122
}
105123

@@ -171,6 +189,8 @@ private function getRequestedLanguageUid(
171189
}
172190

173191
/**
192+
* Look up the TypoScript configuration for the language UID for the given language code
193+
*
174194
* @param TypoScriptFrontendController $frontendController
175195
* @param string $languageCode
176196
* @return int
@@ -193,6 +213,31 @@ private function getLanguageIdForCode(TypoScriptFrontendController $frontendCont
193213
}
194214
}
195215

216+
/**
217+
* Look up the TypoScript configuration for the language code matching the given language UID
218+
*
219+
* Reverse lookup for `getLanguageIdForCode()`
220+
*
221+
* @param TypoScriptFrontendController $frontendController
222+
* @param int $languageUid
223+
* @return string|null
224+
*/
225+
private function getLanguageCodeForId(TypoScriptFrontendController $frontendController, int $languageUid): ?string
226+
{
227+
$languages = $this->readConfigurationFromTyposcript(
228+
'plugin.tx_rest.settings.languages',
229+
$frontendController
230+
);
231+
232+
foreach ($languages as $code => $uid) {
233+
if (is_numeric($uid) && (int)$uid === $languageUid) {
234+
return $code;
235+
}
236+
}
237+
238+
return null;
239+
}
240+
196241
/**
197242
* Retrieve the TypoScript configuration for the given key path
198243
*
@@ -235,7 +280,7 @@ private function getRequestedPrimaryLanguageCode(ServerRequestInterface $request
235280

236281
if (class_exists('Locale')) {
237282
/** @noinspection PhpComposerExtensionStubsInspection PhpFullyQualifiedNameUsageInspection */
238-
return \Locale::getPrimaryLanguage(\Locale::acceptFromHttp($headerValue));
283+
return \Locale::getPrimaryLanguage((string)\Locale::acceptFromHttp($headerValue));
239284
}
240285

241286
if (preg_match('/^[a-z]{2}/', $headerValue, $matches)) {
@@ -247,35 +292,23 @@ private function getRequestedPrimaryLanguageCode(ServerRequestInterface $request
247292

248293
/**
249294
* @param TypoScriptFrontendController $frontendController
250-
* @param int|null $requestedLanguageUid
251-
* @param string|null $requestedLanguageCode
295+
* @param LanguageInformation|null $languageInformation
252296
*/
253297
private function setRequestedLanguage(
254298
TypoScriptFrontendController $frontendController,
255-
?int $requestedLanguageUid,
256-
?string $requestedLanguageCode
299+
?LanguageInformation $languageInformation
257300
): void {
258-
if (null !== $requestedLanguageUid) {
259-
$frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid;
301+
if (null !== $languageInformation) {
302+
$frontendController->config['config']['sys_language_uid'] = $languageInformation->getUid();
260303
// Add LinkVars and language to work with correct localized labels
261304
$frontendController->config['config']['linkVars'] = 'L(int)';
262-
$frontendController->config['config']['language'] = $requestedLanguageCode;
305+
$frontendController->config['config']['language'] = $languageInformation->getCode();
263306
}
264307

265-
$frontendController->settingLocale();
266-
}
267-
268-
/**
269-
* Initialize language object
270-
*
271-
* @param ServerRequestInterface $request
272-
*/
273-
public function initializeLanguageObject(ServerRequestInterface $request)
274-
{
275-
if (!isset($GLOBALS['LANG']) || !is_object($GLOBALS['LANG'])) {
276-
/** @var LanguageService $GLOBALS ['LANG'] */
277-
$GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class);
278-
$GLOBALS['LANG']->init($this->getRequestedPrimaryLanguageCode($request));
308+
// Invoke the internal method to initialize the language system
309+
if (is_callable([$frontendController, 'settingLanguage'])) {
310+
$frontendController->settingLanguage();
279311
}
312+
$frontendController->settingLocale();
280313
}
281314
}

Documentation/FAQ.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,17 @@ Internationalization and localization
252252

253253
The extension supports different types to handle localized requests.
254254

255-
- Since version `3.6.0` TYPO3's site handling is supported
256-
- Specify the `L` `GET`-parameter
257-
- Specify a `Accept-Language` header and define a mapping from the header value to the sys-language UID in TypoScript
258-
```typo3_typoscript
259-
plugin.tx_rest.settings {
260-
languages {
261-
de-DE = 1
262-
}
255+
All languages must be registered in the language map:
256+
257+
```typo3_typoscript
258+
plugin.tx_rest.settings {
259+
languages {
260+
en = 0
261+
de = 1
263262
}
264-
```
263+
}
264+
```
265+
266+
- Since version `3.6.0` TYPO3's site handling is supported
267+
- Specify the `GET`-parameter `L` with the language UID
268+
- Specify a `Accept-Language` header

0 commit comments

Comments
 (0)