Completed
Pull Request — master (#857)
by Lex
13:03
created

DatabaseRepository::allDisabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules;
4
5
use Countable;
6
use Illuminate\Cache\CacheManager;
7
use Illuminate\Container\Container;
8
use Illuminate\Contracts\Config\Repository as ConfigRepository;
9
use Illuminate\Contracts\Routing\UrlGenerator;
10
use Illuminate\Filesystem\Filesystem;
11
use Illuminate\Support\Traits\Macroable;
12
use Nwidart\Modules\Contracts\RepositoryInterface;
13
use Nwidart\Modules\Entities\Module as ModuleEntity;
14
use Nwidart\Modules\Exceptions\ModuleNotFoundException;
15
16
abstract class DatabaseRepository implements RepositoryInterface, Countable
17
{
18
    use Macroable;
19
20
    /**
21
     * Application instance.
22
     *
23
     * @var \Illuminate\Contracts\Foundation\Application
24
     */
25
    protected $app;
26
27
    /**
28
     * The module path.
29
     *
30
     * @var string|null
31
     */
32
    protected $path;
33
34
    /**
35
     * The scanned paths.
36
     *
37
     * @var array
38
     */
39
    protected $paths = [];
40
41
    /**
42
     * @var string
43
     */
44
    protected $stubPath;
45
    /**
46
     * @var UrlGenerator
47
     */
48
    private $url;
49
    /**
50
     * @var ConfigRepository
51
     */
52
    private $config;
53
    /**
54
     * @var Filesystem
55
     */
56
    private $files;
57
    /**
58
     * @var CacheManager
59
     */
60
    private $cache;
61
62
    /**
63
     * The constructor.
64
     *
65
     * @param Container   $app
66
     * @param string|null $path
67
     */
68 View Code Duplication
    public function __construct(Container $app, $path = null)
69
    {
70
        $this->app = $app;
0 ignored issues
show
Documentation Bug introduced by
It seems like $app of type object<Illuminate\Container\Container> is incompatible with the declared type object<Illuminate\Contra...Foundation\Application> of property $app.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
71
        $this->path = $path;
72
        $this->url = $app['url'];
73
        $this->config = $app['config'];
74
        $this->files = $app['files'];
75
        $this->cache = $app['cache'];
76
    }
77
78
    /**
79
     * Get all modules.
80
     *
81
     * @return mixed
82
     */
83
    public function all()
84
    {
85
        if (!$this->config('cache.enabled')) {
86
            return $this->scan();
87
        }
88
89
        return $this->formatCached($this->getCached());
90
    }
91
92
    /**
93
     * Get cached modules.
94
     *
95
     * @return array
96
     */
97
    public function getCached()
98
    {
99
        return $this->cache->remember($this->config('cache.key'), $this->config('cache.lifetime'), function () {
100
            return $this->toCollection()->toArray();
101
        });
102
    }
103
104
    /**
105
     * Scan & get all available modules.
106
     *
107
     * @return array
108
     */
109
    public function scan()
110
    {
111
        $entities = ModuleEntity::all();
112
113
        return $this->parse($entities);
0 ignored issues
show
Bug introduced by
It seems like $entities defined by \Nwidart\Modules\Entities\Module::all() on line 111 can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, Nwidart\Modules\DatabaseRepository::parse() does only seem to accept object<Illuminate\Database\Eloquent\Collection>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
114
    }
115
116
    /**
117
     * Get modules as modules collection instance.
118
     *
119
     * @return \Nwidart\Modules\Collection
120
     */
121
    public function toCollection()
122
    {
123
        return new Collection($this->scan());
124
    }
125
126
    /**
127
     * Get scanned paths.
128
     *
129
     * @return array
130
     */
131
    public function getScanPaths()
132
    {
133
        // TODO: Unused thus remove
134
    }
135
136
    /**
137
     * Determine whether the given module exist.
138
     *
139
     * @param $name
140
     *
141
     * @return bool
142
     */
143
    public function has($name) : bool
144
    {
145
        return array_key_exists($name, $this->all());
146
    }
147
148
    /**
149
     * Get list of enabled modules.
150
     *
151
     * @return mixed
152
     */
153
    public function allEnabled()
154
    {
155
        return $this->getByStatus(true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
156
    }
157
158
    /**
159
     * Get list of disabled modules.
160
     *
161
     * @return mixed
162
     */
163
    public function allDisabled()
164
    {
165
        return $this->getByStatus(false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166
    }
167
168
    /**
169
     * Get count from all modules.
170
     *
171
     * @return int
172
     */
173
    public function count()
174
    {
175
        return count($this->all());
176
    }
177
178
    /**
179
     * Get all ordered modules.
180
     *
181
     * @param string $direction
182
     * @return mixed
183
     */
184
    public function getOrdered($direction = 'asc')
185
    {
186
        $entities = ModuleEntity::orderBy('sequence', $direction)->get();
187
188
        return $this->parse($entities);
0 ignored issues
show
Bug introduced by
It seems like $entities defined by \Nwidart\Modules\Entitie...ce', $direction)->get() on line 186 can also be of type array<integer,object<Ill...base\Eloquent\Builder>>; however, Nwidart\Modules\DatabaseRepository::parse() does only seem to accept object<Illuminate\Database\Eloquent\Collection>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
189
    }
190
191
    /**
192
     * Get modules by the given status.
193
     *
194
     * @param int $status
195
     *
196
     * @return mixed
197
     */
198
    public function getByStatus($status)
199
    {
200
        $entities = ModuleEntity::where('is_active', $status)->get();
201
202
        return $this->parse($entities);
203
    }
204
205
    /**
206
     * Find a specific module.
207
     *
208
     * @param $name
209
     * @return Module|null
210
     */
211
    public function find(string $name)
212
    {
213
        $entity = ModuleEntity::findByName($name);
214
215
        if (!$entity) {
216
            return null;
217
        }
218
219
        return $this->createModule($this->app, $entity->name, $entity->path);
220
    }
221
222
    /**
223
     * Find all modules that are required by a module. If the module cannot be found, throw an exception.
224
     *
225
     * @param $name
226
     * @return array
227
     * @throws ModuleNotFoundException
228
     */
229 View Code Duplication
    public function findRequirements($name): array
230
    {
231
        $requirements = [];
232
233
        $module = $this->findOrFail($name);
234
235
        foreach ($module->getRequires() as $requirementName) {
236
            $requirements[] = $this->findByAlias($requirementName);
237
        }
238
239
        return $requirements;
240
    }
241
242
    /**
243
     * Find a specific module. If there return that, otherwise throw exception.
244
     *
245
     * @param $name
246
     *
247
     * @return mixed
248
     * @throws \Nwidart\Modules\Exceptions\ModuleNotFoundException
249
     */
250 View Code Duplication
    public function findOrFail(string $name)
251
    {
252
        $module = $this->find($name);
253
254
        if ($module !== null) {
255
            return $module;
256
        }
257
258
        throw new ModuleNotFoundException("Module [{$name}] does not exist!");
259
    }
260
261
    /**
262
     * Find a specific module. If there return that, otherwise create it.
263
     *
264
     * @param $name
265
     *
266
     * @return Module
267
     */
268
    public function findByNameOrCreate(string $name)
269
    {
270
        $module = $this->find($name);
0 ignored issues
show
Unused Code introduced by
$module is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
271
272
        return $this->createModule($this->app, $name, $this->getModulePath($name));
273
    }
274
275
    /**
276
     * @param $name
277
     * @return string
278
     */
279
    public function getModulePath($name)
280
    {
281
        return $this->getPath() . '/' . $name;
282
    }
283
284
    /**
285
     * @return \Illuminate\Filesystem\Filesystem
286
     */
287
    public function getFiles()
288
    {
289
        return $this->files;
290
    }
291
292
    /**
293
     * Get a specific config data from a configuration file.
294
     *
295
     * @param string      $key
296
     *
297
     * @param string|null $default
298
     * @return mixed
299
     */
300
    public function config(string $key, $default = null)
301
    {
302
        return $this->config->get('modules.' . $key, $default);
303
    }
304
305
    /**
306
     * Get a module path.
307
     *
308
     * @return string
309
     */
310
    public function getPath(): string
311
    {
312
        return $this->path ?: $this->config('paths.modules', base_path($this->config->get('paths.modules')));
313
    }
314
315
    /**
316
     * Find a specific module by its alias.
317
     *
318
     * @param string $alias
319
     * @return Module|void
320
     */
321
    public function findByAlias(string $alias)
322
    {
323
        foreach ($this->all() as $module) {
324
            if ($module->getAlias() === $alias) {
325
                return $module;
326
            }
327
        }
328
329
        return;
330
    }
331
332
    /**
333
     * Boot the modules.
334
     */
335
    public function boot(): void
336
    {
337
        foreach ($this->getOrdered() as $module) {
338
            $module->boot();
339
        }
340
    }
341
342
    /**
343
     * Register the modules.
344
     */
345
    public function register(): void
346
    {
347
        foreach ($this->getOrdered() as $module) {
348
            $module->register();
349
        }
350
    }
351
352
    /**
353
     * Get asset path for a specific module.
354
     *
355
     * @param string $module
356
     * @return string
357
     */
358
    public function assetPath(string $module): string
359
    {
360
        return $this->config('paths.assets') . '/' . $module;
361
    }
362
363
    /**
364
     * Delete a specific module.
365
     *
366
     * @param string $module
367
     * @return bool
368
     * @throws \Nwidart\Modules\Exceptions\ModuleNotFoundException
369
     */
370
    public function delete(string $module): bool
371
    {
372
        return $this->findOrFail($module)->delete();
373
    }
374
375
    /**
376
     * Determine whether the given module is activated.
377
     *
378
     * @param string $name
379
     * @return bool
380
     * @throws ModuleNotFoundException
381
     */
382
    public function isEnabled(string $name): bool
383
    {
384
        return $this->findOrFail($name)->isEnabled();
385
    }
386
387
    /**
388
     * Determine whether the given module is not activated.
389
     *
390
     * @param string $name
391
     * @return bool
392
     * @throws ModuleNotFoundException
393
     */
394
    public function isDisabled(string $name): bool
395
    {
396
        return !$this->isEnabled($name);
397
    }
398
399
    /**
400
     * Format the cached data as array of modules.
401
     *
402
     * @param array $cached
403
     *
404
     * @return array
405
     */
406 View Code Duplication
    protected function formatCached($cached)
407
    {
408
        $modules = [];
409
410
        foreach ($cached as $name => $module) {
411
            $modules[$name] = $this->createModule($this->app, $name, $this->getModulePath($name));
412
        }
413
414
        return $modules;
415
    }
416
417
    /**
418
     * Creates a new Module instance
419
     *
420
     * @param Container $app
0 ignored issues
show
Bug introduced by
There is no parameter named $app. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
421
     * @param string $args
422
     * @param string $path
0 ignored issues
show
Bug introduced by
There is no parameter named $path. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
423
     * @return \Nwidart\Modules\Module
424
     */
425
    abstract protected function createModule(...$args);
426
427
    /**
428
     * Parse from ModuleEntityCollection to Module array
429
     *
430
     * @param \Illuminate\Database\Eloquent\Collection $entities
431
     * @return array
432
     */
433
    protected function parse(\Illuminate\Database\Eloquent\Collection $entities)
434
    {
435
        $modules = [];
436
437
        foreach ($entities as $entity) {
438
            $modules[$entity->name] = $this->createModule($this->app, $entity->name, $entity->path);
439
        }
440
441
        return $modules;
442
    }
443
}
444