139 lines
4.7 KiB
PHP
139 lines
4.7 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\Backend\Form\FormDataProvider;
|
|
|
|
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
|
|
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
|
|
|
/**
|
|
* Remove or disable fields (select, category, language) in the form when no
|
|
* selectable items are available, or when only a single choice exists (language
|
|
* fields).
|
|
*
|
|
* For regular users, the field is removed entirely. When backend debug mode is
|
|
* enabled ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] = true), the field is
|
|
* kept as readOnly with an info badge, so admins can identify configuration
|
|
* issues such as missing records or restrictive TSconfig.
|
|
*
|
|
* Existing database values are not affected: fields not rendered in the form
|
|
* are simply not submitted, so DataHandler preserves their stored values.
|
|
*
|
|
* Fields can opt out via TCA config 'showIfEmpty' => true.
|
|
*/
|
|
readonly class TcaColumnsRemoveEmptyRelations implements FormDataProviderInterface
|
|
{
|
|
public function addData(array $result): array
|
|
{
|
|
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
|
|
if (!$this->isApplicableField($fieldConfig)) {
|
|
continue;
|
|
}
|
|
|
|
if ($fieldConfig['config']['showIfEmpty'] ?? false) {
|
|
continue;
|
|
}
|
|
|
|
$type = $fieldConfig['config']['type'] ?? '';
|
|
|
|
if ($type === 'language') {
|
|
if ($this->hasMultipleLanguageChoices($fieldConfig)) {
|
|
continue;
|
|
}
|
|
} elseif ($this->hasMeaningfulItems($fieldConfig)) {
|
|
continue;
|
|
}
|
|
|
|
if ($this->getBackendUser()->shallDisplayDebugInformation()) {
|
|
$result['processedTca']['columns'][$fieldName]['config']['readOnly'] = true;
|
|
$result['processedTca']['columns'][$fieldName]['config']['fieldInformation']['noSelectableItemsAvailable'] = [
|
|
'renderType' => 'noSelectableItemsAvailable',
|
|
];
|
|
} else {
|
|
unset($result['processedTca']['columns'][$fieldName]);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Check if this field type should be handled by this provider.
|
|
*/
|
|
private function isApplicableField(array $fieldConfig): bool
|
|
{
|
|
return in_array($fieldConfig['config']['type'] ?? '', ['select', 'category', 'language'], true);
|
|
}
|
|
|
|
/**
|
|
* Check if the field has meaningful selectable items.
|
|
*
|
|
* For fields with foreign_table, only items from the foreign table (positive
|
|
* integer UIDs) count. Static items like "Hide at login" (-1) or dividers
|
|
* are not meaningful on their own — they require actual foreign records to
|
|
* be useful (e.g., access restriction options require fe_groups to exist,
|
|
* otherwise there can be no frontend login).
|
|
*/
|
|
private function hasMeaningfulItems(array $fieldConfig): bool
|
|
{
|
|
$items = $fieldConfig['config']['items'] ?? [];
|
|
$hasForeignTable = !empty($fieldConfig['config']['foreign_table']);
|
|
|
|
foreach ($items as $item) {
|
|
$value = (string)($item['value'] ?? $item[1] ?? '');
|
|
if ($value === '' || $value === '--div--') {
|
|
continue;
|
|
}
|
|
if ($hasForeignTable) {
|
|
if ((int)$value > 0) {
|
|
return true;
|
|
}
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if a language field has more than one real language choice.
|
|
* Filters out --div-- separators and the -1 "All languages" special item,
|
|
* since on a single-language site neither provides a meaningful choice.
|
|
*/
|
|
private function hasMultipleLanguageChoices(array $fieldConfig): bool
|
|
{
|
|
$items = $fieldConfig['config']['items'] ?? [];
|
|
$realLanguageCount = 0;
|
|
foreach ($items as $item) {
|
|
$value = $item['value'] ?? '';
|
|
if ((string)$value === '--div--' || (int)$value === -1) {
|
|
continue;
|
|
}
|
|
$realLanguageCount++;
|
|
if ($realLanguageCount > 1) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private function getBackendUser(): BackendUserAuthentication
|
|
{
|
|
return $GLOBALS['BE_USER'];
|
|
}
|
|
}
|