Argument   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 401
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 1
dl 0
loc 401
ccs 84
cts 84
cp 1
rs 9.68
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A createFromArray() 0 12 2
A getSettableArgumentParams() 0 14 1
A name() 0 4 1
A setName() 0 4 1
A prefix() 0 4 1
A setPrefix() 0 4 1
A longPrefix() 0 4 1
A setLongPrefix() 0 4 1
A hasPrefix() 0 4 2
A description() 0 4 1
A setDescription() 0 4 1
A isRequired() 0 4 1
A setRequired() 0 4 1
A noValue() 0 4 1
A setNoValue() 0 5 1
A castTo() 0 4 1
A setCastTo() 0 11 3
A defaultValue() 0 4 1
A setDefaultValue() 0 7 2
A value() 0 8 2
A values() 0 8 2
A setValue() 0 5 1
A castToString() 0 4 1
A castToInt() 0 4 1
A castToFloat() 0 4 1
A castToBool() 0 4 1
1
<?php
2
3
namespace League\CLImate\Argument;
4
5
use League\CLImate\Exceptions\UnexpectedValueException;
6
use function is_array;
7
8
class Argument
9
{
10
    /**
11
     * An argument's name.
12
     *
13
     * Use this name when internally referring to the argument.
14
     *
15
     * @var string
16
     */
17
    protected $name;
18
19
    /**
20
     * An argument's short representation.
21
     *
22
     * @var string
23
     */
24
    protected $prefix;
25
26
    /**
27
     * An argument's long representation.
28
     *
29
     * @var string
30
     */
31
    protected $longPrefix;
32
33
    /**
34
     * An argument's description.
35
     *
36
     * @var string
37
     */
38
    protected $description;
39
40
    /**
41
     * Whether or not an argument is required.
42
     *
43
     * @var bool
44
     */
45
    protected $required = false;
46
47
    /**
48
     * Whether or not an argument only needs to be defined to have a value.
49
     *
50
     * These arguments have the value true when they are defined on the command
51
     * line.
52
     *
53
     * @var bool
54
     */
55
    protected $noValue = false;
56
57
    /**
58
     * Which data type to cast an argument's value to.
59
     *
60
     * Valid data types are "string", "int", "float", and "bool".
61
     *
62
     * @var string
63
     */
64
    protected $castTo = 'string';
65
66
    /**
67
     * An argument's default value.
68
     *
69
     * @var string
70
     */
71
    protected $defaultValue = [];
72
73
    /**
74
     * An argument's value, after type casting.
75
     *
76
     * @var string[]|int[]|float[]|bool[]
77
     */
78
    protected $values = [];
79
80
    /**
81
     * Build a new command argument.
82 48
     *
83
     * @param string $name
84 48
     */
85 48
    public function __construct($name)
86
    {
87
        $this->setName($name);
88
    }
89
90
    /**
91
     * Build a new command argument from an array.
92
     *
93
     * @param string $name
94
     * @param array $params
95 48
     *
96
     * @return Argument
97 48
     */
98 48
    public static function createFromArray($name, array $params)
99
    {
100 48
        $argument = new Argument($name);
101 48
        $params   = self::getSettableArgumentParams($params);
102 48
103 44
        foreach ($params as $key => $value) {
104
            $method = 'set' . ucwords($key);
105 44
            $argument->{$method}($value);
106 8
        }
107 8
108
        return $argument;
109 44
    }
110
111
    /**
112
     * Get argument params based on settable properties
113
     *
114
     * @param array $params
115
     *
116
     * @return array
117
     */
118
    protected static function getSettableArgumentParams(array $params)
119 48
    {
120
        $allowed = [
121
                    'prefix',
122 48
                    'longPrefix',
123 48
                    'description',
124 48
                    'required',
125 48
                    'noValue',
126 48
                    'castTo',
127 48
                    'defaultValue',
128 48
                ];
129 48
130
        return array_intersect_key($params, array_flip($allowed));
131 48
    }
132
133
    /**
134
     * Retrieve an argument's name.
135
     *
136
     * Use this name when internally referring to the argument.
137
     *
138
     * @return string
139
     */
140
    public function name()
141 24
    {
142
        return $this->name;
143 24
    }
144
145
    /**
146
     * Set an argument's name.
147
     *
148
     * Use this name when internally referring to the argument.
149
     *
150
     * @param string $name
151
     */
152
    protected function setName($name)
153 48
    {
154
        $this->name = trim($name);
155 48
    }
156 48
157
    /**
158
     * Retrieve an argument's short form.
159
     *
160
     * @return string
161
     */
162
    public function prefix()
163 24
    {
164
        return $this->prefix;
165 24
    }
166
167
    /**
168
     * Set an argument's short form.
169
     *
170
     * @param string $prefix
171
     */
172
    protected function setPrefix($prefix)
173 20
    {
174
        $this->prefix = trim($prefix);
175 20
    }
176 20
177
    /**
178
     * Retrieve an argument's long form.
179
     *
180
     * @return string
181
     */
182
    public function longPrefix()
183 24
    {
184
        return $this->longPrefix;
185 24
    }
186
187
    /**
188
     * Set an argument's short form.
189
     *
190
     * @param string $longPrefix
191
     */
192
    protected function setLongPrefix($longPrefix)
193 20
    {
194
        $this->longPrefix = trim($longPrefix);
195 20
    }
196 20
197
    /**
198
     * Determine if an argument has a prefix.
199
     *
200
     * @return bool
201
     */
202
    public function hasPrefix()
203 20
    {
204
        return $this->prefix() || $this->longPrefix();
205 20
    }
206
207
    /**
208
     * Retrieve an argument's description.
209
     *
210
     * @return string
211
     */
212
    public function description()
213 4
    {
214
        return $this->description;
215 4
    }
216
217
    /**
218
     * Set an argument's description.
219
     *
220
     * @param string $description
221
     */
222
    protected function setDescription($description)
223 4
    {
224
        $this->description = trim($description);
225 4
    }
226 4
227
    /**
228
     * Determine whether or not an argument is required.
229
     *
230
     * @return bool
231
     */
232
    public function isRequired()
233 20
    {
234
        return $this->required;
235 20
    }
236
237
    /**
238
     * Set whether an argument is required or not.
239
     *
240
     * @param bool $required
241
     */
242
    protected function setRequired($required)
243 8
    {
244
        $this->required = (bool) $required;
245 8
    }
246 8
247
    /**
248
     * Determine whether or not an argument only needs to be defined to have a
249
     * value.
250
     *
251
     * @return bool
252
     */
253
    public function noValue()
254 40
    {
255
        return $this->noValue;
256 40
    }
257
258
    /**
259
     * Set whether or not an argument only needs to be defined to have a value.
260
     *
261
     * @param bool $noValue
262
     */
263
    protected function setNoValue($noValue)
264 12
    {
265
        $this->setCastTo('bool');
266 12
        $this->noValue = (bool) $noValue;
267 12
    }
268 12
269
    /**
270
     * Retrieve the data type to cast an argument's value to.
271
     *
272
     * @return string
273
     */
274
    public function castTo()
275 4
    {
276
        return $this->castTo;
277 4
    }
278
279
    /**
280
     * Set the data type to cast an argument's value to.
281
     *
282
     * Valid data types are "string", "int", "float", and "bool".
283
     *
284
     * @param string $castTo
285
     *
286
     * @return void
287
     * @throws UnexpectedValueException if $castTo is not a valid data type.
288 32
     */
289
    protected function setCastTo($castTo)
290 32
    {
291 4
        if (!in_array($castTo, ['string', 'int', 'float', 'bool'])) {
292
            throw new UnexpectedValueException(
293
                "An argument may only be cast to the data type "
294 4
                . "'string', 'int', 'float', or 'bool'."
295
            );
296
        }
297 28
298 28
        $this->castTo = $this->noValue() ? 'bool' : $castTo;
299
    }
300
301
    /**
302
     * Retrieve an argument's default values.
303
     *
304
     * @return string
305 44
     */
306
    public function defaultValue()
307 44
    {
308
        return $this->defaultValue;
309
    }
310
311
    /**
312
     * Set an argument's default value.
313
     *
314
     * @param string $defaultValue
315 8
     */
316
    public function setDefaultValue($defaultValue)
317 8
    {
318 8
        if (!is_array($defaultValue)) {
319
            $defaultValue = [$defaultValue];
320
        }
321
        $this->defaultValue = $defaultValue;
0 ignored issues
show
Documentation Bug introduced by Craig Duncan
It seems like $defaultValue of type array is incompatible with the declared type string of property $defaultValue.

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...
322
    }
323
324
    /**
325
     * Retrieve an argument's value.
326
     *
327 28
     * Argument values are type cast based on the value of $castTo.
328
     *
329 28
     * @return string|int|float|bool
330
     */
331
    public function value()
332
    {
333
        if ($this->values) {
0 ignored issues
show
Bug Best Practice introduced by Bob Weinand
The expression $this->values of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
334
            return end($this->values);
335
        }
336
        $cast_method = 'castTo' . ucwords($this->castTo);
337
        return $this->{$cast_method}(current($this->defaultValue()));
338
    }
339 36
340
    /**
341 36
     * Retrieve an argument's values.
342 36
     *
343 36
     * Argument values are type cast based on the value of $castTo.
344
     *
345
     * @return string[]|int[]|float[]|bool[]
346
     */
347
    public function values()
348
    {
349
        if ($this->values) {
0 ignored issues
show
Bug Best Practice introduced by Bob Weinand
The expression $this->values of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
350 24
            return $this->values;
351
        }
352 24
        $cast_method = 'castTo' . ucwords($this->castTo);
353
        return array_map([$this, $cast_method], $this->defaultValue());
354
    }
355
356
    /**
357
     * Set an argument's value based on its command line entry.
358
     *
359
     * Argument values are type cast based on the value of $castTo.
360 4
     *
361
     * @param string|bool $value
362 4
     */
363
    public function setValue($value)
364
    {
365
        $cast_method = 'castTo' . ucwords($this->castTo);
366
        $this->values[] = $this->{$cast_method}($value);
367
    }
368
369
    /**
370 4
     * @param string $value
371
     *
372 4
     * @return string
373
     */
374
    protected function castToString($value)
375
    {
376
        return (string) $value;
377
    }
378
379
    /**
380 8
     * @param string $value
381
     *
382 8
     * @return int
383
     */
384
    protected function castToInt($value)
385
    {
386
        return (int) $value;
387
    }
388
389
    /**
390
     * @param string $value
391
     *
392
     * @return float
393
     */
394
    protected function castToFloat($value)
395
    {
396
        return (float) $value;
397
    }
398
399
    /**
400
     * @param string $value
401
     *
402
     * @return bool
403
     */
404
    protected function castToBool($value)
405
    {
406
        return (bool) $value;
407
    }
408
}
409