Passed
Push — main ( 8320d0...c2748c )
by Andrey
45:28 queued 42:35
created

BaseCommand   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 323
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 21
Bugs 15 Features 0
Metric Value
eloc 125
c 21
b 15
f 0
dl 0
loc 323
ccs 157
cts 157
cp 1
rs 8.72
wmc 46

29 Methods

Rating   Name   Duplication   Size   Complexity  
A files() 0 12 2
A locales() 0 9 2
A filesLength() 0 17 3
A packages() 0 5 1
A hasInline() 0 5 1
A end() 0 7 1
A plugins() 0 16 2
A processing() 0 7 1
A boolOption() 0 5 2
A action() 0 5 1
A targetLocales() 0 5 1
A start() 0 7 1
A ranFiles() 0 14 2
A getPlugins() 0 5 1
A ranLocales() 0 11 2
A validateLocale() 0 5 1
A processed() 0 7 1
A process() 0 11 3
A localesLength() 0 11 2
A ran() 0 10 2
A hasFull() 0 5 1
A validatePackage() 0 5 1
A hasProcessed() 0 5 2
A pushProcessed() 0 6 3
A clean() 0 5 1
A ranPlugins() 0 15 3
A hasForce() 0 5 1
A handle() 0 7 1
A message() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like BaseCommand often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BaseCommand, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Helldar\LaravelLangPublisher\Console;
4
5
use Helldar\LaravelLangPublisher\Concerns\Containable;
6
use Helldar\LaravelLangPublisher\Concerns\Logger;
7
use Helldar\LaravelLangPublisher\Concerns\Pathable;
8
use Helldar\LaravelLangPublisher\Constants\Locales as LocalesList;
9
use Helldar\LaravelLangPublisher\Contracts\Actionable;
10
use Helldar\LaravelLangPublisher\Contracts\Plugin;
11
use Helldar\LaravelLangPublisher\Contracts\Processor;
12
use Helldar\LaravelLangPublisher\Facades\Config;
13
use Helldar\LaravelLangPublisher\Facades\Info;
14
use Helldar\LaravelLangPublisher\Facades\Locales;
15
use Helldar\LaravelLangPublisher\Facades\Packages;
16
use Helldar\LaravelLangPublisher\Facades\Validator;
17
use Helldar\LaravelLangPublisher\Services\Command\Locales as LocalesSupport;
18
use Helldar\LaravelLangPublisher\Support\Info as InfoSupport;
19
use Helldar\Support\Facades\Helpers\Arr;
20
use Helldar\Support\Facades\Helpers\Filesystem\File;
21
use Helldar\Support\Facades\Helpers\Str;
22
use Illuminate\Console\Command;
23
24
abstract class BaseCommand extends Command
25
{
26
    use Containable;
27
    use Logger;
28
    use Pathable;
29
30
    protected $action;
31
32
    protected $locales_length = 0;
33
34
    protected $files_length = 0;
35
36
    protected $files;
37
38
    protected $locales;
39
40
    protected $plugins;
41
42
    protected $processed = [];
43
44 18
    public function handle()
45
    {
46 18
        $this->setLogger();
47 18
        $this->start();
48 18
        $this->clean();
49 18
        $this->ran();
50 15
        $this->end();
51 15
    }
52
53
    abstract protected function processor(?string $filename): Processor;
54
55 17
    protected function ran(): void
56
    {
57 17
        $this->log('Starting processing of the package list...');
58
59 17
        foreach ($this->packages() as $package) {
60 17
            $this->log('Plugins handling:', $package);
61
62 17
            $this->validatePackage($package);
63
64 15
            $this->ranLocales($package);
65
        }
66 14
    }
67
68 15
    protected function ranLocales(string $package): void
69
    {
70 15
        $this->log('Starting processing of the locales list for the', $package, 'package...');
71
72 15
        foreach ($this->locales() as $locale) {
73 15
            $this->log('Localization handling:', $locale);
74
75 15
            $this->validateLocale($locale);
76
77 14
            $this->ranFiles($package, $locale);
78 14
            $this->ranPlugins($package, $locale);
79
        }
80 14
    }
81
82 14
    protected function ranFiles(string $package, string $locale): void
83
    {
84 14
        $this->log('Starting processing of the files for the', $package, 'package and', $locale, 'localization...');
85
86 14
        foreach ($this->files($package) as $filename) {
87 14
            $this->log('Processing the localization file:', $filename);
88
89 14
            $this->processing($locale, $filename, $package);
90
91 14
            $status = $this->process($package, $locale, $filename);
92
93 14
            $this->pushProcessed($filename);
94
95 14
            $this->processed($locale, $filename, $status, $package);
96
        }
97 14
    }
98
99 14
    protected function ranPlugins(string $package, string $locale): void
100
    {
101 14
        $this->log('Starting processing of plugin files for the', $package, 'package and', $locale, 'localization...');
102
103 14
        foreach ($this->plugins() as $plugin) {
104 14
            foreach ($plugin->source() as $source) {
105 14
                $target = $plugin->targetPath($locale, $source);
106
107 14
                $this->processing($locale, $source, $package);
108
109 14
                $status = $this->process($package, $locale, $source, $target);
110
111 14
                $this->pushProcessed($target);
112
113 14
                $this->processed($locale, $source, $status, $package);
114
            }
115
        }
116 14
    }
117
118 15
    protected function process(?string $package, ?string $locale, ?string $source, string $target = null): string
119
    {
120 15
        $this->log('Launching the processor for localization:', $locale, ',', $source);
121
122 15
        return $this->processor($source)
123 15
            ->force($this->hasForce() || $this->hasProcessed($target))
124 15
            ->whenPackage($package)
125 15
            ->whenLocale($locale)
126 15
            ->whenSourceFilename($source, $this->hasInline())
127 15
            ->whenTargetFilename($target ?: $source)
128 15
            ->run();
129
    }
130
131 15
    protected function locales(): array
132
    {
133 15
        $this->log('Getting a list of localizations...');
134
135 15
        if (! empty($this->locales)) {
136 14
            return $this->locales;
137
        }
138
139 15
        return $this->locales = LocalesSupport::make($this->input, $this->output, $this->action(), $this->targetLocales())->get();
140
    }
141
142 7
    protected function targetLocales(): array
143
    {
144 7
        $this->log('Getting a list of installed localizations...');
145
146 7
        return Locales::installed();
147
    }
148
149 18
    protected function packages(): array
150
    {
151 18
        $this->log('Getting a list of packages available for processing...');
152
153 18
        return Packages::get();
154
    }
155
156 15
    protected function files(string $package): array
157
    {
158 15
        $this->log('Getting a list of files for the ', $package, 'package...');
159
160 15
        if ($this->files[$package] ?? false) {
161 14
            return $this->files[$package];
162
        }
163
164 15
        $path = $this->pathSource($package, LocalesList::ENGLISH);
165
166 15
        return $this->files[$package] = File::names($path, static function ($filename) {
167 15
            return ! Str::contains($filename, 'inline');
168 15
        });
169
    }
170
171
    /**
172
     * @return array|\Helldar\LaravelLangPublisher\Plugins\Plugin[]
173
     */
174 14
    protected function plugins(): array
175
    {
176 14
        if (! empty($this->plugins)) {
177 14
            return $this->plugins;
178
        }
179
180 14
        $plugins = array_map(static function ($plugin) {
181
            /* @var \Helldar\LaravelLangPublisher\Plugins\Plugin $plugin */
182 14
            return $plugin::make();
183 14
        }, $this->getPlugins());
184
185 14
        $plugins = array_filter($plugins, static function (Plugin $plugin) {
186 14
            return $plugin->has();
187 14
        });
188
189 14
        return $this->plugins = $plugins;
190
    }
191
192 18
    protected function start(): void
193
    {
194 18
        $this->log('Running the console command:', parent::class);
195
196 18
        $action = $this->action()->present(true);
197
198 18
        $this->info($action . ' localizations...');
199 18
    }
200
201 15
    protected function end(): void
202
    {
203 15
        $this->log('Completing the execution of the console command...');
204
205 15
        $action = $this->action()->past();
206
207 15
        $this->info('Localizations have ben successfully ' . $action . '.');
208 15
    }
209
210 15
    protected function processing(string $locale, string $filename, string $package = null): void
211
    {
212 15
        $this->log('Displaying a message about the start of file processing: locale is', $locale, ', filename is', $filename, ', package is', $package . '...');
213
214 15
        $message = $this->message($locale, $filename, $package)->start();
215
216 15
        $this->output->write($message);
217 15
    }
218
219 15
    protected function processed(string $locale, string $filename, string $status, string $package = null): void
220
    {
221 15
        $this->log('Displaying a message about the finish of file processing: locale is', $locale, ', filename is', $filename, ', package is', $package . '...');
222
223 15
        $message = $this->message($locale, $filename, $package)->finish($status);
224
225 15
        $this->output->writeln($message);
226 15
    }
227
228 15
    protected function message(string $locale, string $filename, string $package = null): InfoSupport
229
    {
230 15
        $this->log('Preparing an object for displaying a message: locale is', $locale, ', filename is', $filename, ', package is', $package . '...');
231
232 15
        return Info::same()
233 15
            ->package($package)
234 15
            ->locale($locale, $this->localesLength())
235 15
            ->filename($filename, $this->filesLength());
236
    }
237
238 15
    protected function localesLength(): int
239
    {
240 15
        $this->log('Getting the maximum length of a localization string...');
241
242 15
        if ($this->locales_length > 0) {
243 15
            return $this->locales_length;
244
        }
245
246 15
        $this->log('Calculating the maximum length of a localization string...');
247
248 15
        return $this->locales_length = Arr::longestStringLength($this->locales());
249
    }
250
251 15
    protected function filesLength(): int
252
    {
253 15
        $this->log('Getting the maximum length of a filenames...');
254
255 15
        if ($this->files_length > 0) {
256 15
            return $this->files_length;
257
        }
258
259 15
        $this->log('Calculating the maximum length of a filenames...');
260
261 15
        $files = [];
262
263 15
        foreach ($this->packages() as $package) {
264 15
            $files = array_merge($files, $this->files($package));
265
        }
266
267 15
        return $this->files_length = Arr::longestStringLength(array_unique($files));
268
    }
269
270 15
    protected function hasInline(): bool
271
    {
272 15
        $this->log('Getting a use case for a validation file.');
273
274 15
        return Config::hasInline();
275
    }
276
277 14
    protected function getPlugins(): array
278
    {
279 14
        $this->log('Getting a list of plugins...');
280
281 14
        return Config::plugins();
282
    }
283
284 18
    protected function action(): Actionable
285
    {
286 18
        $this->log('Getting the action...');
287
288 18
        return $this->container($this->action);
289
    }
290
291 14
    protected function pushProcessed(?string $filename): void
292
    {
293 14
        $this->log('Add a link to the processed file to the cache:', $filename);
294
295 14
        if ($filename && ! $this->hasProcessed($filename)) {
296 14
            $this->processed[] = $filename;
297
        }
298 14
    }
299
300 15
    protected function hasProcessed(?string $filename): bool
301
    {
302 15
        $this->log('Check if the file was processed earlier:', $filename);
303
304 15
        return $filename && in_array($filename, $this->processed, true);
305
    }
306
307 14
    protected function hasForce(): bool
308
    {
309 14
        $this->log('Getting the value of the "force" option...');
310
311 14
        return $this->boolOption('force');
312
    }
313
314 2
    protected function hasFull(): bool
315
    {
316 2
        $this->log('Getting the value of the "full" option...');
317
318 2
        return $this->boolOption('full');
319
    }
320
321 14
    protected function boolOption(string $key): bool
322
    {
323 14
        $this->log('Getting the value of the "', $key, '" option...');
324
325 14
        return $this->hasOption($key) && $this->option($key);
326
    }
327
328 16
    protected function validateLocale(string $locale): void
329
    {
330 16
        $this->log('Calling the localization validation method: ', $locale, '...');
331
332 16
        Validator::locale($locale);
333 15
    }
334
335 17
    protected function validatePackage(string $package): void
336
    {
337 17
        $this->log('Calling the package validation method: ', $package, '...');
338
339 17
        Validator::package($package);
340 15
    }
341
342 18
    protected function clean(): void
343
    {
344 18
        $this->log('Clear the variable from the saved localizations...');
345
346 18
        $this->locales = null;
347 18
    }
348
}
349