Passed
Push — 1.0.0-dev ( ea6d41...cf37bc )
by nguereza
03:00
created

FormValidation::setRules()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 11
rs 10
c 2
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 GNU GPL License (GPL)
9
     *
10
     * Copyright (C) 2017 Tony NGUEREZA
11
     *
12
     * This program is free software; you can redistribute it and/or
13
     * modify it under the terms of the GNU General Public License
14
     * as published by the Free Software Foundation; either version 3
15
     * of the License, or (at your option) any later version.
16
     *
17
     * This program is distributed in the hope that it will be useful,
18
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     * GNU General Public License for more details.
21
     *
22
     * You should have received a copy of the GNU General Public License
23
     * along with this program; if not, write to the Free Software
24
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
     */
26
27
28
        class FormValidation extends BaseClass {
29
		 
30
        /**
31
         * The form validation status
32
         * @var boolean
33
         */
34
        protected $_success = false;
35
36
        /**
37
         * The list of errors messages
38
         * @var array
39
         */
40
        protected $_errorsMessages = array();
41
        
42
        // Array of rule sets, fieldName => PIPE seperated ruleString
43
        protected $_rules = array();
44
        
45
        // Array of errors, niceName => Error Message
46
        protected $_errors = array();
47
        
48
        // Array of post Key => Nice name labels
49
        protected $_labels = array();
50
        
51
        /**
52
         * The errors delimiters
53
         * @var array
54
         */
55
        protected $_allErrorsDelimiter = array('<div class="error">', '</div>');
56
57
        /**
58
         * The each error delimiter
59
         * @var array
60
         */
61
        protected $_eachErrorDelimiter = array('<p class="error">', '</p>');
62
        
63
        /**
64
         * Indicated if need force the validation to be failed
65
         * @var boolean
66
         */
67
        protected $_forceFail = false;
68
69
        /**
70
         * The list of the error messages overrides by the original
71
         * @var array
72
         */
73
        protected $_errorPhraseOverrides = array();
74
75
        /**
76
         * The data to be validated, the default is to use $_POST
77
         * @var array
78
         */
79
        private $data = array();
80
81
82
        /**
83
         * The database instance
84
         * @var object
85
         */
86
        private $databaseInstance = null;
87
88
        /**
89
         * Set all errors and rule sets empty, and sets success to false.
90
         *
91
         * @return void
92
         */
93
        public function __construct() {
94
            parent::__construct();
95
           
96
            //Load form validation language message
97
            Loader::lang('form_validation');
98
            $obj = & get_instance();
99
            $this->_errorsMessages = array(
100
                        'required'         => $obj->lang->get('fv_required'),
101
                        'min_length'       => $obj->lang->get('fv_min_length'),
102
                        'max_length'       => $obj->lang->get('fv_max_length'),
103
                        'exact_length'     => $obj->lang->get('fv_exact_length'),
104
                        'less_than'        => $obj->lang->get('fv_less_than'),
105
                        'greater_than'     => $obj->lang->get('fv_greater_than'),
106
                        'matches'          => $obj->lang->get('fv_matches'),
107
                        'valid_email'      => $obj->lang->get('fv_valid_email'),
108
                        'not_equal'        => array(
109
                                                'post:key' => $obj->lang->get('fv_not_equal_post_key'),
110
                                                'string'   => $obj->lang->get('fv_not_equal_string')
111
                                            ),
112
                        'depends'          => $obj->lang->get('fv_depends'),
113
                        'is_unique'        => $obj->lang->get('fv_is_unique'),
114
                        'is_unique_update' => $obj->lang->get('fv_is_unique_update'),
115
                        'exists'           => $obj->lang->get('fv_exists'),
116
                        'regex'            => $obj->lang->get('fv_regex'),
117
                        'in_list'          => $obj->lang->get('fv_in_list'),
118
                        'numeric'          => $obj->lang->get('fv_numeric'),
119
                        'callback'         => $obj->lang->get('fv_callback'),
120
                    );
121
            $this->_resetValidation();
122
            $this->setData($obj->request->post(null));
123
        }
124
125
        /**
126
         * Set the database instance
127
         * @param object $database the database instance
128
         */
129
        public function setDatabase(Database $database) {
130
            $this->databaseInstance = $database;
131
            return $this;
132
        }
133
134
        /**
135
         * Get the database instance
136
         * @return object the database instance
137
         */
138
        public function getDatabase() {
139
            return $this->databaseInstance;
140
        }
141
142
        /**
143
         * Reset the form validation instance
144
         */
145
        protected function _resetValidation() {
146
            $this->_rules                = array();
147
            $this->_labels               = array();
148
            $this->_errorPhraseOverrides = array();
149
            $this->_errors               = array();
150
            $this->_success              = false;
151
            $this->_forceFail            = false;
152
            $this->data                  = array();
153
        }
154
155
        /**
156
         * Set the form validation data
157
         * @param array $data the values to be validated
158
         *
159
         * @return FormValidation Current instance of object.
160
         */
161
        public function setData(array $data) {
162
            $this->logger->debug('Setting the form validation data, the values are: ' . stringfy_vars($data));
163
            $this->data = $data;
164
            return $this;
165
        }
166
167
        /**
168
         * Get the form validation data
169
         * @return array the form validation data to be validated
170
         */
171
        public function getData() {
172
            return $this->data;
173
        }
174
175
        /**
176
         * Get the validation function name to validate a rule
177
         *
178
         * @return string the function name
179
         */
180
        protected function _toCallCase($funcName, $prefix = '_validate') {
181
            $funcName = strtolower($funcName);
182
            $finalFuncName = $prefix;
183
            foreach (explode('_', $funcName) as $funcNamePart) {
184
                $finalFuncName .= strtoupper($funcNamePart[0]) . substr($funcNamePart, 1);
185
            }
186
            return $finalFuncName;
187
        }
188
189
        /**
190
         * Returns the boolean of the data status success. It goes by the simple
191
         *
192
         * @return boolean Whether or not the data validation has succeeded
193
         */
194
        public function isSuccess() {
195
            return $this->_success;
196
        }
197
198
        /**
199
         * Checks if the request method is POST or the Data to be validated is set
200
         *
201
         * @return boolean Whether or not the form has been submitted or the data is available for validation.
202
         */
203
        public function canDoValidation() {
204
            return get_instance()->request->method() === 'POST' || !empty($this->data);
205
        }
206
207
        /**
208
         * Runs _run once POST data has been submitted or data is set manually.
209
         *
210
         * @return boolean
211
         */
212
        public function run() {
213
            if ($this->canDoValidation()) {
214
                $this->logger->info('The data to validate are listed below: ' . stringfy_vars($this->getData()));
215
                $this->_run();
216
            }
217
            return $this->isSuccess();
218
        }
219
220
        /**
221
         * Validate the CSRF 
222
         * @return void 
223
         */
224
        protected function validateCSRF() {
225
            if (get_instance()->request->method() == 'POST') {
226
                $this->logger->debug('Check if CSRF is enabled in configuration');
227
                //first check for CSRF
228
                if (get_config('csrf_enable', false) && !Security::validateCSRF()) {
229
                    show_error('Invalide data, Cross Site Request Forgery do his job, the data to validate is corrupted.');
230
                } else {
231
                    $this->logger->info('CSRF is not enabled in configuration or not set manully, no need to check it');
232
                }
233
            }
234
        }
235
        
236
        /**
237
         * Takes and trims each data, if it has any rules, we parse the rule string and run
238
         * each rule against the data value. Sets _success to true if there are no errors
239
         * afterwards.
240
         */
241
        protected function _run() {
242
            //validate CSRF
243
            $this->validateCSRF();
244
            /////////////////////////////////////////////
245
            $this->_forceFail = false;
246
247
            foreach ($this->getData() as $inputName => $inputVal) {
248
                if (is_array($this->data[$inputName])) {
249
                    $this->data[$inputName] = array_map('trim', $this->data[$inputName]);
250
                } else {
251
                    $this->data[$inputName] = trim($this->data[$inputName]);
252
                }
253
254
                if (array_key_exists($inputName, $this->_rules)) {
255
                    foreach ($this->_parseRuleString($this->_rules[$inputName]) as $eachRule) {
256
                        $this->_validateRule($inputName, $this->data[$inputName], $eachRule);
257
                    }
258
                }
259
            }
260
            $this->_success = empty($this->_errors) && $this->_forceFail === false;
261
        }
262
263
        /**
264
         * Adds a rule to a form data validation field.
265
         *
266
         * @param string $inputField Name of the field or the data key to add a rule to
267
         * @param string $ruleSets PIPE seperated string of rules
268
         *
269
         * @return FormValidation Current instance of object.
270
         */
271
        public function setRule($inputField, $inputLabel, $ruleSets) {
272
            $this->_rules[$inputField] = $ruleSets;
273
            $this->_labels[$inputField] = $inputLabel;
274
            $this->logger->info('Set the field rule: name [' . $inputField . '], label [' . $inputLabel . '], rules [' . $ruleSets . ']');
275
            return $this;
276
        }
277
278
        /**
279
         * Takes an array of rules and uses setRule() to set them, accepts an array
280
         * of rule names rather than a pipe-delimited string as well.
281
         * @param array $ruleSets
282
         *
283
         * @return FormValidation Current instance of object.
284
         */
285
        public function setRules(array $ruleSets) {
286
            foreach ($ruleSets as $ruleSet) {
287
                $pipeDelimitedRules = null;
288
                if (is_array($ruleSet['rules'])) {
289
                    $pipeDelimitedRules = implode('|', $ruleSet['rules']);
290
                } else {
291
                    $pipeDelimitedRules = $ruleSet['rules'];
292
                }
293
                $this->setRule($ruleSet['name'], $ruleSet['label'], $pipeDelimitedRules);
294
            }
295
            return $this;
296
        }
297
298
        /**
299
         * This method creates the global errors delimiter, each argument occurs once, at the beginning, and
300
         * end of the errors block respectively.
301
         *
302
         * @param string $start Before block of errors gets displayed, HTML allowed.
303
         * @param string $end After the block of errors gets displayed, HTML allowed.
304
         *
305
         * @return FormValidation Current instance of object.
306
         */
307
        public function setErrorsDelimiter($start, $end) {
308
            $this->_allErrorsDelimiter[0] = $start;
309
            $this->_allErrorsDelimiter[1] = $end;
310
            return $this;
311
        }
312
313
        /**
314
         * This is the individual error delimiter, each argument occurs once before and after
315
         * each individual error listed.
316
         *
317
         * @param string $start Displayed before each error.
318
         * @param string $end Displayed after each error.
319
         * 
320
         * @return FormValidation Current instance of object.
321
         */
322
        public function setErrorDelimiter($start, $end) {
323
            $this->_eachErrorDelimiter[0] = $start;
324
            $this->_eachErrorDelimiter[1] = $end;
325
            return $this;
326
        }
327
328
        /**
329
         * Get the each errors delimiters
330
         *
331
         * @return array
332
         */
333
        public function getErrorDelimiter() {
334
            return $this->_eachErrorDelimiter;
335
        }
336
337
        /**
338
         * Get the all errors delimiters
339
         *
340
         * @return array
341
         */
342
        public function getErrorsDelimiter() {
343
            return $this->_allErrorsDelimiter;
344
        }
345
346
        /**
347
         * This sets a custom error message that can override the default error phrase provided
348
         * by FormValidation, it can be used in the format of setMessage('rule', 'error phrase')
349
         * which will globally change the error phrase of that rule, or in the format of:
350
         * setMessage('rule', 'fieldname', 'error phrase') - which will only change the error phrase for
351
         * that rule, applied on that field.
352
         *
353
         * @return boolean True on success, false on failure.
354
         */
355
        public function setMessage() {
356
            $numArgs = func_num_args();
357
            switch ($numArgs) {
358
                default:
359
                    return false;
360
                // A global rule error message
361
                case 2:
362
                    foreach ($this->post(null) as $key => $val) {
363
                        $this->_errorPhraseOverrides[$key][func_get_arg(0)] = func_get_arg(1);
364
                    }
365
                    break;
366
                // Field specific rule error message
367
                case 3:
368
                    $this->_errorPhraseOverrides[func_get_arg(1)][func_get_arg(0)] = func_get_arg(2);
369
                    break;
370
            }
371
            return true;
372
        }
373
374
        /**
375
         * Adds a custom error message in the errorSet array, that will
376
         * forcibly display it.
377
         *
378
         * @param string $inputName The form input name or data key
379
         * @param string $errorMessage Error to display
380
         *
381
         * @return formValidation Current instance of the object
382
         */
383
        public function setCustomError($inputName, $errorMessage) {
384
            $errorMessage = str_replace('%1', $this->_labels[$inputName], $errorMessage);
385
            $this->_errors[$inputName] = $errorMessage;
386
            return $this;
387
        }
388
389
        /**
390
         * Allows for an accesor to any/all post values, if a value of null is passed as the key, it
391
         * will recursively find all keys/values of the $_POST array or data array. It also automatically trims
392
         * all values.
393
         *
394
         * @param string $key Key of $this->data to be found, pass null for all Key => Val pairs.
395
         * @param boolean $trim Defaults to true, trims all $this->data values.
396
         * @return string|array Array of post or data values if null is passed as key, string if only one key is desired.
397
         */
398
        public function post($key = null, $trim = true) {
399
            $returnValue = null;
400
            if (is_null($key)) {
401
                $returnValue = array();
402
                foreach ($this->data  as $key => $val) {
403
                    $returnValue[$key] = $this->post($key, $trim);
404
                }
405
            } else {
406
                $returnValue = (array_key_exists($key, $this->getData())) ? (($trim) ? trim($this->data[$key]) : $this->data[$key]) : null;
407
            }
408
            return $returnValue;
409
        }
410
411
        /**
412
         * Gets all errors from errorSet and displays them, can be echo out from the
413
         * function or just returned.
414
         *
415
         * @param boolean $limit number of error to display or return
416
         * @param boolean $echo Whether or not the values are to be returned or displayed
417
         *
418
         * @return string Errors formatted for output
419
         */
420
        public function displayErrors($limit = null, $echo = true) {
421
            list($errorsStart, $errorsEnd) = $this->_allErrorsDelimiter;
422
            list($errorStart, $errorEnd) = $this->_eachErrorDelimiter;
423
            $errorOutput = $errorsStart;
424
            $i = 0;
425
            if (!empty($this->_errors)) {
426
                foreach ($this->_errors as $fieldName => $error) {
427
                    if ($i === $limit) { 
428
                        break; 
429
                    }
430
                    $errorOutput .= $errorStart;
431
                    $errorOutput .= $error;
432
                    $errorOutput .= $errorEnd;
433
                    $i++;
434
                }
435
            }
436
            $errorOutput .= $errorsEnd;
437
            echo ($echo) ? $errorOutput : '';
438
            return (!$echo) ? $errorOutput : null;
439
        }
440
441
        /**
442
         * Returns raw array of errors in no format instead of displaying them
443
         * formatted.
444
         *
445
         * @return array
446
         */
447
        public function returnErrors() {
448
            return $this->_errors;
449
        }
450
451
        /**
452
         * Breaks up a PIPE seperated string of rules, and puts them into an array.
453
         *
454
         * @param string $ruleString String to be parsed.
455
         *
456
         * @return array Array of each value in original string.
457
         */
458
        protected function _parseRuleString($ruleString) {
459
            $ruleSets = array();
460
            /*
461
            //////////////// hack for regex rule that can contain "|"
462
            */
463
            if (strpos($ruleString, 'regex') !== false) {
464
                $regexRule = array();
465
                $rule = '#regex\[\/(.*)\/([a-zA-Z0-9]?)\]#';
466
                preg_match($rule, $ruleString, $regexRule);
467
                $ruleStringTemp = preg_replace($rule, '', $ruleString);
468
                if (!empty($regexRule[0])) {
469
                    $ruleSets[] = $regexRule[0];
470
                }
471
                 $ruleStringRegex = explode('|', $ruleStringTemp);
472
                foreach ($ruleStringRegex as $rule) {
473
                    $rule = trim($rule);
474
                    if ($rule) {
475
                        $ruleSets[] = $rule;
476
                    }
477
                }
478
                 
479
            }
480
            /***********************************/
481
            else {
482
                if (strpos($ruleString, '|') !== FALSE) {
483
                    $ruleSets = explode('|', $ruleString);
484
                } else {
485
                    $ruleSets[] = $ruleString;
486
                }
487
            }
488
            return $ruleSets;
489
        }
490
491
        /**
492
         * Returns whether or not a field obtains the rule "required".
493
         *
494
         * @param string $fieldName Field to check if required.
495
         *
496
         * @return boolean Whether or not the field is required.
497
         */
498
        protected function _fieldIsRequired($fieldName) {
499
            $rules = $this->_parseRuleString($this->_rules[$fieldName]);
500
            return (in_array('required', $rules));
501
        }
502
503
        /**
504
         * Takes a data input name, it's value, and the rule it's being validated against (ex: max_length[16])
505
         * and adds an error to the errorSet if it fails validation of the rule.
506
         *
507
         * @param string $inputName Name or key of the validation data
508
         * @param string $inputVal Value of the validation data
509
         * @param string $ruleName Rule to be validated against, including args (exact_length[5])
510
         * @return void
511
         */
512
        protected function _validateRule($inputName, $inputVal, $ruleName) {
513
            $this->logger->debug('Rule validation of field [' . $inputName . '], value [' . $inputVal . '], rule [' . $ruleName . ']');
514
            // Array to store args
515
            $ruleArgs = array();
516
517
            preg_match('/\[(.*)\]/', $ruleName, $ruleArgs);
518
519
            // Get the rule arguments, realRule is just the base rule name
520
            // Like min_length instead of min_length[3]
521
            $ruleName = preg_replace('/\[(.*)\]/', '', $ruleName);
522
            
523
            if (method_exists($this, $this->_toCallCase($ruleName))) {
524
                $methodToCall = $this->_toCallCase($ruleName);
525
                call_user_func(array($this, $methodToCall), $inputName, $ruleName, $ruleArgs);
526
            }
527
            return;
528
        }
529
530
        /**
531
         * Set error for the given field or key
532
         *
533
         * @param string $inputName the input or key name
534
         * @param string $ruleName the rule name
535
         * @param array|string $replacements
536
         */
537
        protected function _setError($inputName, $ruleName, $replacements = array()) {
538
            $rulePhraseKeyParts = explode(',', $ruleName);
539
            $rulePhrase = null;
540
            foreach ($rulePhraseKeyParts as $rulePhraseKeyPart) {
541
                if (array_key_exists($rulePhraseKeyPart, $this->_errorsMessages)) {
542
                    $rulePhrase = $this->_errorsMessages[$rulePhraseKeyPart];
543
                } else {
544
                    $rulePhrase = $rulePhrase[$rulePhraseKeyPart];
545
                }
546
            }
547
            // Any overrides?
548
            if (array_key_exists($inputName, $this->_errorPhraseOverrides) && array_key_exists($ruleName, $this->_errorPhraseOverrides[$inputName])) {
549
                $rulePhrase = $this->_errorPhraseOverrides[$inputName][$ruleName];
550
            }
551
            // Type cast to array in case it's a string
552
            $replacements = (array) $replacements;
553
            $replacementCount = count($replacements);
554
            for ($i = 1; $i <= $replacementCount; $i++) {
555
                $key = $i - 1;
556
                $rulePhrase = str_replace('%' . $i, $replacements[$key], $rulePhrase);
557
            }
558
            if (!array_key_exists($inputName, $this->_errors)) {
559
                $this->_errors[$inputName] = $rulePhrase;
560
            }
561
        }
562
563
        /**
564
         * Used to run a callback for the callback rule, as well as pass in a default
565
         * argument of the data value. For example the username field having a rule:
566
         * callback[userExists] will call the function userExists() with parameter data[username].
567
         *
568
         * @param type $inputArg
569
         * @param string $callbackFunc
570
         *
571
         * @return boolean
572
         */
573
        protected function _runCallback($inputArg, $callbackFunc) {
574
            return call_user_func($callbackFunc, $inputArg);
575
        }
576
577
        /**
578
         * Gets a specific label of a specific field input name.
579
         *
580
         * @param string $inputName
581
         *
582
         * @return string
583
         */
584
        protected function _getLabel($inputName) {
585
            return (array_key_exists($inputName, $this->_labels)) ? $this->_labels[$inputName] : $inputName;
586
        }
587
		
588
        /**
589
         * Peform validation for the rule "required"
590
         * @param  string $inputName the form field or data key name used
591
         * @param  string $ruleName  the rule name for this validation ("required")
592
         * @param  array  $ruleArgs  the rules argument
593
         */
594
        protected function _validateRequired($inputName, $ruleName, array $ruleArgs) {
595
            $inputVal = $this->post($inputName);
596
            if ($inputVal == '') {
597
                $this->_setError($inputName, $ruleName, $this->_getLabel($inputName));
598
            }
599
        }
600
601
        /**
602
         * Perform validation for the honey pot so means for the validation to be failed
603
         * @param  string $inputName the form field or data key name used
604
         * @param  string $ruleName  the rule name for this validation
605
         * @param  array  $ruleArgs  the rules argument
606
         */
607
        protected function _validateHoneypot($inputName, $ruleName, array $ruleArgs) {
608
            if ($this->data[$inputName] != '') {
609
                $this->_forceFail = true;
610
            }
611
        }
612
613
        /**
614
         * Peform validation for the rule "callback"
615
         * @param  string $inputName the form field or data key name used
616
         * @param  string $ruleName  the rule name for this validation ("callback")
617
         * @param  array  $ruleArgs  the rules argument
618
         */
619
        protected function _validateCallback($inputName, $ruleName, array $ruleArgs) {
620
            if (function_exists($ruleArgs[1]) && array_key_exists($inputName, $this->data)) {
621
                $result = $this->_runCallback($this->data[$inputName], $ruleArgs[1]);
622
                if (!$result) {
623
                    $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
624
                }
625
            }
626
        }
627
628
        /**
629
         * Peform validation for the rule "depends"
630
         * @param  string $inputName the form field or data key name used
631
         * @param  string $ruleName  the rule name for this validation ("depends")
632
         * @param  array  $ruleArgs  the rules argument
633
         */
634
        protected function _validateDepends($inputName, $ruleName, array $ruleArgs) {
635
            if (array_key_exists($ruleArgs[1], $this->_errors)) {
636
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
637
            }
638
        }
639
640
        /**
641
         * Peform validation for the rule "not_equal"
642
         * @param  string $inputName the form field or data key name used
643
         * @param  string $ruleName  the rule name for this validation ("not_equal")
644
         * @param  array  $ruleArgs  the rules argument
645
         */
646
        protected function _validateNotEqual($inputName, $ruleName, array $ruleArgs) {
647
            $canNotEqual = explode(',', $ruleArgs[1]);
648
            foreach ($canNotEqual as $doNotEqual) {
649
                $inputVal = $this->post($inputName);
650
                if (preg_match('/post:(.*)/', $doNotEqual)) {
651
                    if ($inputVal == $this->data[str_replace('post:', '', $doNotEqual)]) {
652
                        $this->_setError($inputName, $ruleName . ',post:key', array($this->_getLabel($inputName), $this->_getLabel(str_replace('post:', '', $doNotEqual))));
653
                        continue;
654
                    }
655
                } else {
656
                    if ($inputVal == $doNotEqual) {
657
                        $this->_setError($inputName, $ruleName . ',string', array($this->_getLabel($inputName), $doNotEqual));
658
                        continue;
659
                    }
660
                }
661
            }
662
        }
663
664
        /**
665
         * Peform validation for the rule "matches"
666
         * @param  string $inputName the form field or data key name used
667
         * @param  string $ruleName  the rule name for this validation ("matches")
668
         * @param  array  $ruleArgs  the rules argument
669
         */
670
        protected function _validateMatches($inputName, $ruleName, array $ruleArgs) {
671
            $inputVal = $this->post($inputName);
672
            if ($inputVal != $this->data[$ruleArgs[1]]) {
673
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
674
            }
675
        }
676
677
        /**
678
         * Peform validation for the rule "valid_email"
679
         * @param  string $inputName the form field or data key name used
680
         * @param  string $ruleName  the rule name for this validation ("valid_email")
681
         * @param  array  $ruleArgs  the rules argument
682
         */
683
        protected function _validateValidEmail($inputName, $ruleName, array $ruleArgs) {
684
            $inputVal = $this->post($inputName);
685
            if (!preg_match("/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i", $inputVal)) {
686
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
687
                    return;
688
                }
689
                $this->_setError($inputName, $ruleName, $this->_getLabel($inputName));
690
            }
691
        }
692
693
        /**
694
         * Peform validation for the rule "exact_length"
695
         * @param  string $inputName the form field or data key name used
696
         * @param  string $ruleName  the rule name for this validation ("exact_length")
697
         * @param  array  $ruleArgs  the rules argument
698
         */
699
        protected function _validateExactLength($inputName, $ruleName, array $ruleArgs) {
700
            $inputVal = $this->post($inputName);
701
            if (strlen($inputVal) != $ruleArgs[1]) { // $ruleArgs[0] is [length] $rulesArgs[1] is just length
702
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
703
                    return;
704
                }
705
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
706
            }
707
        }
708
709
        /**
710
         * Peform validation for the rule "max_length"
711
         * @param  string $inputName the form field or data key name used
712
         * @param  string $ruleName  the rule name for this validation ("max_length")
713
         * @param  array  $ruleArgs  the rules argument
714
         */
715
        protected function _validateMaxLength($inputName, $ruleName, array $ruleArgs) {
716
            $inputVal = $this->post($inputName);
717
            if (strlen($inputVal) > $ruleArgs[1]) { // $ruleArgs[0] is [length] $rulesArgs[1] is just length
718
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
719
                    return;
720
                }
721
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
722
            }
723
        }
724
725
        /**
726
         * Peform validation for the rule "min_length"
727
         * @param  string $inputName the form field or data key name used
728
         * @param  string $ruleName  the rule name for this validation ("min_length")
729
         * @param  array  $ruleArgs  the rules argument
730
         */
731
        protected function _validateMinLength($inputName, $ruleName, array $ruleArgs) {
732
            $inputVal = $this->post($inputName);
733
            if (strlen($inputVal) < $ruleArgs[1]) { // $ruleArgs[0] is [length] $rulesArgs[1] is just length
734
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
735
                    return;
736
                }
737
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
738
            }
739
        }
740
    	
741
        /**
742
         * Peform validation for the rule "less_than"
743
         * @param  string $inputName the form field or data key name used
744
         * @param  string $ruleName  the rule name for this validation ("less_than")
745
         * @param  array  $ruleArgs  the rules argument
746
         */
747
        protected function _validateLessThan($inputName, $ruleName, array $ruleArgs) {
748
            $inputVal = $this->post($inputName);
749
            if ($inputVal >= $ruleArgs[1]) { 
750
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
751
                    return;
752
                }
753
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
754
            }
755
        }
756
    	
757
        /**
758
         * Peform validation for the rule "greater_than"
759
         * @param  string $inputName the form field or data key name used
760
         * @param  string $ruleName  the rule name for this validation ("greater_than")
761
         * @param  array  $ruleArgs  the rules argument
762
         */
763
        protected function _validateGreaterThan($inputName, $ruleName, array $ruleArgs) {
764
            $inputVal = $this->post($inputName);
765
            if ($inputVal <= $ruleArgs[1]) {
766
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
767
                    return;
768
                }
769
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
770
            }
771
        }
772
    	
773
        /**
774
         * Peform validation for the rule "numeric"
775
         * @param  string $inputName the form field or data key name used
776
         * @param  string $ruleName  the rule name for this validation ("numeric")
777
         * @param  array  $ruleArgs  the rules argument
778
         */
779
        protected function _validateNumeric($inputName, $ruleName, array $ruleArgs) {
780
            $inputVal = $this->post($inputName);
781
            if (!is_numeric($inputVal)) {
782
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
783
                    return;
784
                }
785
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
786
            }
787
        }
788
		
789
        /**
790
         * Peform validation for the rule "exists"
791
         * @param  string $inputName the form field or data key name used
792
         * @param  string $ruleName  the rule name for this validation ("exists")
793
         * @param  array  $ruleArgs  the rules argument
794
         */
795
        protected function _validateExists($inputName, $ruleName, array $ruleArgs) {
796
            $inputVal = $this->post($inputName);
797
            if (!is_object($this->databaseInstance)) {
798
                $obj = & get_instance();
799
                if (isset($obj->database)) {
800
                    $this->databaseInstance = $obj->database;
801
                } 
802
            }
803
            list($table, $column) = explode('.', $ruleArgs[1]);
804
            $this->databaseInstance->getQueryBuilder()->from($table)
805
                                                        ->where($column, $inputVal);
806
            $this->databaseInstance->get();
807
            if ($this->databaseInstance->numRows() <= 0) {
808
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
809
                    return;
810
                }
811
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
812
            }
813
        }
814
815
        /**
816
         * Peform validation for the rule "is_unique"
817
         * @param  string $inputName the form field or data key name used
818
         * @param  string $ruleName  the rule name for this validation ("is_unique")
819
         * @param  array  $ruleArgs  the rules argument
820
         */
821
        protected function _validateIsUnique($inputName, $ruleName, array $ruleArgs) {
822
            $inputVal = $this->post($inputName);
823
            if (!is_object($this->databaseInstance)) {
824
                $obj = & get_instance();
825
                if (isset($obj->database)) {
826
                    $this->databaseInstance = $obj->database;
827
                } 
828
            }
829
            list($table, $column) = explode('.', $ruleArgs[1]);
830
            $this->databaseInstance->getQueryBuilder()->from($table)
831
                                                        ->where($column, $inputVal);
832
            $this->databaseInstance->get();
833
            if ($this->databaseInstance->numRows() > 0) {
834
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
835
                    return;
836
                }
837
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
838
            }
839
        }
840
    	
841
        /**
842
         * Peform validation for the rule "is_unique_update"
843
         * @param  string $inputName the form field or data key name used
844
         * @param  string $ruleName  the rule name for this validation ("is_unique_update")
845
         * @param  array  $ruleArgs  the rules argument
846
         */
847
        protected function _validateIsUniqueUpdate($inputName, $ruleName, array $ruleArgs) {
848
            $inputVal = $this->post($inputName);
849
            if (!is_object($this->databaseInstance)) {
850
                $obj = & get_instance();
851
                if (isset($obj->database)) {
852
                    $this->databaseInstance = $obj->database;
853
                } 
854
            }
855
            $data = explode(',', $ruleArgs[1]);
856
            if (count($data) < 2) {
857
                return;
858
            }
859
            list($table, $column) = explode('.', $data[0]);
860
            list($field, $val)    = explode('=', $data[1]);
861
            $this->databaseInstance->getQueryBuilder()->from($table)
862
                                                        ->where($column, $inputVal)
863
                                                        ->where($field, '!=', trim($val));
864
            $this->databaseInstance->get();
865
            if ($this->databaseInstance->numRows() > 0) {
866
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
867
                    return;
868
                }
869
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
870
            }
871
        }
872
873
        /**
874
         * Peform validation for the rule "in_list"
875
         * @param  string $inputName the form field or data key name used
876
         * @param  string $ruleName  the rule name for this validation ("in_list")
877
         * @param  array  $ruleArgs  the rules argument
878
         */
879
        protected function _validateInList($inputName, $ruleName, array $ruleArgs) {
880
            $inputVal = $this->post($inputName);
881
            $list = explode(',', $ruleArgs[1]);
882
            $list = array_map('trim', $list);
883
            if (!in_array($inputVal, $list)) {
884
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
885
                    return;
886
                }
887
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName), $this->_getLabel($ruleArgs[1])));
888
            }
889
        }
890
891
        /**
892
         * Peform validation for the rule "regex"
893
         * @param  string $inputName the form field or data key name used
894
         * @param  string $ruleName  the rule name for this validation ("regex")
895
         * @param  array  $ruleArgs  the rules argument
896
         */
897
        protected function _validateRegex($inputName, $ruleName, array $ruleArgs) {
898
            $inputVal = $this->post($inputName);
899
            $regex = $ruleArgs[1];
900
            if (!preg_match($regex, $inputVal)) {
901
                if (!$this->_fieldIsRequired($inputName) && empty($this->data[$inputName])) {
902
                    return;
903
                }
904
                $this->_setError($inputName, $ruleName, array($this->_getLabel($inputName)));
905
            }
906
        }
907
        
908
    }
909