From 0dfac264de6cb24cf16a29dc955a6e2105c98f97 Mon Sep 17 00:00:00 2001 From: Thomas Hohn <thomas@hohn.dk> Date: Mon, 6 Feb 2017 12:01:25 +0100 Subject: [PATCH] [BUGFIX] Coalesce hook calls in DataHandler::processRemapStack() DataHandler's hook processDatamap_afterDatabaseOperations is processed in two ways. In case modifications do not contain any new relation that just has been created, the hook is executed directly. If that's not the case, executing this hook is deferred and will happen after the remap stack has been processed. Calling the hook directly happens exactly once for each modified record, where invocations in DataHandler::processRemapStack() might happen more than once, depending on the amount of relation fields that contain new references and have been remapped. This change coalesces these invocations which results that the hooks processDatamap_afterDatabaseOperations is exactly called once for each modified record - which is the expected behavior. Change-Id: Ib7e65ce170c8f9ba8f7577b79073b1ed9213a0b9 Resolves: #79635 Releases: master, 7.6 Reviewed-on: https://review.typo3.org/51552 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Thomas Hohn <thomas@hohn.dk> Tested-by: Thomas Hohn <thomas@hohn.dk> Reviewed-by: Frank Naegler <frank.naegler@typo3.org> Tested-by: Oliver Hader <oliver.hader@typo3.org> Reviewed-by: Oliver Hader <oliver.hader@typo3.org> --- .../core/Classes/DataHandling/DataHandler.php | 36 ++++++++++++++----- .../DataHandling/DataHandler/HookTest.php | 7 ---- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index 3a669f405b59..ecb3f7476d92 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -6076,6 +6076,7 @@ class DataHandler // Processes the remap stack: if (is_array($this->remapStack)) { $remapFlexForms = []; + $hookPayload = []; foreach ($this->remapStack as $remapAction) { // If no position index for the arguments was set, skip this remap action: @@ -6151,18 +6152,18 @@ class DataHandler $remapFlexForms[$flexFormId][$flexFormPath] = $newValue; } - // Process waiting Hook: processDatamap_afterDatabaseOperations: + + // Collect elements that shall trigger processDatamap_afterDatabaseOperations if (isset($this->remapStackRecords[$table][$rawId]['processDatamap_afterDatabaseOperations'])) { $hookArgs = $this->remapStackRecords[$table][$rawId]['processDatamap_afterDatabaseOperations']; - // Update field with remapped data: - $hookArgs['fieldArray'][$field] = $newValue; - // Process waiting hook objects: - $hookObjectsArr = $hookArgs['hookObjectsArr']; - foreach ($hookObjectsArr as $hookObj) { - if (method_exists($hookObj, 'processDatamap_afterDatabaseOperations')) { - $hookObj->processDatamap_afterDatabaseOperations($hookArgs['status'], $table, $rawId, $hookArgs['fieldArray'], $this); - } + if (!isset($hookPayload[$table][$rawId])) { + $hookPayload[$table][$rawId] = [ + 'status' => $hookArgs['status'], + 'fieldArray' => $hookArgs['fieldArray'], + 'hookObjects' => $hookArgs['hookObjectsArr'], + ]; } + $hookPayload[$table][$rawId]['fieldArray'][$field] = $newValue; } } @@ -6171,6 +6172,23 @@ class DataHandler $this->updateFlexFormData($flexFormId, $modifications); } } + + foreach ($hookPayload as $tableName => $rawIdPayload) { + foreach ($rawIdPayload as $rawId => $payload) { + foreach ($payload['hookObjects'] as $hookObject) { + if (!method_exists($hookObject, 'processDatamap_afterDatabaseOperations')) { + continue; + } + $hookObject->processDatamap_afterDatabaseOperations( + $payload['status'], + $tableName, + $rawId, + $payload['fieldArray'], + $this + ); + } + } + } } // Processes the remap stack actions: if ($this->remapStackActions) { diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php index 6c72ea72ea49..ee32d0e14641 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php @@ -204,13 +204,6 @@ class HookTest extends AbstractDataHandlerActionTestCase 'fieldArray' => [ 'header' => 'Testing #1', self::FIELD_ContentHotel => 1, - ], - ], - // @todo Fix the double invocation for this tt_content record - [ - 'table' => self::TABLE_Content, - 'fieldArray' => [ - 'header' => 'Testing #1', self::FIELD_Categories => 1, ], ], -- GitLab