Commit 7ec4d01e authored by Christian Kuhn's avatar Christian Kuhn Committed by Wouter Wolters
Browse files

[BUGFIX] Override flex form field label with page TSConfig

Move the data handling to calculate a final field label
value from PaletteAndSingleFieldContainer to an own data
provider and register this provider for full database records
and for flex form processing.
This way flex form field label overrides via page TSConfig are fixed,
eg. this changes the "Order By" label of ext:news flex form:

TCEFORM.tt_content.pi_flexform.news_pi1.sDEF.settings\.orderBy.label = override

Language specific overrides in flex fields now work as well

...settings\.orderBy.label.fr = French override

Change-Id: I02474e9cca9db3e949c217f21f5704ec16641545
Resolves: #75606
Releases: master, 7.6
Reviewed-on: https://review.typo3.org/47919


Reviewed-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: Stefan Froemken's avatarStefan Froemken <froemken@gmail.com>
Tested-by: Stefan Froemken's avatarStefan Froemken <froemken@gmail.com>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
parent 30d48182
......@@ -137,10 +137,14 @@ class PaletteAndSingleContainer extends AbstractContainer
if (!empty($childResultArray['html'])) {
$mainStructureCounter ++;
$fieldLabel = '';
if (!empty($this->data['processedTca']['columns'][$fieldName]['label'])) {
$fieldLabel = $this->data['processedTca']['columns'][$fieldName]['label'];
}
$targetStructure[$mainStructureCounter] = array(
'type' => 'single',
'fieldName' => $fieldConfiguration['fieldName'],
'fieldLabel' => $this->getSingleFieldLabel($fieldName, $fieldConfiguration['fieldLabel']),
'fieldLabel' => $fieldLabel,
'fieldHtml' => $childResultArray['html'],
);
}
......@@ -212,10 +216,14 @@ class PaletteAndSingleContainer extends AbstractContainer
if (!empty($singleFieldContentArray['html'])) {
$foundRealElement = true;
$fieldLabel = '';
if (!empty($this->data['processedTca']['columns'][$fieldName]['label'])) {
$fieldLabel = $this->data['processedTca']['columns'][$fieldName]['label'];
}
$resultStructure[] = array(
'type' => 'single',
'fieldName' => $fieldName,
'fieldLabel' => $this->getSingleFieldLabel($fieldName, $fieldArray['fieldLabel']),
'fieldLabel' => $fieldLabel,
'fieldHtml' => $singleFieldContentArray['html'],
);
$singleFieldContentArray['html'] = '';
......@@ -375,41 +383,6 @@ class PaletteAndSingleContainer extends AbstractContainer
return implode(LF, $content);
}
/**
* Determine label of a single field (not a palette label)
*
* @param string $fieldName The field name to calculate the label for
* @param string $labelFromShowItem Given label, typically from show item configuration
* @return string Field label
*/
protected function getSingleFieldLabel($fieldName, $labelFromShowItem)
{
$languageService = $this->getLanguageService();
$table = $this->data['tableName'];
$label = $labelFromShowItem;
if (!empty($this->data['processedTca']['columns'][$fieldName]['label'])) {
$label = $this->data['processedTca']['columns'][$fieldName]['label'];
}
if (!empty($labelFromShowItem)) {
$label = $labelFromShowItem;
}
$fieldTSConfig = [];
if (isset($this->data['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'])
&& is_array($this->data['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'])
) {
$fieldTSConfig = $this->data['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'];
}
if (!empty($fieldTSConfig['label'])) {
$label = $fieldTSConfig['label'];
}
if (!empty($fieldTSConfig['label.'][$languageService->lang])) {
$label = $fieldTSConfig['label.'][$languageService->lang];
}
return $languageService->sL($label);
}
/**
* TRUE if field is of type user and to wrapping is requested
*
......
<?php
namespace TYPO3\CMS\Backend\Form\FormDataProvider;
/*
* 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\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService;
/**
* Works on processedTca to determine the final value of field labels.
*
* processedTca['columns]['aField']['label']
*/
class TcaColumnsProcessFieldLabels implements FormDataProviderInterface
{
/**
* Iterate over all processedTca columns fields
*
* @param array $result Result array
* @return array Modified result array
*/
public function addData(array $result)
{
$result = $this->setLabelFromShowitemAndPalettes($result);
$result = $this->setLabelFromPageTsConfig($result);
$result = $this->translatelabels($result);
return $result;
}
/**
* The label of a single field can be set in the showitem configuration
* of the record type and as palettes showitem as second ";" separated argument:
*
* processedTca['types']['aType']['showitem'] = 'aFieldName;aLabelOverride, --palette--;;aPaletteName'
* processedTca['palettes']['aPaletteName']['showitem'] = 'anotherFieldName;anotherLabelOverride'
*
*
* @param array $result Result array
* @return array Modified result array
*/
protected function setLabelFromShowitemAndPalettes(array $result)
{
$recordTypeValue = $result['recordTypeValue'];
// flex forms don't have a showitem / palettes configuration - early return
if (!isset($result['processedTca']['types'][$recordTypeValue]['showitem'])) {
return $result;
}
$showItemArray = GeneralUtility::trimExplode(',', $result['processedTca']['types'][$recordTypeValue]['showitem']);
foreach ($showItemArray as $aShowItemFieldString) {
$aShowItemFieldArray = GeneralUtility::trimExplode(';', $aShowItemFieldString);
$aShowItemFieldArray = [
'fieldName' => $aShowItemFieldArray[0],
'fieldLabel' => $aShowItemFieldArray[1] ?: null,
'paletteName' => $aShowItemFieldArray[2] ?: null,
];
if ($aShowItemFieldArray['fieldName'] === '--div--') {
// tabs are not of interest here
continue;
} elseif ($aShowItemFieldArray['fieldName'] === '--palette--') {
// showitem references to a palette field. unpack the palette and process
// label overrides that may be in there.
if (!isset($result['processedTca']['palettes'][$aShowItemFieldArray['paletteName']]['showitem'])) {
// No palette with this name found? Skip it.
continue;
}
$palettesArray = GeneralUtility::trimExplode(
',',
$result['processedTca']['palettes'][$aShowItemFieldArray['paletteName']]['showitem']
);
foreach ($palettesArray as $aPalettesString) {
$aPalettesArray = GeneralUtility::trimExplode(';', $aPalettesString);
$aPalettesArray = [
'fieldName' => $aPalettesArray[0],
'fieldLabel' => $aPalettesArray[1] ?: null,
];
if (!empty($aPalettesArray['fieldLabel'])
&& isset($result['processedTca']['columns'][$aPalettesArray['fieldName']])
) {
$result['processedTca']['columns'][$aPalettesArray['fieldName']]['label'] = $aPalettesArray['fieldLabel'];
}
}
} else {
// If the field has a label in the showitem configuration of this record type, use it.
// showitem = 'aField, aFieldWithLabelOverride;theLabel, anotherField'
if (!empty($aShowItemFieldArray['fieldLabel'])
&& isset($result['processedTca']['columns'][$aShowItemFieldArray['fieldName']])
) {
$result['processedTca']['columns'][$aShowItemFieldArray['fieldName']]['label'] = $aShowItemFieldArray['fieldLabel'];
}
}
}
return $result;
}
/**
* pageTsConfig can override labels:
*
* TCEFORM.aTable.aField.label = 'override'
* TCEFORM.aTable.aField.label.en = 'override'
*
* @param array $result Result array
* @return array Modified result array
*/
protected function setLabelFromPageTsConfig(array $result)
{
$languageService = $this->getLanguageService();
$table = $result['tableName'];
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfiguration) {
$fieldTSConfig = [];
if (isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'])
&& is_array($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'])
) {
$fieldTSConfig = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'];
}
if (!empty($fieldTSConfig['label'])) {
$result['processedTca']['columns'][$fieldName]['label'] = $fieldTSConfig['label'];
}
if (!empty($fieldTSConfig['label.'][$languageService->lang])) {
$result['processedTca']['columns'][$fieldName]['label'] = $fieldTSConfig['label.'][$languageService->lang];
}
}
return $result;
}
/**
* Translate all labels if needed.
*
* @param array $result Result array
* @return array Modified result array
*/
protected function translateLabels(array $result)
{
$languageService = $this->getLanguageService();
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfiguration) {
if (!isset($fieldConfiguration['label'])) {
continue;
}
$result['processedTca']['columns'][$fieldName]['label'] = $languageService->sL($fieldConfiguration['label']);
}
return $result;
}
/**
* @return LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}
......@@ -21,7 +21,7 @@ use TYPO3\CMS\Core\Utility\MathUtility;
/**
* Create final showitem configuration in processedTca for types and palette
* fields
* Handles all the nasty defails like subtypes_addlist and friends.
* Handles all the nasty details like subtypes_addlist and friends.
*/
class TcaTypesShowitem implements FormDataProviderInterface
{
......
......@@ -90,7 +90,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsDefaultDataFormUserTsIfColumnIsDefinedInTca()
public function addDataSetsDefaultDataFromUserTsIfColumnIsDefinedInTca()
{
$input = [
'command' => 'new',
......@@ -121,7 +121,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataDoesNotSetDefaultDataFormUserTsIfColumnIsMissingInTca()
public function addDataDoesNotSetDefaultDataFromUserTsIfColumnIsMissingInTca()
{
$input = [
'command' => 'new',
......@@ -149,7 +149,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsDefaultDataFormPageTsIfColumnIsDefinedInTca()
public function addDataSetsDefaultDataFromPageTsIfColumnIsDefinedInTca()
{
$input = [
'command' => 'new',
......@@ -180,7 +180,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataDoesNotSetDefaultDataFormPageTsIfColumnIsMissingInTca()
public function addDataDoesNotSetDefaultDataFromPageTsIfColumnIsMissingInTca()
{
$input = [
'command' => 'new',
......@@ -208,7 +208,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsDefaultDataOverrulingFormPageTs()
public function addDataSetsDefaultDataOverrulingFromPageTs()
{
$input = [
'command' => 'new',
......@@ -320,7 +320,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsDefaultDataFormGetIfColumnIsDenfinedInTca()
public function addDataSetsDefaultDataFromGetIfColumnIsDefinedInTca()
{
$input = [
'command' => 'new',
......@@ -351,7 +351,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsDefaultDataFromPostIfColumnIsDenfinedInTca()
public function addDataSetsDefaultDataFromPostIfColumnIsDefinedInTca()
{
$input = [
'command' => 'new',
......@@ -420,7 +420,7 @@ class DatabaseRowInitializeNewTest extends UnitTestCase
/**
* @test
*/
public function addDataDoesNotSetDefaultDataFormGetPostIfColumnIsMissingInTca()
public function addDataDoesNotSetDefaultDataFromGetPostIfColumnIsMissingInTca()
{
$input = [
'command' => 'new',
......
<?php
namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
/*
* 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\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels;
use TYPO3\CMS\Core\Tests\UnitTestCase;
use TYPO3\CMS\Lang\LanguageService;
/**
* Test case
*/
class TcaColumnsProcessFieldLabelsTest extends UnitTestCase
{
/**
* @var TcaColumnsProcessFieldLabels
*/
protected $subject;
protected function setUp()
{
$this->subject = new TcaColumnsProcessFieldLabels();
}
/**
* @test
*/
public function addDataKeepsLabelAsIsIfNoOverrideIsGiven()
{
$input = [
'processedTca' => [
'columns' => [
'aField' => [
'label' => 'foo',
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('foo')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
$expected = $input;
$this->assertSame($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLabelFromShowitem()
{
$input = [
'processedTca' => [
'columns' => [
'aField' => [
'label' => 'origLabel',
],
],
'types' => [
'aType' => [
'showitem' => 'aField;aLabelOverride',
],
],
],
'recordTypeValue' => 'aType',
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('aLabelOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
$expected = $input;
$expected['processedTca']['columns']['aField']['label'] = 'aLabelOverride';
$this->assertSame($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLabelFromPalettesShowitem()
{
$input = [
'processedTca' => [
'columns' => [
'aField' => [
'label' => 'origLabel',
],
],
'types' => [
'aType' => [
'showitem' => '--palette--;;aPalette',
],
],
'palettes' => [
'aPalette' => [
'showitem' => 'aField;aLabelOverride',
],
],
],
'recordTypeValue' => 'aType',
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('aLabelOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
$expected = $input;
$expected['processedTca']['columns']['aField']['label'] = 'aLabelOverride';
$this->assertSame($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLabelFromPageTsConfig()
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => [
'label' => 'origLabel',
],
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'label' => 'aLabelOverride',
],
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->sL('aLabelOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
$expected = $input;
$expected['processedTca']['columns']['aField']['label'] = 'aLabelOverride';
$this->assertSame($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLabelFromPageTsConfigForSpecificLanguage()
{
$input = [
'tableName' => 'aTable',
'processedTca' => [
'columns' => [
'aField' => [
'label' => 'origLabel',
],
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'label.' => [
'fr' => 'aLabelOverride',
],
],
],
],
],
];
$languageServiceProphecy = $this->prophesize(LanguageService::class);
$languageServiceProphecy->lang = 'fr';
$languageServiceProphecy->sL('aLabelOverride')->shouldBeCalled()->willReturnArgument(0);
$GLOBALS['LANG'] = $languageServiceProphecy->reveal();
$expected = $input;
$expected['processedTca']['columns']['aField']['label'] = 'aLabelOverride';
$this->assertSame($expected, $this->subject->addData($input));
}
}
......@@ -447,7 +447,12 @@ return array(
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRecordTypeValue::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseSystemLanguageRows::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class,
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsRemoveUnused::class
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsRemoveUnused::class,
),
),
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class => array(
'depends' => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
),
),
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexFetch::class => array(
......@@ -456,6 +461,7 @@ return array(
\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\TcaFlexPrepare::class => array(
......@@ -531,11 +537,16 @@ return array(
),
'flexFormSegment' => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => array(),
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaGroup::class => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class => array(
'depends' => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class,
),
),
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaGroup::class => array(
'depends' => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaColumnsProcessFieldLabels::class,
),
),
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class => array(
'depends' => array(
\TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment