Completed
Pull Request — master (#1163)
by
unknown
01:51
created

LaravelDatabaseRepository::getCached()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
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
                    $modules[$row->name] = $this->createModule($this->app, $row->name, $row->path);
58
                }
59
            }
60
        }
61
62
        return $modules;
63
    }
64
65
    /**
66
     * Get all modules as laravel collection instance.
67
     *
68
     * @param $status
69
     *
70
     * @return Collection
71
     */
72
    public function collections($status = 1): Collection
73
    {
74
        return new Collection($this->getByStatus($status));
75
    }
76
77
    /**
78
     * Get module path for a specific module.
79
     *
80
     * @param $name
81
     *
82
     * @return string
83
     */
84
    public function getModulePath($name)
85
    {
86
        $module = $this->find($name);
87
        if ($module) {
88
            return $module->getPath() . '/';
89
        }
90
91
        return $this->getPath() . '/' . Str::studly($name) . '/';
92
    }
93
94
    /**
95
     * Get modules by status.
96
     *
97
     * @param $status
98
     *
99
     * @return array
100
     */
101 View Code Duplication
    public function getByStatus($status): array
102
    {
103
        $modules = [];
104
105
        foreach ($this->all() as $name => $module) {
106
            if ($module->isStatus($status) == $status) {
107
                $modules[$name] = $module;
108
            }
109
        }
110
111
        return $modules;
112
    }
113
114
    /**
115
     * Format the cached data as array of modules.
116
     *
117
     * @param array $cached
118
     *
119
     * @return array
120
     */
121
    protected function formatCached($cached)
122
    {
123
        $modules = [];
124
125
        foreach ($cached as $moduleEntity) {
126
            $module = $this->createModule($this->app, $moduleEntity['name'], $moduleEntity['path']);
127
            $module->setAttributes($moduleEntity->toArray());
128
            $modules[$moduleEntity['name']] = $module;
129
        }
130
131
        return $modules;
132
    }
133
134
    /**
135
     * Get cached modules from database.
136
     *
137
     * @return ModuleEntity[]
138
     */
139
    public function getCached()
140
    {
141
        return $this->app['cache']->remember($this->config('cache.key'), $this->config('cache.lifetime'), function () {
142
            return $this->getModel()->all();
143
        });
144
    }
145
146
    public function all(): array
147
    {
148
        // Do not load or register if there are no modules table yet.
149
        if (!Schema::hasTable('modules')) {
150
            return [];
151
        }
152
153
        return parent::all();
154
    }
155
156
    public function create($params, $force = true, $isApi = true, $isPlain = true)
157
    {
158
        $moduleType = $this->getModuleType($isApi, $isPlain); // Custom later.
159
        /** @var DatabaseModuleGenerator $generator */
160
        $generator = with(new DatabaseModuleGenerator($params['name']));
161
        $code = $generator
162
            ->setFilesystem(app('files'))
163
            ->setModule($this)
164
            ->setConfig(app('config'))
165
            ->setActivator(app(ActivatorInterface::class))
166
            ->setForce($force)
167
            ->setType($moduleType)
168
            ->setActive($params['is_active'])
169
            ->setSilentOutput(true) // Don't use console output
170
            ->generate();
171
172
        return $code ? $this->find($params['name']) : false;
173
    }
174
175
    /**
176
     * Get module type .
177
     *
178
     * @param bool $isApi
179
     * @param bool $isPlain
180
     *
181
     * @return string
182
     */
183
    public function getModuleType($isApi = true, $isPlain = true)
184
    {
185
        if ($isPlain && $isApi) {
186
            return 'web';
187
        }
188
        if ($isPlain) {
189
            return 'plain';
190
        } elseif ($isApi) {
191
            return 'api';
192
        } else {
193
            return 'web';
194
        }
195
    }
196
197
    /**
198
     * Get module used for cli session.
199
     * @return string
200
     * @throws ModuleNotFoundException|FileNotFoundException
201
     */
202
    public function getUsedNow(): string
203
    {
204
        $module = $this->getFiles()->get($this->getUsedStoragePath());
205
        if (!$module) {
206
            return '';
207
        }
208
209
        return $this->findOrFail($module);
210
    }
211
212
    public function migrateFileToDatabase($forceUpdate = false)
213
    {
214
        $paths = $this->getScanPaths();
215
        $modules = [];
216
217
        foreach ($paths as $key => $path) {
218
            $manifests = $this->getFiles()->glob("{$path}/module.json");
219
220
            is_array($manifests) || $manifests = [];
221
222
            foreach ($manifests as $manifest) {
223
                $json = Json::make($manifest);
224
                $data = $json->getAttributes();
225
                $data['path'] = str_replace('module.json', '', $json->getPath());
226
                if (!isset($data['version'])) {
227
                    $data['version'] = '1.0.0';
228
                }
229
                $module = $this->find($data['name']);
230
                $data = $this->validateAttributes($data);
231
                if (!$module) {
232
                    $modules[] = $this->getModel()->create($data);
233
                } else {
234
                    // Check version, if version is higher then update module.json into database.
235
                    // Can use force update here.
236
                    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...
237
                        $modules[] = $this->getModel()->where(['name' => $data['name']])->update($data);
238
                    }
239
                }
240
            }
241
        }
242
243
        $this->register();
244
        $this->boot();
245
246
        return $modules;
247
    }
248
249
    public function update($name)
250
    {
251
        return $this->findOrFail($name)->update(new Updater($this));
252
    }
253
254
    /**
255
     * Validate array attributes before insert/update into database.
256
     *
257
     * @param array $attributes
258
     * @param array $allows
259
     *
260
     * @return array
261
     */
262
    protected function validateAttributes(array $attributes, array $allows = [])
263
    {
264
        if (empty($allows)) {
265
            $allows = $this->getModel()->getFillable();
266
        }
267
268
        return array_filter($attributes, function ($k) use ($allows) {
269
            return in_array($k, $allows);
270
        }, ARRAY_FILTER_USE_KEY);
271
    }
272
}
273