AdminLtePluginCommand::getPluginStatus()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 10
1
<?php
2
3
namespace JeroenNoten\LaravelAdminLte\Console;
4
5
use Illuminate\Console\Command;
6
use JeroenNoten\LaravelAdminLte\Console\PackageResources\PluginsResource;
7
8
class AdminLtePluginCommand extends Command
9
{
10
    /**
11
     * The name and signature of the console command.
12
     *
13
     * @var string
14
     */
15
    protected $signature = 'adminlte:plugins
16
        {operation=list : The type of operation: list, install or remove}
17
        {--plugin=* : To apply the operation only over the specified plugins, the value should be a plugin key}
18
        {--force : To force the overwrite of existing files during an installation process}
19
        {--interactive : To allow the operation process guide you through it}';
20
21
    /**
22
     * The console command description.
23
     *
24
     * @var string
25
     */
26
    protected $description = 'Manages the installation and removal of additional AdminLTE plugins';
27
28
    /**
29
     * Array with the operations handlers.
30
     *
31
     * @var array
32
     */
33
    protected $opHandlers;
34
35
    /**
36
     * The plugins package resource instance.
37
     *
38
     * @var PluginsResource
39
     */
40
    protected $plugins;
41
42
    /**
43
     * Array with the possible statuses of the plugins.
44
     *
45
     * @var array
46
     */
47
    protected $status = [
48
        'installed' => [
49
            'label' => 'Installed',
50
            'legend' => 'The plugin is published and matches with the package original plugin',
51
            'color' => 'green',
52
        ],
53
        'mismatch' => [
54
            'label' => 'Mismatch',
55
            'legend' => 'The plugin is published but mismatches with the package original plugin (update available or plugin modified)',
56
            'color' => 'yellow',
57
        ],
58
        'uninstalled' => [
59
            'label' => 'Not Installed',
60
            'legend' => 'The plugin is not published',
61
            'color' => 'red',
62
        ],
63
    ];
64
65
    /**
66
     * Create a new command instance.
67
     *
68
     * @return void
69
     */
70 28
    public function __construct()
71
    {
72 28
        parent::__construct();
73
74
        // Fill the available operations handlers.
75
76 28
        $this->opHandlers = [
77 28
            'list' => [$this, 'showPlugins'],
78 28
            'install' => [$this, 'installPlugins'],
79 28
            'remove' => [$this, 'removePlugins'],
80 28
        ];
81
82
        // Create the plugins resource instance.
83
84 28
        $this->plugins = new PluginsResource();
85
    }
86
87
    /**
88
     * Execute the console command.
89
     *
90
     * @return void
91
     */
92 7
    public function handle()
93
    {
94
        // Get the type of operation to perform.
95
96 7
        $op = $this->argument('operation');
97
98
        // Check if the operation is valid.
99
100 7
        if (! isset($this->opHandlers[$op])) {
101 1
            $this->error("The specified operation: {$op} is not valid!");
102
103 1
            return;
104
        }
105
106
        // Call the handler of the operation.
107
108 6
        $handler = $this->opHandlers[$op];
109 6
        $handler();
110
    }
111
112
    /**
113
     * Displays a list with the installation status of the plugins.
114
     *
115
     * @return void
116
     */
117 2
    protected function showPlugins()
118
    {
119
        // Get the list of affected plugins on the current operation.
120
121 2
        $pluginsKeys = $this->getAffectedPlugins();
122
123
        // Get the installation status of the affected plugins.
124
125 2
        $this->line('Verifying the installation of the plugins...');
126 2
        $pluginsStatus = $this->getPluginsStatus($pluginsKeys);
127 2
        $this->line('');
128 2
        $this->line('All plugins verified successfully!');
129
130
        // Display the plugins installation status.
131
132 2
        $this->line('');
133 2
        $this->line('Plugins Status:');
134 2
        $this->showPluginsStatus($pluginsStatus);
135
136
        // Display the legends table.
137
138 2
        $this->line('');
139 2
        $this->line('Status legends:');
140 2
        $this->showStatusLegends();
141
    }
142
143
    /**
144
     * Gets the list of plugins keys that should be affected by an operation.
145
     *
146
     * @return array
147
     */
148 6
    protected function getAffectedPlugins()
149
    {
150
        // First, check if the user has specified the plugins keys.
151
152 6
        if (! empty($this->option('plugin'))) {
153 4
            return $this->option('plugin');
154
        }
155
156
        // Otherwise, return a list with all the available plugins keys.
157
158 2
        return array_keys($this->plugins->getSourceData());
159
    }
160
161
    /**
162
     * Gets the installation status of the specicied plugins keys.
163
     *
164
     * @param  array  $pluginsKeys  Array with the plugins keys to evaluate
165
     * @return array
166
     */
167 2
    protected function getPluginsStatus($pluginsKeys)
168
    {
169
        // Define the array that will hold the resources status.
170
171 2
        $status = [];
172
173
        // Create and initialize a progress bar.
174
175 2
        $bar = $this->output->createProgressBar(count($pluginsKeys));
176 2
        $bar->start();
177
178
        // Get the installation status of each plugin.
179
180 2
        foreach ($pluginsKeys as $key) {
181 2
            $pluginData = $this->plugins->getSourceData($key);
182
183 2
            if (empty($pluginData)) {
184 1
                $this->line('');
185 1
                $this->error("The plugin key: {$key} is not valid!");
186 1
                $bar->advance();
187 1
                continue;
188
            }
189
190 2
            $status[$key] = $this->getPluginStatus($key);
191 2
            $bar->advance();
192
        }
193
194 2
        $bar->finish();
195
196
        // Return the plugins status.
197
198 2
        return $status;
199
    }
200
201
    /**
202
     * Displays the status of the specified plugins.
203
     *
204
     * @param  array  $pluginsStatus  Array with the status of plugins
205
     * @return void
206
     */
207 2
    protected function showPluginsStatus($pluginsStatus)
208
    {
209
        // Define the table headers.
210
211 2
        $tblHeader = [
212 2
            $this->styleOutput('Plugin Name', 'cyan'),
213 2
            $this->styleOutput('Plugin Key', 'cyan'),
214 2
            $this->styleOutput('Status', 'cyan'),
215 2
        ];
216
217
        // Create the table rows.
218
219 2
        $tblContent = [];
220
221 2
        foreach ($pluginsStatus as $key => $status) {
222 2
            $pluginData = $this->plugins->getSourceData($key);
223 2
            $tblContent[] = [$pluginData['name'], $key, $status];
224
        }
225
226
        // Display the plugins installation status.
227
228 2
        $this->table($tblHeader, $tblContent);
229
    }
230
231
    /**
232
     * Gets the installation status of a plugin.
233
     *
234
     * @param  string  $pluginKey  The plugin key
235
     * @return string
236
     */
237 2
    protected function getPluginStatus($pluginKey)
238
    {
239 2
        $status = $this->status['uninstalled'];
240
241 2
        if ($this->plugins->installed($pluginKey)) {
242 2
            $status = $this->status['installed'];
243 1
        } elseif ($this->plugins->exists($pluginKey)) {
244 1
            $status = $this->status['mismatch'];
245
        }
246
247 2
        return $this->styleOutput($status['label'], $status['color']);
248
    }
249
250
    /**
251
     * Displays the legends of the possible status values.
252
     *
253
     * @return void
254
     */
255 2
    protected function showStatusLegends()
256
    {
257
        // Create the table headers for the legends.
258
259 2
        $tblHeader = [
260 2
            $this->styleOutput('Status', 'cyan'),
261 2
            $this->styleOutput('Description', 'cyan'),
262 2
        ];
263
264
        // Create the table rows for the legends.
265
266 2
        $tblContent = [];
267
268 2
        foreach ($this->status as $status) {
269 2
            $tblContent[] = [
270 2
                $this->styleOutput($status['label'], $status['color']),
271 2
                $status['legend'],
272 2
            ];
273
        }
274
275
        // Display the legends table.
276
277 2
        $this->table($tblHeader, $tblContent);
278
    }
279
280
    /**
281
     * Gives output style to the specified text.
282
     *
283
     * @param  string  $text  The text to be styled
284
     * @param  string  $color  The output color for the text
285
     * @return string
286
     */
287 6
    protected function styleOutput($text, $color)
288
    {
289 6
        return "<fg={$color}>{$text}</>";
290
    }
291
292
    /**
293
     * Installs the specified list of plugins (all if none specified).
294
     *
295
     * @return void
296
     */
297 4
    protected function installPlugins()
298
    {
299 4
        $summary = [];
300
301
        // Get the list of plugins to be installed.
302
303 4
        $pluginsKeys = $this->getAffectedPlugins();
304
305
        // Create a progress bar.
306
307 4
        $bar = $this->output->createProgressBar(count($pluginsKeys));
308 4
        $bar->start();
309
310
        // Install the plugins.
311
312 4
        foreach ($pluginsKeys as $pluginKey) {
313
            // Install the plugin, if it's a valid plugin key.
314
315 4
            if (empty($this->plugins->getSourceData($pluginKey))) {
316 1
                $this->line('');
317 1
                $this->error("The plugin key: {$pluginKey} is not valid!");
318 1
                $status = $this->styleOutput('Invalid', 'red');
319 4
            } elseif ($this->installPlugin($pluginKey)) {
320 4
                $status = $this->styleOutput('Installed', 'green');
321
            } else {
322 2
                $status = $this->styleOutput('Not Installed', 'red');
323
            }
324
325 4
            $summary[] = [$pluginKey, $status];
326 4
            $bar->advance();
327
        }
328
329
        // Finish the progress bar.
330
331 4
        $bar->finish();
332 4
        $this->line('');
333 4
        $this->line('The installation of plugins is complete. Summary:');
334 4
        $this->line('');
335
336
        // Show summary of installed plugins.
337
338 4
        $this->showSummaryTable($summary);
339
    }
340
341
    /**
342
     * Installs the specified plugin. Returns whether the plugin was installed.
343
     *
344
     * @param  string  $pluginKey  The plugin string key
345
     * @return bool
346
     */
347 4
    protected function installPlugin($pluginKey)
348
    {
349
        // Customize the output messages.
350
351 4
        $confirmMsg = $this->plugins->getInstallMessage('install') ?? '';
352 4
        $overwriteMsg = $this->plugins->getInstallMessage('overwrite') ?? '';
353
354 4
        $confirmMsg = strtr($confirmMsg, [':plugin' => $pluginKey]);
355 4
        $overwriteMsg = strtr($overwriteMsg, [':plugin' => $pluginKey]);
356
357
        // Check if the --interactive option is enabled.
358
359 4
        if ($this->option('interactive') && ! $this->confirm($confirmMsg)) {
360 1
            return false;
361
        }
362
363
        // Check for overwrite warning
364
365 4
        $shouldWarnOverwrite = ! $this->option('force')
366 4
            && $this->plugins->exists($pluginKey);
367
368 4
        if ($shouldWarnOverwrite && ! $this->confirm($overwriteMsg)) {
369 1
            return false;
370
        }
371
372
        // Install the plugin.
373
374 4
        $this->plugins->install($pluginKey);
375
376 4
        return true;
377
    }
378
379
    /**
380
     * Removes the specified list of plugins (all if none specified).
381
     *
382
     * @return void
383
     */
384 3
    protected function removePlugins()
385
    {
386 3
        $summary = [];
387
388
        // Get the list of plugins to remove.
389
390 3
        $pluginsKeys = $this->getAffectedPlugins();
391
392
        // Create a progress bar.
393
394 3
        $bar = $this->output->createProgressBar(count($pluginsKeys));
395 3
        $bar->start();
396
397
        // Remove the plugins.
398
399 3
        foreach ($pluginsKeys as $pluginKey) {
400
            // Remove the plugin, if it's a valid plugin key.
401
402 3
            if (empty($this->plugins->getSourceData($pluginKey))) {
403 1
                $this->line('');
404 1
                $this->error("The plugin key: {$pluginKey} is not valid!");
405 1
                $status = $this->styleOutput('Invalid', 'red');
406 3
            } elseif ($this->removePlugin($pluginKey)) {
407 3
                $status = $this->styleOutput('Removed', 'green');
408
            } else {
409 1
                $status = $this->styleOutput('Not Removed', 'red');
410
            }
411
412 3
            $summary[] = [$pluginKey, $status];
413 3
            $bar->advance();
414
        }
415
416
        // Finish the progress bar.
417
418 3
        $bar->finish();
419 3
        $this->line('');
420 3
        $this->line('The removal of plugins is complete. Summary:');
421 3
        $this->line('');
422
423
        // Show summary of removed plugins.
424
425 3
        $this->showSummaryTable($summary);
426
    }
427
428
    /**
429
     * Removes/Uninstalls the specified plugin. Returns whether the plugin was
430
     * removed.
431
     *
432
     * @param  string  $pluginKey  The plugin string key
433
     * @return bool
434
     */
435 3
    protected function removePlugin($pluginKey)
436
    {
437
        // Customize the output messages.
438
439 3
        $confirmMsg = $this->plugins->getInstallMessage('remove') ?? '';
440 3
        $confirmMsg = strtr($confirmMsg, [':plugin' => $pluginKey]);
441
442
        // Check if the --interactive option is enabled.
443
444 3
        if ($this->option('interactive') && ! $this->confirm($confirmMsg)) {
445 1
            return false;
446
        }
447
448
        // Remove the plugin.
449
450 3
        $this->plugins->uninstall($pluginKey);
451
452 3
        return true;
453
    }
454
455
    /**
456
     * Show the summary table for some operation.
457
     *
458
     * @param  array  $rows  The table rows.
459
     * @return void
460
     */
461 4
    protected function showSummaryTable($rows)
462
    {
463 4
        $header = [
464 4
            $this->styleOutput('Plugin Key', 'cyan'),
465 4
            $this->styleOutput('Status', 'cyan'),
466 4
        ];
467
468 4
        $this->table($header, $rows);
469
    }
470
}
471