From 026c5d5cc3a62706761a5104b8f06fc7b2b3aad4 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Wed, 2 Aug 2023 08:59:02 -0700 Subject: [PATCH] Fixed #13456 Resolves #13462 --- CHANGELOG.md | 1 + src/models/ProjectConfigData.php | 62 ++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e8f7c638b1..bf6bfae74bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Fixed an error that occurred when deleting a volume with a missing filesystem type. - Fixed a bug where Color field values were illegible within selected element index rows. - Fixed a bug where multi-site content could be overwritten when creating a draft. ([#13451](https://github.com/craftcms/cms/issues/13451)) +- Fixed a bug where some nested component names weren’t getting deleted from the `meta.__names__` array in the project config. ([#13456](https://github.com/craftcms/cms/issues/13456)) ## 4.4.16.1 - 2023-07-19 diff --git a/src/models/ProjectConfigData.php b/src/models/ProjectConfigData.php index c32a4b4d822..3fce1b53d83 100644 --- a/src/models/ProjectConfigData.php +++ b/src/models/ProjectConfigData.php @@ -63,23 +63,21 @@ public function commitChanges(mixed $oldValue, mixed $newValue, string $path, bo $projectConfig = Craft::$app->getProjectConfig(); $valueChanged = $triggerUpdate || $projectConfig->forceUpdate || ProjectConfigHelper::encodeValueAsString($oldValue) !== ProjectConfigHelper::encodeValueAsString($newValue); - if ($newValue === null && is_array($oldValue)) { - $this->removeContainedProjectConfigNames(pathinfo($path, PATHINFO_EXTENSION), $oldValue); - } elseif (is_array($newValue)) { - $this->setContainedProjectConfigNames(pathinfo($path, PATHINFO_EXTENSION), $newValue); - } - - if ($valueChanged && !$projectConfig->muteEvents) { - $event = new ConfigEvent(compact('path', 'oldValue', 'newValue')); - if ($newValue === null && $oldValue !== null) { - // Fire a 'removeItem' event - $projectConfig->trigger(ProjectConfigService::EVENT_REMOVE_ITEM, $event); - } elseif ($oldValue === null && $newValue !== null) { - // Fire an 'addItem' event - $projectConfig->trigger(ProjectConfigService::EVENT_ADD_ITEM, $event); - } else { - // Fire an 'updateItem' event - $projectConfig->trigger(ProjectConfigService::EVENT_UPDATE_ITEM, $event); + if ($valueChanged) { + $this->updateContainedProjectConfigNames(pathinfo($path, PATHINFO_EXTENSION), $oldValue, $newValue); + + if (!$projectConfig->muteEvents) { + $event = new ConfigEvent(compact('path', 'oldValue', 'newValue')); + if ($newValue === null && $oldValue !== null) { + // Fire a 'removeItem' event + $projectConfig->trigger(ProjectConfigService::EVENT_REMOVE_ITEM, $event); + } elseif ($oldValue === null && $newValue !== null) { + // Fire an 'addItem' event + $projectConfig->trigger(ProjectConfigService::EVENT_ADD_ITEM, $event); + } else { + // Fire an 'updateItem' event + $projectConfig->trigger(ProjectConfigService::EVENT_UPDATE_ITEM, $event); + } } } @@ -142,11 +140,38 @@ public function getProjectConfigNameChanges(): array return $this->projectConfigNameChanges; } + private function updateContainedProjectConfigNames(string $lastPathSegment, mixed $oldValue, mixed $newValue): void + { + // Normalize both values to arrays + $newValue = is_array($newValue) ? $newValue : []; + $oldValue = is_array($oldValue) ? $oldValue : []; + + if (StringHelper::isUUID($lastPathSegment)) { + if (isset($newValue['name'])) { + // Set/update it + $this->projectConfigNameChanges[$lastPathSegment] = $newValue['name']; + } elseif (isset($oldValue['name'])) { + // Remove it + $this->projectConfigNameChanges[$lastPathSegment] = null; + } + } + + $keys = array_unique(array_merge( + array_keys($newValue), + array_keys($oldValue), + )); + + foreach ($keys as $key) { + $this->updateContainedProjectConfigNames($key, $oldValue[$key] ?? [], $newValue[$key] ?? []); + } + } + /** * Set all the contained project config names to the buffer. * * @param string $lastPathSegment * @param array $data + * @deprecated in 4.4.17 */ protected function setContainedProjectConfigNames(string $lastPathSegment, array $data): void { @@ -167,6 +192,7 @@ protected function setContainedProjectConfigNames(string $lastPathSegment, array * * @param string $lastPathSegment * @param array $data + * @deprecated in 4.4.17 */ protected function removeContainedProjectConfigNames(string $lastPathSegment, array $data): void { @@ -177,7 +203,7 @@ protected function removeContainedProjectConfigNames(string $lastPathSegment, ar foreach ($data as $key => $value) { // Traverse further if (is_array($value)) { - $this->setContainedProjectConfigNames($key, $value); + $this->removeContainedProjectConfigNames($key, $value); } } }