From a6a7a5b9181dc82926495752f58ff5dd7789b11c Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Sat, 11 Apr 2020 22:27:26 +0200 Subject: [PATCH] [BUGFIX] Respect page TSconfig in drag & drop of page tree With this change the default values for new records in DataHandler are now respected based on the resolved page ID, allowing to deal with pageTS for specific sites or subpages. Resolves: #89211 Releases: master, 9.5 Change-Id: I4d889a857f04f2284c8643cd4253653fea0f2e19 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63406 Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Riccardo De Contardi <erredeco@gmail.com> Tested-by: Jonas Eberle <flightvision@googlemail.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> --- .../core/Classes/DataHandling/DataHandler.php | 48 +++++- .../DataHandler/DefaultValuesTest.php | 147 ++++++++++++++++++ 2 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index c52c28d78e7d..113556477d6d 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -755,6 +755,35 @@ class DataHandler implements LoggerAwareInterface } } + /** + * When a new record is created, all values that haven't been set but are set via PageTSconfig / UserTSconfig + * get applied here. + * + * This is only executed for new records. The most important part is that the pageTS of the actual resolved $pid + * is taken, and a new field array with empty defaults is set again. + * + * @param string $table + * @param int $pageId + * @param array $prepopulatedFieldArray + * @return array + */ + protected function applyDefaultsForFieldArray(string $table, int $pageId, array $prepopulatedFieldArray): array + { + // First set TCAdefaults respecting the given PageID + $tcaDefaults = BackendUtility::getPagesTSconfig($pageId)['TCAdefaults.'] ?? null; + // Re-apply $this->defaultValues settings + $this->setDefaultsFromUserTS($tcaDefaults); + $cleanFieldArray = $this->newFieldArray($table); + if (isset($prepopulatedFieldArray['pid'])) { + $cleanFieldArray['pid'] = $prepopulatedFieldArray['pid']; + } + $sortColumn = $GLOBALS['TCA'][$table]['ctrl']['sortby'] ?? null; + if ($sortColumn !== null && isset($prepopulatedFieldArray[$sortColumn])) { + $cleanFieldArray[$sortColumn] = $prepopulatedFieldArray[$sortColumn]; + } + return $cleanFieldArray; + } + /** * Dummy method formerly used for file handling. * @@ -1049,13 +1078,18 @@ class DataHandler implements LoggerAwareInterface // Here the "pid" is set IF NOT the old pid was a string pointing to a place in the subst-id array. [$tscPID] = BackendUtility::getTSCpid($table, $id, $old_pid_value ?: $fieldArray['pid']); - if ($status === 'new' && $table === 'pages') { - $fieldArray = $this->pagePermissionAssembler->applyDefaults( - $fieldArray, - (int)$tscPID, - (int)$this->userid, - (int)$this->BE_USER->firstMainGroup - ); + if ($status === 'new') { + // Apply TCAdefaults from pageTS + $fieldArray = $this->applyDefaultsForFieldArray($table, (int)$tscPID, $fieldArray); + // Apply page permissions as well + if ($table === 'pages') { + $fieldArray = $this->pagePermissionAssembler->applyDefaults( + $fieldArray, + (int)$tscPID, + (int)$this->userid, + (int)$this->BE_USER->firstMainGroup + ); + } } // Processing of all fields in incomingFieldArray and setting them in $fieldArray $fieldArray = $this->fillInFieldArray($table, $id, $fieldArray, $incomingFieldArray, $theRealPid, $status, $tscPID); diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php new file mode 100644 index 000000000000..698cc70afa95 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php @@ -0,0 +1,147 @@ +<?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\Core\Tests\Functional\DataHandling\DataHandler; + +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase; +use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; + +/** + * Tests various places to set default values properly for new records + */ +class DefaultValuesTest extends AbstractDataHandlerActionTestCase +{ + /** + * @var int + */ + const PAGE_DATAHANDLER = 88; + + /** + * @var string + */ + protected $scenarioDataSetDirectory = 'typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DataSet/'; + + protected function setUp(): void + { + parent::setUp(); + $this->importScenarioDataSet('LiveDefaultPages'); + $this->importScenarioDataSet('LiveDefaultElements'); + $this->backendUser->workspace = 0; + } + + /** + * @test + */ + public function defaultValuesFromTCAForNewRecordsIsRespected(): void + { + $GLOBALS['TCA']['pages']['columns']['keywords']['config']['default'] = 'a few,random,keywords'; + $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [ + 'title' => 'A new age' + ]); + $newPageId = reset($map['pages']); + $newPageRecord = BackendUtility::getRecord('pages', $newPageId); + self::assertEquals($newPageRecord['keywords'], $GLOBALS['TCA']['pages']['columns']['keywords']['config']['default']); + + $GLOBALS['TCA']['tt_content']['columns']['header']['config']['default'] = 'Pre-set header'; + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'header' => '', + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + // Empty header is used, because it was handed in + self::assertEquals($newContentRecord['header'], ''); + + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + self::assertEquals($newContentRecord['header'], $GLOBALS['TCA']['tt_content']['columns']['header']['config']['default']); + } + + /** + * @test + */ + public function defaultValuesFromGlobalTSconfigForNewRecordsIsRespected(): void + { + ExtensionManagementUtility::addPageTSConfig(' +TCAdefaults.pages.keywords = from pagets, with love +TCAdefaults.tt_content.header = global space'); + $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [ + 'title' => 'A new age' + ]); + $newPageId = reset($map['pages']); + $newPageRecord = BackendUtility::getRecord('pages', $newPageId); + self::assertEquals($newPageRecord['keywords'], 'from pagets, with love'); + + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'header' => '', + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + // Empty header is used, because it was handed in + self::assertEquals($newContentRecord['header'], ''); + + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + self::assertEquals($newContentRecord['header'], 'global space'); + } + + /** + * @test + */ + public function defaultValuesFromPageSpecificTSconfigForNewRecordsIsRespected(): void + { + ExtensionManagementUtility::addPageTSConfig(' +TCAdefaults.pages.keywords = from pagets, with love +TCAdefaults.tt_content.header = global space'); + $this->actionService->modifyRecord('pages', self::PAGE_DATAHANDLER, [ + 'TSconfig' => ' + +TCAdefaults.pages.keywords = I am specific, not generic +TCAdefaults.tt_content.header = local space + +']); + $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [ + 'title' => 'A new age' + ]); + $newPageId = reset($map['pages']); + $newPageRecord = BackendUtility::getRecord('pages', $newPageId); + self::assertEquals($newPageRecord['keywords'], 'I am specific, not generic'); + + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'header' => '', + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + // Empty header is used, because it was handed in + self::assertEquals($newContentRecord['header'], ''); + + $map = $this->actionService->createNewRecord('tt_content', $newPageId, [ + 'bodytext' => 'Random bodytext' + ]); + $newContentId = reset($map['tt_content']); + $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId); + self::assertEquals($newContentRecord['header'], 'local space'); + } +} -- GitLab