160 lines
5.2 KiB
PHP
160 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* 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!
|
|
*/
|
|
|
|
namespace TYPO3\CMS\Core\Context;
|
|
|
|
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)
|
|
* - the requested language of the current page (frontend)
|
|
* - used in menus and links to generate "links in language with this ID"
|
|
*
|
|
* "contentId" (int)
|
|
* - the language of records to be fetched
|
|
* - if empty, "languageId" is used.
|
|
*
|
|
* "fallbackChain"
|
|
* - when "fallback" go with
|
|
* - depends on what "contentId" value should be set
|
|
* - defined in config.sys_language_mode (strict/content_fallback:4,5,stop/ignore?)
|
|
* - 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"
|
|
*
|
|
* "overlayType"
|
|
* - defines which way the records should be fetched from
|
|
* - 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 is 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
|
|
*/
|
|
final readonly class LanguageAspect implements AspectInterface
|
|
{
|
|
public const string OVERLAYS_OFF = 'off'; // config.sys_language_overlay = 0
|
|
public const string OVERLAYS_MIXED = 'mixed'; // config.sys_language_overlay = 1 (keep the ones that are only available in default language)
|
|
public const string OVERLAYS_ON = 'on'; // "hideNonTranslated"
|
|
public const string OVERLAYS_ON_WITH_FLOATING = 'includeFloating'; // "hideNonTranslated" + records that are only available in polish
|
|
|
|
/**
|
|
* Create the default language
|
|
*/
|
|
public function __construct(
|
|
private int $id = 0,
|
|
private ?int $contentId = null,
|
|
private string $overlayType = self::OVERLAYS_ON_WITH_FLOATING,
|
|
private array $fallbackChain = [],
|
|
) {}
|
|
|
|
/**
|
|
* Used language overlay
|
|
*/
|
|
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.
|
|
*/
|
|
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)
|
|
*/
|
|
public function getContentId(): int
|
|
{
|
|
return $this->contentId ?? $this->id;
|
|
}
|
|
|
|
public function getFallbackChain(): array
|
|
{
|
|
return $this->fallbackChain;
|
|
}
|
|
|
|
/**
|
|
* Whether overlays should be done
|
|
*/
|
|
public function doOverlays(): bool
|
|
{
|
|
return $this->getContentId() > 0 && $this->overlayType !== self::OVERLAYS_OFF;
|
|
}
|
|
|
|
/**
|
|
* Here for compatibility reasons
|
|
*/
|
|
public function getLegacyLanguageMode(): string
|
|
{
|
|
if ($this->fallbackChain === ['off']) {
|
|
return '';
|
|
}
|
|
if (empty($this->fallbackChain)) {
|
|
return 'strict';
|
|
}
|
|
return 'content_fallback';
|
|
}
|
|
|
|
/**
|
|
* Here for compatibility reasons
|
|
*/
|
|
public function getLegacyOverlayType(): string
|
|
{
|
|
return match ($this->overlayType) {
|
|
self::OVERLAYS_ON_WITH_FLOATING, self::OVERLAYS_ON => 'hideNonTranslated',
|
|
self::OVERLAYS_MIXED => '1',
|
|
default => '0',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Fetch a property.
|
|
*
|
|
* @throws AspectPropertyNotFoundException
|
|
*/
|
|
public function get(string $name): int|string|array
|
|
{
|
|
switch ($name) {
|
|
case 'id':
|
|
return $this->id;
|
|
case 'contentId':
|
|
return $this->getContentId();
|
|
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);
|
|
}
|
|
}
|