From bebebedbbc0332f008453a02f180910ca371536c Mon Sep 17 00:00:00 2001 From: brandonkelly <brandon@pixelandtonic.com> Date: Fri, 8 Nov 2024 17:18:07 -0800 Subject: [PATCH] Only look for duplicate UUIDs within project config data Resolves #16032 --- CHANGELOG.md | 1 + .../m230511_215903_content_refactor.php | 33 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e4960b5dc8..2d712f6d87e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Fixed a bug where the `utils/fix-field-layout-uids` command was misidentifying missing/duplicate UUID issues. +- Fixed an error that could occur when upgrading to Craft 5, if unused field layouts contained duplicate UUIDs. ([#16032](https://github.com/craftcms/cms/issues/16032)) ## 5.4.10.1 - 2024-11-07 diff --git a/src/migrations/m230511_215903_content_refactor.php b/src/migrations/m230511_215903_content_refactor.php index 67fb80b4ea2..360be680725 100644 --- a/src/migrations/m230511_215903_content_refactor.php +++ b/src/migrations/m230511_215903_content_refactor.php @@ -3,10 +3,10 @@ namespace craft\migrations; use Craft; -use craft\db\Migration; use craft\db\Query; use craft\db\Table; use craft\elements\User; +use craft\fieldlayoutelements\CustomField; use craft\helpers\ArrayHelper; use yii\console\Exception; @@ -22,18 +22,26 @@ public function safeUp(): bool { // Before anything else, be absolutely certain that all custom fields' layout elements have unique UUIDs $uids = []; - $fieldsService = Craft::$app->getFields(); - foreach ($fieldsService->getAllLayouts() as $fieldLayout) { - $typeLabel = class_exists($fieldLayout->type) ? $fieldLayout->type::lowerDisplayName() : $fieldLayout->type; - $a = in_array(mb_strtolower($typeLabel[0] ?? ''), ['a', 'e', 'i', 'o', 'u']) ? 'An' : 'A'; - foreach ($fieldLayout->getCustomFieldElements() as $layoutElement) { - if (!isset($layoutElement->uid)) { - throw new Exception("$a $typeLabel field layout element is missing its UUID. Reinstall Craft CMS ^4.4.14 and run `utils/fix-field-layout-uids` before upgrading to Craft CMS 5."); - } - if (isset($uids[$layoutElement->uid])) { - throw new Exception("$a $typeLabel field layout element has a duplicate UUID. Reinstall Craft CMS ^4.4.14 and run `utils/fix-field-layout-uids` before upgrading to Craft CMS 5."); + + $projectConfigService = Craft::$app->getProjectConfig(); + $layoutConfigs = array_merge( + array_values($projectConfigService->find(fn(array $item, string $itemPath) => str_ends_with($itemPath, '.fieldLayout'))), + ...array_values($projectConfigService->find(fn(array $item, string $itemPath) => str_ends_with($itemPath, '.fieldLayouts'))), + ); + + foreach ($layoutConfigs as $layoutConfig) { + foreach ($layoutConfig['tabs'] ?? [] as $tabConfig) { + foreach ($tabConfig['elements'] ?? [] as $elementConfig) { + if (($elementConfig['type'] ?? null) === CustomField::class) { + if (empty($elementConfig['uid'])) { + throw new Exception('A field layout element is missing its UUID. Reinstall Craft CMS ^4.4.14 and run `utils/fix-field-layout-uids` before upgrading to Craft CMS 5.'); + } + if (isset($uids[$elementConfig['uid']])) { + throw new Exception('A field layout element has a duplicate UUID. Reinstall Craft CMS ^4.4.14 and run `utils/fix-field-layout-uids` before upgrading to Craft CMS 5.'); + } + $uids[$elementConfig['uid']] = true; + } } - $uids[$layoutElement->uid] = true; } } @@ -99,6 +107,7 @@ public function safeUp(): bool } $indexedMatrixFieldConfigs[$matrixFieldUid] = $matrixFieldConfig; } + $fieldsService = Craft::$app->getFields(); foreach ($projectConfig->get('matrixBlockTypes') ?? [] as $blockTypeUid => $blockTypeConfig) { if (!isset($indexedMatrixFieldConfigs[$blockTypeConfig['field']])) { continue;