Test Setup Failed
Push — ft/tiptap-editor ( 7b0ae7...cd4579 )
by
unknown
08:28
created

LocalizeRepeatFieldCommand::localizeRepeatField()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
nc 4
nop 2
dl 0
loc 30
rs 9.4555
c 1
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Chief\App\Console;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Thinktomorrow\Chief\Sites\ChiefSites;
7
8
class LocalizeRepeatFieldCommand extends BaseCommand
9
{
10
    protected $signature = 'chief:localize-repeat-field {classes} {key}';
11
12
    protected $description = 'Move localized repeat items to localized repeat format';
13
14
    public function __construct()
15
    {
16
        parent::__construct();
17
    }
18
19
    public function handle(): void
20
    {
21
        $classes = explode(',', $this->argument('classes'));
22
        $fieldKey = $this->argument('key');
23
24
        foreach ($classes as $class) {
25
26
            $models = $class::withoutGlobalScopes()->get();
27
28
            $models->each(function ($model) use ($fieldKey) {
29
                $this->localizeRepeatField($model, $fieldKey);
30
            });
31
32
            $this->info('All ['.$class.'] models have their ['.$fieldKey.'] values updated.');
33
        }
34
    }
35
36
    private function localizeRepeatField(Model $model, string $fieldKey): void
37
    {
38
        $value = $model->dynamic($fieldKey);
39
40
        if (! isset($value)) {
41
            $this->warn('Model ['.$model::class.' '.$model->id.'] does not have a ['.$fieldKey.'] field.');
42
43
            return;
44
        }
45
46
        if (! is_array($value) || empty($value)) {
47
            $this->warn('Model ['.$model::class.' '.$model->id.'] does not have a ['.$fieldKey.'] field that is an array.');
48
49
            return;
50
        }
51
52
        $keys = array_keys($value);
53
54
        if (! is_int($keys[0])) {
55
            $this->info('Model ['.$model::class.' '.$model->id.'] is already a converted ['.$fieldKey.'] field.');
56
57
            return;
58
        }
59
60
        $value = $this->transformLocalizedArray($value);
61
62
        $model->setDynamic($fieldKey, $value);
63
        $model->save();
64
65
        $this->info('Model ['.$model::class.' '.$model->id.'] has ['.$fieldKey.'] repeat value localized.');
66
    }
67
68
    private function transformLocalizedArray(array $items): array
69
    {
70
        $result = [];
71
72
        foreach ($items as $item) {
73
            $locales = [];
74
75
            foreach ($item as $property => $translations) {
76
                // We hope that at least one subitem is localized...
77
                if (is_array($translations)) {
78
                    $locales = array_unique(array_merge($locales, array_keys($translations)));
79
                }
80
            }
81
82
            if (empty($locales)) {
83
                $locales = ChiefSites::locales();
84
            }
85
86
            foreach ($locales as $locale) {
87
                $entry = [];
88
89
                foreach ($item as $property => $translations) {
90
                    if (! is_array($translations)) {
91
                        $entry[$property] = $translations;
92
93
                        continue;
94
                    }
95
96
                    $entry[$property] = $translations[$locale] ?? null;
97
                }
98
99
                $result[$locale][] = $entry;
100
            }
101
        }
102
103
        return $result;
104
    }
105
}
106