Issues (115)

src/Commands/MakeAllCommand.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace VGirol\JsonApi\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputOption;
10
11
class MakeAllCommand extends Command
12
{
13
    use FixResolveCommand;
14
15
    /**
16
     * The name of the console command.
17
     *
18
     * @var string
19
     */
20
    protected $name = 'make:jsonapi:all';
21
22
    /**
23
     * The console command description.
24
     *
25
     * @var string
26
     */
27
    protected $description =
28
    'Creates all the files associated to a JsonApi model (model, form request, resource, controller) ' .
29
    'and updates routes and configuration.';
30
31
    /**
32
     * Undocumented variable
33
     *
34
     * @var array
35
     */
36
    protected $data = [];
37
38
    /**
39
     * Undocumented variable
40
     *
41
     * @var array
42
     */
43
    private $usedCommands = [];
44
45
    /**
46
     * Create a new console command instance.
47
     *
48
     * @return void
49
     */
50
    public function __construct()
51
    {
52
        $this->registerCommands([
53
            'model' => MakeModelCommand::class,
54
            'request' => MakeRequestCommand::class,
55
            'resources' => MakeResourcesCommand::class,
56
            'controller' => MakeControllerCommand::class,
57
            'alias' => AliasCommand::class,
58
            'routes' => RouteCommand::class
59
        ]);
60
61
        parent::__construct();
62
    }
63
64
    /**
65
     * Get the console command arguments.
66
     *
67
     * @return array
68
     */
69
    protected function getArguments()
70
    {
71
        return $this->collectArguments(
72
            [
73
                ['name', InputArgument::REQUIRED, 'The base name of all generated classes (without namespace)']
74
            ]
75
        );
76
    }
77
78
    /**
79
     * Get the console command options.
80
     *
81
     * @return array
82
     */
83
    public function getOptions()
84
    {
85
        return $this->collectOptions(
86
            [
87
                ['jsonapi-request', null, InputOption::VALUE_NONE, 'Generate a form request class for JSON:API'],
88
                ['jsonapi-controller', null, InputOption::VALUE_NONE, 'Generate a controller class for JSON:API'],
89
                ['jsonapi-resources', null, InputOption::VALUE_NONE, 'Generate a resource class for JSON:API'],
90
            ],
91
            [
92
                'api-model',
93
                'api-request',
94
                'api-controller',
95
                'api-resource-ro',
96
                'api-resource-roc',
97
                'api-resource-ri',
98
                'api-resource-ric',
99
                'controller'
100
            ]
101
        );
102
    }
103
104
    /**
105
     * Execute the console command.
106
     *
107
     * @return mixed
108
     */
109
    public function handle()
110
    {
111
        foreach ($this->usedCommands as $type => $commandName) {
112
            $method = 'call' . ucfirst(strtolower($type));
113
114
            if (!method_exists($this, $method)) {
115
                $method = 'callDefault';
116
            }
117
118
            call_user_func_array(
119
                [$this, $method],
120
                [ $commandName, $type]
121
            );
122
        }
123
    }
124
125
    /**
126
     * Undocumented function
127
     *
128
     * @param string $commandName
129
     * @param string $commandType
130
     *
131
     * @return void
132
     */
133
    protected function callDefault(string $commandName, string $commandType)
134
    {
135
        if ($this->hasOption("jsonapi-{$commandType}") && ($this->option("jsonapi-{$commandType}") === false)) {
136
            return;
137
        }
138
139
        $this->executeCommand(
140
            $commandName,
141
            $this->extractParametersForCommand(
142
                $commandName,
143
                function ($value, $key) use ($commandType) {
144
                    if ($key === 'name') {
145
                        switch ($commandType) {
146
                            case 'request':
147
                                $value .= 'FormRequest';
148
                                break;
149
                            case 'controller':
150
                                $value .= 'Controller';
151
                                break;
152
                        }
153
                    }
154
155
                    return $value;
156
                }
157
            )
158
        );
159
    }
160
161
    /**
162
     * Undocumented function
163
     *
164
     * @param string $commandName
165
     *
166
     * @return void
167
     */
168
    protected function callAlias(string $commandName)
169
    {
170
        $parameters = $this->extractParametersForCommand($commandName);
171
        if (array_key_exists('model', $this->data)) {
172
            $parameters->put('--api-model', $this->data['model']);
173
        }
174
        if (array_key_exists('request', $this->data)) {
175
            $parameters->put('--api-request', $this->data['request']);
176
        }
177
        if (array_key_exists('controller', $this->data)) {
178
            $parameters->put('--api-controller', $this->data['controller']);
179
        }
180
        foreach (['ro', 'ri', 'roc', 'ric'] as $resType) {
181
            if (array_key_exists("resource-{$resType}", $this->data)) {
182
                $parameters->put("--api-resource-{$resType}", $this->data["resource-{$resType}"]);
183
            }
184
        }
185
186
        $this->executeCommand($commandName, $parameters);
187
    }
188
189
    /**
190
     * Undocumented function
191
     *
192
     * @param string $commandName
193
     *
194
     * @return void
195
     */
196
    protected function callRoutes(string $commandName)
197
    {
198
        $parameters = $this->extractParametersForCommand($commandName);
199
        if (array_key_exists('controller', $this->data)) {
200
            $parameters->put(
201
                '--controller',
202
                str_replace('\\', '\\\\', str_replace('App\\Http\\Controllers\\', '', $this->data['controller']))
203
            );
204
        }
205
206
        $this->executeCommand($commandName, $parameters);
207
    }
208
209
    /**
210
     * Undocumented function
211
     *
212
     * @param array $commands
213
     *
214
     * @return $this
215
     */
216
    protected function registerCommands(array $commands)
217
    {
218
        $this->usedCommands = \array_merge($this->usedCommands, $commands);
219
220
        return $this;
221
    }
222
223
    /**
224
     * Undocumented function
225
     *
226
     * @param array $prepend
227
     * @param array $excluded
228
     *
229
     * @return array
230
     */
231
    protected function collectArguments(array $prepend, array $excluded = []): array
232
    {
233
        return $this->collectParameters('argument', $prepend, $excluded);
234
    }
235
236
    /**
237
     * Undocumented function
238
     *
239
     * @param array $prepend
240
     * @param array $excluded
241
     *
242
     * @return array
243
     */
244
    protected function collectOptions(array $prepend, array $excluded = []): array
245
    {
246
        return $this->collectParameters('option', $prepend, $excluded);
247
    }
248
249
    /**
250
     * Undocumented function
251
     *
252
     * @param string     $commandName
253
     * @param Collection $parameters
254
     *
255
     * @return void
256
     */
257
    protected function executeCommand(string $commandName, $parameters)
258
    {
259
        $command = $this->resolveCommand($commandName);
260
        $this->call($command, $parameters->toArray());
261
262
        $this->data = \array_merge(
263
            \call_user_func([$command, 'collectResults']),
264
            $this->data
265
        );
266
    }
267
268
    /**
269
     * Undocumented function
270
     *
271
     * @param string $type
272
     * @param array  $prependParameters
273
     * @param array  $excludedParameters
274
     *
275
     * @return array
276
     */
277
    private function collectParameters(
278
        string $type,
279
        array $prependParameters,
280
        array $excludedParameters = []
281
    ): array {
282
        $methodName = 'get' . ucfirst($type) . 's';
283
        $createName = 'createInput' . ucfirst($type);
284
285
        return collect($prependParameters)
286
            ->map(
287
                /**
288
                 * @param array $item
289
                 */
290
                function ($item) use ($createName) {
291
                    return call_user_func_array([$this, $createName], $item);
292
                }
293
            )
294
            ->merge(
295
                collect($this->usedCommands)
296
                    ->filter()
297
                    ->values()
298
                    ->flatMap(
299
                        /**
300
                         * @param string $commandName
301
                         */
302
                        function ($commandName) use ($methodName) {
303
                            return $this->getCommandParameters($commandName, $methodName);
304
                        }
305
                    )
306
            )->unique(
307
                /**
308
                 * @param InputArgument|InputOption $item
309
                 */
310
                function ($item) {
311
                    return $item->getName();
312
                }
313
            )->filter(
314
                /**
315
                 * @param InputArgument|InputOption $item
316
                 */
317
                function ($item) use ($excludedParameters) {
318
                    return !\in_array($item->getName(), $excludedParameters);
319
                }
320
            )->values()
321
            ->toArray();
322
    }
323
324
    /**
325
     * Undocumented function
326
     *
327
     * @param string $commandName
328
     * @param string $methodName
329
     *
330
     * @return array
331
     */
332
    private function getCommandParameters(string $commandName, string $methodName): array
333
    {
334
        return call_user_func([resolve($commandName)->getDefinition(), $methodName]);
0 ignored issues
show
The method getDefinition() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

334
        return call_user_func([resolve($commandName)->/** @scrutinizer ignore-call */ getDefinition(), $methodName]);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
335
    }
336
337
    /**
338
     * Undocumented function
339
     *
340
     * @param string  $name
341
     * @param integer $mode
342
     * @param string  $description
343
     * @param mixed   $default
344
     *
345
     * @return InputArgument
346
     */
347
    private function createInputArgument(string $name, int $mode = null, string $description = '', $default = null)
348
    {
349
        return new InputArgument($name, $mode, $description, $default);
350
    }
351
352
    /**
353
     * Undocumented function
354
     *
355
     * @param string  $name
356
     * @param string  $shortcut
357
     * @param integer $mode
358
     * @param string  $description
359
     * @param mixed   $default
360
     *
361
     * @return InputOption
362
     */
363
    private function createInputOption(string $name, string $shortcut = null, int $mode = null, string $description = '', $default = null)
364
    {
365
        return new InputOption($name, $shortcut, $mode, $description, $default);
366
    }
367
368
    /**
369
     * Undocumented function
370
     *
371
     * @param string $commandName
372
     *
373
     * @return Collection
374
     */
375
    private function extractParametersForCommand(string $commandName, callable $callback = null): Collection
376
    {
377
        $parameters = $this->extractArguments($this->getCommandParameters($commandName, 'getArguments'))
378
            ->merge($this->extractOptions($this->getCommandParameters($commandName, 'getOptions')));
379
380
        return ($callback === null) ? $parameters : $parameters->map($callback);
381
    }
382
383
    /**
384
     * Undocumented function
385
     *
386
     * @param array $allowed
387
     *
388
     * @return Collection
389
     */
390
    private function extractArguments(array $allowed): Collection
391
    {
392
        return collect($this->arguments())
393
            ->filter(function ($value, $key) use ($allowed) {
394
                return in_array(
395
                    $key,
396
                    collect($allowed)->map(
397
                        function ($obj) {
398
                            return $obj->getName();
399
                        }
400
                    )->toArray()
401
                );
402
            })
403
            ->map(
404
                function ($value, $key) {
405
                    if ($key === 'name') {
406
                        $namespaces = [
407
                            $this->laravel->getNamespace(),
408
                            config()->get('jsonapi.modelNamespace', null) . '\\'
409
                        ];
410
                        foreach ($namespaces as $namespace) {
411
                            if (Str::startsWith($value, $namespace)) {
412
                                $value = Str::replaceFirst($namespace, '', $value);
413
                            }
414
                        }
415
                    }
416
417
                    return $value;
418
                }
419
            );
420
    }
421
422
    /**
423
     * Undocumented function
424
     *
425
     * @param array $allowed
426
     *
427
     * @return Collection
428
     */
429
    private function extractOptions(array $allowed = null): Collection
430
    {
431
        return collect($this->options())
432
            ->filter(function ($value, $key) use ($allowed) {
433
                return in_array(
434
                    $key,
435
                    collect($allowed)->map(
436
                        function ($obj) {
437
                            return $obj->getName();
438
                        }
439
                    )->toArray()
440
                );
441
            })
442
            ->mapWithKeys(function ($item, $key) {
443
                return ["--{$key}" => $item];
444
            });
445
    }
446
}
447