Passed
Push — master ( 58fc63...427199 )
by Richard
10:20 queued 10s
created

ArtomatorControllerCommand   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 258
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 258
rs 10
c 0
b 0
f 0
wmc 23

9 Methods

Rating   Name   Duplication   Size   Complexity  
A buildClass() 0 18 1
A buildSchemaReplacements() 0 10 2
A getDefaultNamespace() 0 3 1
A getStub() 0 10 2
A parseModel() 0 15 3
A getOptions() 0 9 1
A parseRequest() 0 15 3
A buildModelReplacements() 0 21 3
B parseAuthors() 0 25 7
1
<?php
2
3
namespace PWWEB\Artomator\Commands;
4
5
use Illuminate\Support\Str;
6
use InvalidArgumentException;
7
use Illuminate\Console\GeneratorCommand;
8
use Laracasts\Generators\Migrations\SchemaParser;
0 ignored issues
show
Bug introduced by
The type Laracasts\Generators\Migrations\SchemaParser was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use PWWEB\Artomator\Migrations\SyntaxBuilder;
10
use Symfony\Component\Console\Input\InputOption;
11
12
class ArtomatorControllerCommand extends GeneratorCommand
13
{
14
    /**
15
     * The console command name.
16
     *
17
     * @var string
18
     */
19
    protected $name = 'artomator:controller';
20
21
    /**
22
     * The console command description.
23
     *
24
     * @var string
25
     */
26
    protected $description = 'Create a new controller class';
27
28
    /**
29
     * The type of class being generated.
30
     *
31
     * @var string
32
     */
33
    protected $type = 'Controller';
34
35
    /**
36
     * The package of class being generated.
37
     *
38
     * @var string
39
     */
40
    protected $package = null;
41
42
    /**
43
     * Get the stub file for the generator.
44
     *
45
     * @return string
46
     */
47
    protected function getStub()
48
    {
49
        $stub = 'controller.model.stub';
50
        $path = base_path() . config('artomator.stubPath');
51
        $path = $path . $stub;
52
53
        if (file_exists($path)) {
54
            return $path;
55
        } else {
56
            return __DIR__ . '/Stubs/' . $stub;
57
        }
58
    }
59
60
    /**
61
     * Get the default namespace for the class.
62
     *
63
     * @param  string  $rootNamespace
64
     * @return string
65
     */
66
    protected function getDefaultNamespace($rootNamespace)
67
    {
68
        return $rootNamespace.'\Http\Controllers';
69
    }
70
71
    /**
72
     * Build the class with the given name.
73
     *
74
     * Remove the base controller import if we are already in base namespace.
75
     *
76
     * @param  string  $name
77
     * @return string
78
     */
79
    protected function buildClass($name)
80
    {
81
        $controllerNamespace = $this->getNamespace($name);
82
83
        $replace = [];
84
85
        // if ($this->option('parent')) {
86
        //     $replace = $this->buildParentReplacements();
87
        // }
88
        $replace = $this->buildSchemaReplacements($replace);
89
        $replace = $this->buildModelReplacements($replace);
90
91
        $replace["use {$controllerNamespace}\Controller;\n"] = '';
92
93
        return str_replace(
94
            array_keys($replace),
95
            array_values($replace),
96
            parent::buildClass($name)
97
        );
98
    }
99
100
    /**
101
     * Build the schema replacement values.
102
     *
103
     * @param array $replace
104
     * @return array
105
     */
106
107
    protected function buildSchemaReplacements(array $replace)
108
    {
109
        if ($schema = $this->option('schema')) {
110
            $schema = (new SchemaParser)->parse($schema);
111
        }
112
113
        $syntax = new SyntaxBuilder();
114
115
        return array_merge($replace, [
116
            '{{schema_data}}' => $syntax->createDataSchema($schema),
117
        ]);
118
    }
119
120
    /**
121
     * Build the replacements for a parent controller.
122
     *
123
     * @return array
124
     */
125
    // protected function buildParentReplacements()
126
    // {
127
    //     $parentModelClass = $this->parseModel($this->option('parent'));
128
    //
129
    //     if (! class_exists($parentModelClass)) {
130
    //         if ($this->confirm("A {$parentModelClass} model does not exist. Do you want to generate it?", true)) {
131
    //             $this->call('make:model', ['name' => $parentModelClass]);
132
    //         }
133
    //     }
134
    //
135
    //     return [
136
    //         'ParentDummyFullModelClass' => $parentModelClass,
137
    //         'ParentDummyModelClass' => class_basename($parentModelClass),
138
    //         'ParentDummyModelVariable' => lcfirst(class_basename($parentModelClass)),
139
    //     ];
140
    // }
141
142
    /**
143
     * Build the model replacement values.
144
     *
145
     * @param  array  $replace
146
     * @return array
147
     */
148
    protected function buildModelReplacements(array $replace)
149
    {
150
        $modelClass = $this->parseModel((string) $this->option('model'));
151
        $requestClass = $this->parseRequest((string) $this->option('model'));
152
153
        if (! class_exists($modelClass)) {
154
            if ($this->confirm("A {$modelClass} model does not exist. Do you want to generate it?", true)) {
155
                $this->call('make:model', ['name' => $modelClass]);
156
            }
157
        }
158
159
        return array_merge($replace, [
160
            'DummyFullModelClass' => $modelClass,
161
            'DummyRequestClass' => $requestClass,
162
            'DummyModelClass' => class_basename($modelClass),
163
            'DummyModelVariable' => lcfirst(class_basename($modelClass)),
164
            'DummyPackageVariable' => strtolower($this->package) . ".",
165
            'DummyPackagePlaceholder' => config('app.name'),
166
            'DummyCopyrightPlaceholder' => config('artomator.copyright'),
167
            'DummyLicensePlaceholder' => config('artomator.license'),
168
            'DummyAuthorPlaceholder' => $this->parseAuthors(config('artomator.authors')),
169
        ]);
170
    }
171
172
    /**
173
     * Get the formatted author(s) from the config file.
174
     *
175
     * @param  string[] $authors Authors array.
176
     *
177
     * @return string Formmated string of authors.
178
     */
179
    protected function parseAuthors($authors)
180
    {
181
        if (is_array($authors) === false and is_string($authors) === false) {
0 ignored issues
show
introduced by
The condition is_array($authors) === false is always false.
Loading history...
182
            throw new InvalidArgumentException('Authors must be an array of strings or a string.');
183
        }
184
185
        $formatted = '';
186
187
        if (is_array($authors) === true) {
188
            if (is_string($authors[0]) === false) {
189
                throw new InvalidArgumentException('The array of authors must be strings.');
190
            }
191
            $formatted .= array_shift($authors);
192
193
            foreach ($authors as $author) {
194
                if (is_string($author) === false) {
195
                    throw new InvalidArgumentException('The array of authors must be strings.');
196
                }
197
                $formatted .= "\n * @author    " . $author;
198
            }
199
        } else {
200
            $formatted .= $authors;
201
        }
202
203
        return $formatted;
204
    }
205
206
    /**
207
     * Get the fully-qualified model class name.
208
     *
209
     * @param  string  $model
210
     * @return string
211
     *
212
     * @throws \InvalidArgumentException
213
     */
214
    protected function parseModel($model)
215
    {
216
        if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) {
217
            throw new InvalidArgumentException('Model name contains invalid characters.');
218
        }
219
220
        $this->package = trim(str_replace('/', '.', substr($model, 0, strrpos($model, '/')))) ?? null;
221
222
        $model = trim(str_replace('/', '\\', $model), '\\');
223
224
        if (! Str::startsWith($model, $rootNamespace = $this->laravel->getNamespace())) {
225
            $model = $rootNamespace.'Models\\'.$model;
226
        }
227
228
        return $model;
229
    }
230
231
    /**
232
     * Get the fully-qualified request class name.
233
     *
234
     * @param  string  $model
235
     * @return string
236
     *
237
     * @throws \InvalidArgumentException
238
     */
239
    protected function parseRequest($model)
240
    {
241
        if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) {
242
            throw new InvalidArgumentException('Model name contains invalid characters.');
243
        }
244
245
        $this->package = trim(str_replace('/', '.', substr($model, 0, strrpos($model, '/')))) ?? null;
246
247
        $model = trim(str_replace('/', '\\', $model), '\\');
248
249
        if (! Str::startsWith($model, $rootNamespace = $this->laravel->getNamespace())) {
250
            $model = $rootNamespace.'Http\\Requests\\'.$model;
251
        }
252
253
        return $model;
254
    }
255
256
    /**
257
     * Get the console command options.
258
     *
259
     * @return array
260
     */
261
    protected function getOptions()
262
    {
263
        return [
264
            ['model', 'm', InputOption::VALUE_REQUIRED, 'Generate a resource controller for the given model.'],
265
            ['resource', 'r', InputOption::VALUE_NONE, 'Generate a resource controller class.'],
266
            ['invokable', 'i', InputOption::VALUE_NONE, 'Generate a single method, invokable controller class.'],
267
            ['parent', 'p', InputOption::VALUE_OPTIONAL, 'Generate a nested resource controller class.'],
268
            ['api', null, InputOption::VALUE_NONE, 'Exclude the create and edit methods from the controller.'],
269
            ['schema', 's', InputOption::VALUE_OPTIONAL, 'Optional schema to be attached to the migration', null],
270
        ];
271
    }
272
}
273