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

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

Added better error response when mcve engine not running.

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