Skip to content

Commit

Permalink
[BUGFIX] Do not transform text when RTE is disabled
Browse files Browse the repository at this point in the history
The TcaText data provider transforms a given database
field value with the RteHtmlParser as soon as `enableRichtext`
is set for the field in TCA. This means, the data provider
did previously not checked, whether RTE is disabled for the
user in general or for this specific field by configuration
(e.g. page TSconfig). This therefore led, among others, to
"normal" text being falsely wrapped with `<p>` tags.

This is now fixed by checking all relevant settings before
actually transforming the database field value.

Resolves: #94915
Releases: master, 10.4
Change-Id: I5af4e9997c28269be959ea9e63e12cfee5e991af
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70737
Tested-by: core-ci <typo3@b13.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
  • Loading branch information
o-ba committed Aug 24, 2021
1 parent 74578fd commit 71bc923
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 14 deletions.
31 changes: 20 additions & 11 deletions typo3/sysext/backend/Classes/Form/FormDataProvider/TcaText.php
Expand Up @@ -18,6 +18,7 @@
namespace TYPO3\CMS\Backend\Form\FormDataProvider;

use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Configuration\Richtext;
use TYPO3\CMS\Core\Html\RteHtmlParser;
use TYPO3\CMS\Core\Utility\GeneralUtility;
Expand All @@ -41,7 +42,8 @@ public function addData(array $result)
continue;
}

if (isset($fieldConfig['config']['enableRichtext']) && (bool)$fieldConfig['config']['enableRichtext'] === true) {
// Check if richtext is enabled for the field and the user did not disable RTE in general
if (($fieldConfig['config']['enableRichtext'] ?? false) && $this->getBackendUser()->isRTE()) {
$richtextConfigurationProvider = GeneralUtility::makeInstance(Richtext::class);
$richtextConfiguration = $richtextConfigurationProvider->getConfiguration(
$result['tableName'],
Expand All @@ -50,20 +52,27 @@ public function addData(array $result)
(string)$result['recordTypeValue'],
$fieldConfig['config']
);
// remember RTE preset name
$result['processedTca']['columns'][$fieldName]['config']['richtextConfigurationName'] = $fieldConfig['config']['richtextConfiguration'] ?? '';
// Add final resolved configuration to TCA array
$result['processedTca']['columns'][$fieldName]['config']['richtextConfiguration'] = $richtextConfiguration;

// If eval=null is set for field, value might be null ... don't transform anything in this case.
if ($result['databaseRow'][$fieldName] !== null) {
// Process "from-db-to-rte" on current value
$richTextParser = GeneralUtility::makeInstance(RteHtmlParser::class);
$result['databaseRow'][$fieldName] = $richTextParser->transformTextForRichTextEditor($result['databaseRow'][$fieldName], $richtextConfiguration['proc.'] ?? []);
// Transform if richtext is not disabled in configuration
if (!($richtextConfiguration['disabled'] ?? false)) {
// remember RTE preset name
$result['processedTca']['columns'][$fieldName]['config']['richtextConfigurationName'] = $fieldConfig['config']['richtextConfiguration'] ?? '';
// Add final resolved configuration to TCA array
$result['processedTca']['columns'][$fieldName]['config']['richtextConfiguration'] = $richtextConfiguration;
// If eval=null is set for field, value might be null ... don't transform anything in this case.
if ($result['databaseRow'][$fieldName] !== null) {
// Process "from-db-to-rte" on current value
$richTextParser = GeneralUtility::makeInstance(RteHtmlParser::class);
$result['databaseRow'][$fieldName] = $richTextParser->transformTextForRichTextEditor($result['databaseRow'][$fieldName], $richtextConfiguration['proc.'] ?? []);
}
}
}
}

return $result;
}

protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
}
121 changes: 120 additions & 1 deletion typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaTextTest.php
Expand Up @@ -18,6 +18,7 @@
namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;

use TYPO3\CMS\Backend\Form\FormDataProvider\TcaText;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Configuration\Richtext;
use TYPO3\CMS\Core\Html\RteHtmlParser;
use TYPO3\CMS\Core\Utility\GeneralUtility;
Expand All @@ -31,8 +32,12 @@ class TcaTextTest extends UnitTestCase
/**
* @test
*/
public function addDataSetsRichtextConfigurationAndTransformsContent()
public function addDataSetsRichtextConfigurationAndTransformsContent(): void
{
$beUserProphecy = $this->prophesize(BackendUserAuthentication::class);
$beUserProphecy->isRTE()->willReturn(true);
$GLOBALS['BE_USER'] = $beUserProphecy->reveal();

$input = [
'tableName' => 'aTable',
'effectivePid' => 42,
Expand Down Expand Up @@ -100,4 +105,118 @@ public function addDataSetsRichtextConfigurationAndTransformsContent()

self::assertSame($expected, (new TcaText())->addData($input));
}

/**
* @test
*/
public function addDataDoesNotTransformsContentWhenRichtextIsNotSet(): void
{
$beUserProphecy = $this->prophesize(BackendUserAuthentication::class);
$beUserProphecy->isRTE()->willReturn(true);
$GLOBALS['BE_USER'] = $beUserProphecy->reveal();

$input = [
'tableName' => 'aTable',
'effectivePid' => 42,
'recordTypeValue' => 23,
'databaseRow' => [
'aField' => 'notProcessedContent',
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'text',
]
],
],
],
];

// No processing should be performed
$expected = $input;
self::assertSame($expected, (new TcaText())->addData($input));
}

/**
* @test
*/
public function addDataDoesNotTransformsContentWhenRichtextIsDisabledInConfiguration(): void
{
$beUserProphecy = $this->prophesize(BackendUserAuthentication::class);
$beUserProphecy->isRTE()->willReturn(true);
$GLOBALS['BE_USER'] = $beUserProphecy->reveal();

$input = [
'tableName' => 'aTable',
'effectivePid' => 42,
'recordTypeValue' => 23,
'databaseRow' => [
'aField' => 'notProcessedContent',
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'text',
'enableRichtext' => true,
],
],
],
],
];

$richtextConfigurationProphecy = $this->prophesize(Richtext::class);
GeneralUtility::addInstance(Richtext::class, $richtextConfigurationProphecy->reveal());

$richtextConfigurationProphecy
->getConfiguration(
'aTable',
'aField',
42,
23,
[
'type' => 'text',
'enableRichtext' => true,
]
)
->willReturn(['disabled' => '1']);

// No processing should be performed
$expected = $input;
self::assertSame($expected, (new TcaText())->addData($input));
}

/**
* @test
*/
public function addDataDoesNotTransformsContentWhenRichtextIsDisabledForUser(): void
{
$beUserProphecy = $this->prophesize(BackendUserAuthentication::class);
$beUserProphecy->isRTE()->willReturn(false);
$GLOBALS['BE_USER'] = $beUserProphecy->reveal();

$input = [
'tableName' => 'aTable',
'effectivePid' => 42,
'recordTypeValue' => 23,
'databaseRow' => [
'aField' => 'notProcessedContent',
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'text',
'enableRichtext' => true,
],
],
],
],
];

// No processing should be performed
$expected = $input;
self::assertSame($expected, (new TcaText())->addData($input));
}
}
Expand Up @@ -639,9 +639,9 @@ public function calcPerms($row)
* @return bool
* @internal should only be used from within TYPO3 Core
*/
public function isRTE()
public function isRTE(): bool
{
return (bool)$this->uc['edit_RTE'];
return (bool)($this->uc['edit_RTE'] ?? false);
}

/**
Expand Down

0 comments on commit 71bc923

Please sign in to comment.