Commit b62b6e31 authored by Oliver Bartsch's avatar Oliver Bartsch
Browse files

[BUGFIX] Do not transform text when RTE is disabled

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/+/70674


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
parent 92e04f10
......@@ -18,6 +18,7 @@ declare(strict_types=1);
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;
......@@ -41,7 +42,8 @@ class TcaText implements FormDataProviderInterface
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'],
......@@ -50,20 +52,27 @@ class TcaText implements FormDataProviderInterface
(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'];
}
}
......@@ -17,7 +17,9 @@ declare(strict_types=1);
namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
use Prophecy\PhpUnit\ProphecyTrait;
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;
......@@ -28,12 +30,17 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
*/
class TcaTextTest extends UnitTestCase
{
use \Prophecy\PhpUnit\ProphecyTrait;
use ProphecyTrait;
/**
* @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,
......@@ -101,4 +108,118 @@ class TcaTextTest extends UnitTestCase
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));
}
}
......@@ -586,9 +586,9 @@ class BackendUserAuthentication extends AbstractUserAuthentication
* @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);
}
/**
......
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