-
Notifications
You must be signed in to change notification settings - Fork 5
/
ValidatingBasicObject.php
272 lines (247 loc) · 8.32 KB
/
ValidatingBasicObject.php
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
<?php
/**
* This is a variant of basic object that has validations.
*
* Validations are added to the model by implementing
* protected function validation_hooks() (void)
*
* In this function you can either use predefined validations by calling
* $this->predefined_validation_name('column_name') (see below)
* or by creating your own validations.
*
* To indicate an error call $this->add_error($variable_name,$error_msg)
* Use $variable_name = 'base' to add generic errors.
* This adds an error to $this->errors[$variable_name].
*
* Validations are run automaticly on commit unless specified (argument to commit)
*
* ====Predefined validations====
* The variable $var in the call to all validations are the _name_ of the variable
* All validations support an option assoc array as a optional last argument.
* All validations support the option "message" that override the default message.
* Validation specific options are defined below
* --------------------------
*
* validate_presence_of($var)
*
* Validates that $var is set
* -------------------------
* validate_numericality_of($var)
* Validates that $var is a number
* options:
* only_integers: true|false, default: false
* allow_null: true|false, default: false
* -------------------------
*
* validate_lenght_of($var)
*
* Validates the lenght of $var
* If no options are set no check is made
* If more than one options are set, multiple checks will be made
* options:
* is: Lenght must be exactly this value
* minimum: Lenght must be at least this value
* maximum: Lenght must be at most this value
* ------------------------
*
* validate_in_range($var)
* Validates that the variable is in the range given
* If no options are set no check is made
* If more than one options are set, multiple checks will be made
* options:
* minimum: Smallest allowed value
* maximum: Largest allowed value
*-------------------------
*
* validate_format_of($var,$format)
*
* Validates the format of $var
* The second option is a regular expression to match
* options:
* allow_null: Consider null to be a valid (default: false)
* ------------------------
*
* validate_date($var)
*
* Validates that $var is a date
* options:
* allow_null: Consider null to be a valid date (default: false)
* ------------------------
*
* validate_equal_to($var,$val)
*
* Validates that the value of $var matches $val
* options:
* not_equal: Set to true to instead validate not equal
* ==================================
*/
class ValidatingBasicObject extends BasicObject {
public $errors=array();
/**
* Runs validation hooks. Returns true if this instance validates
* All errors are filled into $errors
*/
public function validate() {
$this->errors = array();
$this->validation_hooks();
return !$this->has_errors();
}
/**
* Does not perform any check, but returns true if
* a previous validation found errors
*/
public function has_errors() {
return (count($this->errors) > 0);;
}
/**
* Override this function and call validations to run validations
*/
protected function validation_hooks() {}
public function add_error($var, $msg) {
//if(!isset($this->errors[$var]))
//$this->errors[$var] = array();
$this->errors[$var][] = $msg;
}
public function commit($validate=true) {
if($validate && !$this->validate()) {
throw new ValidationException($this);
}
parent::commit();
}
public function __clone() {
parent::__clone();
$this->errors = array(); //Reset errors
}
/***********
* Validators
**********/
/**
* Validates that $var is set
*/
protected function validate_presence_of($var,$options=array()) {
if($this->$var == null || $this->$var == "") {
$message = "måste fyllas i";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
}
/**
* Validates that $var is a number
* options:
* only_integers: true|false, default: false
* allow_null: true|false, default: false
*/
protected function validate_numericality_of($var,$options=array()) {
if(isset($options['allow_null']) && $options['allow_null'] && $this->$var == null)
return;
if(isset($options['only_integers']) && $options['only_integers']) {
if(!is_numeric($this->$var) || preg_match('/\A[+-]?\d+\Z/',$this->$var)!=1) {
$message = "måste vara ett heltal";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
} else if(!is_numeric($this->$var)){
$message = "måste vara ett nummer";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
}
/**
* Validates the length of $var
* If no options are set no check is made
* If more than one options are set, multiple checks will be made
* options:
* is: Length must be exactly this value
* minimum: Length must be at least this value
* maximum: Length must be at most this value
*/
protected function validate_length_of($var,$options=array()) {
$len = strlen($this->$var);
if(isset($options['is']) && $len != $options['is']) {
$message = "måste vara exakt {$options['is']} tecken lång";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
if(isset($options['minimum']) && $len < $options['minimum']) {
$message = "måste vara minst {$options['minimum']} tecken lång";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
if(isset($options['maximum']) && $len > $options['maximum'] ) {
$message = "får inte vara längre än {$options['maximum']} tecken";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
}
/**
* Validates that the variable is in the range given
* If no options are set no check is made
* If more than one options are set, multiple checks will be made
* options:
* minimum: Smallest allowed value
* maximum: Largest allowed value
*/
protected function validate_in_range($var,$options=array()) {
if(isset($options['minimum']) && $options['minimum'] >= $this->$var) {
$message = "måste vara minst {$options['minimum']}";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
if(isset($options['maximum']) && $options['maximum'] <= $this->$var) {
$message = "får inte vara större än {$options['maximum']}";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
}
/**
* Validates the format of $var
* The second option is a regular expression to match
* options:
* message: The error message to show. Default: "ogiltligt format"
* allow_null: Consider null to be a valid (default: false)
*/
protected function validate_format_of($var,$format,$options=array()) {
if(isset($options['allow_null']) && $options['allow_null'] && $this->$var == null)
return;
if(preg_match($format,$this->$var) != 1) {
$this->add_error($var,isset($options['message'])?$options['message']:"ogiltligt format");
}
}
/**
* Validates that $var is a date
* options:
* allow_null: Consider null to be a valid date (default: false)
*/
protected function validate_date($var,$options=array()) {
if(isset($options['allow_null']) && $options['allow_null'] && $this->$var == null)
return;
if(strtotime($this->$var)==false) {
$this->add_error($var,isset($options['message'])?$options['message']:"måste vara ett datum");
}
}
/**
* Validates that the value of $var matches $val
* options:
* not_equal: Set to true to instead validate not equal
*/
protected function validate_equal_to($var,$val,$options=array()) {
if($this->$var != $val && (
!isset($options['not_equal']) || !$options['not_equal']
)) {
$message = "måste vara $val";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
} else if(isset($options['not_equal']) && $options['not_equal'] &&
$this->var == $var
) {
$message = "får inte vara $val";
$this->add_error($var,isset($options['message'])?$options['message']:$message);
}
}
}
/**
* Exception thrown when validations fail
*/
class ValidationException extends Exception {
public $errors;
public $object;
/**
* @param BasicObject $object The object that validations failed in
*/
public function __construct($object) {
$this->object = $object;
$this->errors = $object->errors;
$this->message = "Validations failed in $object.\n Errors: ".print_r($this->errors,true);
}
}