Completed
Push — master ( 0fd405...f8ea68 )
by Nicolas
8s
created

SeedCommand   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 6.56%

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 7
dl 0
loc 191
ccs 4
cts 61
cp 0.0656
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 19 3
A getModuleRepository() 0 9 2
A getModuleByName() 0 9 2
C moduleSeed() 0 23 7
A dbSeed() 0 16 3
A renderException() 0 4 1
A reportException() 0 4 1
A getArguments() 0 6 1
A getOptions() 0 7 1
A getSeederName() 0 10 1
1
<?php
2
3
namespace Nwidart\Modules\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Contracts\Debug\ExceptionHandler;
7
use Illuminate\Support\Str;
8
use Nwidart\Modules\Module;
9
use Nwidart\Modules\Repository;
10
use Nwidart\Modules\Support\Config\GenerateConfigReader;
11
use Nwidart\Modules\Traits\ModuleCommandTrait;
12
use RuntimeException;
13
use Symfony\Component\Console\Input\InputArgument;
14
use Symfony\Component\Console\Input\InputOption;
15
16
class SeedCommand extends Command
17
{
18
    use ModuleCommandTrait;
19
20
    /**
21
     * The console command name.
22
     *
23
     * @var string
24
     */
25
    protected $name = 'module:seed';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Run database seeder from the specified module or from all modules.';
33
34
    /**
35
     * Execute the console command.
36
     * @throws FatalThrowableError
37
     */
38
    public function handle()
39
    {
40
        try {
41
            if ($name = $this->argument('module')) {
42
                $name = Str::studly($name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type array; however, Illuminate\Support\Str::studly() does only seem to accept string, 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...
43
                $this->moduleSeed($this->getModuleByName($name));
44
            } else {
45
                $modules = $this->getModuleRepository()->getOrdered();
46
                array_walk($modules, [$this, 'moduleSeed']);
47
                $this->info('All modules seeded.');
48
            }
49
        } catch (\Throwable $e) {
50
            $this->reportException($e);
0 ignored issues
show
Compatibility introduced by
$e of type object<Throwable> is not a sub-type of object<Exception>. It seems like you assume a concrete implementation of the interface Throwable to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
51
52
            $this->renderException($this->getOutput(), $e);
0 ignored issues
show
Compatibility introduced by
$e of type object<Throwable> is not a sub-type of object<Exception>. It seems like you assume a concrete implementation of the interface Throwable to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
53
54
            return 1;
55
        }
56
    }
57
58
    /**
59
     * @throws RuntimeException
60
     *
61
     * @return Repository
62
     */
63
    public function getModuleRepository()
64
    {
65
        $modules = $this->laravel['modules'];
66
        if (!$modules instanceof Repository) {
67
            throw new RuntimeException("Module repository not found!");
68
        }
69
70
        return $modules;
71
    }
72
73
    /**
74
     * @param $name
75
     *
76
     * @throws RuntimeException
77
     *
78
     * @return Module
79
     */
80
    public function getModuleByName($name)
81
    {
82
        $modules = $this->getModuleRepository();
83
        if ($modules->has($name) === false) {
84
            throw new RuntimeException("Module [$name] does not exists.");
85
        }
86
87
        return $modules->get($name);
0 ignored issues
show
Deprecated Code introduced by
The method Nwidart\Modules\Repository::get() has been deprecated.

This method has been deprecated.

Loading history...
88
    }
89
90
    /**
91
     * @param Module $module
92
     *
93
     * @return void
94
     */
95
    public function moduleSeed(Module $module)
96
    {
97
        $seeders = [];
98
        $name = $module->getName();
99
        $config = $module->get('migration');
100
        if (is_array($config) && array_key_exists('seeds', $config)) {
101
            foreach ((array)$config['seeds'] as $class) {
102
                if (class_exists($class)) {
103
                    $seeders[] = $class;
104
                }
105
            }
106
        } else {
107
            $class = $this->getSeederName($name); //legacy support
108
            if (class_exists($class)) {
109
                $seeders[] = $class;
110
            }
111
        }
112
113
        if (count($seeders) > 0) {
114
            array_walk($seeders, [$this, 'dbSeed']);
115
            $this->info("Module [$name] seeded.");
116
        }
117
    }
118
119
    /**
120
     * Seed the specified module.
121
     *
122
     * @param string $className
123
     */
124
    protected function dbSeed($className)
125
    {
126
        $params = [
127
            '--class' => $className,
128
        ];
129
130
        if ($option = $this->option('database')) {
131
            $params['--database'] = $option;
132
        }
133
134
        if ($option = $this->option('force')) {
135
            $params['--force'] = $option;
136
        }
137
138
        $this->call('db:seed', $params);
139
    }
140
141
    /**
142
     * Get master database seeder name for the specified module.
143
     *
144
     * @param string $name
145
     *
146
     * @return string
147
     */
148
    public function getSeederName($name)
149
    {
150
        $name = Str::studly($name);
151
152
        $namespace = $this->laravel['modules']->config('namespace');
153
        $seederPath = GenerateConfigReader::read('seeder');
154
        $seederPath = str_replace('/', '\\', $seederPath->getPath());
155
156
        return $namespace . '\\' . $name . '\\' . $seederPath . '\\' . $name . 'DatabaseSeeder';
157
    }
158
159
    /**
160
     * Report the exception to the exception handler.
161
     *
162
     * @param  \Symfony\Component\Console\Output\OutputInterface  $output
163
     * @param  \Exception  $e
164
     * @return void
165
     */
166
    protected function renderException($output, \Exception $e)
167
    {
168
        $this->laravel[ExceptionHandler::class]->renderForConsole($output, $e);
169
    }
170
171
    /**
172
     * Report the exception to the exception handler.
173
     *
174
     * @param  \Exception  $e
175
     * @return void
176
     */
177
    protected function reportException(\Exception $e)
178
    {
179
        $this->laravel[ExceptionHandler::class]->report($e);
180
    }
181
182
    /**
183
     * Get the console command arguments.
184
     *
185
     * @return array
186
     */
187 91
    protected function getArguments()
188
    {
189
        return [
190 91
            ['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
191
        ];
192
    }
193
194
    /**
195
     * Get the console command options.
196
     *
197
     * @return array
198
     */
199 91
    protected function getOptions()
200
    {
201
        return [
202 91
            ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed.'],
203
            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
204
        ];
205
    }
206
}
207