-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TASK] Add LanguageAspect to Contexts
This change adds a new Aspect called "Language" which bundles most existing TypoScript options on frontend language fetching. A factory allows to migrate the logic from TSFE. Major / Important Changes: - RootlineUtility is decoupled from PageRepository - TSFE->sys_language_mode is not necessary anymore - TSFE->sys_language_contentOL can be substituted by "overlayType" of Aspect - A new PageRepository->getLanguageOverlay() bundles all other methods - A lot of common public properties in TSFE are now deprecated Next steps: - Isolate calls from RootlineUtility/PageRepository more from each other and from TSFE - Migrate PageRepository "-1" parameters to "null" - Migrate usages PageRepository->getRootline() to RootlineUtility::__construct() - Then deprecate PageRepository->getRootLine() - Migrate Extbase QuerySettings to Contexts Resolves: #85543 Releases: master Change-Id: I8d177222a244a8d1fd66a884e9fc50b107f27e20 Reviewed-on: https://review.typo3.org/57424 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de> Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
- Loading branch information
1 parent
7a17c8d
commit 4003c5f
Showing
27 changed files
with
844 additions
and
277 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
namespace TYPO3\CMS\Core\Context; | ||
|
||
/* | ||
* This file is part of the TYPO3 CMS project. | ||
* | ||
* It is free software; you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License, either version 2 | ||
* of the License, or any later version. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.txt file that was distributed with this source code. | ||
* | ||
* The TYPO3 project - inspiring people to share! | ||
*/ | ||
|
||
use TYPO3\CMS\Core\Context\Exception\AspectPropertyNotFoundException; | ||
|
||
/** | ||
* The Aspect is usually available as "language" property, and | ||
* can be used to find out the "overlay"/data retrieval strategy. | ||
* | ||
* | ||
* "id" (languageId, int) | ||
* - formally known as $TSFE->sys_language_uid | ||
* - the requested language of the current page (frontend) | ||
* - used in menus and links to generate "links in language with this ID" | ||
* | ||
* "contentId" (int) | ||
* - formally known as $TSFE->sys_language_content | ||
* - the language of records to be fetched | ||
* - if empty, "languageId" is used. | ||
* | ||
* "fallbackChain" | ||
* - when "fallback" go with | ||
* - depends what "contentId" value should be set | ||
* - defined in config.sys_language_mode (strict/content_fallback:4,5,stop/ignore?) | ||
* - previously known as $TSFE->sys_language_mode | ||
* - defines "contentId" based on "if the current page is available in this language" | ||
* - "strict" | ||
* - "fallback" if current page is not available, check the fallbackChain" | ||
* - "fallbackAndIgnore" | ||
* | ||
* "overlays" | ||
* - defines which way the records should be fetched from ($TSFE->sys_language_contentOL and config.sys_language_overlay) | ||
* - usually you fetch language 0 and -1, then take the "contentId" and "overlay" them | ||
* - here you have two choices | ||
* 1. "on" if there is no overlay, do not render the default language records ("hideNonTranslated") | ||
* 2. "mixed" - if there no overlay, just keep the default language, possibility to have mixed languages - config.sys_language_overlay = 1 | ||
* 3. "off" - do not do overlay, only fetch records available in the current "contentId" (see above), and do not care about overlays or fallbacks - fallbacks could be an option here, actually that is placed on top | ||
* 4. "includeFloating" - on + includeRecordsWithoutDefaultTranslation | ||
*/ | ||
class LanguageAspect implements AspectInterface | ||
{ | ||
/** | ||
* @var int | ||
*/ | ||
protected $id = 0; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
protected $contentId = 0; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
protected $fallbackChain = []; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $overlayType; | ||
|
||
public const OVERLAYS_OFF = 'off'; // config.sys_language_overlay = 0 | ||
public const OVERLAYS_MIXED = 'mixed'; // config.sys_language_overlay = 1 (keep the ones that are only available in default language) | ||
public const OVERLAYS_ON = 'on'; // "hideNonTranslated" | ||
public const OVERLAYS_ON_WITH_FLOATING = 'includeFloating'; // "hideNonTranslated" + records that are only available in polish | ||
|
||
/** | ||
* Create the default language | ||
* | ||
* @param int $id | ||
* @param int|null $contentId | ||
* @param string $overlayType | ||
* @param array $fallbackChain | ||
*/ | ||
public function __construct(int $id = 0, int $contentId = null, string $overlayType = self::OVERLAYS_ON_WITH_FLOATING, array $fallbackChain = []) | ||
{ | ||
$this->overlayType = $overlayType; | ||
$this->id = $id; | ||
$this->contentId = $contentId === null ? $this->id : $contentId; | ||
$this->fallbackChain = $fallbackChain; | ||
} | ||
|
||
/** | ||
* Used language overlay | ||
* | ||
* @return string | ||
*/ | ||
public function getOverlayType(): string | ||
{ | ||
return $this->overlayType; | ||
} | ||
|
||
/** | ||
* Returns the language ID the current page was requested, | ||
* this is relevant when building menus or links to other pages. | ||
* | ||
* @return int | ||
*/ | ||
public function getId(): int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
/** | ||
* Contains the language UID of the content records that should be overlaid to would be fetched. | ||
* This is especially useful when a page requested with language=4 should fall back to showing | ||
* content of language=2 (see fallbackChain) | ||
* | ||
* @return int | ||
*/ | ||
public function getContentId(): int | ||
{ | ||
return $this->contentId; | ||
} | ||
|
||
public function getFallbackChain(): array | ||
{ | ||
return $this->fallbackChain; | ||
} | ||
|
||
/** | ||
* Whether overlays should be done | ||
* | ||
* @return bool | ||
*/ | ||
public function doOverlays(): bool | ||
{ | ||
return $this->contentId > 0 && $this->overlayType !== self::OVERLAYS_OFF; | ||
} | ||
|
||
/** | ||
* Previously known as TSFE->sys_language_mode, here for compatibility reasons | ||
* | ||
* @return string | ||
*/ | ||
public function getLegacyLanguageMode(): string | ||
{ | ||
if ($this->fallbackChain === ['off']) { | ||
return ''; | ||
} | ||
if (empty($this->fallbackChain)) { | ||
return 'strict'; | ||
} | ||
if ($this->fallbackChain === [-1]) { | ||
return 'ignore'; | ||
} | ||
return 'content_fallback'; | ||
} | ||
|
||
/** | ||
* Previously known as TSFE->sys_language_contentOL, here for compatibility reasons | ||
* | ||
* @return string | ||
*/ | ||
public function getLegacyOverlayType(): string | ||
{ | ||
switch ($this->overlayType) { | ||
case self::OVERLAYS_ON_WITH_FLOATING: | ||
case self::OVERLAYS_ON: | ||
return 'hideNonTranslated'; | ||
case self::OVERLAYS_MIXED: | ||
return '1'; | ||
case self::OVERLAYS_OFF: | ||
default: | ||
return '0'; | ||
} | ||
} | ||
|
||
/** | ||
* Fetch a property. | ||
* | ||
* @param string $name | ||
* @return int|string|array | ||
* @throws AspectPropertyNotFoundException | ||
*/ | ||
public function get(string $name) | ||
{ | ||
switch ($name) { | ||
case 'id': | ||
return $this->id; | ||
case 'contentId': | ||
return $this->contentId; | ||
case 'fallbackChain': | ||
return $this->fallbackChain; | ||
case 'overlayType': | ||
return $this->overlayType; | ||
case 'legacyLanguageMode': | ||
return $this->getLegacyLanguageMode(); | ||
case 'legacyOverlayType': | ||
return $this->getLegacyOverlayType(); | ||
} | ||
throw new AspectPropertyNotFoundException('Property "' . $name . '" not found in Aspect "' . __CLASS__ . '".', 1530448504); | ||
} | ||
} |
Oops, something went wrong.