FormValidation::checkRuleDefaultValue()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
    /**
4
     * TNH Framework
5
     *
6
     * A simple PHP framework using HMVC architecture
7
     *
8
     * This content is released under the MIT License (MIT)
9
     *
10
     * Copyright (c) 2017 TNH Framework
11
     *
12
     * Permission is hereby granted, free of charge, to any person obtaining a copy
13
     * of this software and associated documentation files (the "Software"), to deal
14
     * in the Software without restriction, including without limitation the rights
15
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
     * copies of the Software, and to permit persons to whom the Software is
17
     * furnished to do so, subject to the following conditions:
18
     *
19
     * The above copyright notice and this permission notice shall be included in all
20
     * copies or substantial portions of the Software.
21
     *
22
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
     * SOFTWARE.
29
     */
30
    
31
    class FormValidation extends BaseClass {
32
33
        /**
34
         * The list of validation rules
35
         *
36
         * Format:
37
         * [field1] => array(rule1, rule2)
38
         * [field2] => array(rule3, rule3)
39
         *
40
         * @var array
41
         */
42
        private $rules = array();
43
44
        /**
45
         * The list of field labels
46
         *
47
         * Format:
48
         * [field1] => 'label 1'
49
         * [field2] => 'label 2'
50
         *
51
         * @var array
52
         */
53
        private $labels = array();
54
55
        /**
56
         * The list of errors messages
57
         * Format:
58
         * [field1] => 'error message 1';
59
         * [field2] => 'error message 2';
60
         * 
61
         * @var array
62
         */
63
        private $errors = array();
64
65
        /**
66
         * The validation status
67
         * @var boolean
68
         */
69
        private $valid = false;
70
71
        /**
72
         * Whether we force validation to be an error
73
         * @var boolean
74
         */
75
        private $forceError = false;
76
        
77
        /**
78
         * The list of rules errors messages
79
         *
80
         * Format:
81
         * [rule1] => 'message 1';
82
         * [rule2] => 'message 2';
83
         * Message can contain placeholder: {field}, {label}, {value}, {paramValue}, {field2}'
84
         *
85
         * @var array
86
         */
87
        private $messages = array();
88
        
89
        /**
90
         * The list of the custom errors messages overrides by the original
91
         *
92
         * Format:
93
         * [field1][rule1] = message 1
94
         * [field2][rule2] = message 2
95
         *
96
         * @var array
97
         */
98
        private $customErrors = array();
99
        
100
        /**
101
         * The data to be validated, the default is to use $_POST
102
         * @var array
103
         */
104
        private $data = array();
105
106
        /**
107
         * Construct new Form Validation instance
108
         * Reset the field to the default value
109
         * Set the rules validations messages
110
         * And if data of $_POST exists set it as the default
111
         */
112
        public function __construct() {
113
            parent::__construct();
114
115
            //Reset the validation instance
116
            $this->reset();
117
118
            //Set default messages for each validation rule
119
            $this->setValidationMessages();
120
121
            //Set default data to validation from $_POST
122
            if (is_array(get_instance()->request->post(null))) {
123
                $this->setData(get_instance()->request->post(null));
124
            }
125
        }
126
127
         /**
128
         * Reset the form validation instance
129
         *
130
         * @return object the current instance
131
         */
132
        public function reset() {
133
            $this->rules        = array();
134
            $this->labels       = array();
135
            $this->errors       = array();
136
            $this->customErrors = array();
137
            $this->valid        = false;
138
            $this->forceError   = false;
139
            $this->data         = array();
140
            return $this;
141
        }
142
        
143
        /**
144
         * Set the validation data
145
         * @param array $data the data to be validated
146
         *
147
         * @return object the current instance.
148
         */
149
        public function setData(array $data) {
150
            $this->logger->debug('Setting the form validation data, the values are: ' . stringify_vars($data));
151
            $this->data = $data;
152
            return $this;
153
        }
154
155
         /**
156
         * Return the validation data
157
         * 
158
         * @return array the validation data
159
         */
160
        public function getData() {
161
            return $this->data;
162
        }
163
164
        /**
165
         * Add new validation rule.
166
         *
167
         * @param string $field name of the field or the data key to add a rule to
168
         * @param string $label the value of the field label
169
         * @param string|array $rule pipe seperated string or array of validation rules
170
         *
171
         * @return object the current instance.
172
         */
173
        public function setRule($field, $label, $rule) {
174
            $rules = array();
175
            //if the rule is array
176
            if (is_array($rule)) {
177
                $rules = $rule;
178
            } else {
179
                //the rule is not an array explode pipe values
180
                $rules = explode('|', $rule);
181
            }
182
            $this->rules[$field] = $rules;
183
            $this->labels[$field] = $label;
184
            return $this;
185
        }
186
187
        /**
188
         * Takes an array of rules and uses $this->setRule() to set them.
189
         * @param array $rules the array of rule
190
         *
191
         * @return object the current instance.
192
         */
193
        public function setRules(array $rules) {
194
            foreach ($rules as $rule) {
195
                $this->setRule($rule['name'], $rule['label'], $rule['rules']);
196
            }
197
            return $this;
198
        }
199
200
        /**
201
         * Return the list of the validations rules
202
         * @return array
203
         */
204
        public function getRules() {
205
            return $this->rules;
206
        }
207
208
         /**
209
         * Return the list of the validations rules for the given field
210
         * 
211
         * @return array
212
         */
213
        public function getFieldRules($field) {
214
            $rules = array();
215
            if (array_key_exists($field, $this->rules)) {
216
                $rules = $this->rules[$field];
217
            }
218
            return $rules;
219
        }
220
221
        /**
222
         * Return the value for the given field if exists otherwise null
223
         * will be returned
224
         * 
225
         * @return mixed
226
         */
227
        public function getFieldValue($field) {
228
             $value = null;
229
            if (array_key_exists($field, $this->data)) {
230
                $value = $this->data[$field];
231
            }
232
            return $value;
233
        }
234
235
        /**
236
         * Return the label for the given field if exists otherwise null
237
         * will be returned
238
         * 
239
         * @return string|null
240
         */
241
        public function getFieldLabel($field) {
242
            $label = null;
243
            if (array_key_exists($field, $this->labels)) {
244
                $label = $this->labels[$field];
245
            }
246
            return $label;
247
        }
248
            
249
        
250
       /**
251
        * Return the list of validation errors
252
        * 
253
        * @return array the errors list. 
254
        * Format:
255
        *  [field1] => 'error message 1', 
256
        *  [field2] => 'error message 2' 
257
        */
258
       public function getErrors() {
259
            return $this->errors;
260
        }
261
262
        /**
263
         * Process the data validation for each field, if it has any rules, run
264
         * each rule against the data value. 
265
         * and finally set $this->valid to true if there are no errors otherwise set to false
266
         * in case of error
267
         */
268
        public function validate() {
269
            //if the data is empty just return false
270
            if (empty($this->data)) {
271
                return false;
272
            }
273
            //Apply some filter/clean in the data to validate
274
            $this->filterValidationData();
275
276
            //Check the CSRF status
277
            $this->checkCsrf();
278
279
            //Now loop in each field rule and validate it
280
            foreach ($this->rules as $field => $rules) {
281
                $this->validateField($field, $rules);
282
            }
283
            $this->valid = empty($this->errors) && $this->forceError === false;
284
            return $this->valid;
285
        }
286
287
        /**
288
         * Return the validation status
289
         * @return boolean
290
         */
291
        public function isValid() {
292
            return $this->valid;
293
        }
294
295
        /**
296
         * Set a custom error message that can override the default error phrase provided.
297
         *  
298
         * If the parameter $field is null so means will set the error message for
299
         * all fields for the given rule, otherwise only error message for this field and rule will be set
300
         * the others fields use the default one for this rule.
301
         *
302
         * @param string $rule the name of the rule to set error message for.
303
         * @param string $message the error message it can contains the placeholder
304
         * {field}, {label}, {value}, {paramValue}, {field2}.
305
         * @param string|null $field if not null will set the error message only for this field and rule
306
         *
307
         * @return object the current instance.
308
         */
309
        public function setCustomErrorMessage($rule, $message, $field = null) {
310
            //1st if field is null all fields for this rule will be set to the same message
311
            //2nd if field is not null set only for this field
312
            if ($field !== null) {
313
                $this->customErrors[$field][$rule] = $message;
314
            } else {
315
                foreach (array_keys($this->rules) as $field) {
316
                    $this->customErrors[$field][$rule] = $message;
317
                }
318
            }
319
            return $this;
320
        }
321
322
        /**
323
         * Set the validation error for the given field
324
         * @param string $field      the error field
325
         * @param string $rule       the name of the rule raise this error
326
         * @param mixed $paramValue the value of rule parameter
327
         * Example: min_length[17], the $paramValue will be "17"
328
         * @param string|null $field2     the second field used in some validation rule like "matches", "not_equal"
329
         *
330
         * @return object the current instance
331
         */
332
        protected function setFieldError($field, $rule, $paramValue = null, $field2 = null) {
333
            //do we have error before?
334
            if (!array_key_exists($field, $this->errors)) {
335
                $this->errors[$field] = $this->getFieldErrorMessage($field, $rule, $paramValue, $field2);
336
            }
337
            return $this;
338
        }
339
340
        /**
341
         * Set the validation error for the given field by checking if the field is not required
342
         * or contains the value
343
         * @param string $field      the error field
344
         * @param mixed $value      the value of field
345
         * @param string $rule       the name of the rule raise this error
346
         * @param mixed $paramValue the value of rule parameter
347
         * Example: min_length[17], the $paramValue will be "17"
348
         * @param string|null $field2     the second field used in some validation rule like "matches", "not_equal"
349
         *
350
         */
351
         protected function setFieldErrorWithRequiredCheck($field, $value, $rule, $paramValue = null, $field2 = null) {
352
            //if the field is not required and his value is not set don't set error
353
            //but in case the field have value validate it
354
            if (!$this->fieldIsRequired($field) && strlen($value) <= 0) {
355
                return;
356
            }
357
            $this->setFieldError($field, $rule, $paramValue, $field2);
358
        }
359
360
        /**
361
         * Set the error for given field if condition(s) match(es).
362
         * 
363
         * @param boolean $conditions the condtion to evaluate, if true so means set the error for given field
364
         * @param string $field      the error field
365
         * @param mixed $value      the value of field
366
         * @param string $rule       the name of the rule raise this error
367
         * @param mixed $paramValue the value of rule parameter
368
         * Example: min_length[17], the $paramValue will be "17"
369
         * @param string|null $field2     the second field used in some validation rule like "matches", "not_equal"
370
         *
371
         */
372
        protected function setSimpleFieldError($conditions, $field, $value, $rule, $paramValue = null, $field2 = null) {
373
            if ($conditions) {
374
                $this->setFieldErrorWithRequiredCheck($field, $value, $rule, $paramValue, $field2);
375
            }
376
        }
377
378
        /**
379
         * Check whether the given field is required or not
380
         * @param  string $field the name of the field
381
         * @return boolean
382
         */
383
        protected function fieldIsRequired($field) {
384
            $rules = $this->getFieldRules($field);
385
            return in_array('required', $rules);
386
        }
387
        
388
        /**
389
         * Return the name of the method to use to validate the given rule
390
         * each method has a prefix of "checkRule"
391
         * @param  string $rule the name of the rule
392
         * @return string       the name of the validation method
393
         */
394
        protected function getRuleValidationMethod($rule) {
395
             $parts = explode('_', $rule);
396
             $parts = array_map('ucfirst', $parts);
397
             return 'checkRule' . implode('', $parts);
398
        }
399
        
400
        /**
401
         * This method is used to apply some filter rule on the validation data
402
         * like remove space, do some clean, etc.
403
         * @return object the current instance
404
         */
405
        protected function filterValidationData() {
406
            foreach ($this->data as $key => $value ) {
407
                if (is_string($value)) {
408
                   $this->data[$key] = trim($value);
409
                } else if(is_array($value)) {
410
                    $this->data[$key] = array_map('trim', $value);
411
                }
412
            }
413
            return $this;
414
        }
415
416
        /**
417
         * Validate the CSRF if the current request method is POST
418
         * and the check of CSRF is enabled in the configuration
419
         */
420
        protected function checkCsrf() {
421
            if (get_instance()->request->method() == 'POST') {
422
                $this->logger->debug('Check if CSRF is enabled in configuration');
423
                //first check for CSRF
424
                if (get_config('csrf_enable', false) && !get_instance()->security->validateCSRF()) {
425
                    $this->forceError = true;
426
                    show_error('Invalid data, Cross Site Request Forgery do his job, the data to validate is corrupted.');
427
                } else {
428
                    $this->logger->info('CSRF is not enabled in configuration or not set manully, no need to check it');
429
                }
430
            }
431
        }
432
              
433
        /**
434
         * Return the validation error message content for the given field
435
         * after replace all placeholders with their values
436
         * @param string $field      the error field
437
         * @param string $rule       the name of the rule raise this error
438
         * @param mixed $paramValue the value of rule parameter
439
         * Example: min_length[17], the $paramValue will be "17"
440
         * @param string|null $field2     the second field used in some validation rule like "matches", "not_equal"
441
         *
442
         * @return string the error message
443
         */
444
        protected function getFieldErrorMessage($field, $rule, $paramValue = null, $field2 = null) {
445
            $template = array(
446
                            '{field}'      => $field,
447
                            '{value}'      => $this->getFieldValue($field),
448
                            '{label}'      => $this->getFieldLabel($field),
449
                            '{paramValue}' => $paramValue
450
                            );
451
            if ($field2 !== null) {
452
                $template['{field2}']  = $field2;
453
                $template['{value2}'] = $this->getFieldValue($field2);
454
                $template['{label2}'] = $this->getFieldLabel($field2);
455
             }     
456
            $message = $this->messages[$rule];
457
            //Check for custom message
458
            if (isset($this->customErrors[$field][$rule])) {
459
                $message = $this->customErrors[$field][$rule];
460
            }
461
            return strtr($message, $template);
462
        }
463
464
        /**
465
         * Perform validation for the given field
466
         * @param  string $field the field name
467
         * @param  array $rules the list of rule to validate
468
         */
469
        protected function validateField($field, array $rules) {
470
            foreach ($rules as $rule) {
471
                $match = array();
472
                $paramValue = null;
473
                //Is the rule with parameter ??
474
                preg_match('/\[(.*)\]/', $rule, $match);
475
                if (isset($match[1])) {
476
                    $paramValue = $match[1];
477
                }
478
                //Now get the real rule name for example 
479
                //min_length[34]
480
                //the name will be "min_length" and paramValue will be "14"
481
                $realRuleName = preg_replace('/\[(.*)\]/', '', $rule);
482
483
                //Get the name of the method to validate this rule
484
                $method = $this->getRuleValidationMethod($realRuleName);
485
                if (method_exists($this, $method)) {
486
                       call_user_func_array(array($this, $method), array($field, $realRuleName, $paramValue));
487
                } else {
488
                    $this->forceError = true;
489
                    show_error('Invalid validaton rule "' . $realRuleName . '"');
490
                }
491
            }
492
        }
493
        
494
        /**
495
         * Set the validation messages using translation messages
496
         */
497
        protected function setValidationMessages() {
498
            //Load form validation language message
499
            get_instance()->loader->lang('form_validation');
500
            
501
            $this->messages['required']         = get_instance()->lang->get('fv_required');
502
            $this->messages['min_length']       = get_instance()->lang->get('fv_min_length');
503
            $this->messages['max_length']       = get_instance()->lang->get('fv_max_length');
504
            $this->messages['exact_length']     = get_instance()->lang->get('fv_exact_length');
505
            $this->messages['matches']          = get_instance()->lang->get('fv_matches');
506
            $this->messages['not_equal']        = get_instance()->lang->get('fv_not_equal');
507
            $this->messages['min']              = get_instance()->lang->get('fv_min');
508
            $this->messages['max']              = get_instance()->lang->get('fv_max');
509
            $this->messages['between']          = get_instance()->lang->get('fv_between');
510
            $this->messages['in_list']          = get_instance()->lang->get('fv_in_list');
511
            $this->messages['numeric']          = get_instance()->lang->get('fv_numeric');
512
            $this->messages['integer']          = get_instance()->lang->get('fv_integer');
513
            $this->messages['integer_natural']  = get_instance()->lang->get('fv_integer_natural');
514
            $this->messages['alpha']            = get_instance()->lang->get('fv_alpha');
515
            $this->messages['alpha_dash']       = get_instance()->lang->get('fv_alpha_dash');
516
            $this->messages['alnum']            = get_instance()->lang->get('fv_alnum');
517
            $this->messages['alnum_dash']       = get_instance()->lang->get('fv_alnum_dash');
518
            $this->messages['email']            = get_instance()->lang->get('fv_email');
519
            $this->messages['date']             = get_instance()->lang->get('fv_date');
520
            $this->messages['date_before']      = get_instance()->lang->get('fv_date_before');
521
            $this->messages['date_after']       = get_instance()->lang->get('fv_date_after');
522
            $this->messages['url']              = get_instance()->lang->get('fv_url');
523
            $this->messages['ip']               = get_instance()->lang->get('fv_ip');
524
            $this->messages['ipv4']             = get_instance()->lang->get('fv_ipv4');
525
            $this->messages['ipv6']             = get_instance()->lang->get('fv_ipv6');
526
            $this->messages['is_unique']        = get_instance()->lang->get('fv_is_unique');
527
            $this->messages['is_unique_update'] = get_instance()->lang->get('fv_is_unique_update');
528
            $this->messages['exists']           = get_instance()->lang->get('fv_exists');
529
            $this->messages['regex']            = get_instance()->lang->get('fv_regex');
530
            $this->messages['callback']         = get_instance()->lang->get('fv_callback');
531
        }
532
        
533
534
        /* ---------------------------------------------------------------------------------- */
535
        ///////////////////////////////////////////////////////////////////////////////////////
536
        /**************************** RULES VALIDATION METHODS ******************************/
537
        /////////////////////////////////////////////////////////////////////////////////////
538
        
539
        /**
540
         * Validation of rule "default_value[param]"
541
         *
542
         * NOTE: This one it's not a validation rule it just check if the value for the
543
         * given field is null, empty and set it by the parameter value.
544
         * 
545
         * @param  string $field the name of the field or data key name used
546
         * @param  string $rule  the rule name for this validation ("default_value")
547
         * @param  string|null  $paramValue  the rule parameter
548
         */
549
        protected function checkRuleDefaultValue($field, $rule, $paramValue) {
550
            $value = $this->getFieldValue($field);
551
            if (strlen($value) <= 0) {
552
                $this->data[$field] = $paramValue;
553
            }
554
        }
555
            
556
        /**
557
         * Validation of rule "required"
558
         * 
559
         * @param  string $field the name of the field or data key name used
560
         * @param  string $rule  the rule name for this validation ("required")
561
         * @param  string|null  $paramValue  the rule parameter
562
         */
563
        protected function checkRuleRequired($field, $rule, $paramValue) {
564
            $value = $this->getFieldValue($field);
565
            if ((is_array($value) && count($value) === 0) || $value == '') {
566
                $this->setFieldError($field, $rule, $paramValue);
567
            }
568
        }
569
        
570
        /**
571
         * Validation of rule "min_length[param]"
572
         * 
573
         * @param  string $field the name of the field or data key name used
574
         * @param  string $rule  the rule name for this validation ("min_length")
575
         * @param  string|null  $paramValue  the rule parameter
576
         */ 
577
        protected function checkRuleMinLength($field, $rule, $paramValue) {
578
           $value = $this->getFieldValue($field);  
579
           $this->setSimpleFieldError(
580
                                     strlen($value) < $paramValue, 
581
                                     $field, 
582
                                     $value, 
583
                                     $rule, 
584
                                     $paramValue
585
                                 );
586
        }
587
588
        /**
589
         * Validation of rule "max_length[param]"
590
         * 
591
         * @param  string $field the name of the field or data key name used
592
         * @param  string $rule  the rule name for this validation ("max_length")
593
         * @param  string|null  $paramValue  the rule parameter
594
         */
595
        protected function checkRuleMaxLength($field, $rule, $paramValue) {
596
           $value = $this->getFieldValue($field);
597
           $this->setSimpleFieldError(
598
                                     strlen($value) > $paramValue, 
599
                                     $field, 
600
                                     $value, 
601
                                     $rule, 
602
                                     $paramValue
603
                                 );
604
        }
605
606
        /**
607
         * Validation of rule "exact_length[param]"
608
         * 
609
         * @param  string $field the name of the field or data key name used
610
         * @param  string $rule  the rule name for this validation ("exact_length")
611
         * @param  string|null  $paramValue  the rule parameter
612
         */
613
        protected function checkRuleExactLength($field, $rule, $paramValue) {
614
           $value = $this->getFieldValue($field);
615
           $this->setSimpleFieldError(
616
                                     strlen($value) != $paramValue, 
617
                                     $field, 
618
                                     $value, 
619
                                     $rule, 
620
                                     $paramValue
621
                                 );
622
        }
623
624
        /**
625
         * Validation of rule "matches[param]"
626
         * 
627
         * @param  string $field the name of the field or data key name used
628
         * @param  string $rule  the rule name for this validation ("matches")
629
         * @param  string|null  $paramValue  the rule parameter
630
         */
631
        protected function checkRuleMatches($field, $rule, $paramValue) {
632
            $value = $this->getFieldValue($field);    
633
            $this->setSimpleFieldError(
634
                                     $value != $this->getFieldValue($paramValue), 
635
                                     $field, 
636
                                     $value, 
637
                                     $rule, 
638
                                     $paramValue,
639
                                     $paramValue //field2
640
                                 );
641
        }
642
643
        /**
644
         * Validation of rule "not_equal[param]"
645
         * 
646
         * @param  string $field the name of the field or data key name used
647
         * @param  string $rule  the rule name for this validation ("not_equal")
648
         * @param  string|null  $paramValue  the rule parameter
649
         */
650
        protected function checkRuleNotEqual($field, $rule, $paramValue) {
651
            $value = $this->getFieldValue($field);    
652
            $this->setSimpleFieldError(
653
                                     $value == $this->getFieldValue($paramValue), 
654
                                     $field, 
655
                                     $value, 
656
                                     $rule, 
657
                                     $paramValue,
658
                                     $paramValue //field2
659
                                 );
660
        }
661
662
        /**
663
         * Validation of rule "min[param]"
664
         * 
665
         * @param  string $field the name of the field or data key name used
666
         * @param  string $rule  the rule name for this validation ("min")
667
         * @param  string|null  $paramValue  the rule parameter
668
         */
669
        protected function checkRuleMin($field, $rule, $paramValue) {
670
            $value = $this->getFieldValue($field);  
671
            $this->setSimpleFieldError(
672
                                 $value < $paramValue, 
673
                                 $field, 
674
                                 $value, 
675
                                 $rule, 
676
                                 $paramValue
677
                             );
678
        }
679
680
        /**
681
         * Validation of rule "max[param]"
682
         * 
683
         * @param  string $field the name of the field or data key name used
684
         * @param  string $rule  the rule name for this validation ("max")
685
         * @param  string|null  $paramValue  the rule parameter
686
         */
687
        protected function checkRuleMax($field, $rule, $paramValue) {
688
            $value = $this->getFieldValue($field); 
689
            $this->setSimpleFieldError(
690
                                 $value > $paramValue, 
691
                                 $field, 
692
                                 $value, 
693
                                 $rule, 
694
                                 $paramValue
695
                             );
696
        }
697
698
        /**
699
         * Validation of rule "between[param]" param format is x,y
700
         * Example: between[1,100]
701
         * 
702
         * @param  string $field the name of the field or data key name used
703
         * @param  string $rule  the rule name for this validation ("between")
704
         * @param  string|null  $paramValue  the rule parameter
705
         */
706
        protected function checkRuleBetween($field, $rule, $paramValue) {
707
            $value = $this->getFieldValue($field);    
708
            $betweens = explode(',', $paramValue, 2);
709
            $betweens = array_map('trim', $betweens);
710
            $this->setSimpleFieldError(
711
                                 ($value < $betweens[0]) || ($value > $betweens[1]), 
712
                                 $field, 
713
                                 $value, 
714
                                 $rule, 
715
                                 $paramValue
716
                             );
717
        }
718
719
        /**
720
         * Validation of rule "in_list[param]" param format is a,b,c,d
721
         * Example: in_list[1,3,56,100]
722
         * 
723
         * @param  string $field the name of the field or data key name used
724
         * @param  string $rule  the rule name for this validation ("in_list")
725
         * @param  string|null  $paramValue  the rule parameter
726
         */
727
        protected function checkRuleInList($field, $rule, $paramValue) {
728
            $value = $this->getFieldValue($field);    
729
            $list = explode(',', $paramValue);
730
            $list = array_map('trim', $list);
731
            $paramValue = implode(',', $list);
732
            $this->setSimpleFieldError(
733
                                 !in_array($value, $list), 
734
                                 $field, 
735
                                 $value, 
736
                                 $rule, 
737
                                 $paramValue
738
                             ); 
739
        }
740
741
        /**
742
         * Validation of rule "numeric"
743
         * 
744
         * @param  string $field the name of the field or data key name used
745
         * @param  string $rule  the rule name for this validation ("numeric")
746
         * @param  string|null  $paramValue  the rule parameter
747
         */
748
        protected function checkRuleNumeric($field, $rule, $paramValue) {
749
            $value = $this->getFieldValue($field);    
750
            $this->setSimpleFieldError(
751
                                 !is_numeric($value), 
752
                                 $field, 
753
                                 $value, 
754
                                 $rule, 
755
                                 $paramValue
756
                             );
757
        }
758
759
        /**
760
         * Validation of rule "integer"
761
         * 
762
         * @param  string $field the name of the field or data key name used
763
         * @param  string $rule  the rule name for this validation ("integer")
764
         * @param  string|null  $paramValue  the rule parameter
765
         */
766
        protected function checkRuleInteger($field, $rule, $paramValue) {
767
            $value = $this->getFieldValue($field);  
768
             $this->setSimpleFieldError(
769
                                 filter_var($value, FILTER_VALIDATE_INT) === false, 
770
                                 $field, 
771
                                 $value, 
772
                                 $rule, 
773
                                 $paramValue
774
                             );
775
        }
776
777
        /**
778
         * Validation of rule "integer_natural"
779
         * 
780
         * @param  string $field the name of the field or data key name used
781
         * @param  string $rule  the rule name for this validation ("integer_natural")
782
         * @param  string|null  $paramValue  the rule parameter
783
         */
784
        protected function checkRuleIntegerNatural($field, $rule, $paramValue) {
785
            $value = $this->getFieldValue($field);
786
            $this->setSimpleFieldError(
787
                                 filter_var($value, FILTER_VALIDATE_INT) === false || $value < 0, 
788
                                 $field, 
789
                                 $value, 
790
                                 $rule, 
791
                                 $paramValue
792
                             );
793
        }
794
795
        /**
796
         * Validation of rule "alpha"
797
         * 
798
         * @param  string $field the name of the field or data key name used
799
         * @param  string $rule  the rule name for this validation ("alpha")
800
         * @param  string|null  $paramValue  the rule parameter
801
         */
802
        protected function checkRuleAlpha($field, $rule, $paramValue) {
803
            $value = $this->getFieldValue($field);
804
            $this->setSimpleFieldError(
805
                                 !preg_match('/^[\pL\pM\s]+$/u', $value), 
806
                                 $field, 
807
                                 $value, 
808
                                 $rule, 
809
                                 $paramValue
810
                             );
811
        }
812
813
        /**
814
         * Validation of rule "alpha_dash"
815
         * 
816
         * @param  string $field the name of the field or data key name used
817
         * @param  string $rule  the rule name for this validation ("alpha_dash")
818
         * @param  string|null  $paramValue  the rule parameter
819
         */
820
        protected function checkRuleAlphaDash($field, $rule, $paramValue) {
821
            $value = $this->getFieldValue($field);
822
            $this->setSimpleFieldError(
823
                                 !preg_match('/^[\pL\pM_-]+$/u', $value), 
824
                                 $field, 
825
                                 $value, 
826
                                 $rule, 
827
                                 $paramValue
828
                             );
829
        }
830
831
        /**
832
         * Validation of rule "alnum"
833
         * 
834
         * @param  string $field the name of the field or data key name used
835
         * @param  string $rule  the rule name for this validation ("alnum")
836
         * @param  string|null  $paramValue  the rule parameter
837
         */
838
        protected function checkRuleAlnum($field, $rule, $paramValue) {
839
            $value = $this->getFieldValue($field);
840
            $this->setSimpleFieldError(
841
                                 !preg_match('/^[\pL\pM\pN\s]+$/u', $value), 
842
                                 $field, 
843
                                 $value, 
844
                                 $rule, 
845
                                 $paramValue
846
                             );
847
        }
848
849
        /**
850
         * Validation of rule "alnum_dash"
851
         * 
852
         * @param  string $field the name of the field or data key name used
853
         * @param  string $rule  the rule name for this validation ("alnum_dash")
854
         * @param  string|null  $paramValue  the rule parameter
855
         */
856
        protected function checkRuleAlnumDash($field, $rule, $paramValue) {
857
            $value = $this->getFieldValue($field);
858
            $this->setSimpleFieldError(
859
                                 !preg_match('/^[\pL\pM\pN_-]+$/u', $value), 
860
                                 $field, 
861
                                 $value, 
862
                                 $rule, 
863
                                 $paramValue
864
                             );
865
        }
866
867
        /**
868
         * Validation of rule "email"
869
         * 
870
         * @param  string $field the name of the field or data key name used
871
         * @param  string $rule  the rule name for this validation ("email")
872
         * @param  string|null  $paramValue  the rule parameter
873
         */
874
        protected function checkRuleEmail($field, $rule, $paramValue) {
875
            $value = $this->getFieldValue($field); 
876
            $this->setSimpleFieldError(
877
                                 filter_var($value, FILTER_VALIDATE_EMAIL) === false, 
878
                                 $field, 
879
                                 $value, 
880
                                 $rule, 
881
                                 $paramValue
882
                             );
883
        }
884
885
        /**
886
         * Validation of rule "date[param]" param can be a valid 
887
         * value supported by function date()
888
         * 
889
         * @param  string $field the name of the field or data key name used
890
         * @param  string $rule  the rule name for this validation ("date")
891
         * @param  string|null  $paramValue  the rule parameter
892
         */
893
        protected function checkRuleDate($field, $rule, $paramValue) {
894
            $value = $this->getFieldValue($field);
895
            $format = $paramValue;
896
            $dateValue = date_create_from_format($format, $value);  
897
            $this->setSimpleFieldError(
898
                                 $dateValue === false || $dateValue->format($format) !== $value, 
899
                                 $field, 
900
                                 $value, 
901
                                 $rule, 
902
                                 $paramValue
903
                             );
904
        }
905
906
        /**
907
         * Validation of rule "date_before[param]" param can be a valid 
908
         * value supported by function strtotime()
909
         * 
910
         * @param  string $field the name of the field or data key name used
911
         * @param  string $rule  the rule name for this validation ("date_before")
912
         * @param  string|null  $paramValue  the rule parameter
913
         */
914
        protected function checkRuleDateBefore($field, $rule, $paramValue) {
915
            $value = $this->getFieldValue($field);
916
             $this->setSimpleFieldError(
917
                                 strtotime($value) >= strtotime($paramValue), 
918
                                 $field, 
919
                                 $value, 
920
                                 $rule, 
921
                                 $paramValue
922
                             );
923
        }
924
925
        /**
926
         * Validation of rule "date_after[param]" param can be a valid 
927
         * value supported by function strtotime()
928
         * 
929
         * @param  string $field the name of the field or data key name used
930
         * @param  string $rule  the rule name for this validation ("date_after")
931
         * @param  string|null  $paramValue  the rule parameter
932
         */
933
        protected function checkRuleDateAfter($field, $rule, $paramValue) {
934
            $value = $this->getFieldValue($field);
935
            $this->setSimpleFieldError(
936
                                 strtotime($value) <= strtotime($paramValue), 
937
                                 $field, 
938
                                 $value, 
939
                                 $rule, 
940
                                 $paramValue
941
                             );
942
        }
943
944
        /**
945
         * Validation of rule "url"
946
         * 
947
         * @param  string $field the name of the field or data key name used
948
         * @param  string $rule  the rule name for this validation ("url")
949
         * @param  string|null  $paramValue  the rule parameter
950
         */
951
        protected function checkRuleUrl($field, $rule, $paramValue) {
952
            $value = $this->getFieldValue($field);
953
            $this->setSimpleFieldError(
954
                                 filter_var($value, FILTER_VALIDATE_URL) === false, 
955
                                 $field, 
956
                                 $value, 
957
                                 $rule, 
958
                                 $paramValue
959
                             );
960
        }
961
962
        /**
963
         * Validation of rule "ip", the correct value can be ipv4, ipv6, for specific rule
964
         * use the rule below like ipv4 or ipv6.
965
         * 
966
         * @param  string $field the name of the field or data key name used
967
         * @param  string $rule  the rule name for this validation ("ip")
968
         * @param  string|null  $paramValue  the rule parameter
969
         */
970
        protected function checkRuleIp($field, $rule, $paramValue) {
971
            $value = $this->getFieldValue($field);   
972
            $this->setSimpleFieldError(
973
                                 filter_var($value, FILTER_VALIDATE_IP) === false, 
974
                                 $field, 
975
                                 $value, 
976
                                 $rule, 
977
                                 $paramValue
978
                             );
979
        }
980
981
        /**
982
         * Validation of rule "ipv4"
983
         * 
984
         * @param  string $field the name of the field or data key name used
985
         * @param  string $rule  the rule name for this validation ("ipv4")
986
         * @param  string|null  $paramValue  the rule parameter
987
         */
988
        protected function checkRuleIpv4($field, $rule, $paramValue) {
989
            $value = $this->getFieldValue($field);  
990
            $this->setSimpleFieldError(
991
                                 filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false, 
992
                                 $field, 
993
                                 $value, 
994
                                 $rule, 
995
                                 $paramValue
996
                             );
997
        }
998
999
        /**
1000
         * Validation of rule "ipv6"
1001
         * 
1002
         * @param  string $field the name of the field or data key name used
1003
         * @param  string $rule  the rule name for this validation ("ipv6")
1004
         * @param  string|null  $paramValue  the rule parameter
1005
         */
1006
        protected function checkRuleIpv6($field, $rule, $paramValue) {
1007
            $value = $this->getFieldValue($field);   
1008
            $this->setSimpleFieldError(
1009
                                 filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false, 
1010
                                 $field, 
1011
                                 $value, 
1012
                                 $rule, 
1013
                                 $paramValue
1014
                             );
1015
        }
1016
1017
        /**
1018
         * Validation of rule "is_unique[param]" param value format is
1019
         * [tablename.fieldname]
1020
         * 
1021
         * @param  string $field the name of the field or data key name used
1022
         * @param  string $rule  the rule name for this validation ("is_unique")
1023
         * @param  string|null  $paramValue  the rule parameter
1024
         */
1025
        protected function checkRuleIsUnique($field, $rule, $paramValue) {
1026
            $obj = & get_instance();
1027
            //@codeCoverageIgnoreStart
1028
            if (!isset($obj->database)) {
1029
                return;
1030
            }
1031
            //@codeCoverageIgnoreEnd
1032
            $value = $this->getFieldValue($field);    
1033
            list($table, $column) = explode('.', $paramValue);
1034
            $obj->database->getQueryBuilder()->from($table)
1035
                                              ->where($column, $value);
1036
            $obj->database->get();
1037
            if ($obj->database->numRows() > 0) {
1038
                $this->setFieldErrorWithRequiredCheck($field, $value, $rule, $paramValue);
1039
            }
1040
        }
1041
1042
        /**
1043
         * Validation of rule "is_unique_update[param]" param value format is
1044
         * [tablename.fieldname,keyfield=value]
1045
         * 
1046
         * @param  string $field the name of the field or data key name used
1047
         * @param  string $rule  the rule name for this validation ("is_unique_update")
1048
         * @param  string|null  $paramValue  the rule parameter
1049
         */
1050
        protected function checkRuleIsUniqueUpdate($field, $rule, $paramValue) {
1051
            $obj = & get_instance();
1052
            //@codeCoverageIgnoreStart
1053
            if (!isset($obj->database)) {
1054
                return;
1055
            }
1056
            //@codeCoverageIgnoreEnd
1057
            $value = $this->getFieldValue($field);  
1058
            $data = explode(',', $paramValue, 2);
1059
            list($table, $column) = explode('.', $data[0]);
1060
            list($columnKey, $valueKey) = explode('=', $data[1]);
1061
            $obj->database->getQueryBuilder()->from($table)
1062
                                              ->where($column, $value)
1063
                                              ->where($columnKey, '!=', trim($valueKey));
1064
            $obj->database->get();
1065
            if ($obj->database->numRows() > 0) {
1066
                $this->setFieldErrorWithRequiredCheck($field, $value, $rule, $paramValue);
1067
            }
1068
        }
1069
1070
        /**
1071
         * Validation of rule "exists[param]" param value format is
1072
         * [tablename.fieldname]
1073
         * 
1074
         * @param  string $field the name of the field or data key name used
1075
         * @param  string $rule  the rule name for this validation ("exists")
1076
         * @param  string|null  $paramValue  the rule parameter
1077
         */
1078
        protected function checkRuleExists($field, $rule, $paramValue) {
1079
            $obj = & get_instance();
1080
            //@codeCoverageIgnoreStart
1081
            if (!isset($obj->database)) {
1082
                return;
1083
            }
1084
            //@codeCoverageIgnoreEnd
1085
            $value = $this->getFieldValue($field);    
1086
            list($table, $column) = explode('.', $paramValue);
1087
            $obj->database->getQueryBuilder()->from($table)
1088
                                              ->where($column, $value);
1089
            $obj->database->get();
1090
            if ($obj->database->numRows() <= 0) {
1091
                $this->setFieldErrorWithRequiredCheck($field, $value, $rule, $paramValue);
1092
            }
1093
        }
1094
1095
        /**
1096
         * Validation of rule "regex[param]" param can be any value supported by
1097
         * function preg_match()
1098
         * 
1099
         * @param  string $field the name of the field or data key name used
1100
         * @param  string $rule  the rule name for this validation ("regex")
1101
         * @param  string|null  $paramValue  the rule parameter
1102
         */
1103
        protected function checkRuleRegex($field, $rule, $paramValue) {
1104
            $value = $this->getFieldValue($field);
1105
             $this->setSimpleFieldError(
1106
                                 !preg_match($paramValue, $value), 
1107
                                 $field, 
1108
                                 $value, 
1109
                                 $rule, 
1110
                                 $paramValue
1111
                             );       
1112
        }
1113
1114
        /**
1115
         * Validation of rule "callback[param]" param can be any value supported by
1116
         * function is_callable() and this callable must accept one argument for
1117
         * the field value and must return false or true for the validation status.
1118
         * Example:
1119
         *
1120
         * function check_username_exists($value) {
1121
         *   //some check
1122
         *   return {true|false}
1123
         * }
1124
         * 
1125
         * @param  string $field the name of the field or data key name used
1126
         * @param  string $rule  the rule name for this validation ("required")
1127
         * @param  string|null  $paramValue  the rule parameter
1128
         */
1129
        protected function checkRuleCallback($field, $rule, $paramValue) {
1130
            $value = $this->getFieldValue($field);    
1131
            if (is_callable($paramValue)) {
1132
                $this->setSimpleFieldError(
1133
                                 call_user_func_array($paramValue, array($value)) === false, 
1134
                                 $field, 
1135
                                 $value, 
1136
                                 $rule, 
1137
                                 $paramValue
1138
                             ); 
1139
            } else{
1140
                $this->forceError = true;
1141
                show_error('The callback validation function/method "' . $paramValue . '" does not exist');
1142
            }
1143
        }
1144
1145
    }
1146