Skip to content

Commit e88e13d

Browse files
feat: New kirby uuid:duplicates command
1 parent 494ea08 commit e88e13d

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ This should print the Kirby CLI version and a list of available commands
7373
- kirby security
7474
- kirby unzip
7575
- kirby upgrade
76+
- kirby uuid:duplicates
7677
- kirby uuid:generate
7778
- kirby uuid:populate
7879
- kirby uuid:remove

commands/uuid/duplicates.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
use Kirby\CLI\Commands\UUID\Duplicates;
6+
7+
return [
8+
'description' => 'Find and optionally fix duplicate UUIDs',
9+
'args' => [
10+
'fix' => [
11+
'description' => 'Fix duplicate UUIDs by generating new ones',
12+
'noValue' => true,
13+
],
14+
],
15+
'command' => Duplicates::command(...)
16+
];
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Kirby\CLI\Commands\UUID;
6+
7+
use Kirby\CLI\CLI;
8+
use Kirby\Cms\ModelWithContent;
9+
use Kirby\Uuid\Uuid;
10+
11+
class Duplicates
12+
{
13+
protected static function check(CLI $cli, ModelWithContent $model, array &$uuids, array &$duplicates): void
14+
{
15+
$uuid = $model->content()->get('uuid');
16+
17+
if ($uuid->isEmpty() === true) {
18+
return;
19+
}
20+
21+
$uuid = $model->uuid()->toString();
22+
23+
// the UUID already exists for another model
24+
if (isset($uuids[$uuid])) {
25+
$duplicates[] = $uuid;
26+
27+
if ($cli->arg('fix') === true) {
28+
$model->uuid()->clear();
29+
$model->update([
30+
'uuid' => Uuid::generate()
31+
]);
32+
$model->uuid()->populate(true);
33+
$cli->print('✅ The duplicate UUID ' . $uuid . ' for ' . $model->id() . ' has been regenerated');
34+
} else {
35+
$cli->error('The UUID ' . $uuid . ' for ' . $model->id() . ' exists (' . $uuids[$uuid] . ')');
36+
}
37+
}
38+
39+
$uuids[$uuid] = $model->id();
40+
}
41+
42+
public static function command(CLI $cli): void
43+
{
44+
$kirby = $cli->kirby();
45+
$fix = $cli->arg('fix');
46+
47+
if ($fix === true) {
48+
$cli->confirmToContinue('Duplicate UUIDs will be removed and regenerated. This can break links in fields that use the UUID as reference. Do you want to continue?');
49+
}
50+
51+
$uuids = [];
52+
$duplicates = [];
53+
$site = $kirby->site();
54+
55+
$kirby->impersonate('kirby');
56+
57+
// go through all site files
58+
foreach ($site->files() as $file) {
59+
static::check($cli, $file, $uuids, $duplicates);
60+
}
61+
62+
// go through all pages
63+
foreach ($site->index(drafts: true) as $page) {
64+
static::check($cli, $page, $uuids, $duplicates);
65+
66+
// go through all files
67+
foreach ($page->files() as $file) {
68+
static::check($cli, $file, $uuids, $duplicates);
69+
}
70+
}
71+
72+
// go through all users
73+
foreach ($cli->kirby()->users() as $user) {
74+
static::check($cli, $user, $uuids, $duplicates);
75+
76+
// go through all files
77+
foreach ($user->files() as $file) {
78+
static::check($cli, $file, $uuids, $duplicates);
79+
}
80+
}
81+
82+
if (count($uuids) === 0) {
83+
$cli->success('There are no UUID duplicates');
84+
} elseif ($fix === true) {
85+
$cli->success(count($duplicates) . ' duplicates have been fixed');
86+
} else {
87+
$cli->print(count($duplicates) . ' duplicates! You can fix them with kirby uuid:duplicates --fix');
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)