InputHandler::dispatchRouter()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 17
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Cli\Server;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override 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...
17
use Throwable;
18
use Valkyrja\Cli\Interaction\Config as InteractionConfig;
19
use Valkyrja\Cli\Interaction\Enum\ExitCode;
20
use Valkyrja\Cli\Interaction\Input\Contract\Input;
21
use Valkyrja\Cli\Interaction\Message\Banner;
22
use Valkyrja\Cli\Interaction\Message\ErrorMessage;
23
use Valkyrja\Cli\Interaction\Message\Message;
24
use Valkyrja\Cli\Interaction\Message\NewLine;
25
use Valkyrja\Cli\Interaction\Output\Contract\Output;
26
use Valkyrja\Cli\Middleware;
27
use Valkyrja\Cli\Middleware\Handler\Contract\ExitedHandler;
28
use Valkyrja\Cli\Middleware\Handler\Contract\InputReceivedHandler;
29
use Valkyrja\Cli\Middleware\Handler\Contract\ThrowableCaughtHandler;
30
use Valkyrja\Cli\Routing\Command\VersionCommand;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Cli\Routing\Command\VersionCommand 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...
31
use Valkyrja\Cli\Routing\Contract\Router;
32
use Valkyrja\Cli\Routing\Data\Option\NoInteractionOptionParameter;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Cli\Routing\Dat...eractionOptionParameter 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...
33
use Valkyrja\Cli\Routing\Data\Option\QuietOptionParameter;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Cli\Routing\Dat...on\QuietOptionParameter 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...
34
use Valkyrja\Cli\Routing\Data\Option\SilentOptionParameter;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Cli\Routing\Dat...n\SilentOptionParameter 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...
35
use Valkyrja\Cli\Routing\Data\Option\VersionOptionParameter;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Cli\Routing\Dat...\VersionOptionParameter 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...
36
use Valkyrja\Cli\Server\Contract\InputHandler as Contract;
37
use Valkyrja\Container\Contract\Container;
38
use Valkyrja\Support\Exiter;
39
40
/**
41
 * Class InputHandler.
42
 *
43
 * @author Melech Mizrachi
44
 */
45
class InputHandler implements Contract
46
{
47
    /**
48
     * RequestHandler constructor.
49
     */
50
    public function __construct(
51
        protected Container $container = new \Valkyrja\Container\Container(),
52
        protected Router $router = new \Valkyrja\Cli\Routing\Router(),
53
        protected InputReceivedHandler $inputReceivedHandler = new Middleware\Handler\InputReceivedHandler(),
54
        protected ThrowableCaughtHandler $throwableCaughtHandler = new Middleware\Handler\ThrowableCaughtHandler(),
55
        protected ExitedHandler $exitedHandler = new Middleware\Handler\ExitedHandler(),
56
        protected InteractionConfig $interactionConfig = new InteractionConfig(),
57
    ) {
58
    }
59
60
    /**
61
     * Handle the input.
62
     *
63
     * @param Input $input The input
64
     *
65
     * @return Output
66
     */
67
    #[Override]
68
    public function handle(Input $input): Output
69
    {
70
        try {
71
            $this->setInteractivity($input);
72
73
            if (
74
                $input->hasOption(VersionOptionParameter::SHORT_NAME)
75
                || $input->hasOption(VersionOptionParameter::NAME)
76
            ) {
77
                $input = $input->withCommandName(VersionCommand::NAME);
78
            }
79
80
            $output = $this->dispatchRouter($input);
81
        } catch (Throwable $throwable) {
82
            $output = $this->getOutputFromThrowable($input, $throwable);
83
            $output = $this->throwableCaughtHandler->throwableCaught($input, $output, $throwable);
84
        }
85
86
        // Set the returned output in the container
87
        $this->container->setSingleton(Output::class, $output);
88
89
        return $output;
90
    }
91
92
    /**
93
     * Handle exiting the handler.
94
     *
95
     * @param Input  $input  The input
96
     * @param Output $output The output
97
     *
98
     * @return void
99
     */
100
    #[Override]
101
    public function exit(Input $input, Output $output): void
102
    {
103
        // Dispatch the exited middleware
104
        $this->exitedHandler->exited($input, $output);
105
    }
106
107
    /**
108
     * Run the handler.
109
     *
110
     * @param Input $input
111
     *
112
     * @return void
113
     */
114
    #[Override]
115
    public function run(Input $input): void
116
    {
117
        $output = $this->handle($input);
118
119
        $output->writeMessages();
120
121
        $this->exit($input, $output);
122
123
        $exitCode = $output->getExitCode();
124
125
        if ($exitCode instanceof ExitCode) {
126
            $exitCode = $exitCode->value;
127
        }
128
129
        Exiter::exit($exitCode);
130
    }
131
132
    /**
133
     * Set the interactivity.
134
     *
135
     * @param Input $input The input
136
     *
137
     * @return void
138
     */
139
    protected function setInteractivity(Input $input): void
140
    {
141
        if (
142
            $input->hasOption(NoInteractionOptionParameter::SHORT_NAME)
143
            || $input->hasOption(NoInteractionOptionParameter::NAME)
144
        ) {
145
            $this->interactionConfig->isInteractive = false;
146
        }
147
148
        if (
149
            $input->hasOption(QuietOptionParameter::SHORT_NAME)
150
            || $input->hasOption(QuietOptionParameter::NAME)
151
        ) {
152
            $this->interactionConfig->isQuiet = true;
153
        }
154
155
        if (
156
            $input->hasOption(SilentOptionParameter::SHORT_NAME)
157
            || $input->hasOption(SilentOptionParameter::NAME)
158
        ) {
159
            $this->interactionConfig->isSilent = true;
160
        }
161
    }
162
163
    /**
164
     * Dispatch the input via the router.
165
     *
166
     * @param Input $input The input
167
     *
168
     * @return Output
169
     */
170
    protected function dispatchRouter(Input $input): Output
171
    {
172
        // Set the request object in the container
173
        $this->container->setSingleton(Input::class, $input);
174
175
        // Dispatch the before input received middleware
176
        $inputAfterMiddleware = $this->inputReceivedHandler->inputReceived($input);
177
178
        // If the return value after middleware is a response return it
179
        if ($inputAfterMiddleware instanceof Output) {
180
            return $inputAfterMiddleware;
181
        }
182
183
        // Set the returned request in the container
184
        $this->container->setSingleton(Input::class, $inputAfterMiddleware);
185
186
        return $this->router->dispatch($inputAfterMiddleware);
187
    }
188
189
    /**
190
     * Get an output from a throwable.
191
     *
192
     * @param Input     $input     The input
193
     * @param Throwable $throwable The throwable
194
     *
195
     * @return Output
196
     */
197
    protected function getOutputFromThrowable(Input $input, Throwable $throwable): Output
198
    {
199
        $commandName = $input->getCommandName();
200
201
        return (new \Valkyrja\Cli\Interaction\Output\Output(
202
            exitCode: ExitCode::ERROR
203
        ))
204
            ->withMessages(
205
                new Banner(new ErrorMessage('Cli Server Error:')),
206
                new NewLine(),
207
                new ErrorMessage('Command:'),
208
                new Message(" $commandName"),
209
                new NewLine(),
210
                new NewLine(),
211
                new ErrorMessage('Message:'),
212
                new Message(' ' . $throwable->getMessage()),
213
                new NewLine(),
214
                new NewLine(),
215
                new ErrorMessage('Line:'),
216
                new Message(' ' . ((string) $throwable->getLine())),
217
                new NewLine(),
218
                new NewLine(),
219
                new ErrorMessage('Trace:'),
220
                new NewLine(),
221
                new Message($throwable->getTraceAsString() . "\n"),
222
            );
223
    }
224
}
225