Passed
Push — master ( 70acef...8b9af3 )
by Florian
07:10 queued 02:43
created

PluginsResource   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 499
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 221
c 1
b 0
f 0
dl 0
loc 499
ccs 98
cts 98
cp 1
rs 9.36
wmc 38

14 Methods

Rating   Name   Duplication   Size   Complexity  
A uninstall() 0 5 3
A installPlugin() 0 14 3
A installed() 0 9 3
A resourceInstalled() 0 14 2
A install() 0 5 3
A pluginExists() 0 17 4
A uninstallPlugin() 0 14 3
A preparePlugin() 0 31 3
A exportResource() 0 11 2
A pluginInstalled() 0 17 4
A getSourceData() 0 11 2
A __construct() 0 21 1
A exists() 0 9 3
A uninstallResource() 0 6 2
1
<?php
2
3
namespace JeroenNoten\LaravelAdminLte\Console\PackageResources;
4
5
use JeroenNoten\LaravelAdminLte\Helpers\CommandHelper;
6
7
class PluginsResource extends PackageResource
8
{
9
    /**
10
     * The available plugins data. A plugin can contain next data keys:
11
     * - name: The name of the plugin.
12
     * - source: The source of the plugin (relative to base source)
13
     * - target: The target of the plugin (relative to base target)
14
     * - resources: An array with resources data items.
15
     * - ignore: A list of file patterns to ignore.
16
     * - recursive: Whether to copy files recursively (default is true).
17
     *
18
     * When the target is not specified, the source will be used as the
19
     * relative path to the base target destination. A resource can contain the
20
     * same keys that are availables for a plugin.
21
     *
22
     * @var array
23
     */
24
    protected $plugins = [
25
        'bootstrap4DualListbox' => [
26
            'name' => 'Bootstrap4 Dual Listbox',
27
            'source' => 'bootstrap4-duallistbox',
28
        ],
29
        'bootstrapColorpicker' => [
30
            'name' => 'Bootstrap Colorpicker',
31
            'source' => 'bootstrap-colorpicker',
32
        ],
33
        'bootstrapSlider' => [
34
            'name' => 'Bootstrap Slider',
35
            'source' => 'bootstrap-slider',
36
        ],
37
        'bootstrapSwitch' => [
38
            'name' => 'Bootstrap Switch',
39
            'source' => 'bootstrap-switch',
40
        ],
41
        'bsCustomFileInput' => [
42
            'name' => 'bs-custom-file-input',
43
            'source' => 'bs-custom-file-input',
44
        ],
45
        'chartJs' => [
46
            'name' => 'Chart.js',
47
            'source' => 'chart.js',
48
        ],
49
        'datatables' => [
50
            'name' => 'Datatables',
51
            'resources' => [
52
                ['source' => 'datatables', 'target' => 'datatables/js'],
53
                ['source' => 'datatables-bs4', 'target' => 'datatables'],
54
            ],
55
        ],
56
        'datatablesPlugins' => [
57
            'name' => 'Datatables Plugins',
58
            'resources' => [
59
                ['source' => 'datatables-autofill', 'target' => 'datatables-plugins/autofill'],
60
                ['source' => 'datatables-buttons', 'target' => 'datatables-plugins/buttons'],
61
                ['source' => 'datatables-colreorder', 'target' => 'datatables-plugins/colreorder'],
62
                ['source' => 'datatables-fixedcolumns', 'target' => 'datatables-plugins/fixedcolumns'],
63
                ['source' => 'datatables-fixedheader', 'target' => 'datatables-plugins/fixedheader'],
64
                ['source' => 'datatables-keytable', 'target' => 'datatables-plugins/keytable'],
65
                ['source' => 'datatables-responsive', 'target' => 'datatables-plugins/responsive'],
66
                ['source' => 'datatables-rowgroup', 'target' => 'datatables-plugins/rowgroup'],
67
                ['source' => 'datatables-rowreorder', 'target' => 'datatables-plugins/rowreorder'],
68
                ['source' => 'datatables-scroller', 'target' => 'datatables-plugins/scroller'],
69
                ['source' => 'datatables-select', 'target' => 'datatables-plugins/select'],
70
                ['source' => 'pdfmake', 'target' => 'datatables-plugins/pdfmake'],
71
                ['source' => 'jszip', 'target' => 'datatables-plugins/jszip'],
72
            ],
73
        ],
74
        'daterangepicker' => [
75
            'name' => 'Date Range Picker',
76
            'resources' => [
77
                ['source' => 'daterangepicker'],
78
                ['source' => 'moment'],
79
            ],
80
        ],
81
        'ekkoLightbox' => [
82
            'name' => 'Ekko Lightbox',
83
            'source' => 'ekko-lightbox',
84
        ],
85
        'fastclick' => [
86
            'name' => 'FastClick',
87
            'source' => 'fastclick',
88
        ],
89
        'filterizr' => [
90
            'name' => 'Filterizr',
91
            'source' => 'filterizr',
92
            'ignore' => ['*.d.ts'],
93
            'recursive' => false,
94
        ],
95
        'flagIconCss' => [
96
            'name' => 'Flag Icon Css',
97
            'source' => 'flag-icon-css',
98
        ],
99
        'flot' => [
100
            'name' => 'Flot',
101
            'source' => 'flot',
102
        ],
103
        'fullcalendar' => [
104
            'name' => 'Fullcalendar',
105
            'source' => 'fullcalendar',
106
            'ignore' => ['*.d.ts', '*.json', '*.md'],
107
        ],
108
        'fullcalendarPlugins' => [
109
            'name' => 'Fullcalendar Plugins',
110
            'resources' => [
111
                ['source' => 'fullcalendar-bootstrap', 'target' => 'fullcalendar-plugins/bootstrap'],
112
                ['source' => 'fullcalendar-daygrid', 'target' => 'fullcalendar-plugins/daygrid'],
113
                ['source' => 'fullcalendar-interaction', 'target' => 'fullcalendar-plugins/interaction'],
114
                ['source' => 'fullcalendar-timegrid', 'target' => 'fullcalendar-plugins/timegrid'],
115
            ],
116
            'ignore' => ['*.d.ts', '*.json', '*.md'],
117
        ],
118
        'icheckBootstrap' => [
119
            'name' => 'iCheck Bootstrap',
120
            'source' => 'icheck-bootstrap',
121
            'ignore' => ['*.json', '*.md'],
122
        ],
123
        'inputmask' => [
124
            'name' => 'InputMask',
125
            'source' => 'inputmask',
126
        ],
127
        'ionRangslider' => [
128
            'name' => 'Ion.RangeSlider',
129
            'source' => 'ion-rangeslider',
130
            'ignore' => ['*.json', '*.md', '.editorconfig'],
131
        ],
132
        'jqueryKnob' => [
133
            'name' => 'jQuery Knob',
134
            'source' => 'jquery-knob',
135
        ],
136
        'jqueryMapael' => [
137
            'name' => 'jQuery Mapael',
138
            'resources' => [
139
                ['source' => 'jquery-mapael'],
140
                ['source' => 'raphael'],
141
                ['source' => 'jquery-mousewheel'],
142
            ],
143
            'ignore' => ['*.json', '*.md', '.editorconfig'],
144
        ],
145
        'jqueryUi' => [
146
            'name' => 'jQuery UI',
147
            'resources' => [
148
                ['source' => 'jquery-ui'],
149
                ['source' => 'jquery-ui/images'],
150
            ],
151
            'recursive' => false,
152
        ],
153
        'jqueryValidation' => [
154
            'name' => 'jQuery Validation',
155
            'source' => 'jquery-validation',
156
        ],
157
        'jqvmap' => [
158
            'name' => 'jQVMap',
159
            'source' => 'jqvmap',
160
        ],
161
        'jsgrid' => [
162
            'name' => 'jsGrid',
163
            'resources' => [
164
                ['source' => 'jsgrid'],
165
                ['source' => 'jsgrid/i18n'],
166
            ],
167
            'recursive' => false,
168
        ],
169
        'paceProgress' => [
170
            'name' => 'Pace Progress',
171
            'source' => 'pace-progress',
172
        ],
173
        'select2' => [
174
            'name' => 'Select 2 with Bootstrap 4 Theme',
175
            'resources' => [
176
                ['source' => 'select2'],
177
                ['source' => 'select2-bootstrap4-theme'],
178
            ],
179
            'ignore' => ['*.json', '*.md'],
180
        ],
181
        'sparklines' => [
182
            'name' => 'Sparklines',
183
            'source' => 'sparklines',
184
        ],
185
        'summernote' => [
186
            'name' => 'Summernote',
187
            'source' => 'summernote',
188
        ],
189
        'sweetalert2' => [
190
            'name' => 'Sweetalert 2 with Bootstrap 4 Theme',
191
            'resources' => [
192
                ['source' => 'sweetalert2'],
193
                ['source' => 'sweetalert2-theme-bootstrap-4'],
194
            ],
195
        ],
196
        'tempusdominusBootstrap4' => [
197
            'name' => 'Tempus Dominus for Bootstrap 4',
198
            'source' => 'tempusdominus-bootstrap-4',
199
        ],
200
        'toastr' => [
201
            'name' => 'Toastr',
202
            'source' => 'toastr',
203
        ],
204
    ];
205
206
    /**
207
     * Create a new resource instance.
208
     *
209
     * @return void
210
     */
211 20
    public function __construct()
212
    {
213
        // Fill the basic resource data.
214
215 20
        $this->description = 'The set of AdminLTE additional plugins';
216 20
        $this->required = false;
217
218
        // Define the base source folder of the plugins.
219
220 20
        $this->source = base_path('vendor/almasaeed2010/adminlte/plugins');
221
222
        // Define the base target destination for the plugins.
223
224 20
        $this->target = public_path('vendor');
225
226
        // Fill the set of installation messages templates.
227
228 20
        $this->messages = [
229
            'install'   => 'Install the AdminLTE :plugin plugin?',
230
            'overwrite' => 'The :plugin plugin already exists. Want to replace the plugin?',
231
            'remove'    => 'Do you really want to remove the :plugin plugin?',
232
        ];
233 20
    }
234
235
    /**
236
     * Gets the plugins source data.
237
     *
238
     * @param string $pluginKey A plugin string key
239
     * @return array
240
     */
241 4
    public function getSourceData($pluginKey = null)
242
    {
243
        // Check if we need to get data of a specific AdminLTE plugin.
244
245 4
        if (isset($pluginKey)) {
246 4
            return $this->plugins[$pluginKey] ?? null;
247
        }
248
249
        // Otherwise, return all the AdminLTE plugins data.
250
251 2
        return $this->plugins;
252
    }
253
254
    /**
255
     * Install/Export a plugin.
256
     *
257
     * @param string $pluginKey A plugin string key
258
     * @return void
259
     */
260 4
    public function install($pluginKey = null)
261
    {
262 4
        if (isset($pluginKey) && isset($this->plugins[$pluginKey])) {
263 4
            $plugin = $this->preparePlugin($this->plugins[$pluginKey]);
264 4
            $this->installPlugin($plugin);
265
        }
266 4
    }
267
268
    /**
269
     * Uninstall/Remove a plugin.
270
     *
271
     * @param string $pluginKey A plugin string key
272
     * @return void
273
     */
274 4
    public function uninstall($pluginKey = null)
275
    {
276 4
        if (isset($pluginKey) && isset($this->plugins[$pluginKey])) {
277 4
            $plugin = $this->preparePlugin($this->plugins[$pluginKey]);
278 4
            $this->uninstallPlugin($plugin);
279
        }
280 4
    }
281
282
    /**
283
     * Check if a plugin already exists on the target destination.
284
     *
285
     * @param string $pluginKey A plugin string key
286
     * @return bool
287
     */
288 4
    public function exists($pluginKey = null)
289
    {
290 4
        if (isset($pluginKey) && isset($this->plugins[$pluginKey])) {
291 3
            $plugin = $this->preparePlugin($this->plugins[$pluginKey]);
292
293 3
            return $this->pluginExists($plugin);
294
        }
295
296 1
        return false;
297
    }
298
299
    /**
300
     * Check if a plugin is correctly installed.
301
     *
302
     * @param string $pluginKey A plugin string key
303
     * @return bool
304
     */
305 5
    public function installed($pluginKey = null)
306
    {
307 5
        if (isset($pluginKey) && isset($this->plugins[$pluginKey])) {
308 4
            $plugin = $this->preparePlugin($this->plugins[$pluginKey]);
309
310 4
            return $this->pluginInstalled($plugin);
311
        }
312
313 1
        return false;
314
    }
315
316
    /**
317
     * Prepare a plugin with some sort of normalizations.
318
     *
319
     * @param array $plugin An array with the plugin data
320
     * @return array An array with normalized plugin data
321
     */
322 4
    protected function preparePlugin($plugin)
323
    {
324
        // Add source and target when not defined.
325
326 4
        $plugin['source'] = $plugin['source'] ?? '';
327 4
        $plugin['target'] = $plugin['target'] ?? $plugin['source'];
328
329
        // Add fully qualified paths and default values.
330
331 4
        $DS = DIRECTORY_SEPARATOR;
332 4
        $plugin['source'] = $this->source.$DS.$plugin['source'];
333 4
        $plugin['target'] = $this->target.$DS.$plugin['target'];
334 4
        $plugin['ignore'] = $plugin['ignore'] ?? [];
335 4
        $plugin['recursive'] = $plugin['recursive'] ?? true;
336
337
        // Add fully qualified paths and default values on the resources.
338
339 4
        if (isset($plugin['resources'])) {
340 3
            foreach ($plugin['resources'] as $key => $res) {
341 3
                $res['target'] = $res['target'] ?? $res['source'];
342 3
                $res['source'] = $plugin['source'].$DS.$res['source'];
343 3
                $res['target'] = $plugin['target'].$DS.$res['target'];
344 3
                $res['ignore'] = $res['ignore'] ?? $plugin['ignore'];
345 3
                $res['recursive'] = $res['recursive'] ?? $plugin['recursive'];
346 3
                $plugin['resources'][$key] = $res;
347
            }
348
        }
349
350
        // Return normalized plugin data.
351
352 4
        return $plugin;
353
    }
354
355
    /**
356
     * Install the specified AdminLTE plugin.
357
     *
358
     * @param array $plugin An array with the plugin data
359
     * @return void
360
     */
361 4
    protected function installPlugin($plugin)
362
    {
363
        // Check if we need to export the entire plugin.
364
365 4
        if (! isset($plugin['resources'])) {
366 4
            $this->exportResource($plugin);
367
368 4
            return;
369
        }
370
371
        // Otherwise, export only the specified plugin resources.
372
373 2
        foreach ($plugin['resources'] as $res) {
374 2
            $this->exportResource($res);
375
        }
376 2
    }
377
378
    /**
379
     * Exports the specified resource (usually a folder).
380
     *
381
     * @param array $res An array with the resource data
382
     * @return void
383
     */
384 4
    protected function exportResource($res)
385
    {
386
        // Check the resource source type.
387
388 4
        if (is_dir($res['source'])) {
389 4
            CommandHelper::copyDirectory(
390 4
                $res['source'],
391 4
                $res['target'],
392 4
                $res['force'] ?? true,
393 4
                $res['recursive'] ?? true,
394 4
                $res['ignore'] ?? []
395
            );
396
        }
397 4
    }
398
399
    /**
400
     * Check if the specified plugin already exists on the target destination.
401
     *
402
     * @param array $plugin An array with the plugin data
403
     * @return bool
404
     */
405 3
    protected function pluginExists($plugin)
406
    {
407
        // When the plugin is not a resources list, check if target exists.
408
409 3
        if (! isset($plugin['resources'])) {
410 3
            return file_exists($plugin['target']);
411
        }
412
413
        // Otherwise, check if any of the resources already exists.
414
415 3
        foreach ($plugin['resources'] as $res) {
416 3
            if (file_exists($res['target'])) {
417 1
                return true;
418
            }
419
        }
420
421 3
        return false;
422
    }
423
424
    /**
425
     * Check if the specified plugin is correctly installed.
426
     *
427
     * @param array $plugin An array with the plugin data
428
     * @return bool
429
     */
430 4
    protected function pluginInstalled($plugin)
431
    {
432
        // When the plugin is not a resources list, check if installed.
433
434 4
        if (! isset($plugin['resources'])) {
435 4
            return $this->resourceInstalled($plugin);
436
        }
437
438
        // Otherwise, check if all the resources are installed.
439
440 3
        foreach ($plugin['resources'] as $res) {
441 3
            if (! $this->resourceInstalled($res)) {
442 3
                return false;
443
            }
444
        }
445
446 2
        return true;
447
    }
448
449
    /**
450
     * Check if the specified resource is correctly installed.
451
     *
452
     * @param array $res An array with the resource data
453
     * @return bool
454
     */
455 4
    protected function resourceInstalled($res)
456
    {
457 4
        $installed = false;
458
459 4
        if (is_dir($res['source'])) {
460 4
            $installed = (bool) CommandHelper::compareDirectories(
461 4
                $res['source'],
462 4
                $res['target'],
463 4
                $res['recursive'] ?? true,
464 4
                $res['ignore'] ?? []
465
            );
466
        }
467
468 4
        return $installed;
469
    }
470
471
    /**
472
     * Uninstall or remove the specified plugin.
473
     *
474
     * @param array $plugin An array with the plugin data
475
     * @return void
476
     */
477 4
    protected function uninstallPlugin($plugin)
478
    {
479
        // Check if we need to remove the entire plugin.
480
481 4
        if (! isset($plugin['resources'])) {
482 4
            $this->uninstallResource($plugin);
483
484 4
            return;
485
        }
486
487
        // Otherwise, remove only the specified plugin resources.
488
489 2
        foreach ($plugin['resources'] as $res) {
490 2
            $this->uninstallResource($res);
491
        }
492 2
    }
493
494
    /**
495
     * Removes the specified resource (usually a folder).
496
     *
497
     * @param array $res An array with the resource data
498
     * @return void
499
     */
500 4
    protected function uninstallResource($res)
501
    {
502 4
        $target = $res['target'];
503
504 4
        if (is_dir($target)) {
505 4
            CommandHelper::removeDirectory($target);
506
        }
507 4
    }
508
}
509