Skip to content

Commit

Permalink
Only look for duplicate UUIDs within project config data
Browse files Browse the repository at this point in the history
Resolves #16032
  • Loading branch information
brandonkelly committed Nov 9, 2024
1 parent 13ddd08 commit bebebed
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
33 changes: 21 additions & 12 deletions src/migrations/m230511_215903_content_refactor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bebebed

Please sign in to comment.