Completed
Pull Request — master (#1163)
by
unknown
02:32
created

LaravelDatabaseRepository::migrateFileToDatabase()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 5
nop 0
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\Laravel;
4
5
use Illuminate\Contracts\Filesystem\FileNotFoundException;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Support\Facades\Schema;
8
use Illuminate\Support\Str;
9
use Nwidart\Modules\Collection;
10
use Nwidart\Modules\Contracts\ActivatorInterface;
11
use Nwidart\Modules\Contracts\DatabaseRepositoryInterface;
12
use Nwidart\Modules\Entities\ModuleEntity;
13
use Nwidart\Modules\Exceptions\ModuleNotFoundException;
14
use Nwidart\Modules\Generators\DatabaseModuleGenerator;
15
use Nwidart\Modules\Json;
16
use Nwidart\Modules\Laravel\DatabaseModule as Module;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Nwidart\Modules\Laravel\Module.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
18
class LaravelDatabaseRepository extends LaravelFileRepository implements DatabaseRepositoryInterface
19
{
20
    protected function createModule(...$args)
21
    {
22
        return new Module(...$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...
23
    }
24
25
    /**
26
     * @return ModuleEntity|Builder
27
     */
28
    public function getModel()
29
    {
30
        return new ModuleEntity();
31
    }
32
33
    /**
34
     * Scan & get all available modules.
35
     */
36
    public function scan()
37
    {
38
        /**
39
         * @var ModuleEntity[] $rows
40
         */
41
        $rows = $this->getModel()->get();
0 ignored issues
show
Bug introduced by
The method get does only exist in Illuminate\Database\Eloquent\Builder, but not in Nwidart\Modules\Entities\ModuleEntity.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
42
        $modules = [];
43
        if (!empty($rows)) {
44
            foreach ($rows as $row) {
45
                if (file_exists($row->path)) {
46
                    $modules[$row->name] = $this->createModule($this->app, $row->name, $row->path);
47
                }
48
            }
49
        }
50
51
        return $modules;
52
    }
53
54
    /**
55
     * Determine whether the given module exist.
56
     *
57
     * @param $name
58
     *
59
     * @return bool
60
     */
61
    public function has($name): bool
62
    {
63
        return $this->getModel()->where('name', $name)->exists();
0 ignored issues
show
Bug introduced by
The method where does only exist in Illuminate\Database\Eloquent\Builder, but not in Nwidart\Modules\Entities\ModuleEntity.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
64
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69
    public function find(string $name)
70
    {
71
        /** @var ModuleEntity $module */
72
        $module = $this->getModel()->where('name', $name)->first();
0 ignored issues
show
Bug introduced by
The method where does only exist in Illuminate\Database\Eloquent\Builder, but not in Nwidart\Modules\Entities\ModuleEntity.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
73
        if (!$module) {
74
            return null;
75
        }
76
        if (!file_exists($module->path)) {
77
            return null;
78
        }
79
80
        return $this->createModule($this->app, $module->name, $module->path);
81
    }
82
83
    /**
84
     * Get all modules as laravel collection instance.
85
     *
86
     * @param $status
87
     *
88
     * @return Collection
89
     */
90
    public function collections($status = 1): Collection
91
    {
92
        return new Collection($this->getByStatus($status));
93
    }
94
95
    /**
96
     * Get module path for a specific module.
97
     *
98
     * @param $name
99
     *
100
     * @return string
101
     */
102
    public function getModulePath($name)
103
    {
104
        $module = $this->find($name);
105
        if ($module) {
106
            return $module->getPath() . '/';
107
        }
108
109
        return $this->getPath() . '/' . Str::studly($name) . '/';
110
    }
111
112
    /**
113
     * Get modules by status.
114
     *
115
     * @param $status
116
     *
117
     * @return array
118
     */
119 View Code Duplication
    public function getByStatus($status): array
120
    {
121
        $modules = [];
122
123
        foreach ($this->all() as $name => $module) {
124
            if ($module->isStatus($status) == $status) {
125
                $modules[$name] = $module;
126
            }
127
        }
128
129
        return $modules;
130
    }
131
132
    /**
133
     * Format the cached data as array of modules.
134
     *
135
     * @param array $cached
136
     *
137
     * @return array
138
     */
139
    protected function formatCached($cached)
140
    {
141
        $modules = [];
142
143
        foreach ($cached as $moduleEntity) {
144
            $module = $this->createModule($this->app, $moduleEntity['name'], $moduleEntity['path']);
145
            $module->setAttributes($moduleEntity->toArray());
146
            $modules[$moduleEntity['name']] = $module;
147
        }
148
149
        return $modules;
150
    }
151
152
    /**
153
     * Get cached modules from database.
154
     *
155
     * @return ModuleEntity[]
156
     */
157
    public function getCached()
158
    {
159
        return $this->app['cache']->remember($this->config('cache.key'), $this->config('cache.lifetime'), function () {
160
            return $this->getModel()->all();
0 ignored issues
show
Bug introduced by
The method all does only exist in Nwidart\Modules\Entities\ModuleEntity, but not in Illuminate\Database\Eloquent\Builder.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
161
        });
162
    }
163
164
    public function all(): array
165
    {
166
        // Do not load or register if there are no modules table yet.
167
        if (!Schema::hasTable('modules')) {
168
            return [];
169
        }
170
171
        return parent::all();
172
    }
173
174
    public function create($params, $force = true, $isApi = true, $isPlain = true)
175
    {
176
        $moduleType = $this->getModuleType($isApi, $isPlain); // Custom later.
177
        /** @var DatabaseModuleGenerator $generator */
178
        $generator = with(new DatabaseModuleGenerator($params['name']));
179
        $code = $generator
180
            ->setFilesystem(app('files'))
181
            ->setModule($this)
182
            ->setConfig(app('config'))
183
            ->setActivator(app(ActivatorInterface::class))
184
            ->setForce($force)
185
            ->setType($moduleType)
186
            ->setActive($params['is_active'])
187
            ->setSilentOutput(true) // Don't use console output
188
            ->generate();
189
190
        return $code ? $this->find($params['name']) : false;
191
    }
192
193
    /**
194
     * Get module type .
195
     *
196
     * @param bool $isApi
197
     * @param bool $isPlain
198
     *
199
     * @return string
200
     */
201
    public function getModuleType($isApi = true, $isPlain = true)
202
    {
203
        if ($isPlain && $isApi) {
204
            return 'web';
205
        }
206
        if ($isPlain) {
207
            return 'plain';
208
        } elseif ($isApi) {
209
            return 'api';
210
        } else {
211
            return 'web';
212
        }
213
    }
214
215
    /**
216
     * Get module used for cli session.
217
     * @return string
218
     * @throws ModuleNotFoundException|FileNotFoundException
219
     */
220
    public function getUsedNow(): string
221
    {
222
        $module = $this->getFiles()->get($this->getUsedStoragePath());
223
        if (!$module) {
224
            return '';
225
        }
226
227
        return $this->findOrFail($module);
228
    }
229
230
    public function migrateFileToDatabase()
231
    {
232
        $paths = $this->getScanPaths();
233
        $modules = [];
234
235
        foreach ($paths as $key => $path) {
236
            $manifests = $this->getFiles()->glob("{$path}/module.json");
237
238
            is_array($manifests) || $manifests = [];
239
240
            foreach ($manifests as $manifest) {
241
                $json = Json::make($manifest);
242
                $data = $json->getAttributes();
243
                $data['path'] = str_replace('module.json', '', $json->getPath());
244
                $modules[] = $this->getModel()->create($data);
0 ignored issues
show
Bug introduced by
The method create does only exist in Illuminate\Database\Eloquent\Builder, but not in Nwidart\Modules\Entities\ModuleEntity.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
245
            }
246
        }
247
248
        return $modules;
249
    }
250
}
251