-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathVariableValidator.php
More file actions
344 lines (323 loc) · 14.7 KB
/
VariableValidator.php
File metadata and controls
344 lines (323 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
<?php
declare(strict_types=1);
namespace CommentManager;
/**
* Provides functions for validating the value of a method parameter or return value
* The value is validated against the Doc Block comment for the parameter or return value
*
* @category UtilityClass
* @author Nadir Latif <nadir@pakjiddat.pk>
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General private License, version 2
*/
final class VariableValidator
{
/**
* It checks if the variable value matches the given type
* It checks if the variable value is in given range provided the range is given
*
* @param array $tag_details details of the parsed parameter tag
* @param mixed $param_value the value of the method parameter
* @param string $function_name the name of the function
* @param array $callback_data optional the custom validation callback function
* callback => array the custom callback function. the first index is the object, the second is the function name
* params => array the parameters for the callback function
*
* @return array $validation_result the result of validating the method parameters
* is_valid => bool indicates that the parameter value is valid
* message => string the message describing the result of validation
*/
public function ValidateVariable(
array $tag_details,
$param_value,
string $function_name,
?array $callback_data = null
) : array {
/** The result of validating the method */
$validation_result = array("is_valid" => true, "message" => "");
/** The variable name */
$variable_name = $tag_details['variable_name'];
/** If the validation rule is custom */
if ($tag_details["rule"] == "custom") {
/** The name of the variable to validate is set */
$callback_data["params"] = array($variable_name, $param_value, $function_name);
/** The callback parameters are sorted */
ksort($callback_data["params"]);
/** The validation result. The custom callback function is called */
$validation_result = call_user_func_array($callback_data["callback"], $callback_data["params"]);
}
else {
/** If the parameter type is an integer */
if ($tag_details['type'] == "int") {
/** The parameter value is converted to int */
$param_value = (int) $param_value;
/** The validation message is set */
$validation_result["message"] = $this->ValidateIntVariable($tag_details, $param_value);
}
/** If the parameter type is string */
else if ($tag_details['type'] == "string") {
/** The validation message is set */
$validation_result["message"] = $this->ValidateStringVariable($tag_details, $param_value);
}
/** If the parameter type is bool */
else if ($tag_details['type'] == "bool") {
/** If the parameter value is not a bool */
if (!is_bool($param_value))
/** The validation message is set */
$validation_result["message"] = "Parameter: " . $variable_name . " is not a bool";
}
/** If the parameter type is object */
else if ($tag_details['type'] == "object") {
/** If the parameter value is not an object */
if (!is_object($param_value))
/** The validation message is set */
$validation_result["message"] = "Parameter: " . $variable_name . " is not an object";
}
/** If the parameter type is array */
else if ($tag_details['type'] == "array") {
/** The validation message is set */
$validation_result["message"] = $this->ValidateArrayVariable(
$tag_details,
$param_value,
$function_name,
$callback_data
);
}
/** If the parameter type is json */
else if ($tag_details['type'] == "json") {
/** If the parameter value is not in json format */
if (!UtilitiesFramework::Factory("stringutils")->IsJson($param_value)) {
/** The validation message is set */
$validation_result["message"] = "Parameter: " . $variable_name . " is not in json format";
}
else {
/** The parameter value is json decoded */
$param_value = json_decode($param_value, true);
/** The validation message is set */
$validation_result["message"] = $this->ValidateArrayVariable(
$tag_details,
$param_value,
$function_name,
$callback_data
);
}
}
}
/** If the validation message is empty */
if ($validation_result["message"] != "") {
/** The result of validation is set to true */
$validation_result["is_valid"] = false;
}
return $validation_result;
}
/**
* Used to validate the value of an integer variable
*
* @param array $tag_details details of the parsed parameter tag
* @param int $param_value the value of the method parameter
*
* @return string $message the result of validation
*/
private function ValidateIntVariable(array $tag_details, int $param_value)
{
/** The result of validation */
$message = "";
/** If the parameter value is not an integer */
if (!is_numeric($param_value)) {
/** The validation message is set */
$message = "Parameter: " . $tag_details['variable_name'] . " is not an integer";
}
/** If the validation rule is range */
else if ($tag_details["rule"] == "range") {
/** The minimum and maximum values for the parameter */
list($min_value, $max_value) = explode("-", $tag_details['rule_data']);
/** If the parameter value is out of range then the error message is set */
if ($param_value < $min_value || $param_value > $max_value) {
/** The validation message is set */
$message = "The value: " . $param_value . " for the parameter: ";
$message .= $tag_details['variable_name'] . " is out of range";
}
}
return $message;
}
/**
* Used to validate the value of a string variable
*
* @param array $tag_details details of the parsed parameter tag
* @param string $param_value the value of the method parameter
*
* @return string $message the result of validation
*/
private function ValidateStringVariable(array $tag_details, string $param_value)
{
/** The result of validation */
$message = "";
/** If the parameter value is not a string */
if (!is_string($param_value)) {
/** The validation message is set */
$message = "Parameter: " . $tag_details['variable_name'] . " is not a string";
}
/** If the validation rule is list */
else if ($tag_details["rule"] == "list") {
/** The possible values for the string. The values must be separated with ',' */
$possible_string_values = explode(",", $tag_details['rule_data']);
/** If the parameter value is not one of the possible values then the error message is set */
if (!in_array($param_value, $possible_string_values)) {
/** The validation message is set */
$message = "Parameter value: " . $param_value . " for the parameter: " .
$tag_details['variable_name'] . " is not an allowed value. " .
"Allowed values: " . str_replace(",", ",", $tag_details['range']);
}
}
/** If the validation rule is email */
else if ($tag_details["rule"] == "email") {
/** If the parameter value is not one of the possible values then the error message is set */
if (!filter_var($param_value, FILTER_VALIDATE_EMAIL)) {
/** The validation message is set */
$message = "Parameter value: " . $param_value . " for the parameter: " .
$tag_details['variable_name'] . " is not a valid email";
}
}
return $message;
}
/**
* Used to validate the value of an array variable
*
* @param array $tag_details details of the parsed parameter tag
* @param mixed $param_value the value of the method parameter
* @param string $function_name the name of the function
* @param array $callback_data the custom validation callback function
* callback => array the custom callback function. the first index is the object, the second is the function name
* params => array the parameters for the callback function
*
* @return string $message the result of validation
*/
private function ValidateArrayVariable(
array $tag_details,
$param_value,
string $function_name,
?array $callback_data = null
) :string {
/** The result of validation */
$message = "";
/** If the parameter value is not an array */
if (!is_array($param_value)) {
/** The validation message is set */
$message = "Parameter: " . $tag_details['variable_name'] . " is not an array";
}
/** If the parameter value range is not given */
else if (isset($tag_details['values'])) {
/** Each parsed comment is checked */
for ($count = 0; $count < count($tag_details['values']); $count++) {
/** The sub option name */
$sub_option_name = $tag_details['values'][$count]['variable_name'];
/** An array element */
$array_element = $tag_details['values'][$count];
/** The associative array is validated */
$message = $this->ValidateAssociativeArray(
$sub_option_name,
$param_value,
$array_element,
$function_name,
$callback_data
);
/** If the array element is not valid, then the loop ends */
if ($message != '') break;
}
}
return $message;
}
/**
* Used to validate the value of a given associative array key
* If the array is an array of associative array, then the value of each array is checked
*
* @param string $key_name the name of the key to validate
* @param array $array_values the associative array values. it can be an array of associative arrays
* @param array $tag_details the parsed array tag element details
* @param string $function_name the name of the function
* @param array $callback_data the custom validation callback function
* callback => array the custom callback function. the first index is the object, the second is the function name
* params => array the parameters for the callback function
*
* @return string $message the result of validation
*/
private function ValidateAssociativeArray(
string $key_name,
array $array_values,
array $tag_details,
string $function_name,
?array $callback_data = null
) : string {
/** The result of validation */
$message = "";
/** If the array has numeric index and each element contains an associative array */
if (isset($array_values[0][$key_name])) {
/** Each array element is validated */
for ($count = 0; $count < count($array_values); $count++) {
/** If the array element does not contain the string index */
if (!isset($array_values[$count][$key_name])) {
/** The validation message is set */
$message = "Array element: " . $key_name . " could not be found";
/** The loop ends */
break;
}
/** The array element value is validated */
$validation_result = $this->ValidateVariable(
$tag_details,
$array_values[$count][$key_name],
$function_name,
$callback_data
);
/** If the validation message is not empty then it is updated and the loop ends */
if ($validation_result['message'] != "") {
$message = "Invalid value: " . var_export($array_values[$count][$key_name], true);
$message .= " for array element: " . $tag_details['variable_name'];
$message .= ". Details: " . $message ;
/** The loop ends */
break;
}
}
}
/** If the array is an associative array */
else {
/** If the array element does not contain the string index */
if (!isset($array_values[$key_name])) {
/** The validation message is set */
$message = "Array element: " . $key_name . " could not be found";
}
/** The array element value is validated */
$validation_result = $this->ValidateVariable(
$tag_details,
$array_values[$key_name],
$function_name,
$callback_data
);
/** If the validation message is not empty then it is updated and the loop ends */
if ($validation_result['message'] != "") {
$message = "Invalid value: " . var_export($array_values[$key_name], true);
$message .= " for array element: " . $tag_details['variable_name'];
$message .= ". Details: " . $validation_result["message"];
}
}
return $message;
}
/**
* Checks if given string is valid json
*
* @param string $data string to be checked
*
* @return boolean $is_valid true if string is valid json. returns false otherwise.
*/
private function IsJson(string $data) : bool
{
/** Indicates that the string is valid json */
$is_valid = false;
/** If the given data is a string */
if (is_string($data)) {
/** It is decoded */
@json_decode($data);
/** The error in json decoding is checked */
$is_valid = (json_last_error() === JSON_ERROR_NONE);
}
return $is_valid;
}
}