SyncCommand::fillMissingKeys()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 3
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace NicolasBeauvais\Transcribe\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Arr;
7
use NicolasBeauvais\Transcribe\Manager;
8
9
class SyncCommand extends Command
10
{
11
    /**
12
     * The name and signature of the console command.
13
     *
14
     * @var string
15
     */
16
    protected $signature = 'transcribe:sync';
17
18
    /**
19
     * The description of the console command.
20
     *
21
     * @var string
22
     */
23
    protected $description = 'Look for translations in views and update missing key in language files.';
24
25
    /**
26
     * The Languages manager instance.
27
     *
28
     * @var \NicolasBeauvais\Transcribe\Manager
29
     */
30
    private $manager;
31
32
    /**
33
     * Command constructor.
34
     *
35
     * @param \NicolasBeauvais\Transcribe\Manager $manager
36
     *
37
     * @return void
38
     */
39
    public function __construct(Manager $manager)
40
    {
41
        parent::__construct();
42
43
        $this->manager = $manager;
44
    }
45
46
    /**
47
     * Execute the console command.
48
     *
49
     * @return mixed
50
     */
51
    public function handle()
52
    {
53
        $translationFiles = $this->manager->files();
54
55
        $this->syncKeysFromFiles($translationFiles);
56
57
        $this->syncKeysBetweenLanguages($translationFiles);
58
59
        $this->info('Done!');
60
    }
61
62
    /**
63
     * Synchronize keys found in project files but missing in languages.
64
     *
65
     * @param $translationFiles
66
     *
67
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
68
     *
69
     * @return void
70
     */
71
    private function syncKeysFromFiles($translationFiles)
72
    {
73
        $this->info('Reading translation keys from files...');
74
75
        // An array of all translation keys as found in project files.
76
        $allKeysInFiles = $this->manager->collectFromFiles();
77
78
        foreach ($translationFiles as $fileName => $languages) {
79
            foreach ($languages as $languageKey => $path) {
80
                $fileContent = $this->manager->getFileContent($path);
81
82
                if (isset($allKeysInFiles[$fileName])) {
83
                    $missingKeys = array_diff($allKeysInFiles[$fileName], array_keys(array_dot($fileContent)));
84
85
                    foreach ($missingKeys as $i => $missingKey) {
86
                        if (Arr::has($fileContent, $missingKey)) {
87
                            unset($missingKeys[$i]);
88
                        }
89
                    }
90
91
                    $this->fillMissingKeys($fileName, $missingKeys, $languageKey);
92
                }
93
            }
94
        }
95
    }
96
97
    /**
98
     * Fill the missing keys with an empty string in the given file.
99
     *
100
     * @param string $fileName
101
     * @param array  $foundMissingKeys
102
     * @param string $languageKey
103
     *
104
     * @return void
105
     */
106
    private function fillMissingKeys($fileName, array $foundMissingKeys, $languageKey)
107
    {
108
        $missingKeys = [];
109
110
        foreach ($foundMissingKeys as $missingKey) {
111
            $missingKeys[$missingKey] = [$languageKey => ''];
112
113
            $this->output->writeln("\"<fg=yellow>{$fileName}.{$missingKey}.{$languageKey}</>\" was added.");
114
        }
115
116
        $this->manager->fillKeys(
117
            $fileName,
118
            $missingKeys
119
        );
120
    }
121
122
    /**
123
     * Synchronize keys that exist in a language but not the other.
124
     *
125
     * @param $translationFiles
126
     *
127
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
128
     *
129
     * @return void
130
     */
131
    private function syncKeysBetweenLanguages($translationFiles)
132
    {
133
        $this->info('Synchronizing language files...');
134
135
        $filesResults = [];
136
137
        // Here we collect the file results
138
        foreach ($translationFiles as $fileName => $languageFiles) {
139
            foreach ($languageFiles as $languageKey => $filePath) {
140
                $filesResults[$fileName][$languageKey] = $this->manager->getFileContent($filePath);
141
            }
142
        }
143
144
        $values = Arr::dot($filesResults);
145
146
        $missing = $this->manager->getKeysExistingInALanguageButNotTheOther($values);
147
148
        foreach ($missing as &$missingKey) {
149
            list($file, $key) = explode('.', $missingKey, 2);
150
151
            list($key, $language) = explode(':', $key, 2);
152
153
            $this->fillMissingKeys($file, [$key], $language);
154
        }
155
    }
156
}
157