Argument   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 399
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 0
dl 0
loc 399
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 function is_array;
6
7
class Argument
8
{
9
    /**
10
     * An argument's name.
11
     *
12
     * Use this name when internally referring to the argument.
13
     *
14
     * @var string
15
     */
16
    protected $name;
17
18
    /**
19
     * An argument's short representation.
20
     *
21
     * @var string
22
     */
23
    protected $prefix;
24
25
    /**
26
     * An argument's long representation.
27
     *
28
     * @var string
29
     */
30
    protected $longPrefix;
31
32
    /**
33
     * An argument's description.
34
     *
35
     * @var string
36
     */
37
    protected $description;
38
39
    /**
40
     * Whether or not an argument is required.
41
     *
42
     * @var bool
43
     */
44
    protected $required = false;
45
46
    /**
47
     * Whether or not an argument only needs to be defined to have a value.
48
     *
49
     * These arguments have the value true when they are defined on the command
50
     * line.
51
     *
52
     * @var bool
53
     */
54
    protected $noValue = false;
55
56
    /**
57
     * Which data type to cast an argument's value to.
58
     *
59
     * Valid data types are "string", "int", "float", and "bool".
60
     *
61
     * @var string
62
     */
63
    protected $castTo = 'string';
64
65
    /**
66
     * An argument's default value.
67
     *
68
     * @var string
69
     */
70
    protected $defaultValue = [];
71
72
    /**
73
     * An argument's value, after type casting.
74
     *
75
     * @var string[]|int[]|float[]|bool[]
76
     */
77
    protected $values = [];
78
79
    /**
80
     * Build a new command argument.
81
     *
82 48
     * @param string $name
83
     */
84 48
    public function __construct($name)
85 48
    {
86
        $this->setName($name);
87
    }
88
89
    /**
90
     * Build a new command argument from an array.
91
     *
92
     * @param string $name
93
     * @param array $params
94
     *
95 48
     * @return Argument
96
     */
97 48
    public static function createFromArray($name, array $params)
98 48
    {
99
        $argument = new Argument($name);
100 48
        $params   = self::getSettableArgumentParams($params);
101 48
102 48
        foreach ($params as $key => $value) {
103 44
            $method = 'set' . ucwords($key);
104
            $argument->{$method}($value);
105 44
        }
106 8
107 8
        return $argument;
108
    }
109 44
110
    /**
111
     * Get argument params based on settable properties
112
     *
113
     * @param array $params
114
     *
115
     * @return array
116
     */
117
    protected static function getSettableArgumentParams(array $params)
118
    {
119 48
        $allowed = [
120
                    'prefix',
121
                    'longPrefix',
122 48
                    'description',
123 48
                    'required',
124 48
                    'noValue',
125 48
                    'castTo',
126 48
                    'defaultValue',
127 48
                ];
128 48
129 48
        return array_intersect_key($params, array_flip($allowed));
130
    }
131 48
132
    /**
133
     * Retrieve an argument's name.
134
     *
135
     * Use this name when internally referring to the argument.
136
     *
137
     * @return string
138
     */
139
    public function name()
140
    {
141 24
        return $this->name;
142
    }
143 24
144
    /**
145
     * Set an argument's name.
146
     *
147
     * Use this name when internally referring to the argument.
148
     *
149
     * @param string $name
150
     */
151
    protected function setName($name)
152
    {
153 48
        $this->name = trim($name);
154
    }
155 48
156 48
    /**
157
     * Retrieve an argument's short form.
158
     *
159
     * @return string
160
     */
161
    public function prefix()
162
    {
163 24
        return $this->prefix;
164
    }
165 24
166
    /**
167
     * Set an argument's short form.
168
     *
169
     * @param string $prefix
170
     */
171
    protected function setPrefix($prefix)
172
    {
173 20
        $this->prefix = trim($prefix);
174
    }
175 20
176 20
    /**
177
     * Retrieve an argument's long form.
178
     *
179
     * @return string
180
     */
181
    public function longPrefix()
182
    {
183 24
        return $this->longPrefix;
184
    }
185 24
186
    /**
187
     * Set an argument's short form.
188
     *
189
     * @param string $longPrefix
190
     */
191
    protected function setLongPrefix($longPrefix)
192
    {
193 20
        $this->longPrefix = trim($longPrefix);
194
    }
195 20
196 20
    /**
197
     * Determine if an argument has a prefix.
198
     *
199
     * @return bool
200
     */
201
    public function hasPrefix()
202
    {
203 20
        return $this->prefix() || $this->longPrefix();
204
    }
205 20
206
    /**
207
     * Retrieve an argument's description.
208
     *
209
     * @return string
210
     */
211
    public function description()
212
    {
213 4
        return $this->description;
214
    }
215 4
216
    /**
217
     * Set an argument's description.
218
     *
219
     * @param string $description
220
     */
221
    protected function setDescription($description)
222
    {
223 4
        $this->description = trim($description);
224
    }
225 4
226 4
    /**
227
     * Determine whether or not an argument is required.
228
     *
229
     * @return bool
230
     */
231
    public function isRequired()
232
    {
233 20
        return $this->required;
234
    }
235 20
236
    /**
237
     * Set whether an argument is required or not.
238
     *
239
     * @param bool $required
240
     */
241
    protected function setRequired($required)
242
    {
243 8
        $this->required = (bool) $required;
244
    }
245 8
246 8
    /**
247
     * Determine whether or not an argument only needs to be defined to have a
248
     * value.
249
     *
250
     * @return bool
251
     */
252
    public function noValue()
253
    {
254 40
        return $this->noValue;
255
    }
256 40
257
    /**
258
     * Set whether or not an argument only needs to be defined to have a value.
259
     *
260
     * @param bool $noValue
261
     */
262
    protected function setNoValue($noValue)
263
    {
264 12
        $this->setCastTo('bool');
265
        $this->noValue = (bool) $noValue;
266 12
    }
267 12
268 12
    /**
269
     * Retrieve the data type to cast an argument's value to.
270
     *
271
     * @return string
272
     */
273
    public function castTo()
274
    {
275 4
        return $this->castTo;
276
    }
277 4
278
    /**
279
     * Set the data type to cast an argument's value to.
280
     *
281
     * Valid data types are "string", "int", "float", and "bool".
282
     *
283
     * @throws \Exception if $castTo is not a valid data type.
284
     * @param string $castTo
285
     */
286
    protected function setCastTo($castTo)
287
    {
288 32
        if (!in_array($castTo, ['string', 'int', 'float', 'bool'])) {
289
            throw new \Exception(
290 32
                "An argument may only be cast to the data type "
291 4
                . "'string', 'int', 'float', or 'bool'."
292
            );
293
        }
294 4
295
        $this->castTo = $this->noValue() ? 'bool' : $castTo;
296
    }
297 28
298 28
    /**
299
     * Retrieve an argument's default values.
300
     *
301
     * @return string
302
     */
303
    public function defaultValue()
304
    {
305 44
        return $this->defaultValue;
306
    }
307 44
308
    /**
309
     * Set an argument's default value.
310
     *
311
     * @param string $defaultValue
312
     */
313
    public function setDefaultValue($defaultValue)
314
    {
315 8
        if (!is_array($defaultValue)) {
316
            $defaultValue = [$defaultValue];
317 8
        }
318 8
        $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...
319
    }
320
321
    /**
322
     * Retrieve an argument's value.
323
     *
324
     * Argument values are type cast based on the value of $castTo.
325
     *
326
     * @return string|int|float|bool
327 28
     */
328
    public function value()
329 28
    {
330
        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...
331
            return end($this->values);
332
        }
333
        $cast_method = 'castTo' . ucwords($this->castTo);
334
        return $this->{$cast_method}(current($this->defaultValue()));
335
    }
336
337
    /**
338
     * Retrieve an argument's values.
339 36
     *
340
     * Argument values are type cast based on the value of $castTo.
341 36
     *
342 36
     * @return string[]|int[]|float[]|bool[]
343 36
     */
344
    public function values()
345
    {
346
        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...
347
            return $this->values;
348
        }
349
        $cast_method = 'castTo' . ucwords($this->castTo);
350 24
        return array_map([$this, $cast_method], $this->defaultValue());
351
    }
352 24
353
    /**
354
     * Set an argument's value based on its command line entry.
355
     *
356
     * Argument values are type cast based on the value of $castTo.
357
     *
358
     * @param string|bool $value
359
     */
360 4
    public function setValue($value)
361
    {
362 4
        $cast_method = 'castTo' . ucwords($this->castTo);
363
        $this->values[] = $this->{$cast_method}($value);
364
    }
365
366
    /**
367
     * @param string $value
368
     *
369
     * @return string
370 4
     */
371
    protected function castToString($value)
372 4
    {
373
        return (string) $value;
374
    }
375
376
    /**
377
     * @param string $value
378
     *
379
     * @return int
380 8
     */
381
    protected function castToInt($value)
382 8
    {
383
        return (int) $value;
384
    }
385
386
    /**
387
     * @param string $value
388
     *
389
     * @return float
390
     */
391
    protected function castToFloat($value)
392
    {
393
        return (float) $value;
394
    }
395
396
    /**
397
     * @param string $value
398
     *
399
     * @return bool
400
     */
401
    protected function castToBool($value)
402
    {
403
        return (bool) $value;
404
    }
405
}
406