Skip to content

Commit e436ee7

Browse files
refact: clean command improvements (#100)
1 parent e5d770d commit e436ee7

File tree

1 file changed

+62
-39
lines changed

1 file changed

+62
-39
lines changed

commands/clean/content.php

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
declare(strict_types = 1);
44

55
use Kirby\CLI\CLI;
6+
use Kirby\Cms\Languages;
67

78
$cleanContent = function (
9+
CLI $cli,
810
Generator $collection,
9-
array|null $ignore = null,
10-
string|null $lang = null
11+
string $lang,
12+
array $ignore = [],
13+
bool $dryrun = false,
1114
): void {
1215
foreach ($collection as $item) {
1316
// get all fields in the content file
@@ -22,69 +25,89 @@
2225

2326
// get the keys and normalize to lowercase
2427
$originalContentKeys = array_keys($contentFields);
25-
$contentFieldKeys = array_map('mb_strtolower', $originalContentKeys);
28+
$contentFieldKeys = array_map('mb_strtolower', $originalContentKeys);
2629

2730
// get all field keys from blueprint and normalize to lowercase
28-
$blueprintFields = array_keys($item->blueprint()->fields());
31+
$blueprintFields = array_keys($item->blueprint()->fields());
2932
$blueprintFieldKeys = array_map('mb_strtolower', $blueprintFields);
3033

3134
// get all field keys that are in $contentFieldKeys but not in $blueprintFieldKeys
3235
$fieldsToBeDeleted = array_diff($contentFieldKeys, $blueprintFieldKeys);
3336

3437
// update page only if there are any fields to be deleted
35-
if (count($fieldsToBeDeleted) > 0) {
36-
// create a mapping: lowercase => original field name
37-
$lowercaseToOriginal = array_combine($contentFieldKeys, $originalContentKeys);
38-
39-
// build data array with original field names as keys and null as values
40-
$data = [];
41-
foreach ($fieldsToBeDeleted as $lowercaseField) {
42-
$originalField = $lowercaseToOriginal[$lowercaseField];
43-
$data[$originalField] = null;
44-
}
38+
if (count($fieldsToBeDeleted) === 0) {
39+
continue;
40+
}
4541

46-
// get the latest version of the item
47-
$version = $item->version('latest');
42+
// create a mapping: lowercase => original field name
43+
$lowercaseToOriginal = array_combine($contentFieldKeys, $originalContentKeys);
4844

49-
// check if the version exists for the given language
50-
// and try to update the page with the data
51-
if ($version->exists($lang ?? 'default') === true) {
52-
$version->update($data, $lang ?? 'default');
53-
}
45+
// build data array with original field names as keys and null as values
46+
$data = [];
47+
48+
foreach ($fieldsToBeDeleted as $lowercaseField) {
49+
$originalField = $lowercaseToOriginal[$lowercaseField];
50+
$data[$originalField] = null;
51+
52+
$cli->out('Remove "' . $originalField . '" from ' . $item::CLASS_ALIAS . ' (' . $item->id() . ')');
53+
}
54+
55+
// don't update models that have changes
56+
if ($item->version('changes')->exists($lang) === true) {
57+
$cli->error('The ' . $item::CLASS_ALIAS . ' (' . $item->id() . ') has changes and cannot be cleaned. Save the changes and try again.');
58+
}
59+
60+
// in a dry-run, the models will not be updated
61+
if ($dryrun === true) {
62+
continue;
63+
}
64+
65+
// get the latest version of the item
66+
$version = $item->version('latest');
67+
68+
// check if the version exists for the given language
69+
// and try to update the page with the data
70+
if ($version->exists($lang) === true) {
71+
$version->update($data, $lang);
5472
}
5573
}
5674
};
5775

5876
return [
5977
'description' => 'Deletes all fields from page, file or user content files that are not defined in the blueprint, no matter if they contain content or not.',
78+
'args' => [
79+
'dry-run' => [
80+
'description' => 'Run the command without actually updating content',
81+
'noValue' => true,
82+
],
83+
],
6084
'command' => static function (CLI $cli) use ($cleanContent): void {
6185

62-
$cli->confirmToContinue('This will delete all fields from content files that are not defined in blueprints, no matter if they contain content or not. Are you sure?');
86+
$kirby = $cli->kirby();
87+
$dryrun = $cli->arg('dry-run');
6388

64-
$kirby = $cli->kirby();
89+
if ($dryrun === false) {
90+
$cli->confirmToContinue('This will delete all fields from content files that are not defined in blueprints, no matter if they contain content or not. Are you sure?');
91+
}
6592

6693
// Authenticate as almighty
6794
$kirby->impersonate('kirby');
6895

6996
// set the fields to be ignored
7097
$ignore = ['uuid', 'title', 'slug', 'template', 'sort', 'focus'];
7198

72-
// call the script for all languages if multilang
73-
if ($kirby->multilang() === true) {
74-
$languages = $kirby->languages();
75-
76-
foreach ($languages as $language) {
77-
// should call kirby models for each loop
78-
// since generators cannot be cloned
79-
// otherwise run into an exception
80-
$collection = $kirby->models();
81-
82-
$cleanContent($collection, $ignore, $language->code());
83-
}
84-
85-
} else {
86-
$collection = $kirby->models();
87-
$cleanContent($collection, $ignore);
99+
// go through all languages
100+
foreach (Languages::ensure() as $language) {
101+
// should call kirby models for each loop
102+
// since generators cannot be cloned
103+
// otherwise run into an exception
104+
$cleanContent(
105+
cli: $cli,
106+
collection: $kirby->models(),
107+
lang: $language->code(),
108+
ignore: $ignore,
109+
dryrun: $dryrun
110+
);
88111
}
89112

90113
$cli->success('The content files have been cleaned');

0 commit comments

Comments
 (0)