Passed
Pull Request — master (#15)
by Richard
06:30
created

ArtomatorCommand::createRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace PWWEB\Artomator\Commands;
4
5
use Illuminate\Support\Str;
6
use InvalidArgumentException;
7
use Illuminate\Console\Command;
8
use Symfony\Component\Console\Input\InputOption;
9
10
class ArtomatorCommand extends Command
11
{
12
    /**
13
     * The console command name.
14
     *
15
     * @var string
16
     */
17
    protected $name = 'artomator';
18
19
    /**
20
     * The console command description.
21
     *
22
     * @var string
23
     */
24
    protected $description = 'Create a new Eloquent model, factory, migration, controller and resource class';
25
26
    /**
27
     * The array of standard included generators.
28
     *
29
     * @var string[]
30
     */
31
    protected $includes = [
32
        'model',
33
        'controller',
34
        'request',
35
        'query',
36
        'type',
37
        'migration',
38
        'seeder',
39
        'factory',
40
    ];
41
42
    /**
43
     * The schema variable.
44
     *
45
     * @var string
46
     */
47
    protected $schema;
48
49
    /**
50
     * Execute the console command.
51
     *
52
     * @return boolean
53
     */
54
    public function handle()
55
    {
56
        $this->info('
57
                         _/                                            _/
58
    _/_/_/  _/  _/_/  _/_/_/_/    _/_/    _/_/_/  _/_/      _/_/_/  _/_/_/_/    _/_/    _/  _/_/
59
 _/    _/  _/_/        _/      _/    _/  _/    _/    _/  _/    _/    _/      _/    _/  _/_/
60
_/    _/  _/          _/      _/    _/  _/    _/    _/  _/    _/    _/      _/    _/  _/
61
 _/_/_/  _/            _/_/    _/_/    _/    _/    _/    _/_/_/      _/_/    _/_/    _/
62
63
______________________________________________________________________________________________/');
64
        $this->name = $this->ask('What is the name of the model you want to build?
65
 Use the form: Primary/Secondary/Tertiary/Name');
66
        $this->name = $this->normaliseName($this->name);
67
68
        $this->parseExcludes();
69
70
        $this->schema = $this->option('schema');
71
72
        if ($this->option('table') !== null) {
73
            $this->schema = $this->insepctTable((string) $this->option('table'));
74
        }
75
76
        if (in_array('model', $this->includes) === true) {
77
            $this->createModel();
78
        }
79
80
        if (in_array('factory', $this->includes) === true) {
81
            $this->createFactory();
82
        }
83
84
        if (in_array('seeder', $this->includes) === true) {
85
            $this->createSeeder();
86
        }
87
88
        if (in_array('migration', $this->includes) === true) {
89
            $this->createMigration();
90
        }
91
92
        if (in_array('controller', $this->includes) === true) {
93
            $this->createController();
94
        }
95
96
        if (in_array('request', $this->includes) === true) {
97
            $this->createRequest();
98
        }
99
100
        if (in_array('query', $this->includes) === true) {
101
            $this->createQuery();
102
        }
103
104
        if (in_array('type', $this->includes) === true) {
105
            $this->createType();
106
        }
107
        return true;
108
    }
109
110
    /**
111
     * Normalise the name input to capitalise each.
112
     *
113
     * @param  string $name Input given by user.
114
     *
115
     * @return string Normalised name input.
116
     */
117
    protected function normaliseName($name)
118
    {
119
        $name = explode('/', $name);
120
        foreach ($name as &$part) {
121
            $part = ucfirst($part);
122
        }
123
        
124
        $name = implode('/', $name);
125
        return $name;
126
    }
127
128
    /**
129
     * Inspect table with the database for schema.
130
     *
131
     * @param string $table The name of the table to insepct.
132
     *
133
     * @return string
134
     */
135
    protected function insepctTable($table)
136
    {
137
        if (\Schema::hasTable($table) !== true) {
138
            return '';
139
        }
140
        $results = [];
141
        $columns = \DB::connection()->select(\DB::raw('describe ' . $table));
142
        foreach ($columns as $column) {
143
            if ($column->Key === 'PRI') {
144
                // $primary = [
145
                //     'type' => $column->Type,
146
                //     'name' => $column->Field,
147
                // ];
148
                continue;
149
            }
150
            $results[] = [
151
                'type' => $column->Type,
152
                'name' => $column->Field,
153
                'key' => $column->Key === 'UNI' ? 'unique' : '',
154
            ];
155
        }
156
157
        $results = array_map(
158
            function($field) {
159
                return $this->addArg($field);
160
            },
161
            $results
162
        );
163
164
        $results = implode(",", $results);
165
166
        return $results;
167
    }
168
169
    /**
170
     * Format the schema for passing to subsequent generators.
171
     *
172
     * @param array $field The field definition.
173
     *
174
     * @return string
175
     */
176
    private function addArg($field)
177
    {
178
        if ($field['key'] !== '') {
179
            $format = "%s:%s:%s";
180
        } else {
181
            $format = "%s:%s";
182
        }
183
        $syntax = sprintf($format, $field['name'], $this->normaliseType($field['type']), $field['key']);
184
        return $syntax;
185
    }
186
187
    /**
188
     * Normalise the type from the inspection to remove the additional information.
189
     *
190
     * @param string $type The field type definition.
191
     *
192
     * @return string
193
     */
194
    private function normaliseType($type)
195
    {
196
        $type = preg_replace("/(\\(.*\\))/is", '', $type);
197
        switch ($type) {
198
            case 'int':
199
            case 'int unsigned':
200
                $type = 'integer';
201
                break;
202
            case 'tinyint':
203
            case 'bool':
204
            case 'boolean':
205
                $type = 'boolean';
206
                break;
207
            case 'varchar':
208
            case 'string':
209
            default:
210
                $type = 'string';
211
                break;
212
        }
213
214
        return $type;
215
    }
216
217
    /**
218
     * Parse the includes and excludes arguments.
219
     *
220
     * @return string[]
221
     */
222
    protected function parseExcludes()
223
    {
224
        if ($this->option('exclude') !== null) {
225
            $exclusions = explode(',', $this->option('exclude'));
0 ignored issues
show
Bug introduced by
It seems like $this->option('exclude') can also be of type string[]; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

225
            $exclusions = explode(',', /** @scrutinizer ignore-type */ $this->option('exclude'));
Loading history...
226
227
            foreach ($exclusions as $exclusion) {
228
                unset($this->includes[array_search(trim($exclusion), $this->includes)]);
229
            }
230
        }
231
    }
232
233
    /**
234
     * Create a model factory for the model.
235
     *
236
     * @return void
237
     */
238
    protected function createFactory()
239
    {
240
        $this->info('Creating Factory');
241
        $factory = $this->name;
242
243
        $this->call(
244
            'make:factory',
245
            [
246
            'name' => "{$factory}Factory",
247
            '--model' => "Models/" . $this->name,
248
            ]
249
        );
250
    }
251
252
    /**
253
     * Create a model.
254
     *
255
     * @return void
256
     */
257
    protected function createModel()
258
    {
259
        $this->info('Creating Model');
260
        $model = $this->name;
261
262
        $this->call(
263
            'artomator:model',
264
            [
265
            'name' => "{$model}",
266
            '--schema' => $this->schema,
267
            ]
268
        );
269
    }
270
271
    /**
272
     * Create a model seeder for the model.
273
     *
274
     * @return void
275
     */
276
    protected function createSeeder()
277
    {
278
        $this->info('Creating Seeder');
279
        $seeder = str_replace('/', '', $this->name);
280
281
        $this->call(
282
            'make:seeder',
283
            [
284
            'name' => "{$seeder}TableSeeder",
285
            ]
286
        );
287
    }
288
289
    /**
290
     * Create a migration file for the model.
291
     *
292
     * @return void
293
     */
294
    protected function createMigration()
295
    {
296
        $this->info('Creating Migration');
297
        $table = Str::snake(Str::pluralStudly(str_replace('/', '', $this->name)));
298
299
        if ($this->schema !== '') {
300
            $this->call(
301
                'artomator:migration',
302
                [
303
                'name' => "create_{$table}_table",
304
                '--schema' => $this->schema,
305
                ]
306
            );
307
        } else {
308
            $this->call(
309
                'make:migration',
310
                [
311
                'name' => "create_{$table}_table",
312
                '--create' => $table,
313
                ]
314
            );
315
        }
316
    }
317
318
    /**
319
     * Create a controller for the model.
320
     *
321
     * @return void
322
     */
323
    protected function createController()
324
    {
325
        $this->info('Creating Controller');
326
        $controller = $this->name;
327
328
        $modelName = $this->name;
329
330
        $this->call(
331
            'artomator:controller',
332
            [
333
            'name' => "{$controller}Controller",
334
            '--model' => $modelName,
335
            '--schema' => $this->schema,
336
            ]
337
        );
338
    }
339
340
    /**
341
     * Create a request for the model.
342
     *
343
     * @return void
344
     */
345
    protected function createRequest()
346
    {
347
        $this->info('Creating Request');
348
349
        $this->call(
350
            'artomator:request',
351
            [
352
            'name' => $this->name,
353
            '--model' => $this->name,
354
            ]
355
        );
356
    }
357
358
    /**
359
     * Create a query for the model.
360
     *
361
     * @return void
362
     */
363
    protected function createQuery()
364
    {
365
        $this->info('Creating Query');
366
        $query = Str::pluralStudly((string) $this->name);
367
368
        $modelName = $this->name;
369
370
        $this->call(
371
            'artomator:query',
372
            [
373
            'name' => "{$query}",
374
            '--model' => $modelName,
375
            '--schema' => $this->schema,
376
            ]
377
        );
378
    }
379
380
    /**
381
     * Create a type for the model.
382
     *
383
     * @return void
384
     */
385
    protected function createType()
386
    {
387
        $this->info('Creating Type');
388
        $type = $this->name;
389
390
        $modelName = $this->name;
391
392
        $this->call(
393
            'artomator:type',
394
            [
395
            'name' => "{$type}",
396
            '--model' => $modelName,
397
            '--schema' => $this->schema,
398
            ]
399
        );
400
    }
401
402
    /**
403
     * Get the console command options.
404
     *
405
     * @return array
406
     */
407
    protected function getOptions()
408
    {
409
        return [
410
            ['schema', 's', InputOption::VALUE_OPTIONAL, 'Optional schema to be attached to the migration', null],
411
            ['exclude', 'e', InputOption::VALUE_OPTIONAL, 'Specify which "Genertors" to exclude'],
412
            ['table', 't', InputOption::VALUE_OPTIONAL, 'Specify which table to inspect'],
413
        ];
414
    }
415
}
416