CommandController   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 98.33%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 11
dl 0
loc 173
ccs 59
cts 60
cp 0.9833
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 10 1
A execute() 0 28 2
B flatten() 0 29 6
A resolve() 0 12 2
B rules() 0 22 8
1
<?php
2
3
namespace Bmatovu\ArtisanGui\Http;
4
5
use Bmatovu\ArtisanGui\Support\Commander;
6
use Illuminate\Contracts\Console\Kernel;
7
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
8
use Illuminate\Http\Request;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Output\BufferedOutput;
11
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
12
13
class CommandController
14
{
15
    /**
16
     * The console kernel.
17
     *
18
     * @var \Illuminate\Contracts\Console\Kernel
19
     */
20
    protected $kernel;
21
22
    /**
23
     * The validation factory implementation.
24
     *
25
     * @var \Illuminate\Contracts\Validation\Factory
26
     */
27
    protected $validationFactory;
28
29
    /**
30
     * Create a new controller instance.
31
     *
32
     * @param \Illuminate\Contracts\Console\Kernel     $kernel
33
     * @param \Illuminate\Contracts\Validation\Factory $validationFactory
34
     *
35
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
36
     */
37 5
    public function __construct(Kernel $kernel, ValidationFactory $validationFactory)
38
    {
39 5
        $this->kernel = $kernel;
40 5
        $this->validationFactory = $validationFactory;
41 5
    }
42
43
    /**
44
     * Get artisan commands.
45
     *
46
     * @return \Illuminate\Http\Response
47
     */
48 1
    public function __invoke()
49
    {
50 1
        $commander = new Commander($this->kernel);
51
52 1
        return response([
0 ignored issues
show
Bug Compatibility introduced by
The expression response(array('namespac...ander->getCommands())); of type Illuminate\Http\Response...Routing\ResponseFactory adds the type Illuminate\Contracts\Routing\ResponseFactory to the return on line 52 which is incompatible with the return type documented by Bmatovu\ArtisanGui\Http\...andController::__invoke of type Illuminate\Http\Response.
Loading history...
53 1
            'namespaces' => $commander->getNamespaces(),
54 1
            'definition' => $commander->getDefinition(),
55 1
            'commands' => $commander->getCommands(),
56
        ]);
57
    }
58
59
    /**
60
     * Execute artisan command.
61
     *
62
     * @param \Illuminate\Http\Request $request
63
     *
64
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
65
     *
66
     * @return \Illuminate\Http\Response
67
     */
68 4
    public function execute(Request $request)
69
    {
70 4
        $command = $this->resolve($request->command);
71
72 3
        $validated = $this->validationFactory->make($request->all(), $this->rules($command))->validate();
73
74 2
        $parameters = array_merge($validated, config('artisan-gui.options'));
75
76 2
        $outputBuffer = new BufferedOutput();
77
78
        try {
79 2
            $exitCode = $this->kernel->call($command->getName(), $parameters, $outputBuffer);
80
            // $output = $this->kernel->output();
81 1
            $output = $outputBuffer->fetch();
82 1
        } catch (\Exception $exception) {
83 1
            return response([
0 ignored issues
show
Bug Compatibility introduced by
The expression response(array('code' =>...n->getMessage()), 500); of type Illuminate\Http\Response...Routing\ResponseFactory adds the type Illuminate\Contracts\Routing\ResponseFactory to the return on line 83 which is incompatible with the return type documented by Bmatovu\ArtisanGui\Http\CommandController::execute of type Illuminate\Http\Response.
Loading history...
84 1
                'code' => $exception->getCode() ?? '',
85 1
                'message' => $exception->getMessage(),
86 1
            ], 500);
87
        }
88
89 1
        return response([
0 ignored issues
show
Bug Compatibility introduced by
The expression response(array('command'... 'output' => $output)); of type Illuminate\Http\Response...Routing\ResponseFactory adds the type Illuminate\Contracts\Routing\ResponseFactory to the return on line 89 which is incompatible with the return type documented by Bmatovu\ArtisanGui\Http\CommandController::execute of type Illuminate\Http\Response.
Loading history...
90 1
            'command' => $command->getName(),
91 1
            'parameters' => $this->flatten($parameters),
92 1
            'exit-code' => $exitCode,
93 1
            'output' => $output,
94
        ]);
95
    }
96
97
    /**
98
     * Flatten command parameters.
99
     *
100
     * @param array $parameters
101
     *
102
     * @return string
103
     */
104 1
    protected function flatten(array $parameters)
105
    {
106 1
        $cli_params = '';
107
108 1
        foreach ($parameters as $name => $value) {
109 1
            if (empty($value)) {
110
                continue;
111
            }
112
113 1
            if (strpos($name, '--') === 0) {
114 1
                if (is_bool($value)) {
115 1
                    $cli_params .= " {$name}";
116
117 1
                    continue;
118
                }
119
            }
120
121 1
            if (is_array($value)) {
122 1
                $items = implode(',', $value);
123 1
                $cli_params .= " {$name}=\"{$items}\"";
124
125 1
                continue;
126
            }
127
128 1
            $cli_params .= " {$name}=\"{$value}\"";
129
        }
130
131 1
        return $cli_params;
132
    }
133
134
    /**
135
     * Resolve command from kernel.
136
     *
137
     * @param string $name Command name
138
     *
139
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
140
     *
141
     * @return \Symfony\Component\Console\Command\Command
142
     */
143 4
    protected function resolve($name): Command
144
    {
145 4
        $commands = $this->kernel->all();
146
147 4
        $command = $commands[$name] ?? null;
148
149 4
        if (! $command) {
150 1
            throw new NotFoundHttpException('Unknown command.');
151
        }
152
153 3
        return $command;
154
    }
155
156
    /**
157
     * Build command validation rules.
158
     *
159
     * @param \Symfony\Component\Console\Command\Command $command
160
     *
161
     * @return array
162
     */
163 3
    protected function rules(Command $command): array
164
    {
165 3
        $rules = [];
166
167 3
        foreach ($command->getDefinition()->getArguments() as $argument) {
168 3
            $rules[$argument->getName()] = array_filter([
169 3
                $argument->isRequired() ? 'required' : 'nullable',
170 3
                $argument->isArray() ? 'array' : '',
171
            ]);
172
        }
173
174 3
        foreach ($command->getDefinition()->getOptions() as $option) {
175 3
            $name = $option->getName();
176
177 3
            $rules["--{$name}"] = array_filter([
178 3
                $option->isValueRequired() ? 'required' : 'nullable',
179 3
                $option->isArray() ? 'array' : ($option->acceptValue() ? 'string' : 'bool'),
180
            ]);
181
        }
182
183 3
        return $rules;
184
    }
185
}
186