This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace nyx\console\input\parameter\definitions; |
||
2 | |||
3 | // External dependencies |
||
4 | use nyx\core; |
||
5 | use nyx\diagnostics; |
||
6 | |||
7 | // Internal dependencies |
||
8 | use nyx\console\input; |
||
9 | |||
10 | /** |
||
11 | * Input Argument Definitions |
||
12 | * |
||
13 | * @version 0.1.0 |
||
14 | * @author Michal Chojnacki <[email protected]> |
||
15 | * @copyright 2012-2017 Nyx Dev Team |
||
16 | * @link https://github.com/unyx/nyx |
||
17 | */ |
||
18 | class Arguments extends input\parameter\Definitions |
||
19 | { |
||
20 | /** |
||
21 | * @var int The number of arguments required to be present in an Input Arguments collection for it to |
||
22 | * to conform to the Definitions in this collection. |
||
23 | */ |
||
24 | private $required = 0; |
||
25 | |||
26 | /** |
||
27 | * @var bool Whether one of the arguments accepts multiple values and therefore must be the last argument |
||
28 | * present in the definition. |
||
29 | */ |
||
30 | private $hasMultiparam = false; |
||
31 | |||
32 | /** |
||
33 | * @var bool Whether one of the arguments is optional, meaning no more required arguments can be defined. |
||
34 | */ |
||
35 | private $hasOptional = false; |
||
36 | |||
37 | /** |
||
38 | * {@inheritdoc} |
||
39 | */ |
||
40 | public function __construct($arguments = null) |
||
41 | { |
||
42 | $this->setCollectedType(input\Argument::class); |
||
43 | |||
44 | parent::__construct($arguments); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Returns the next Input Argument Definition for the given Input Argument values collection, |
||
49 | * unless the collection already exceeds the number of defined Arguments. |
||
50 | * |
||
51 | * @param input\parameter\values\Arguments $values |
||
52 | * @return input\Argument |
||
53 | */ |
||
54 | public function getNextDefinition(input\parameter\values\Arguments $values) : ?input\Argument |
||
55 | { |
||
56 | $nextIndex = $values->count(); |
||
57 | |||
58 | // We are using an associative array internally but we need to match by a numeric index |
||
59 | // in this case, maybe even twice, so let's only grab the values once for that. |
||
60 | /* @var input\Argument[] $items */ |
||
61 | $items = array_values($this->items); |
||
62 | |||
63 | // $items is now 0-indexed, while $nextIndex is a count of all values already set, |
||
64 | // meaning it's 1-indexed. |
||
65 | if (isset($items[$nextIndex])) { |
||
66 | return $items[$nextIndex]; |
||
67 | } |
||
68 | |||
69 | // At this point, there was no further Argument definition present. However, maybe the previous |
||
70 | // Argument accepts multiple values and we are actually supposed to add a value to it? |
||
71 | if (isset($items[$nextIndex - 1]) && $items[$nextIndex - 1]->getValue() instanceof input\values\Multiple) { |
||
72 | return $items[$nextIndex - 1]; |
||
73 | } |
||
74 | |||
75 | return null; |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * {@inheritdoc} |
||
80 | */ |
||
81 | public function replace($items) : core\collections\interfaces\Collection |
||
82 | { |
||
83 | $this->hasMultiparam = false; |
||
84 | $this->hasOptional = false; |
||
85 | $this->required = 0; |
||
86 | |||
87 | foreach ($this->extractItems($items) as $item) { |
||
88 | $this->add(is_array($item) ? $this->unpack($item) : $item); |
||
89 | } |
||
90 | |||
91 | return $this; |
||
0 ignored issues
–
show
|
|||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Adds a Input Argument Definition to this collection. |
||
96 | * |
||
97 | * @param input\Argument $argument The argument definition. |
||
98 | * @throws \InvalidArgumentException When the argument's type is invalid. |
||
99 | * @throws \LogicException When an incorrect argument was given. |
||
100 | * @return $this |
||
101 | */ |
||
102 | public function add(core\interfaces\Named $argument) : core\collections\interfaces\NamedObjectSet |
||
103 | { |
||
104 | // The Collection is locked once populated with an Argument accepting multiple values and since we don't allow |
||
105 | // overwriting by setting, might as well check for this here already. |
||
106 | if ($this->hasMultiparam) { |
||
107 | throw new \LogicException("Cannot define additional arguments after an Argument [name: ".end($this->items)->getName()."] which accepts multiple values."); |
||
108 | } |
||
109 | |||
110 | // Make sure we got the proper type. |
||
111 | if (!$argument instanceof input\Argument) { |
||
112 | throw new \InvalidArgumentException('Expected an instance of ['.input\Argument::class.'], got ['.diagnostics\Debug::getTypeName($argument).'] instead.'); |
||
113 | } |
||
114 | |||
115 | // We'll need those a few times. |
||
116 | $name = $argument->getName(); |
||
117 | $value = $argument->getValue(); |
||
118 | |||
119 | // Arguments are stored by name so no duplicates allowed here. |
||
120 | if (isset($this->items[$name])) { |
||
121 | throw new \LogicException("An Argument with this name [$name] has already been defined."); |
||
122 | } |
||
123 | |||
124 | // Keep track of how many Arguments we will require to be present in the Input later on. |
||
125 | if ($value->is(input\Value::REQUIRED)) { |
||
126 | if ($this->hasOptional) { |
||
127 | throw new \LogicException("Cannot add a required Argument after an optional one."); |
||
128 | } |
||
129 | |||
130 | ++$this->required; |
||
131 | } else { |
||
132 | $this->hasOptional = true; |
||
133 | } |
||
134 | |||
135 | // If the Argument accepts multiple values, this effectively requires it to be the last Argument in |
||
136 | // the definition, which locks this Bag. |
||
137 | if ($value instanceof input\values\Multiple) { |
||
138 | $this->hasMultiparam = true; |
||
139 | } |
||
140 | |||
141 | // Finally, store the Argument. |
||
142 | $this->items[$name] = $argument; |
||
143 | |||
144 | return $this; |
||
0 ignored issues
–
show
The return type of
return $this; (nyx\console\input\parameter\definitions\Arguments ) is incompatible with the return type of the parent method nyx\core\collections\NamedObjectSet::add of type nyx\core\collections\traits\NamedObjectSet .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
145 | } |
||
146 | |||
147 | /** |
||
148 | * {@inheritdoc} |
||
149 | * |
||
150 | * Overridden to update the counters and flags we're keeping track of internally. |
||
151 | */ |
||
152 | public function remove(string $name) : core\collections\interfaces\NamedObjectSet |
||
153 | { |
||
154 | // If no Argument is defined for the given name, there's nothing to remove. |
||
155 | if (!isset($this->items[$name])) { |
||
156 | return $this; |
||
0 ignored issues
–
show
The return type of
return $this; (nyx\console\input\parameter\definitions\Arguments ) is incompatible with the return type of the parent method nyx\core\collections\NamedObjectSet::remove of type nyx\core\collections\traits\NamedObjectSet .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
157 | } |
||
158 | |||
159 | /* @var input\Argument $argument */ |
||
160 | $value = $argument->getValue(); |
||
0 ignored issues
–
show
|
|||
161 | |||
162 | // There's at most one Multiple Value accepting Argument so we can remove that flag safely. |
||
163 | if ($value instanceof input\values\Multiple) { |
||
164 | $this->hasMultiparam = false; |
||
165 | } |
||
166 | |||
167 | // Reduce our counter of required arguments. |
||
168 | if ($value->is(input\Value::REQUIRED)) { |
||
169 | $this->required--; |
||
170 | } |
||
171 | // @fixme - We're not checking whether other Arguments are optional. |
||
172 | else { |
||
173 | $this->hasOptional = true; |
||
174 | } |
||
175 | |||
176 | return parent::remove($name); |
||
0 ignored issues
–
show
The return type of
return parent::remove($name); (nyx\console\input\parameter\definitions\Arguments ) is incompatible with the return type of the parent method nyx\core\collections\NamedObjectSet::remove of type nyx\core\collections\traits\NamedObjectSet .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
177 | } |
||
178 | |||
179 | /** |
||
180 | * Returns the number of Arguments defined in this collection. |
||
181 | * |
||
182 | * @return int |
||
183 | */ |
||
184 | public function count() : int |
||
185 | { |
||
186 | return $this->hasMultiparam ? PHP_INT_MAX : count($this->items); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Returns the number of arguments required to be present in an Input Arguments collection for it to |
||
191 | * to conform to the Definitions in this collection. |
||
192 | * |
||
193 | * @return int |
||
194 | */ |
||
195 | public function required() : int |
||
196 | { |
||
197 | return $this->required; |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Unpacks a sequence of Argument constructor arguments into an Argument instance. |
||
202 | * |
||
203 | * @see \nyx\console\input\Argument::__construct() |
||
204 | * |
||
205 | * @param array $definition The arguments to unpack. The order must match the constructor's signature. |
||
206 | * @return input\Argument |
||
207 | */ |
||
208 | protected function unpack(array $definition) : input\Argument |
||
209 | { |
||
210 | // If the 4th argument is an integer, we are going to assume it's one of the input\Value |
||
211 | // class constants defining the mode and attempt to instantiate a input\Value with such. |
||
212 | if (isset($definition[2]) && is_int($definition[2])) { |
||
213 | $definition[2] = new input\Value($definition[2]); |
||
214 | } |
||
215 | |||
216 | return new input\Argument(...$definition); |
||
0 ignored issues
–
show
$definition is of type array<integer,?,{"2":"?"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
217 | } |
||
218 | } |
||
219 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.