TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:00 +02:00
commit f9941541b7
1178 changed files with 135377 additions and 0 deletions
@@ -0,0 +1,164 @@
<?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\Backend\Configuration\TCA;
use TYPO3\CMS\Core\Country\Country;
use TYPO3\CMS\Core\Country\CountryFilter;
use TYPO3\CMS\Core\Country\CountryProvider;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* This class provides items processor functions for the usage in TCA definition
* @internal
*/
class ItemsProcessorFunctions
{
/**
* Return languages found in already existing site configurations,
* sorted by their value. In case the same language is used with
* different titles, they will be added to the items label field.
* Additionally, a placeholder value is added to allow the creation
* of new site languages.
*/
public function populateAvailableLanguagesFromSites(array &$fieldDefinition): void
{
foreach (GeneralUtility::makeInstance(SiteFinder::class)->getAllSites() as $site) {
foreach ($site->getAllLanguages() as $languageId => $language) {
if (!isset($fieldDefinition['items'][$languageId])) {
$fieldDefinition['items'][$languageId] = [
'label' => $language->getTitle(),
'value' => $languageId,
'icon' => $language->getFlagIdentifier(),
'tempTitles' => [],
];
} elseif ($fieldDefinition['items'][$languageId]['label'] !== $language->getTitle()) {
// Temporarily store different titles
$fieldDefinition['items'][$languageId]['tempTitles'][] = $language->getTitle();
}
}
}
if (!isset($fieldDefinition['items'][0])) {
// Since TcaSiteLanguage has a special behaviour, enforcing the
// default language ("0") to be always added to the site configuration,
// we have to add it to the available items, in case it is not already
// present. This only happens for the first ever created site configuration.
$fieldDefinition['items'][] = ['label' => 'Default', 'value' => 0, 'icon' => '', 'tempTitles' => []];
}
ksort($fieldDefinition['items']);
// Build the final language label
foreach ($fieldDefinition['items'] as &$language) {
$language['label'] .= ' [' . $language['value'] . ']';
if ($language['tempTitles'] !== []) {
$language['label'] .= ' (' . implode(',', array_unique($language['tempTitles'])) . ')';
// Unset the temporary title "storage"
unset($language['tempTitles']);
}
}
unset($language);
// Add PHP_INT_MAX as last - placeholder - value to allow creation of new records
// with the "Create new" button, which is usually not possible in "selector" mode.
// Note: The placeholder will never be displayed in the selector.
$fieldDefinition['items'] = array_values(
array_merge($fieldDefinition['items'], [['label' => 'Placeholder', 'value' => PHP_INT_MAX]])
);
}
/**
* Return language items for use in site_languages.fallbacks
*/
public function populateFallbackLanguages(array &$fieldDefinition): void
{
foreach (GeneralUtility::makeInstance(SiteFinder::class)->getAllSites() as $site) {
foreach ($site->getAllLanguages() as $languageId => $language) {
if (isset($fieldDefinition['row']['languageId'][0])
&& (int)$fieldDefinition['row']['languageId'][0] === $languageId
) {
// Skip current language id
continue;
}
if (!isset($fieldDefinition['items'][$languageId])) {
$fieldDefinition['items'][$languageId] = [
'label' => $language->getTitle(),
'value' => $languageId,
'icon' => $language->getFlagIdentifier(),
'tempTitles' => [],
];
} elseif ($fieldDefinition['items'][$languageId]['label'] !== $language->getTitle()) {
// Temporarily store different titles
$fieldDefinition['items'][$languageId]['tempTitles'][] = $language->getTitle();
}
}
}
ksort($fieldDefinition['items']);
// Build the final language label
foreach ($fieldDefinition['items'] as &$language) {
if ($language['tempTitles'] !== []) {
$language['label'] .= ' (' . implode(',', array_unique($language['tempTitles'])) . ')';
// Unset the temporary title "storage"
unset($language['tempTitles']);
}
}
unset($language);
$fieldDefinition['items'] = array_values($fieldDefinition['items']);
}
public function populateFlags(array &$fieldConfiguration): void
{
$filter = (new CountryFilter())->setExcludeCountries(['um']);
$countries = GeneralUtility::makeInstance(CountryProvider::class)->getFiltered($filter);
/** @var Country $country */
foreach ($countries as $country) {
$code = strtolower($country->getAlpha2IsoCode());
$fieldConfiguration['items'][] = [
'label' => $country->getName(),
'value' => $code,
'icon' => 'flags-' . $code,
'group' => 'countries',
];
}
// Additional country variants
$variants = ['ca-qc', 'es-ct', 'es-ga', 'gb-eng', 'gb-nir', 'gb-sct', 'gb-wls'];
foreach ($variants as $variant) {
$split = explode('-', $variant);
$base = $countries[strtoupper($split[0])];
$fieldConfiguration['items'][] = [
'label' => sprintf('%s - %s', $base->getName(), strtoupper($split[1])),
'value' => $variant,
'icon' => 'flags-' . $variant,
'group' => 'countries',
];
}
$colors = ['black', 'white', 'blue', 'indigo', 'purple', 'pink', 'orange', 'yellow', 'green', 'teal', 'cyan', 'rainbow'];
foreach ($colors as $color) {
$fieldConfiguration['items'][] = [
'label' => $color,
'value' => $color,
'icon' => 'flags-' . $color,
'group' => 'colors',
];
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?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\Backend\Configuration\TCA;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Localization\Locales;
/**
* This class provides user functions for the usage in TCA definition
* @internal
*/
class UserFunctions
{
/**
* Used to build the IRRE title of a site language element
*/
public function getSiteLanguageTitle(array &$parameters): void
{
$record = $parameters['row'];
$languageId = (int)($record['languageId'][0] ?? 0);
if ($languageId === PHP_INT_MAX && str_starts_with((string)($record['uid'] ?? ''), 'NEW')) {
// If we deal with a new record, created via "Create new" (indicated by the PHP_INT_MAX placeholder),
// we use a label as record title, until the real values, especially the language ID, are calculated.
$parameters['title'] = '[' . $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration_tca.xlf:site.languages.new') . ']';
return;
}
$primaryValue = $record['primary'] ?? null;
$isPrimary = false;
if (is_array($primaryValue)) {
$isPrimary = !empty($primaryValue[0]);
} elseif ($primaryValue !== null) {
$isPrimary = (bool)$primaryValue;
}
if (!$isPrimary) {
$isPrimary = ((int)($record['languageId'][0] ?? -1) === 0);
}
$parameters['title'] = sprintf(
'%s %s [%d] (%s) Base: %s%s',
$record['enabled'] ? '' : '[' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:disabled') . ']',
$record['title'],
$languageId,
$record['locale'],
$record['base'],
$isPrimary ? ' ★' : ''
);
}
/**
* Used to build the IRRE title of a site route element
*/
public function getRouteTitle(array &$parameters): void
{
$record = $parameters['row'];
if (($record['type'][0] ?? false) === 'uri') {
$parameters['title'] = sprintf(
'%s %s %s',
$record['route'],
$this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration_tca.xlf:site.routes.irreHeader.redirectsTo'),
$record['source'] ?: '[' . $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:undefined') . ']'
);
} else {
$parameters['title'] = $record['route'];
}
}
/**
* Used to build the IRRE title of a site error handling element
*/
public function getErrorHandlingTitle(array &$parameters): void
{
$record = $parameters['row'];
$format = '%s: %s';
$arguments = [$record['errorCode']];
switch ($record['errorHandler'][0] ?? false) {
case 'Fluid':
$arguments[] = $record['errorFluidTemplate'];
break;
case 'Page':
$arguments[] = $record['errorContentSource'];
break;
case 'PHP':
$arguments[] = $record['errorPhpClassFQCN'];
break;
default:
$arguments[] = $record['errorHandler'][0] ?? '';
}
$parameters['title'] = sprintf($format, ...$arguments);
}
public static function getAllSystemLocales(): array
{
$locales = [];
foreach (Locales::getAllSystemLocales() as $locale) {
$locales[] = ['label' => $locale, 'value' => $locale];
}
return $locales;
}
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}