1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* This file is part of the Aura project for PHP. |
5
|
|
|
* |
6
|
|
|
* @package Aura.Input |
7
|
|
|
* |
8
|
|
|
* @license http://opensource.org/licenses/MIT-license.php MIT |
9
|
|
|
* |
10
|
|
|
*/ |
11
|
|
|
namespace Aura\Input; |
12
|
|
|
|
13
|
|
|
use Aura\Filter_Interface\FilterInterface; |
14
|
|
|
use Aura\Filter_Interface\FailureCollectionInterface; |
15
|
|
|
use Aura\Input\Filter\FailureCollection; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* |
19
|
|
|
* A filter |
20
|
|
|
* |
21
|
|
|
* @package Aura.Input |
22
|
|
|
* |
23
|
|
|
*/ |
24
|
|
|
class Filter implements FilterInterface |
25
|
|
|
{ |
26
|
|
|
/** |
27
|
|
|
* |
28
|
|
|
* The array of rules to be applied to fields. |
29
|
|
|
* |
30
|
|
|
* @var array |
31
|
|
|
* |
32
|
|
|
*/ |
33
|
|
|
protected $rules = []; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* |
37
|
|
|
* The array of failures to be used when rules fail. |
38
|
|
|
* |
39
|
|
|
* @var FailureCollection |
40
|
|
|
* |
41
|
|
|
*/ |
42
|
|
|
protected $failures; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* |
46
|
|
|
* A prototype FailureCollection. |
47
|
|
|
* |
48
|
|
|
* @var FailureCollection |
49
|
|
|
* |
50
|
|
|
*/ |
51
|
|
|
protected $proto_failures; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Initialize filters |
55
|
|
|
*/ |
56
|
|
|
public function __construct(FailureCollectionInterface $failures = null) |
57
|
|
|
{ |
58
|
|
|
if ($failures === null) { |
59
|
|
|
$failures = new FailureCollection(); |
60
|
|
|
} |
61
|
|
|
$this->proto_failures = $failures; |
|
|
|
|
62
|
|
|
$this->init(); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* |
67
|
|
|
* Does nothing |
68
|
|
|
* |
69
|
|
|
*/ |
70
|
|
|
protected function init() |
71
|
|
|
{ |
72
|
|
|
# code... |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* |
77
|
|
|
* Resets all previous filter rules for the field and add the rule. |
78
|
|
|
* |
79
|
|
|
* @param string $field The field name. |
80
|
|
|
* |
81
|
|
|
* @param string $message The message when the rule fails. |
82
|
|
|
* |
83
|
|
|
* @param \Closure $closure A closure that implements the rule. It must |
84
|
|
|
* have the signature `function ($value, &$fields)`; it must return |
85
|
|
|
* boolean true on success, or boolean false on failure. |
86
|
|
|
* |
87
|
|
|
*/ |
88
|
|
|
public function setRule($field, $message, \Closure $closure) |
89
|
|
|
{ |
90
|
|
|
unset($this->rules[$field]); |
91
|
|
|
$this->addRule($field, $message, $closure); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* |
96
|
|
|
* Add multiple rules to a field. |
97
|
|
|
* |
98
|
|
|
* @param string $field The field name. |
99
|
|
|
* |
100
|
|
|
* @param string $message The message when the rule fails. |
101
|
|
|
* |
102
|
|
|
* @param \Closure $closure A closure that implements the rule. It must |
103
|
|
|
* have the signature `function ($value, &$fields)`; it must return |
104
|
|
|
* boolean true on success, or boolean false on failure. |
105
|
|
|
* |
106
|
|
|
*/ |
107
|
|
|
public function addRule($field, $message, \Closure $closure) |
108
|
|
|
{ |
109
|
|
|
$this->rules[$field][] = [$message, $closure]; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* |
114
|
|
|
* Filter (sanitize and validate) the data. |
115
|
|
|
* |
116
|
|
|
* @param mixed $values The values to be filtered. |
117
|
|
|
* |
118
|
|
|
* @return bool True if all rules passed; false if one or more failed. |
119
|
|
|
* |
120
|
|
|
*/ |
121
|
|
|
public function apply(&$values) |
122
|
|
|
{ |
123
|
|
|
$this->failures = clone $this->proto_failures; |
124
|
|
|
|
125
|
|
|
// go through each field rules |
126
|
|
|
foreach ($this->rules as $field => $rules) { |
127
|
|
|
foreach ($rules as $rule) { |
128
|
|
|
// get the message and closure |
129
|
|
|
list($message, $closure) = $rule; |
130
|
|
|
|
131
|
|
|
// apply the closure to the data and get back the result |
132
|
|
|
$passed = $closure($values->$field, $values); |
133
|
|
|
|
134
|
|
|
if (! $passed) { |
135
|
|
|
$this->failures->addMessagesForField($field, $message); |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
// Is the failures empty or not |
141
|
|
|
return $this->failures->isEmpty() ? true : false; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* |
146
|
|
|
* Gets the messages for all fields |
147
|
|
|
* |
148
|
|
|
* @return FailureCollection |
149
|
|
|
* |
150
|
|
|
*/ |
151
|
|
|
public function getFailures() |
152
|
|
|
{ |
153
|
|
|
return $this->failures; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* |
158
|
|
|
* Gets the messages for all fields, or for a single field. |
159
|
|
|
* |
160
|
|
|
* @param string $field If empty, return all messages for all fields; |
161
|
|
|
* otherwise, return only messages for the named field. |
162
|
|
|
* |
163
|
|
|
* @return array |
164
|
|
|
* |
165
|
|
|
*/ |
166
|
|
|
public function getMessages($field = null) |
167
|
|
|
{ |
168
|
|
|
if ($field === null) { |
169
|
|
|
return $this->failures->getMessages(); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $this->failures->getMessagesForField($field); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* |
177
|
|
|
* Manually add messages to a particular field. |
178
|
|
|
* |
179
|
|
|
* @param string $field Add to this field. |
180
|
|
|
* |
181
|
|
|
* @param string|array $messages Add these messages to the field. |
182
|
|
|
* |
183
|
|
|
* @return void |
184
|
|
|
* |
185
|
|
|
*/ |
186
|
|
|
public function addMessages($field, $messages) |
187
|
|
|
{ |
188
|
|
|
$this->failures->addMessagesForField($field, $messages); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
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.