From 8c81e38b5df835ef65b99324479dca214d5884c5 Mon Sep 17 00:00:00 2001 From: Georg Ringer <georg.ringer@gmail.com> Date: Mon, 12 Dec 2022 16:25:14 +0100 Subject: [PATCH] [TASK] Provide more information to itemsProcFunc calls Adding the following information to itemsProcFunc helps extension authors: - effectivePid: correct page id - site: current site Resolves: #99346 Releases: main, 12.4 Change-Id: Ifc54a06c66f3dbf61a2e95f706bb54e74db4b28e Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/82240 Tested-by: core-ci <typo3@b13.com> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- .../FormDataProvider/AbstractItemProvider.php | 3 ++- .../FormDataProvider/TcaSelectItemsTest.php | 9 +++++++++ .../FormDataProvider/TcaCheckboxItemsTest.php | 7 +++++++ .../FormDataProvider/TcaRadioItemsTest.php | 7 +++++++ .../Tests/Unit/Utility/BackendUtilityTest.php | 8 ++++++++ .../DataHandling/ItemProcessingService.php | 19 +++++++++++++++++++ typo3/sysext/core/Configuration/Services.yaml | 3 +++ 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php index c023fc54cf37..be6aec09c2a9 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php @@ -73,6 +73,8 @@ abstract class AbstractItemProvider 'table' => $table, 'row' => $result['databaseRow'], 'field' => $fieldName, + 'effectivePid' => $result['effectivePid'], + 'site' => $result['site'], // IMPORTANT: Below fields are only available in FormEngine context. // They are not used by the DataHandler when processing itemsProcFunc // for checking if a submitted value is valid. This means, in case @@ -92,7 +94,6 @@ abstract class AbstractItemProvider if (!empty($result['flexParentDatabaseRow'])) { $processorParameters['flexParentDatabaseRow'] = $result['flexParentDatabaseRow']; } - try { $items = array_map( fn(array $item) => SelectItem::fromTcaItemArray($item, $config['type']), diff --git a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php index c1c0ba459cb4..f689176f75b5 100644 --- a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php +++ b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php @@ -1894,6 +1894,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -1962,6 +1964,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'inlineTopMostParentTableName' => 'topMostTable', 'inlineTopMostParentFieldName' => 'topMostField', 'effectivePid' => 1, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -2040,6 +2043,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'inlineTopMostParentTableName' => 'topMostTable', 'inlineTopMostParentFieldName' => 'topMostField', 'effectivePid' => 1, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -2127,6 +2131,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'inlineTopMostParentTableName' => 'topMostTable', 'inlineTopMostParentFieldName' => 'topMostField', 'effectivePid' => 1, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -2215,6 +2220,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ @@ -2288,6 +2295,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaCheckboxItemsTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaCheckboxItemsTest.php index cd5383eaa96e..d705dee1c7bb 100644 --- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaCheckboxItemsTest.php +++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaCheckboxItemsTest.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageQueue; use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; @@ -501,6 +502,8 @@ final class TcaCheckboxItemsTest extends UnitTestCase 'inlineTopMostParentTableName' => 'topMostTable', 'inlineTopMostParentFieldName' => 'topMostField', 'databaseRow' => [], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -545,6 +548,8 @@ final class TcaCheckboxItemsTest extends UnitTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ @@ -631,6 +636,8 @@ final class TcaCheckboxItemsTest extends UnitTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRadioItemsTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRadioItemsTest.php index 3a40fcb125ba..1106e44327bf 100644 --- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRadioItemsTest.php +++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaRadioItemsTest.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageQueue; use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; @@ -239,6 +240,8 @@ final class TcaRadioItemsTest extends UnitTestCase 'inlineTopMostParentTableName' => 'topMostTable', 'inlineTopMostParentFieldName' => 'topMostField', 'databaseRow' => [], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'processedTca' => [ 'columns' => [ 'aField' => [ @@ -284,6 +287,8 @@ final class TcaRadioItemsTest extends UnitTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ @@ -365,6 +370,8 @@ final class TcaRadioItemsTest extends UnitTestCase 'databaseRow' => [ 'aField' => 'aValue', ], + 'effectivePid' => 42, + 'site' => new Site('aSite', 456, []), 'pageTsConfig' => [ 'TCEFORM.' => [ 'aTable.' => [ diff --git a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php index ab7811eb0b37..8216e2199fba 100644 --- a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php +++ b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php @@ -23,7 +23,9 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Database\RelationHandler; +use TYPO3\CMS\Core\DataHandling\ItemProcessingService; use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode; use TYPO3\CMS\Core\TypoScript\PageTsConfig; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -921,10 +923,13 @@ final class BackendUtilityTest extends UnitTestCase ['pageTsConfig-pid-to-hash-0', 'hash'], ['pageTsConfig-hash-to-object-hash', new PageTsConfig(new RootNode())], ]); + $siteFinderMock = $this->createMock(SiteFinder::class); + GeneralUtility::addInstance(ItemProcessingService::class, new ItemProcessingService($siteFinderMock)); GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerMock); $label = BackendUtility::getLabelFromItemlist($table, $col, $key); self::assertEquals($label, $expectedLabel); + GeneralUtility::purgeInstances(); } public static function getLabelFromItemListMergedReturnsCorrectFieldsDataProvider(): array @@ -1082,11 +1087,14 @@ final class BackendUtilityTest extends UnitTestCase ['pageTsConfig-pid-to-hash-0', 'hash'], ['pageTsConfig-hash-to-object-hash', new PageTsConfig(new RootNode())], ]); + $siteFinderMock = $this->createMock(SiteFinder::class); + GeneralUtility::addInstance(ItemProcessingService::class, new ItemProcessingService($siteFinderMock)); GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerMock); $GLOBALS['TCA'][$table] = $tca; $label = BackendUtility::getLabelsFromItemsList($table, $col, $keyList, $pageTsConfig); self::assertEquals($expectedLabel, $label); + GeneralUtility::purgeInstances(); } /** diff --git a/typo3/sysext/core/Classes/DataHandling/ItemProcessingService.php b/typo3/sysext/core/Classes/DataHandling/ItemProcessingService.php index c13dd6ab6e09..840957fc15ae 100644 --- a/typo3/sysext/core/Classes/DataHandling/ItemProcessingService.php +++ b/typo3/sysext/core/Classes/DataHandling/ItemProcessingService.php @@ -16,10 +16,14 @@ namespace TYPO3\CMS\Core\DataHandling; use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Exception\SiteNotFoundException; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Schema\Struct\SelectItem; +use TYPO3\CMS\Core\Site\Entity\NullSite; +use TYPO3\CMS\Core\Site\Entity\SiteInterface; +use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -28,6 +32,10 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class ItemProcessingService { + public function __construct( + protected readonly SiteFinder $siteFinder + ) {} + /** * Executes an itemsProcFunc if defined in TCA and returns the combined result (predefined + processed items) * @@ -52,6 +60,8 @@ class ItemProcessingService $params['table'] = $table; $params['row'] = $row; $params['field'] = $field; + $params['effectivePid'] = $realPid; + $params['site'] = $this->resolveSite($realPid); // The itemsProcFunc method may throw an exception. // If it does, display an error message and return items unchanged. @@ -91,6 +101,15 @@ class ItemProcessingService return $selectedItems; } + protected function resolveSite(int $pageId): SiteInterface + { + try { + return $this->siteFinder->getSiteByPageId($pageId); + } catch (SiteNotFoundException $e) { + return new NullSite(); + } + } + protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; diff --git a/typo3/sysext/core/Configuration/Services.yaml b/typo3/sysext/core/Configuration/Services.yaml index c7ef53fd31a4..236f6debec7c 100644 --- a/typo3/sysext/core/Configuration/Services.yaml +++ b/typo3/sysext/core/Configuration/Services.yaml @@ -76,6 +76,9 @@ services: TYPO3\CMS\Core\Database\Schema\SchemaMigrator: public: true + TYPO3\CMS\Core\DataHandling\ItemProcessingService: + public: true + TYPO3\CMS\Core\Database\Schema\SqlReader: public: true -- GitLab