Command::getDispatch()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\Routing\Data;
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 Valkyrja\Cli\Interaction\Message\Contract\Message;
18
use Valkyrja\Cli\Middleware\Contract\CommandDispatchedMiddleware;
19
use Valkyrja\Cli\Middleware\Contract\CommandMatchedMiddleware;
20
use Valkyrja\Cli\Middleware\Contract\ExitedMiddleware;
21
use Valkyrja\Cli\Middleware\Contract\ThrowableCaughtMiddleware;
22
use Valkyrja\Cli\Routing\Data\Contract\ArgumentParameter;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Valkyrja\Cli\Routing\Data\ArgumentParameter. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
23
use Valkyrja\Cli\Routing\Data\Contract\Command as Contract;
24
use Valkyrja\Cli\Routing\Data\Contract\OptionParameter;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Valkyrja\Cli\Routing\Data\OptionParameter. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
25
use Valkyrja\Cli\Routing\Data\Contract\Parameter;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Valkyrja\Cli\Routing\Data\Parameter. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
26
use Valkyrja\Dispatcher\Data\Contract\MethodDispatch;
27
use Valkyrja\Dispatcher\Data\MethodDispatch as DefaultDispatch;
28
29
/**
30
 * Class Command.
31
 *
32
 * @author Melech Mizrachi
33
 */
34
class Command implements Contract
35
{
36
    /** @var ArgumentParameter[] */
37
    protected array $arguments = [];
38
39
    /** @var OptionParameter[] */
40
    protected array $options = [];
41
42
    /**
43
     * @param non-empty-string                            $name                        The name
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
44
     * @param non-empty-string                            $description                 The description
45
     * @param Message                                     $helpText                    The help text
46
     * @param class-string<CommandMatchedMiddleware>[]    $commandMatchedMiddleware    The command matched middleware
47
     * @param class-string<CommandDispatchedMiddleware>[] $commandDispatchedMiddleware The command dispatched middleware
48
     * @param class-string<ThrowableCaughtMiddleware>[]   $throwableCaughtMiddleware   The throwable caught middleware
49
     * @param class-string<ExitedMiddleware>[]            $exitedMiddleware            The exited middleware
50
     * @param Parameter[]                                 $parameters                  The parameters
51
     */
52
    public function __construct(
53
        protected string $name,
54
        protected string $description,
55
        protected Message $helpText,
56
        protected MethodDispatch $dispatch = new DefaultDispatch(self::class, '__construct'),
57
        protected array $commandMatchedMiddleware = [],
58
        protected array $commandDispatchedMiddleware = [],
59
        protected array $throwableCaughtMiddleware = [],
60
        protected array $exitedMiddleware = [],
61
        array $parameters = [],
62
    ) {
63
        foreach ($parameters as $parameter) {
64
            if ($parameter instanceof ArgumentParameter) {
65
                $this->arguments[] = $parameter;
66
            } elseif ($parameter instanceof OptionParameter) {
67
                $this->options[] = $parameter;
68
            }
69
        }
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    #[Override]
76
    public function getName(): string
77
    {
78
        return $this->name;
79
    }
80
81
    /**
82
     * @inheritDoc
83
     */
84
    #[Override]
85
    public function withName(string $name): static
86
    {
87
        $new = clone $this;
88
89
        $new->name = $name;
90
91
        return $new;
92
    }
93
94
    /**
95
     * @inheritDoc
96
     */
97
    #[Override]
98
    public function getDescription(): string
99
    {
100
        return $this->description;
101
    }
102
103
    /**
104
     * @inheritDoc
105
     */
106
    #[Override]
107
    public function withDescription(string $description): static
108
    {
109
        $new = clone $this;
110
111
        $new->description = $description;
112
113
        return $new;
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119
    #[Override]
120
    public function getHelpText(): Message
121
    {
122
        return $this->helpText;
123
    }
124
125
    /**
126
     * @inheritDoc
127
     */
128
    #[Override]
129
    public function withHelpText(Message $helpText): static
130
    {
131
        $new = clone $this;
132
133
        $new->helpText = $helpText;
134
135
        return $new;
136
    }
137
138
    /**
139
     * @inheritDoc
140
     */
141
    #[Override]
142
    public function hasArguments(): bool
143
    {
144
        return $this->arguments !== [];
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150
    #[Override]
151
    public function getArguments(): array
152
    {
153
        return $this->arguments;
154
    }
155
156
    /**
157
     * @inheritDoc
158
     */
159
    #[Override]
160
    public function getArgument(string $name): ArgumentParameter|null
161
    {
162
        $arguments = array_filter($this->arguments, static fn (ArgumentParameter $argument) => $argument->getName() === $name);
163
164
        return reset($arguments) ?: null;
165
    }
166
167
    /**
168
     * @inheritDoc
169
     */
170
    #[Override]
171
    public function withArguments(ArgumentParameter ...$arguments): static
172
    {
173
        $new = clone $this;
174
175
        $new->arguments = $arguments;
176
177
        return $new;
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183
    #[Override]
184
    public function withAddedArguments(ArgumentParameter ...$arguments): static
185
    {
186
        $new = clone $this;
187
188
        $new->arguments = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array($this->arguments, $arguments) of type array<integer,array|arra...act\ArgumentParameter>> is incompatible with the declared type Valkyrja\Cli\Routing\Dat...act\ArgumentParameter[] of property $arguments.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
189
            ...$this->arguments,
190
            ...$arguments,
191
        ];
192
193
        return $new;
194
    }
195
196
    /**
197
     * @inheritDoc
198
     */
199
    #[Override]
200
    public function hasOptions(): bool
201
    {
202
        return $this->options !== [];
203
    }
204
205
    /**
206
     * @inheritDoc
207
     */
208
    #[Override]
209
    public function getOptions(): array
210
    {
211
        return $this->options;
212
    }
213
214
    /**
215
     * @inheritDoc
216
     */
217
    #[Override]
218
    public function getOption(string $name): OptionParameter|null
219
    {
220
        $options = array_filter($this->options, static fn (OptionParameter $option) => $option->getName() === $name);
221
222
        return reset($options) ?: null;
223
    }
224
225
    /**
226
     * @inheritDoc
227
     */
228
    #[Override]
229
    public function withOptions(OptionParameter ...$options): static
230
    {
231
        $new = clone $this;
232
233
        $new->options = $options;
234
235
        return $new;
236
    }
237
238
    /**
239
     * @inheritDoc
240
     */
241
    #[Override]
242
    public function withAddedOptions(OptionParameter ...$options): static
243
    {
244
        $new = clone $this;
245
246
        $new->options = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array($this->options, $options) of type array<integer,array|arra...tract\OptionParameter>> is incompatible with the declared type Valkyrja\Cli\Routing\Dat...tract\OptionParameter[] of property $options.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
247
            ...$this->options,
248
            ...$options,
249
        ];
250
251
        return $new;
252
    }
253
254
    /**
255
     * Get the command matched middleware.
256
     *
257
     * @return class-string<CommandMatchedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandMatchedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandMatchedMiddleware>[].
Loading history...
258
     */
259
    #[Override]
260
    public function getCommandMatchedMiddleware(): array
261
    {
262
        return $this->commandMatchedMiddleware;
263
    }
264
265
    /**
266
     * Create a new command with the specified command matched middleware.
267
     *
268
     * @param class-string<CommandMatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandMatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandMatchedMiddleware>.
Loading history...
269
     *
270
     * @return static
271
     */
272
    #[Override]
273
    public function withCommandMatchedMiddleware(string ...$middleware): static
274
    {
275
        $new = clone $this;
276
277
        $new->commandMatchedMiddleware = $middleware;
278
279
        return $new;
280
    }
281
282
    /**
283
     * Create a new command with added command matched middleware.
284
     *
285
     * @param class-string<CommandMatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandMatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandMatchedMiddleware>.
Loading history...
286
     *
287
     * @return static
288
     */
289
    #[Override]
290
    public function withAddedCommandMatchedMiddleware(string ...$middleware): static
291
    {
292
        $new = clone $this;
293
294
        $new->commandMatchedMiddleware = array_merge($this->commandMatchedMiddleware, $middleware);
295
296
        return $new;
297
    }
298
299
    /**
300
     * Get the command dispatched middleware.
301
     *
302
     * @return class-string<CommandDispatchedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandDispatchedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandDispatchedMiddleware>[].
Loading history...
303
     */
304
    #[Override]
305
    public function getCommandDispatchedMiddleware(): array
306
    {
307
        return $this->commandDispatchedMiddleware;
308
    }
309
310
    /**
311
     * Create a new command with the specified command dispatched middleware.
312
     *
313
     * @param class-string<CommandDispatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandDispatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandDispatchedMiddleware>.
Loading history...
314
     *
315
     * @return static
316
     */
317
    #[Override]
318
    public function withCommandDispatchedMiddleware(string ...$middleware): static
319
    {
320
        $new = clone $this;
321
322
        $new->commandDispatchedMiddleware = $middleware;
323
324
        return $new;
325
    }
326
327
    /**
328
     * Create a new command with added command dispatched middleware.
329
     *
330
     * @param class-string<CommandDispatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<CommandDispatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<CommandDispatchedMiddleware>.
Loading history...
331
     *
332
     * @return static
333
     */
334
    #[Override]
335
    public function withAddedCommandDispatchedMiddleware(string ...$middleware): static
336
    {
337
        $new = clone $this;
338
339
        $new->commandDispatchedMiddleware = array_merge($this->commandDispatchedMiddleware, $middleware);
340
341
        return $new;
342
    }
343
344
    /**
345
     * Get the throwable caught middleware.
346
     *
347
     * @return class-string<ThrowableCaughtMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>[].
Loading history...
348
     */
349
    #[Override]
350
    public function getThrowableCaughtMiddleware(): array
351
    {
352
        return $this->throwableCaughtMiddleware;
353
    }
354
355
    /**
356
     * Create a new command with the specified throwable caught middleware.
357
     *
358
     * @param class-string<ThrowableCaughtMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>.
Loading history...
359
     *
360
     * @return static
361
     */
362
    #[Override]
363
    public function withThrowableCaughtMiddleware(string ...$middleware): static
364
    {
365
        $new = clone $this;
366
367
        $new->throwableCaughtMiddleware = $middleware;
368
369
        return $new;
370
    }
371
372
    /**
373
     * Create a new command with added throwable caught middleware.
374
     *
375
     * @param class-string<ThrowableCaughtMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>.
Loading history...
376
     *
377
     * @return static
378
     */
379
    #[Override]
380
    public function withAddedThrowableCaughtMiddleware(string ...$middleware): static
381
    {
382
        $new = clone $this;
383
384
        $new->throwableCaughtMiddleware = array_merge($this->throwableCaughtMiddleware, $middleware);
385
386
        return $new;
387
    }
388
389
    /**
390
     * Get the exited middleware.
391
     *
392
     * @return class-string<ExitedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ExitedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ExitedMiddleware>[].
Loading history...
393
     */
394
    #[Override]
395
    public function getExitedMiddleware(): array
396
    {
397
        return $this->exitedMiddleware;
398
    }
399
400
    /**
401
     * Create a new command with the specified exited middleware.
402
     *
403
     * @param class-string<ExitedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ExitedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ExitedMiddleware>.
Loading history...
404
     *
405
     * @return static
406
     */
407
    #[Override]
408
    public function withExitedMiddleware(string ...$middleware): static
409
    {
410
        $new = clone $this;
411
412
        $new->exitedMiddleware = $middleware;
413
414
        return $new;
415
    }
416
417
    /**
418
     * Create a new command with added exited middleware.
419
     *
420
     * @param class-string<ExitedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ExitedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ExitedMiddleware>.
Loading history...
421
     *
422
     * @return static
423
     */
424
    #[Override]
425
    public function withAddedExitedMiddleware(string ...$middleware): static
426
    {
427
        $new = clone $this;
428
429
        $new->exitedMiddleware = array_merge($this->exitedMiddleware, $middleware);
430
431
        return $new;
432
    }
433
434
    /**
435
     * @inheritDoc
436
     */
437
    #[Override]
438
    public function getDispatch(): MethodDispatch
439
    {
440
        return $this->dispatch;
441
    }
442
443
    /**
444
     * @inheritDoc
445
     */
446
    #[Override]
447
    public function withDispatch(MethodDispatch $dispatch): static
448
    {
449
        $new = clone $this;
450
451
        $new->dispatch = $dispatch;
452
453
        return $new;
454
    }
455
}
456