Completed
Pull Request — master (#1163)
by
unknown
03:47 queued 10s
created

LaravelDatabaseRepository::getByStatus()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 12
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\Laravel;
4
5
use Illuminate\Contracts\Filesystem\FileNotFoundException;
6
use Illuminate\Support\Facades\Schema;
7
use Illuminate\Support\Str;
8
use Nwidart\Modules\Collection;
9
use Nwidart\Modules\Contracts\ActivatorInterface;
10
use Nwidart\Modules\Contracts\DatabaseRepositoryInterface;
11
use Nwidart\Modules\Entities\ModuleEntity;
12
use Nwidart\Modules\Exceptions\ModuleNotFoundException;
13
use Nwidart\Modules\Generators\DatabaseModuleGenerator;
14
use Nwidart\Modules\Json;
15
use Nwidart\Modules\Process\Updater;
16
17
/**
18
 * Class LaravelDatabaseRepository
19
 * @package Nwidart\Modules\Laravel
20
 * @method DatabaseModule findOrFail(string $name)
21
 */
22
class LaravelDatabaseRepository extends LaravelFileRepository implements DatabaseRepositoryInterface
23
{
24
    /**
25
     * Creates a new Module instance.
26
     *
27
     * @param mixed ...$args
28
     *
29
     * @return DatabaseModule
30
     */
31
    protected function createModule(...$args)
32
    {
33
        return new DatabaseModule(...$args);
0 ignored issues
show
Bug introduced by
The call to DatabaseModule::__construct() misses some required arguments starting with $name.
Loading history...
Documentation introduced by
$args is of type array<integer,*>, but the function expects a object<Illuminate\Container\Container>.

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...
34
    }
35
36
    /**
37
     * @return ModuleEntity
38
     */
39
    public function getModel()
40
    {
41
        return new ModuleEntity();
42
    }
43
44
    /**
45
     * Scan & get all available modules.
46
     */
47
    public function scan()
48
    {
49
        /**
50
         * @var ModuleEntity[] $rows
51
         */
52
        $rows = $this->getModel()->get();
53
        $modules = [];
54
        if (!empty($rows)) {
55
            foreach ($rows as $row) {
56
                if (file_exists($row->path)) {
57
                    $module = $this->createModule($this->app, $row->name, $row->path);
58
                    $module->setAttributes($row->toArray());
59
                    $modules[$row->name] = $module;
60
                }
61
            }
62
        }
63
64
        return $modules;
65
    }
66
67
    /**
68
     * Get all modules as laravel collection instance.
69
     *
70
     * @param $status
71
     *
72
     * @return Collection
73
     */
74
    public function collections($status = 1): Collection
75
    {
76
        return new Collection($this->getByStatus($status));
77
    }
78
79
    /**
80
     * Get module path for a specific module.
81
     *
82
     * @param $name
83
     *
84
     * @return string
85
     */
86
    public function getModulePath($name)
87
    {
88
        $module = $this->find($name);
89
        if ($module) {
90
            return $module->getPath() . '/';
91
        }
92
93
        return $this->getPath() . '/' . Str::studly($name) . '/';
94
    }
95
96
    /**
97
     * Get modules by status.
98
     *
99
     * @param $status
100
     *
101
     * @return array
102
     */
103 View Code Duplication
    public function getByStatus($status): array
104
    {
105
        $modules = [];
106
107
        foreach ($this->all() as $name => $module) {
108
            if ($module->isStatus($status) == $status) {
109
                $modules[$name] = $module;
110
            }
111
        }
112
113
        return $modules;
114
    }
115
116
    /**
117
     * Format the cached data as array of modules.
118
     *
119
     * @param array $cached
120
     *
121
     * @return array
122
     */
123
    protected function formatCached($cached)
124
    {
125
        $modules = [];
126
127
        foreach ($cached as $moduleEntity) {
128
            $module = $this->createModule($this->app, $moduleEntity['name'], $moduleEntity['path']);
129
            $module->setAttributes($moduleEntity->toArray());
130
            $modules[$moduleEntity['name']] = $module;
131
        }
132
133
        return $modules;
134
    }
135
136
    /**
137
     * Get cached modules from database.
138
     *
139
     * @return ModuleEntity[]
140
     */
141
    public function getCached()
142
    {
143
        return $this->app['cache']->remember($this->config('cache.key'), $this->config('cache.lifetime'), function () {
144
            return $this->getModel()->all();
145
        });
146
    }
147
148
    public function all(): array
149
    {
150
        // Do not load or register if there are no modules table yet.
151
        if (!Schema::hasTable('modules')) {
152
            return [];
153
        }
154
155
        return parent::all();
156
    }
157
158
    public function create($params, $force = true, $isApi = true, $isPlain = true)
159
    {
160
        $moduleType = $this->getModuleType($isApi, $isPlain); // Custom later.
161
        /** @var DatabaseModuleGenerator $generator */
162
        $generator = with(new DatabaseModuleGenerator($params['name']));
163
        $code = $generator
164
            ->setFilesystem(app('files'))
165
            ->setModule($this)
166
            ->setConfig(app('config'))
167
            ->setActivator(app(ActivatorInterface::class))
168
            ->setForce($force)
169
            ->setType($moduleType)
170
            ->setActive($params['is_active'])
171
            ->setSilentOutput(true) // Don't use console output
172
            ->generate();
173
174
        return $code ? $this->find($params['name']) : false;
175
    }
176
177
    /**
178
     * Get module type .
179
     *
180
     * @param bool $isApi
181
     * @param bool $isPlain
182
     *
183
     * @return string
184
     */
185
    public function getModuleType($isApi = true, $isPlain = true)
186
    {
187
        if ($isPlain && $isApi) {
188
            return 'web';
189
        }
190
        if ($isPlain) {
191
            return 'plain';
192
        } elseif ($isApi) {
193
            return 'api';
194
        } else {
195
            return 'web';
196
        }
197
    }
198
199
    /**
200
     * Get module used for cli session.
201
     * @return string
202
     * @throws ModuleNotFoundException|FileNotFoundException
203
     */
204
    public function getUsedNow(): string
205
    {
206
        $module = $this->getFiles()->get($this->getUsedStoragePath());
207
        if (!$module) {
208
            return '';
209
        }
210
211
        return $this->findOrFail($module);
212
    }
213
214
    public function migrateFileToDatabase($forceUpdate = false)
215
    {
216
        $paths = $this->getScanPaths();
217
        $modules = [];
218
219
        foreach ($paths as $key => $path) {
220
            $manifests = $this->getFiles()->glob("{$path}/module.json");
221
222
            is_array($manifests) || $manifests = [];
223
224
            foreach ($manifests as $manifest) {
225
                $json = Json::make($manifest);
226
                $data = $json->getAttributes();
227
                $data['path'] = str_replace('module.json', '', $json->getPath());
228
                if (!isset($data['version'])) {
229
                    $data['version'] = '1.0.0';
230
                }
231
                $module = $this->find($data['name']);
232
                $data = $this->validateAttributes($data);
233
                if (!$module) {
234
                    $modules[] = $this->getModel()->create($data);
235
                } else {
236
                    // Check version, if version is higher then update module.json into database.
237
                    // Can use force update here.
238
                    if (version_compare($module->getVersion(), $data['version'], '<') || $forceUpdate) {
0 ignored issues
show
Documentation Bug introduced by
The method getVersion does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
239
                        $modules[] = $this->getModel()->where(['name' => $data['name']])->update($data);
240
                    }
241
                }
242
            }
243
        }
244
245
        $this->register();
246
        $this->boot();
247
248
        return $modules;
249
    }
250
251
    public function update($name)
252
    {
253
        return $this->findOrFail($name)->update(new Updater($this));
254
    }
255
256
    /**
257
     * Validate array attributes before insert/update into database.
258
     *
259
     * @param array $attributes
260
     * @param array $allows
261
     *
262
     * @return array
263
     */
264
    protected function validateAttributes(array $attributes, array $allows = [])
265
    {
266
        if (empty($allows)) {
267
            $allows = $this->getModel()->getFillable();
268
        }
269
270
        return array_filter($attributes, function ($k) use ($allows) {
271
            return in_array($k, $allows);
272
        }, ARRAY_FILTER_USE_KEY);
273
    }
274
275 View Code Duplication
    public function getOrdered($direction = 'asc'): array
276
    {
277
        $modules = $this->allEnabled();
278
279
        uasort($modules, function (DatabaseModule $a, DatabaseModule $b) use ($direction) {
280
            if ($a->get('priority') === $b->get('priority')) {
281
                return 0;
282
            }
283
284
            if ($direction === 'desc') {
285
                return $a->get('priority') < $b->get('priority') ? 1 : -1;
286
            }
287
288
            return $a->get('priority') > $b->get('priority') ? 1 : -1;
289
        });
290
291
        return $modules;
292
    }
293
}
294