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

Last change on this file since 281 was 281, checked in by quinn, 17 years ago

Removed escapeString from the printing of the sort order string. This string should contain raw-sql and quoting it can break things.

File size: 10.3 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 mb_strlen(trim((string)$val)) >= $min && mb_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} == '[' ? mb_substr($e_parts[3], 1, -1) : $e_parts[3];
183
184        // Test length.
185        if (mb_strlen($local) > 64 || mb_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        if ('' == trim($val)) {
209            // Don't be too bothered about empty strings.
210            return true;
211        }
212
213        $timestamp = strtotime($val);
214        // Return values change between php4 and php5.
215        if ('' != trim($val) && ($timestamp === -1 || $timestamp === false)) {
216            return false;
217        } else {
218            return true;
219        }
220    }
221
222
223    /**
224     * Verifies credit card number using the Luhn (mod 10) algorithm.
225     * http://en.wikipedia.org/wiki/Luhn_algorithm
226     *
227     * @param  string  $val   The input data to validate..
228     * @param  string  $cc_num      Card number to verify.
229     * @param  string  $cc_type     Optional, card type to do specific checks.
230     * @return bool    True if no errors found, false otherwise.
231     */
232     function validateCCNumber($val, $cc_type=null)
233     {
234         // Get rid of any non-digits
235         $cc_num = preg_replace('/[^\d]/', '', $val);
236
237         // Perform card-specific checks, if applicable
238         switch ($cc_type) {
239             case CC_TYPE_VISA :
240                 $regex = '/^4\d{15}$|^4\d{12}$/';
241                 break;
242             case CC_TYPE_MASTERCARD :
243                 $regex = '/^5[1-5]\d{14}$/';
244                 break;
245             case CC_TYPE_AMEX :
246                 $regex = '/^3[47]\d{13}$/';
247                 break;
248             case CC_TYPE_DISCOVER :
249                 $regex = '/^6011\d{12}$/';
250                 break;
251             case CC_TYPE_DINERS :
252                 $regex = '/^30[0-5]\d{11}$|^3[68]\d{12}$/';
253                 break;
254             case CC_TYPE_JCB :
255                 $regex = '/^3\d{15}$|^2131|1800\d{11}$/';
256                 break;
257             default :
258                 $regex = '';
259                 break;
260         }
261         
262         if ('' != $regex && !preg_match($regex, $cc_num)) {
263             // Invalid format.
264             return false;
265         }
266
267         // The Luhn formula works right to left, so reverse the number.
268         $cc_num = strrev($cc_num);
269
270         $luhn_total = 0;
271
272         $num = mb_strlen($cc_num);
273         for ($i=0; $i<$num; $i++) {
274             // Get each digit.
275             $digit = mb_substr($cc_num, $i, 1);
276
277             //  If it's an odd digit, double it.
278             if ($i / 2 != floor($i / 2)) {
279                 $digit *= 2;
280             }
281
282             //  If the result is two digits, add them.
283             if (mb_strlen($digit) == 2) {
284                 $digit = mb_substr($digit, 0, 1) + mb_substr($digit, 1, 1);
285             }
286
287             //  Add the current digit to the $luhn_total.
288             $luhn_total += $digit;
289         }
290
291         // If the Total is evenly divisible by 10, it's cool!
292         return $luhn_total % 10 == 0;
293     }
294
295    /**
296     * Check whether a file was selected for uploading. If file is missing, it's an error.
297     *
298     * @param  string $form_name The input data to validate.
299     * @return bool   True if no errors found, false otherwise.
300     */
301    function fileUploaded($form_name)
302    {
303        if (!isset($_FILES[$form_name]['name']) || empty($_FILES[$form_name]['name'])) {
304            return false;
305        }
306       
307        if (is_array($_FILES[$form_name]['name'])) {
308            foreach($_FILES[$form_name]['name'] as $f) {
309                if ('' == $f) {
310                    return false;
311                }
312            }
313        } else {
314            if ('' == $_FILES[$form_name]['name']) {
315                return false;
316            }
317        }
318       
319        return true;
320    }
321
322} // THE END
323
324?>
Note: See TracBrowser for help on using the repository browser.