source: trunk/lib/Validator.inc.php @ 200

Last change on this file since 200 was 200, checked in by scdev, 18 years ago

Changed element validated by fileUploaded to name? because it will not be set if there is a file error.

File size: 10.0 KB
Line 
1<?php
2/**
3 * Validator.inc.php
4 * Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information
5 *
6 * The Validator class provides a methods for validating input against different criteria.
7 * All functions return true if the input passes the test.
8 *
9 * @author    Quinn Comendant <quinn@strangecode.com>
10 * @version   1.0
11 */
12
13// Known credit card types.
14define('CC_TYPE_VISA', 1);
15define('CC_TYPE_MASTERCARD', 2);
16define('CC_TYPE_AMEX', 3);
17define('CC_TYPE_DISCOVER', 4);
18define('CC_TYPE_DINERS', 5);
19define('CC_TYPE_JCB', 6);
20
21// validateEmail return types.
22define('VALIDATE_EMAIL_REGEX_FAIL', 1);
23define('VALIDATE_EMAIL_LENGTH_FAIL', 2);
24define('VALIDATE_EMAIL_MX_FAIL', 3);
25define('VALIDATE_EMAIL_SUCCESS', 4);
26
27class Validator {
28
29    /**
30     * Ensures a value is empty.
31     *
32     * @param  string $val The input data to validate.
33     * @return bool   true if form is not empty, false otherwise.
34     */
35    function notEmpty($val)
36    {
37        return '' != trim((string)$val);
38    }
39
40    /**
41     * Ensures a value is blank.
42     *
43     * @param  string $val The input data to validate.
44     * @return bool   true if form is empty, false otherwise.
45     */
46    function isEmpty($val)
47    {
48        return '' == trim((string)$val);
49    }
50
51    /**
52     * Check whether input is a string.
53     *
54     * @param  string $val The input data to validate.
55     * @return bool   true if form is a string, false otherwise.
56     */
57    function isString($val)
58    {
59        return '' == trim((string)$val) || is_string($val);
60    }
61
62    /**
63     * Check whether input is a number. Allows negative numbers.
64     *
65     * @param  string $val The input data to validate.
66     * @return bool   True if no errors found, false otherwise.
67     */
68    function isNumber($val)
69    {
70        return '' == trim((string)$val) || is_numeric($val);
71    }
72
73    /**
74     * addError if input is NOT an integer. Don't just use is_int() because the
75     * data coming from the user is *really* a string.
76     *
77     * @param  string $val The input data to validate.
78     * @return bool   true if value is an integer
79     */
80    function isInteger($val, $negative_ok=false)
81    {
82        $pattern = $negative_ok ? '/^-?[[:digit:]]+$/' : '/^[[:digit:]]+$/';
83        return '' == trim((string)$val) || (is_numeric($val) && preg_match($pattern, $val));
84    }
85
86    /**
87     * Check whether input is a float. Don't just use is_float() because the
88     * data coming from the user is *really* a string. Integers will also
89     * pass this test.
90     *
91     * @param  string $val The input data to validate.
92     * @return bool   true if value is a float
93     */
94    function isFloat($val, $negative_ok=false)
95    {
96        $pattern = $negative_ok ? '/^-?[[:digit:]]*(?:\.?[[:digit:]]+)$/' : '/^[[:digit:]]*(?:\.?[[:digit:]]+)$/';
97        return '' == trim((string)$val) || (is_numeric($val) && preg_match($pattern, $val));
98    }
99
100    /**
101     * Check whether input is an array.
102     *
103     * @param  string $val The input data to validate.
104     * @return bool   true if value is a float
105     */
106    function isArray($val)
107    {
108        return (is_string($val) && '' == trim((string)$val)) || is_array($val);
109    }
110
111    /**
112     * Check whether input matches the specified perl regular expression
113     * pattern.
114     *
115     * @param  string $val The input data to validate.
116     * @param  int    $regex            PREG that the string must match
117     * @param  bool   $valid_on_match   Set to false to be valid if match, or true
118     *                                  to be valid on no match
119     * @return bool   true if value passes regex test
120     */
121    function checkRegex($val, $regex, $valid_on_match=true)
122    {
123        return $valid_on_match ? preg_match($regex, $val) : !preg_match($regex, $val);
124    }
125
126    /**
127     * Tests if the string length is between specified values. Whitespace excluded for min.
128     *
129     * @param  string $val The input data to validate.
130     * @param  int    $min       minimum length of string, inclusive
131     * @param  int    $max       maximum length of string, inclusive
132     * @return bool   true if string length is within given boundaries
133     */
134    function stringLength($val, $min, $max)
135    {
136        return strlen(trim((string)$val)) >= $min && strlen($val) <= $max;
137    }
138
139    /**
140     * Check whether input is within a valid numeric range.
141     *
142     * @param  string $val The input data to validate.
143     * @param  int    $min       minimum value of number, inclusive
144     * @param  int    $max       maximum value of number, inclusive
145     * @return bool   True if no errors found, false otherwise.
146     */
147    function numericRange($val, $min, $max)
148    {
149        return '' == trim((string)$val) || (is_numeric($val) && $val >= $min && $val <= $max);
150    }
151
152    /**
153     * Validates an email address based on the recommendations in RFC 3696.
154     * Is more loose than restrictive, to allow the many valid variants of
155     * email addresses while catching the most common mistakes.
156     * http://www.faqs.org/rfcs/rfc822.html
157     * http://www.faqs.org/rfcs/rfc2822.html
158     * http://www.faqs.org/rfcs/rfc3696.html
159     * http://www.faqs.org/rfcs/rfc1035.html
160     *
161     * @access  public
162     * @param   string  $val  The input data to validate..
163     * @return  bool    Validity of address.
164     * @author  Quinn Comendant <quinn@strangecode.com>
165     */
166    function validateEmail($val)
167    {
168        require_once 'codebase/lib/Email.inc.php';
169        $e = new Email();
170
171        // Test email address format.
172        if (!preg_match($e->getParam('regex'), $val, $e_parts)) {
173            return VALIDATE_EMAIL_REGEX_FAIL;
174        }
175       
176        // We have a match! Here are the captured subpatterns, on which further tests are run.
177        // The part before the @.
178        $local = $e_parts[2];
179
180        // The part after the @.
181        // If domain is an IP [XXX.XXX.XXX.XXX] strip off the brackets.
182        $domain = $e_parts[3]{0} == '[' ? substr($e_parts[3], 1, -1) : $e_parts[3];
183
184        // Test length.
185        if (strlen($local) > 64 || strlen($domain) > 191) {
186            return VALIDATE_EMAIL_LENGTH_FAIL;
187        }
188
189        // Check domain exists: It's a domain if ip2long fails; Checkdnsrr ensures a MX record exists; Gethostbyname() ensures the domain exists.
190        // Compare ip2long twice for php4 backwards compat.
191        if ((ip2long($domain) == '-1' || ip2long($domain) === false) && function_exists('checkdnsrr') && !checkdnsrr($domain . '.', 'MX') && gethostbyname($domain) == $domain) {
192            return VALIDATE_EMAIL_MX_FAIL;
193        }
194
195        return VALIDATE_EMAIL_SUCCESS;
196    }
197
198    /**
199     * Verifies that date can be processed by the strtotime function.
200     *
201     * @param  string  $val The input data to validate.
202     * @return bool    True if no errors found, false otherwise.
203     */
204    function validateStrDate($val)
205    {
206        $app =& App::getInstance();
207       
208        $timestamp = strtotime($val);
209        // Return values change between php4 and php5.
210        if ($timestamp === -1 || $timestamp === false) {
211            return false;
212        } else {
213            return true;
214        }
215    }
216
217
218    /**
219     * Verifies credit card number.
220     *
221     * @param  string  $val   The input data to validate..
222     * @param  string  $cc_num      Card number to verify.
223     * @param  string  $cc_type     Optional, card type to do specific checks.
224     * @return bool    True if no errors found, false otherwise.
225     */
226     function validateCCNumber($val, $cc_type=null)
227     {
228         // Get rid of any non-digits
229         $cc_num = preg_replace('/[^\d]/', '', $val);
230
231         // Perform card-specific checks, if applicable
232         switch ($cc_type) {
233             case CC_TYPE_VISA :
234                 $regex = '/^4\d{15}$|^4\d{12}$/';
235                 break;
236             case CC_TYPE_MASTERCARD :
237                 $regex = '/^5[1-5]\d{14}$/';
238                 break;
239             case CC_TYPE_AMEX :
240                 $regex = '/^3[47]\d{13}$/';
241                 break;
242             case CC_TYPE_DISCOVER :
243                 $regex = '/^6011\d{12}$/';
244                 break;
245             case CC_TYPE_DINERS :
246                 $regex = '/^30[0-5]\d{11}$|^3[68]\d{12}$/';
247                 break;
248             case CC_TYPE_JCB :
249                 $regex = '/^3\d{15}$|^2131|1800\d{11}$/';
250                 break;
251             default :
252                 $regex = '';
253                 break;
254         }
255         
256         if ('' != $regex && !preg_match($regex, $cc_num)) {
257             // Invalid format.
258             return false;
259         }
260
261         // The Luhn formula works right to left, so reverse the number.
262         $cc_num = strrev($cc_num);
263
264         $luhn_total = 0;
265
266         $num = strlen($cc_num);
267         for ($i=0; $i<$num; $i++) {
268             // Get each digit.
269             $digit = substr($cc_num, $i, 1);
270
271             //  If it's an odd digit, double it.
272             if ($i / 2 != floor($i / 2)) {
273                 $digit *= 2;
274             }
275
276             //  If the result is two digits, add them.
277             if (strlen($digit) == 2) {
278                 $digit = substr($digit, 0, 1) + substr($digit, 1, 1);
279             }
280
281             //  Add the current digit to the $luhn_total.
282             $luhn_total += $digit;
283         }
284
285         // If the Total is evenly divisible by 10, it's cool!
286         return $luhn_total % 10 == 0;
287     }
288
289    /**
290     * Check whether a file was selected for uploading. If file is missing, it's an error.
291     *
292     * @param  string $form_name The input data to validate.
293     * @return bool   True if no errors found, false otherwise.
294     */
295    function fileUploaded($form_name)
296    {
297        if (!isset($_FILES[$form_name]['name']) || empty($_FILES[$form_name]['name'])) {
298            return false;
299        }
300       
301        if (is_array($_FILES[$form_name]['name'])) {
302            foreach($_FILES[$form_name]['name'] as $f) {
303                if ('' == $f) {
304                    return false;
305                }
306            }
307        } else {
308            if ('' == $_FILES[$form_name]['name']) {
309                return false;
310            }
311        }
312       
313        return true;
314    }
315
316} // THE END
317
318?>
Note: See TracBrowser for help on using the repository browser.