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