OptionParameter::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 16
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Option\Contract\Option;
18
use Valkyrja\Cli\Routing\Data\Contract\OptionParameter as Contract;
19
use Valkyrja\Cli\Routing\Enum\OptionMode;
20
use Valkyrja\Cli\Routing\Enum\OptionValueMode;
21
use Valkyrja\Cli\Routing\Exception\InvalidArgumentException;
22
use Valkyrja\Type\Data\Cast;
23
24
use function count;
25
use function in_array;
26
27
/**
28
 * Class OptionParameter.
29
 *
30
 * @author Melech Mizrachi
31
 */
32
class OptionParameter extends Parameter implements Contract
33
{
34
    /**
35
     * @param non-empty-string      $name             The names
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...
36
     * @param non-empty-string      $description      The description
37
     * @param non-empty-string|null $valueDisplayName The value display name
38
     * @param non-empty-string|null $defaultValue     The default value
39
     * @param non-empty-string[]    $shortNames       The short names
40
     * @param non-empty-string[]    $validValues      The valid values
41
     * @param Option[]              $options          The options
42
     */
43
    public function __construct(
44
        string $name,
45
        string $description,
46
        protected string|null $valueDisplayName = null,
47
        Cast|null $cast = null,
48
        protected string|null $defaultValue = null,
49
        protected array $shortNames = [],
50
        protected array $validValues = [],
51
        protected array $options = [],
52
        protected OptionMode $mode = OptionMode::OPTIONAL,
53
        protected OptionValueMode $valueMode = OptionValueMode::DEFAULT,
54
    ) {
55
        parent::__construct(
56
            name: $name,
57
            description: $description,
58
            cast: $cast
59
        );
60
    }
61
62
    /**
63
     * @inheritDoc
64
     */
65
    #[Override]
66
    public function getShortNames(): array
67
    {
68
        return $this->shortNames;
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74
    #[Override]
75
    public function withShortNames(string ...$shortNames): static
76
    {
77
        $new = clone $this;
78
79
        $new->shortNames = $shortNames;
80
81
        return $new;
82
    }
83
84
    /**
85
     * @inheritDoc
86
     */
87
    #[Override]
88
    public function withAddedShortNames(string ...$shortNames): static
89
    {
90
        $new = clone $this;
91
92
        foreach ($shortNames as $shortName) {
93
            if (! in_array($shortName, $new->shortNames, true)) {
94
                $new->shortNames[] = $shortName;
95
            }
96
        }
97
98
        return $new;
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104
    #[Override]
105
    public function getMode(): OptionMode
106
    {
107
        return $this->mode;
108
    }
109
110
    /**
111
     * @inheritDoc
112
     */
113
    #[Override]
114
    public function withMode(OptionMode $mode): static
115
    {
116
        $new = clone $this;
117
118
        $new->mode = $mode;
119
120
        return $new;
121
    }
122
123
    /**
124
     * @inheritDoc
125
     */
126
    #[Override]
127
    public function getValueMode(): OptionValueMode
128
    {
129
        return $this->valueMode;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135
    #[Override]
136
    public function withValueMode(OptionValueMode $valueMode): static
137
    {
138
        $new = clone $this;
139
140
        $new->valueMode = $valueMode;
141
142
        return $new;
143
    }
144
145
    /**
146
     * @inheritDoc
147
     */
148
    #[Override]
149
    public function getValueDisplayName(): string|null
150
    {
151
        return $this->valueDisplayName;
152
    }
153
154
    /**
155
     * @inheritDoc
156
     */
157
    #[Override]
158
    public function withValueDisplayName(string|null $valueName): static
159
    {
160
        $new = clone $this;
161
162
        $new->valueDisplayName = $valueName;
163
164
        return $new;
165
    }
166
167
    /**
168
     * @inheritDoc
169
     */
170
    #[Override]
171
    public function getValidValues(): array
172
    {
173
        return $this->validValues;
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179
    #[Override]
180
    public function withValidValues(string ...$validValues): static
181
    {
182
        $new = clone $this;
183
184
        $new->validValues = $validValues;
185
186
        return $new;
187
    }
188
189
    /**
190
     * @inheritDoc
191
     */
192
    #[Override]
193
    public function withAddedValidValues(string ...$validValues): static
194
    {
195
        $new = clone $this;
196
197
        foreach ($validValues as $validValue) {
198
            if (! in_array($validValue, $new->validValues, true)) {
199
                $new->validValues[] = $validValue;
200
            }
201
        }
202
203
        return $new;
204
    }
205
206
    /**
207
     * @inheritDoc
208
     */
209
    #[Override]
210
    public function getDefaultValue(): string|null
211
    {
212
        return $this->defaultValue;
213
    }
214
215
    /**
216
     * @inheritDoc
217
     */
218
    #[Override]
219
    public function withDefaultValue(string|null $defaultValue = null): static
220
    {
221
        $new = clone $this;
222
223
        $new->defaultValue = $defaultValue;
224
225
        return $new;
226
    }
227
228
    /**
229
     * @inheritDoc
230
     */
231
    #[Override]
232
    public function getOptions(): array
233
    {
234
        return $this->options;
235
    }
236
237
    /**
238
     * @inheritDoc
239
     */
240
    #[Override]
241
    public function withOptions(Option ...$options): static
242
    {
243
        $new = clone $this;
244
245
        $new->options = [];
246
247
        foreach ($options as $option) {
248
            if ($this->valueMode === OptionValueMode::NONE && $option->getValue() !== null) {
249
                throw new InvalidArgumentException("$this->name should have no value");
250
            }
251
252
            $new->options[] = $option;
253
        }
254
255
        return $new;
256
    }
257
258
    /**
259
     * @inheritDoc
260
     */
261
    #[Override]
262
    public function withAddedOptions(Option ...$options): static
263
    {
264
        $new = clone $this;
265
266
        foreach ($options as $option) {
267
            $new->options[] = $option;
268
        }
269
270
        return $new;
271
    }
272
273
    /**
274
     * @inheritDoc
275
     */
276
    #[Override]
277
    public function getCastValues(): array
278
    {
279
        $values   = [];
280
        $cast     = $this->cast;
281
        $castType = $cast->type ?? null;
282
283
        foreach ($this->options as $option) {
284
            if ($cast === null || $castType === null) {
285
                $values[] = $option->getValue();
286
287
                continue;
288
            }
289
290
            $value = $castType::fromValue($option->getValue());
291
292
            if ($cast->convert) {
293
                /** @psalm-suppress MixedAssignment */
294
                $values[] = $value->asValue();
295
296
                continue;
297
            }
298
299
            $values[] = $value;
300
        }
301
302
        return $values;
303
    }
304
305
    /**
306
     * @inheritDoc
307
     */
308
    #[Override]
309
    public function getFirstValue(): string|null
310
    {
311
        $firstItem = $this->options[0] ?? null;
312
313
        return $firstItem?->getValue();
314
    }
315
316
    /**
317
     * @inheritDoc
318
     */
319
    #[Override]
320
    public function areValuesValid(): bool
321
    {
322
        return match (true) {
323
            $this->mode === OptionMode::REQUIRED          => $this->options !== [],
324
            $this->valueMode === OptionValueMode::DEFAULT => count($this->options) <= 1,
325
            default                                       => true,
326
        };
327
    }
328
329
    /**
330
     * @inheritDoc
331
     */
332
    #[Override]
333
    public function validateValues(): static
334
    {
335
        if (! $this->areValuesValid()) {
336
            throw new InvalidArgumentException("$this->name is required");
337
        }
338
339
        return $this;
340
    }
341
}
342