Skip to content

Commit

Permalink
[FEATURE] Allow overriding TCA descriptions with TSconfig
Browse files Browse the repository at this point in the history
This adds a new FormDataProvider, which allows to override the
TCA description property, introduced in #85410, with page TSconfig.

This is especially useful in case a field changes its purpose
depending on the current site or page context, which happens
quite often for e.g. tt_content fields.

Resolves: #93794
Releases: master
Change-Id: I2a8056df440e88c1bd3901796e80ed3f1d94c081
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68561
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Jochen <rothjochen@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jochen <rothjochen@gmail.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
  • Loading branch information
o-ba authored and georgringer committed Mar 25, 2021
1 parent 862effd commit ee24ba6
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?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\Localization\LanguageService;

/**
* Works on processedTca to determine the final value of field descriptions.
*
* processedTca['columns']['aField']['description']
*/
class TcaColumnsProcessFieldDescriptions implements FormDataProviderInterface
{
/**
* Iterate over all processedTca columns fields
*
* @param array $result Result array
* @return array Modified result array
*/
public function addData(array $result): array
{
$result = $this->setDescriptionFromPageTsConfig($result);
$result = $this->translateDescriptions($result);
return $result;
}

/**
* page TSconfig can override description:
*
* TCEFORM.aTable.aField.description = override
* TCEFORM.aTable.aField.description.en = override
*
* @param array $result Result array
* @return array Modified result array
*/
protected function setDescriptionFromPageTsConfig(array $result): array
{
$languageService = $this->getLanguageService();
$tableName = $result['tableName'];
foreach ($result['processedTca']['columns'] ?? [] as $fieldName => $fieldConfiguration) {
$fieldTSconfig = $result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.'] ?? null;
if (!is_array($fieldTSconfig)) {
continue;
}
if (!empty($fieldTSconfig['description'])) {
$result['processedTca']['columns'][$fieldName]['description'] = $fieldTSconfig['description'];
}
if (!empty($fieldTSconfig['description.'][$languageService->lang])) {
$result['processedTca']['columns'][$fieldName]['description'] = $fieldTSconfig['description.'][$languageService->lang];
}
}
return $result;
}

/**
* Translate all descriptions if needed.
*
* @param array $result Result array
* @return array Modified result array
*/
protected function translateDescriptions(array $result): array
{
$languageService = $this->getLanguageService();
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfiguration) {
if (!isset($fieldConfiguration['description'])) {
continue;
}
$result['processedTca']['columns'][$fieldName]['description'] = $languageService->sL($fieldConfiguration['description']);
}
return $result;
}

/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?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\Tests\Unit\Form\FormDataProvider;

use TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

class TcaColumnsProcessFieldDescriptionsTest extends UnitTestCase
{
protected TcaColumnsProcessFieldDescriptions $subject;

protected function setUp(): void
{
parent::setUp();
$this->subject = new TcaColumnsProcessFieldDescriptions();
}

/**
* @test
*/
public function addDataKeepsDescriptionAsIsIfNoOverrideIsGiven(): void
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => [
'description' => 'foo',
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('foo')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();

$expected = $input;
self::assertSame($expected, $this->subject->addData($input));
}

/**
* @test
*/
public function addDataAddsDescriptionToExistingField(): void
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => []
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'description' => 'aNewDescription',
],
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('aNewDescription')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();

$expected = $input;
$expected['processedTca']['columns']['aField']['description'] = 'aNewDescription';
self::assertSame($expected, $this->subject->addData($input));
}

/**
* @test
*/
public function addDataSetsDescriptionFromPageTsConfig(): void
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => [
'description' => 'origDescription',
],
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'description' => 'aDescriptionOverride',
],
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('aDescriptionOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();

$expected = $input;
$expected['processedTca']['columns']['aField']['description'] = 'aDescriptionOverride';
self::assertSame($expected, $this->subject->addData($input));
}

/**
* @test
*/
public function addDataSetsDescriptionFromPageTsConfigForSpecificLanguage(): void
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => [
'description' => 'origDescription',
],
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'description.' => [
'fr' => 'aDescriptionOverride',
],
],
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->lang = 'fr';
$languageServiceProphecy->sL('aDescriptionOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();

$expected = $input;
$expected['processedTca']['columns']['aField']['description'] = 'aDescriptionOverride';
self::assertSame($expected, $this->subject->addData($input));
}
}
21 changes: 21 additions & 0 deletions typo3/sysext/core/Configuration/DefaultConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,20 @@
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\UserTsConfig::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\PageTsConfigMerged::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsRemoveUnused::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexProcess::class => [
Expand Down Expand Up @@ -776,9 +783,16 @@
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaGroup::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaText::class => [
Expand Down Expand Up @@ -1056,10 +1070,17 @@
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaText::class => [
'depends' => [
\TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldDescriptions::class,
],
],
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class => [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.. include:: ../../Includes.txt

========================================================
Feature: #93794 - Override TCA description with TSconfig
========================================================

See :issue:`93794`

Description
===========

The TCA description, introduced in #85410, allows to define a description
for a TCA field, next to its label. Since the purpose of a field may change
depending on the current page, it is now possible to override the TCA
description property with page TSconfig.

.. code-block:: typoscript
TCEFORM.aTable.aField.description = override description
As already known from other properties, this can also be configured for a
specific language.

.. code-block:: typoscript
TCEFORM.aTable.aField.description.de = override description for DE
The option can be used on a per record type basis, too.

.. code-block:: typoscript
TCEFORM.aTable.aField.types.aType.description = override description for aType
Also referencing language labels is supported.

.. code-block:: typoscript
TCEFORM.aTable.aField.description = LLL:EXT:my_ext/Resources/Private/Language/locallang.xlf:override_description
.. note::

The new option can not only be used to override an exisiting property,
but also to set a description for a field, that has not yet been
configured a description in TCA.

.. index:: Backend, TCA, TSConfig, ext:backend

0 comments on commit ee24ba6

Please sign in to comment.