Skip to content

Commit

Permalink
utils/fix-field-layout-uids
Browse files Browse the repository at this point in the history
Resolves #11746
  • Loading branch information
brandonkelly committed Aug 20, 2022
1 parent 2223071 commit 471ba42
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Added
- Added the `utils/fix-field-layout-uids` command. ([#11746](https://github.com/craftcms/cms/issues/11746))

### Changed
- Improved the styling of Categories fields.
- The first field group is now automatically selected by default when creating a new custom field.
Expand Down
101 changes: 101 additions & 0 deletions src/console/controllers/utils/FixFieldLayoutUidsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\console\controllers\utils;

use Craft;
use craft\console\Controller;
use craft\helpers\Console;
use craft\helpers\StringHelper;
use yii\console\ExitCode;

/**
* Fixes any duplicate UUIDs found within field layout components in the project config.
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.2.3
*/
class FixFieldLayoutUidsController extends Controller
{
/**
* Fixes any duplicate UUIDs found within field layout components in the project config.
*
* @return int
*/
public function actionIndex(): int
{
$this->stdout("Looking for duplicate UUIDs ...\n");
$count = 0;
$this->_fixUids(Craft::$app->getProjectConfig()->get(), $count);

if ($count) {
$summary = sprintf('Fixed %s duplicate %s.', $count, $count === 1 ? 'UUID' : 'UUIDs');
} else {
$summary = 'No duplicate UUIDs were found.';
}

$this->stdout('Done. ', Console::FG_GREEN);
$this->stdout("$summary\n");


return ExitCode::OK;
}

private function _fixUids(array $config, int &$count, string $path = '', array &$uids = []): void
{
if (isset($config['fieldLayouts']) && is_array($config['fieldLayouts'])) {
$modified = false;

foreach ($config['fieldLayouts'] as $fieldLayoutUid => &$fieldLayoutConfig) {
if (isset($fieldLayoutConfig['tabs']) && is_array($fieldLayoutConfig['tabs'])) {
foreach ($fieldLayoutConfig['tabs'] as $tabIndex => &$tabConfig) {
$tabPath = ($path ? "$path.": '') . "fieldLayouts.$fieldLayoutUid.tabs.$tabIndex";
$this->_checkUid($tabConfig, $count, $uids, $modified, $tabPath);

if (isset($tabConfig['elements']) && is_array($tabConfig['elements'])) {
foreach ($tabConfig['elements'] as $elementIndex => &$elementConfig) {
$elementPath = "$tabPath.elements.$elementIndex";
$this->_checkUid($elementConfig, $count, $uids, $modified, $elementPath);
}
}
}
}
}

if ($modified) {
Craft::$app->getProjectConfig()->set($path, $config);
}

return;
}

foreach ($config as $key => $value) {
if (is_array($value)) {
$this->_fixUids($value, $count, ($path ? "$path." : '') . $key, $uids);
}
}
}

private function _checkUid(array &$config, int &$count, array &$uids, bool &$modified, string $path): void
{
if (isset($config['uid'])) {
if (isset($uids[$config['uid']])) {
$config['uid'] = StringHelper::UUID();
$count++;
$modified = true;

$this->stdout(' > Duplicate found at ');
$this->stdout($path, Console::FG_CYAN);
$this->stdout(".\n Changing to ");
$this->stdout($config['uid'], Console::FG_CYAN);
$this->stdout(".\n");
} else {
$uids[$config['uid']] = true;
}
}
}
}

0 comments on commit 471ba42

Please sign in to comment.