Completed
Push — master ( 2d05b9...e4f5e9 )
by Nicolas
08:41
created

Repository::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Nwidart\Modules;
4
5
use Countable;
6
use Illuminate\Foundation\Application;
7
use Illuminate\Support\Str;
8
use Nwidart\Modules\Contracts\RepositoryInterface;
9
use Nwidart\Modules\Exceptions\ModuleNotFoundException;
10
use Nwidart\Modules\Process\Installer;
11
use Nwidart\Modules\Process\Updater;
12
13
class Repository implements RepositoryInterface, Countable
14
{
15
    /**
16
     * Application instance.
17
     *
18
     * @var Application
19
     */
20
    protected $app;
21
22
    /**
23
     * The module path.
24
     *
25
     * @var string|null
26
     */
27
    protected $path;
28
29
    /**
30
     * The scanned paths.
31
     *
32
     * @var array
33
     */
34
    protected $paths = [];
35
36
    /**
37
     * @var string
38
     */
39
    protected $stubPath;
40
41
    /**
42
     * The constructor.
43
     *
44
     * @param Application $app
45
     * @param string|null $path
46
     */
47 85
    public function __construct(Application $app, $path = null)
48
    {
49 85
        $this->app = $app;
50 85
        $this->path = $path;
51 85
    }
52
53
    /**
54
     * Add other module location.
55
     *
56
     * @param string $path
57
     *
58
     * @return $this
59
     */
60 12
    public function addLocation($path)
61
    {
62 12
        $this->paths[] = $path;
63
64 12
        return $this;
65
    }
66
67
    /**
68
     * Alternative method for "addPath".
69
     *
70
     * @param string $path
71
     *
72
     * @return $this
73
     */
74 1
    public function addPath($path)
75
    {
76 1
        return $this->addLocation($path);
77
    }
78
79
    /**
80
     * Get all additional paths.
81
     *
82
     * @return array
83
     */
84 1
    public function getPaths()
85
    {
86 1
        return $this->paths;
87
    }
88
89
    /**
90
     * Get scanned modules paths.
91
     *
92
     * @return array
93
     */
94 85
    public function getScanPaths()
95
    {
96 85
        $paths = $this->paths;
97
98 85
        $paths[] = $this->getPath() . '/*';
99
100 85
        if ($this->config('scan.enabled')) {
101
            $paths = array_merge($paths, $this->config('scan.paths'));
102
        }
103
104 85
        return $paths;
105
    }
106
107
    /**
108
     * Get & scan all modules.
109
     *
110
     * @return array
111
     */
112 85
    public function scan()
113
    {
114 85
        $paths = $this->getScanPaths();
115
116 85
        $modules = [];
117
118 85
        foreach ($paths as $key => $path) {
119 85
            $manifests = $this->app['files']->glob("{$path}/module.json");
120
121 85
            is_array($manifests) || $manifests = [];
122
123 85
            foreach ($manifests as $manifest) {
124 53
                $name = Json::make($manifest)->get('name');
125
126 53
                $modules[$name] = new Module($this->app, $name, dirname($manifest));
127 85
            }
128 85
        }
129
130 85
        return $modules;
131
    }
132
133
    /**
134
     * Get all modules.
135
     *
136
     * @return array
137
     */
138 85
    public function all()
139
    {
140 85
        if (!$this->config('cache.enabled')) {
141 85
            return $this->scan();
142
        }
143
144
        return $this->formatCached($this->getCached());
145
    }
146
147
    /**
148
     * Format the cached data as array of modules.
149
     *
150
     * @param array $cached
151
     *
152
     * @return array
153
     */
154
    protected function formatCached($cached)
155
    {
156
        $modules = [];
157
158
        foreach ($cached as $name => $module) {
159
            $path = $this->config('paths.modules') . '/' . $name;
160
161
            $modules[$name] = new Module($this->app, $name, $path);
162
        }
163
164
        return $modules;
165
    }
166
167
    /**
168
     * Get cached modules.
169
     *
170
     * @return array
171
     */
172
    public function getCached()
173
    {
174
        return $this->app['cache']->remember($this->config('cache.key'), $this->config('cache.lifetime'), function () {
175
            return $this->toCollection()->toArray();
176
        });
177
    }
178
179
    /**
180
     * Get all modules as collection instance.
181
     *
182
     * @return Collection
183
     */
184 1
    public function toCollection()
185
    {
186 1
        return new Collection($this->scan());
187
    }
188
189
    /**
190
     * Get modules by status.
191
     *
192
     * @param $status
193
     *
194
     * @return array
195
     */
196 85
    public function getByStatus($status)
197
    {
198 85
        $modules = [];
199
200 85
        foreach ($this->all() as $name => $module) {
201 3
            if ($module->isStatus($status)) {
202 2
                $modules[$name] = $module;
203 2
            }
204 85
        }
205
206 85
        return $modules;
207
    }
208
209
    /**
210
     * Determine whether the given module exist.
211
     *
212
     * @param $name
213
     *
214
     * @return bool
215
     */
216 43
    public function has($name)
217
    {
218 43
        return array_key_exists($name, $this->all());
219
    }
220
221
    /**
222
     * Get list of enabled modules.
223
     *
224
     * @return array
225
     */
226 85
    public function enabled()
227
    {
228 85
        return $this->getByStatus(1);
229
    }
230
231
    /**
232
     * Get list of disabled modules.
233
     *
234
     * @return array
235
     */
236 1
    public function disabled()
237
    {
238 1
        return $this->getByStatus(0);
239
    }
240
241
    /**
242
     * Get count from all modules.
243
     *
244
     * @return int
245
     */
246 1
    public function count()
247
    {
248 1
        return count($this->all());
249
    }
250
251
    /**
252
     * Get all ordered modules.
253
     *
254
     * @param string $direction
255
     *
256
     * @return array
257
     */
258 85
    public function getOrdered($direction = 'asc')
259
    {
260 85
        $modules = $this->enabled();
261
262 85
        uasort($modules, function (Module $a, Module $b) use ($direction) {
263
            if ($a->order == $b->order) {
0 ignored issues
show
Documentation introduced by
The property order does not exist on object<Nwidart\Modules\Module>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
264
                return 0;
265
            }
266
267
            if ($direction == 'desc') {
268
                return $a->order < $b->order ? 1 : -1;
0 ignored issues
show
Documentation introduced by
The property order does not exist on object<Nwidart\Modules\Module>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
269
            }
270
271
            return $a->order > $b->order ? 1 : -1;
0 ignored issues
show
Documentation introduced by
The property order does not exist on object<Nwidart\Modules\Module>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
272 85
        });
273
274 85
        return $modules;
275
    }
276
277
    /**
278
     * Get a module path.
279
     *
280
     * @return string
281
     */
282 85
    public function getPath()
283
    {
284 85
        return $this->path ?: $this->config('paths.modules');
285
    }
286
287
    /**
288
     * Register the modules.
289
     */
290 85
    public function register()
291
    {
292 85
        foreach ($this->getOrdered() as $module) {
293
            $module->register();
294 85
        }
295 85
    }
296
297
    /**
298
     * Boot the modules.
299
     */
300 85
    public function boot()
301
    {
302 85
        foreach ($this->getOrdered() as $module) {
303
            $module->boot();
304 85
        }
305 85
    }
306
307
    /**
308
     * Find a specific module.
309
     * @param $name
310
     * @return mixed|void
311
     */
312 50
    public function find($name)
313
    {
314 50
        foreach ($this->all() as $module) {
315 49
            if ($module->getLowerName() === strtolower($name)) {
316 49
                return $module;
317
            }
318 44
        }
319
320 44
        return;
321
    }
322
323
    /**
324
     * Alternative for "find" method.
325
     * @param $name
326
     * @return mixed|void
327
     */
328 1
    public function get($name)
329
    {
330 1
        return $this->find($name);
331
    }
332
333
    /**
334
     * Find a specific module, if there return that, otherwise throw exception.
335
     *
336
     * @param $name
337
     *
338
     * @return Module
339
     *
340
     * @throws ModuleNotFoundException
341
     */
342 49
    public function findOrFail($name)
343
    {
344 49
        $module = $this->find($name);
345
346 49
        if ($module !== null) {
347 48
            return $module;
348
        }
349
350 44
        throw new ModuleNotFoundException("Module [{$name}] does not exist!");
351
    }
352
353
    /**
354
     * Get all modules as laravel collection instance.
355
     *
356
     * @return Collection
357
     */
358 1
    public function collections()
359
    {
360 1
        return new Collection($this->enabled());
361 1
    }
362
363
    /**
364
     * Get module path for a specific module.
365
     *
366
     * @param $module
367
     *
368
     * @return string
369
     */
370 43
    public function getModulePath($module)
371
    {
372
        try {
373 43
            return $this->findOrFail($module)->getPath() . '/';
374 43
        } catch (ModuleNotFoundException $e) {
375 43
            return $this->getPath() . '/' . Str::studly($module) . '/';
376
        }
377
    }
378
379
    /**
380
     * Get asset path for a specific module.
381
     *
382
     * @param $module
383
     *
384
     * @return string
385
     */
386 2
    public function assetPath($module)
387
    {
388 2
        return $this->config('paths.assets') . '/' . $module;
389
    }
390
391
    /**
392
     * Get a specific config data from a configuration file.
393
     *
394
     * @param $key
395
     *
396
     * @param null $default
397
     * @return mixed
398
     */
399 85
    public function config($key, $default = null)
400
    {
401 85
        return $this->app['config']->get('modules.' . $key, $default);
402
    }
403
404
    /**
405
     * Get storage path for module used.
406
     *
407
     * @return string
408
     */
409 2
    public function getUsedStoragePath()
410
    {
411 2
        if (!$this->app['files']->exists($path = storage_path('app/modules'))) {
412 1
            $this->app['files']->makeDirectory($path, 0777, true);
413 1
        }
414
415 2
        return $path . '/modules.used';
416
    }
417
418
    /**
419
     * Set module used for cli session.
420
     *
421
     * @param $name
422
     *
423
     * @throws ModuleNotFoundException
424
     */
425 1
    public function setUsed($name)
426
    {
427 1
        $module = $this->findOrFail($name);
428
429 1
        $this->app['files']->put($this->getUsedStoragePath(), $module);
430 1
    }
431
432
    /**
433
     * Get module used for cli session.
434
     *
435
     * @return string
436
     */
437 1
    public function getUsedNow()
438
    {
439 1
        return $this->findOrFail($this->app['files']->get($this->getUsedStoragePath()));
440
    }
441
442
    /**
443
     * Get used now.
444
     *
445
     * @return string
446
     */
447 1
    public function getUsed()
448
    {
449 1
        return $this->getUsedNow();
450
    }
451
452
    /**
453
     * Get laravel filesystem instance.
454
     *
455
     * @return \Illuminate\Filesystem\Filesystem
456
     */
457 4
    public function getFiles()
458
    {
459 4
        return $this->app['files'];
460
    }
461
462
    /**
463
     * Get module assets path.
464
     *
465
     * @return string
466
     */
467 2
    public function getAssetsPath()
468
    {
469 2
        return $this->config('paths.assets');
470
    }
471
472
    /**
473
     * Get asset url from a specific module.
474
     *
475
     * @param string $asset
476
     *
477
     * @return string
478
     */
479 1
    public function asset($asset)
480
    {
481 1
        list($name, $url) = explode(':', $asset);
482
483 1
        $baseUrl = str_replace(public_path(), '', $this->getAssetsPath());
484
485 1
        $url = $this->app['url']->asset($baseUrl . "/{$name}/" . $url);
486
487 1
        return str_replace(['http://', 'https://'], '//', $url);
488
    }
489
490
    /**
491
     * Determine whether the given module is activated.
492
     *
493
     * @param string $name
494
     *
495
     * @return bool
496
     */
497 4
    public function active($name)
498
    {
499 4
        return $this->findOrFail($name)->active();
500
    }
501
502
    /**
503
     * Determine whether the given module is not activated.
504
     *
505
     * @param string $name
506
     *
507
     * @return bool
508
     */
509 2
    public function notActive($name)
510
    {
511 2
        return !$this->active($name);
512
    }
513
514
    /**
515
     * Enabling a specific module.
516
     *
517
     * @param string $name
518
     *
519
     * @return bool
520
     */
521 1
    public function enable($name)
522
    {
523 1
        return $this->findOrFail($name)->enable();
524
    }
525
526
    /**
527
     * Disabling a specific module.
528
     *
529
     * @param string $name
530
     *
531
     * @return bool
532
     */
533 1
    public function disable($name)
534
    {
535 1
        return $this->findOrFail($name)->disable();
536
    }
537
538
    /**
539
     * Delete a specific module.
540
     *
541
     * @param string $name
542
     *
543
     * @return bool
544
     */
545 1
    public function delete($name)
546
    {
547 1
        return $this->findOrFail($name)->delete();
548
    }
549
550
    /**
551
     * Update dependencies for the specified module.
552
     *
553
     * @param string $module
554
     */
555
    public function update($module)
556
    {
557
        with(new Updater($this))->update($module);
558
    }
559
560
    /**
561
     * Install the specified module.
562
     *
563
     * @param string $name
564
     * @param string $version
565
     * @param string $type
566
     * @param bool   $subtree
567
     *
568
     * @return \Symfony\Component\Process\Process
569
     */
570
    public function install($name, $version = 'dev-master', $type = 'composer', $subtree = false)
571
    {
572
        $installer = new Installer($name, $version, $type, $subtree);
573
574
        return $installer->run();
575
    }
576
577
    /**
578
     * Get stub path.
579
     *
580
     * @return string
581
     */
582 3
    public function getStubPath()
583
    {
584 3
        if ($this->stubPath !== null) {
585 1
            return $this->stubPath;
586
        }
587
588 2
        if ($this->config('stubs.enabled') === true) {
589 1
            return $this->config('stubs.path');
590
        }
591
592 1
        return $this->stubPath;
593
    }
594
595
    /**
596
     * Set stub path.
597
     *
598
     * @param string $stubPath
599
     *
600
     * @return $this
601
     */
602 1
    public function setStubPath($stubPath)
603
    {
604 1
        $this->stubPath = $stubPath;
605
606 1
        return $this;
607
    }
608
}
609