1
|
|
|
<?php namespace nyx\console\input; |
2
|
|
|
|
3
|
|
|
// Internal dependencies |
4
|
|
|
use nyx\console\input\parameter\definitions; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Input Definition |
8
|
|
|
* |
9
|
|
|
* This class represents a master Input Definition, eg. one that contains definitions for all parameters |
10
|
|
|
* allowed to be present in the Input. |
11
|
|
|
* |
12
|
|
|
* @version 0.1.0 |
13
|
|
|
* @author Michal Chojnacki <[email protected]> |
14
|
|
|
* @copyright 2012-2017 Nyx Dev Team |
15
|
|
|
* @link https://github.com/unyx/nyx |
16
|
|
|
*/ |
17
|
|
|
class Definition |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* @var definitions\Arguments The Definitions of the Arguments that can be present in the Input. |
21
|
|
|
*/ |
22
|
|
|
private $arguments; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var definitions\Options The Definitions of the Options that can be present in the Input. |
26
|
|
|
*/ |
27
|
|
|
private $options; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Constructs a new Input Definition instance. |
31
|
|
|
* |
32
|
|
|
* @param definitions\Arguments|array $arguments The defined Arguments. |
33
|
|
|
* @param definitions\Options|array $options The defined Options. |
34
|
|
|
*/ |
35
|
|
|
public function __construct($arguments = null, $options = null) |
36
|
|
|
{ |
37
|
|
|
$this->arguments = $arguments instanceof definitions\Arguments ? $arguments : new definitions\Arguments($arguments); |
38
|
|
|
$this->options = $arguments instanceof definitions\Options ? $options : new definitions\Options($options); |
|
|
|
|
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Returns the Definitions of the Arguments that can be present in the Input. |
43
|
|
|
* |
44
|
|
|
* @return definitions\Arguments |
45
|
|
|
*/ |
46
|
|
|
public function arguments() : definitions\Arguments |
47
|
|
|
{ |
48
|
|
|
return $this->arguments; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Returns the Definitions of the Options that can be present in the Input. |
53
|
|
|
* |
54
|
|
|
* @return definitions\Options |
55
|
|
|
*/ |
56
|
|
|
public function options() : definitions\Options |
57
|
|
|
{ |
58
|
|
|
return $this->options; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Merges this Definition with other Definition(s) and returns the result as a new instance, meaning this one, |
63
|
|
|
* even though used as base for the merger, will be left unscathed. |
64
|
|
|
* |
65
|
|
|
* The merge order works just like array_merge(). Since all parameters are named, duplicates will be overwritten. |
66
|
|
|
* The method creates two new Parameters collections for the merged Arguments and Options. If you use customized bags |
67
|
|
|
* you will need to override the method, as they are not injected for simplicity's sake. |
68
|
|
|
* |
69
|
|
|
* @param bool|Definition[] $mergeArguments Whether to merge the arguments. Can be omitted (ie. you may |
70
|
|
|
* pass a Definition as the first argument to this method right |
71
|
|
|
* away, in which case the default of "true" will be used). |
72
|
|
|
* @param Definition ...$definitions The Definitions to merge with this one. |
73
|
|
|
* @return Definition The merged Definition as a new instance. |
74
|
|
|
* @throws \InvalidArgumentException When one or more of the parameters is not a Definition |
75
|
|
|
* instance (not including the $mergeArguments bool). |
76
|
|
|
*/ |
77
|
|
|
public function merge($mergeArguments = true, Definition ...$definitions) : Definition |
78
|
|
|
{ |
79
|
|
|
// Whether to merge the arguments. When the first argument is a Definition already, we will use the default |
80
|
|
|
// of true. Otherwise, strip the first argument out of what we assume to be just an array of Definitions |
81
|
|
|
// after the func_get_args() call. |
82
|
|
|
if ($mergeArguments instanceof Definition) { |
83
|
|
|
array_unshift($definitions, $mergeArguments); |
84
|
|
|
$mergeArguments = true; |
85
|
|
|
} else { |
86
|
|
|
$mergeArguments = (bool) $mergeArguments; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
// We are not simply going to merge the arrays. We'll let the collections do their work and report |
90
|
|
|
// any duplicates etc. as necessary. |
91
|
|
|
$arguments = clone $this->arguments; |
92
|
|
|
$options = clone $this->options; |
93
|
|
|
|
94
|
|
|
foreach ($definitions as $definition) { |
95
|
|
|
// Arguments are merged by default but don't necessarily have to be (for instance, help descriptions |
96
|
|
|
// only display the argument for the command itself, not for the whole command chain). |
97
|
|
|
if ($mergeArguments) { |
98
|
|
|
foreach ($definition->arguments as $argument) { |
99
|
|
|
$arguments->add($argument); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
// Options are always merged. |
104
|
|
|
foreach ($definition->options as $option) { |
105
|
|
|
$options->add($option); |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
return new static($arguments, $options); |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.