ShowCommand::handle()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 0
dl 0
loc 17
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 Illuminate\Support\Str;
8
use NicolasBeauvais\Transcribe\Manager;
9
use Symfony\Component\Console\Exception\InvalidArgumentException;
10
11
class ShowCommand extends Command
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'transcribe:show {key} {--c|close} {--lang=}';
19
20
    /**
21
     * The name and signature of the console command.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Show language lines for a given file or key.';
26
27
    /**
28
     * The Languages manager instance.
29
     *
30
     * @var \NicolasBeauvais\Transcribe\Manager
31
     */
32
    private $manager;
33
34
    /**
35
     * Filename to read from.
36
     *
37
     * @var string
38
     */
39
    protected $file;
40
41
    /**
42
     * Key name to show results for.
43
     *
44
     * @var string
45
     */
46
    protected $key;
47
48
    /**
49
     * Array of requested file in different languages.
50
     *
51
     * @var array
52
     */
53
    protected $files;
54
55
    /**
56
     * Array of displayable languages.
57
     *
58
     * @var array
59
     */
60
    protected $languages;
61
62
    /**
63
     * ListCommand constructor.
64
     *
65
     * @param \NicolasBeauvais\Transcribe\Manager $manager
66
     */
67
    public function __construct(Manager $manager)
68
    {
69
        parent::__construct();
70
71
        $this->manager = $manager;
72
    }
73
74
    /**
75
     * Execute the console command.
76
     *
77
     * @return mixed
78
     */
79
    public function handle()
80
    {
81
        $this->parseKey();
82
83
        $this->files = $this->filesFromKey();
84
85
        try {
86
            $this->languages = $this->getLanguages();
87
        } catch (InvalidArgumentException $e) {
88
            $this->error($e->getMessage());
89
90
            return;
91
        }
92
93
        $this->table(
94
            array_merge(['key'], $this->languages),
95
            $this->tableRows()
96
        );
97
    }
98
99
    /**
100
     * The output of the table rows.
101
     *
102
     * @return array
103
     */
104
    private function tableRows()
105
    {
106
        $output = [];
107
108
        $filesContent = [];
109
110
        foreach ($this->files as $languageKey => $file) {
111
            foreach ($filesContent[$languageKey] = Arr::dot($this->manager->getFileContent($file)) as $key => $value) {
112
                if (!$this->shouldShowKey($key)) {
113
                    continue;
114
                }
115
116
                $output[$key]['key'] = $key;
117
                $output[$key][$languageKey] = $value ?: '';
118
            }
119
        }
120
121
        // Now that we have collected all existing values, we are going to fill the
122
        // missing ones with emptiness indicators to balance the table structure
123
        // and alert developers so that they can take proper actions.
124
        foreach ($output as $key => $values) {
125
            $original = [];
126
127
            foreach ($this->languages as $languageKey) {
128
                $original[$languageKey] = isset($values[$languageKey]) && $values[$languageKey]
129
                    ? $values[$languageKey]
130
                    : '<bg=red>  MISSING  </>';
131
            }
132
133
            // Sort the language values based on language name
134
            ksort($original);
135
136
            $output[$key] = array_merge(['key' => "<fg=yellow>$key</>"], $original);
137
        }
138
139
        return array_values($output);
140
    }
141
142
    /**
143
     * Array of requested file in different languages.
144
     *
145
     * @return array
146
     */
147
    private function filesFromKey()
148
    {
149
        try {
150
            return $this->manager->files()[$this->file];
151
        } catch (\ErrorException $e) {
152
            $this->error(sprintf('Language file %s.php not found!', $this->file));
153
154
            return [];
155
        }
156
    }
157
158
    /**
159
     * Parse the given key argument.
160
     *
161
     * @return void
162
     */
163
    private function parseKey()
164
    {
165
        $parts = explode('.', $this->argument('key'), 2);
0 ignored issues
show
Bug introduced by
It seems like $this->argument('key') can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
        $parts = explode('.', /** @scrutinizer ignore-type */ $this->argument('key'), 2);
Loading history...
166
167
        $this->file = $parts[0];
168
169
        $this->key = isset($parts[1]) ? $parts[1] : null;
170
171
        if (Str::contains($this->file, '::')) {
172
            try {
173
                $parts = explode('::', $this->file);
174
175
                $this->manager->setPathToVendorPackage($parts[0]);
176
            } catch (\ErrorException $e) {
177
                $this->error('Could not recognize the package.');
178
179
                return;
180
            }
181
        }
182
    }
183
184
    /**
185
     * Determine if the given key should exist in the output.
186
     *
187
     * @param $key
188
     *
189
     * @return bool
190
     */
191
    private function shouldShowKey($key)
192
    {
193
        if ($this->key) {
194
            if (Str::contains($key, '.') && Str::startsWith($key, $this->key)) {
195
                return true;
196
            }
197
198
            if (!$this->option('close') && $key != $this->key) {
199
                return false;
200
            }
201
202
            if ($this->option('close') && !Str::contains($key, $this->key)) {
203
                return false;
204
            }
205
        }
206
207
        return true;
208
    }
209
210
    /**
211
     * Get the languages to be displayed in the command output.
212
     *
213
     * @return array
214
     */
215
    private function getLanguages()
216
    {
217
        $allLanguages = $this->manager->languages();
218
219
        if (!$this->option('lang')) {
220
            return $allLanguages;
221
        }
222
223
        $userLanguages = explode(',', (string) $this->option('lang'));
224
225
        if ($missingLanguages = array_diff($userLanguages, $allLanguages)) {
226
            throw new InvalidArgumentException('Unknown Language(s) ['.implode(',', $missingLanguages).'].');
227
        }
228
229
        return $userLanguages;
230
    }
231
}
232