1: <?php
2:
3: namespace Alpha\Util\Helper;
4:
5: /**
6: * Generic validation class used throughout the Alpha Framework.
7: *
8: * @since 1.0
9: *
10: * @author John Collins <dev@alphaframework.org>
11: * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
12: * @copyright Copyright (c) 2016, John Collins (founder of Alpha Framework).
13: * All rights reserved.
14: *
15: * <pre>
16: * Redistribution and use in source and binary forms, with or
17: * without modification, are permitted provided that the
18: * following conditions are met:
19: *
20: * * Redistributions of source code must retain the above
21: * copyright notice, this list of conditions and the
22: * following disclaimer.
23: * * Redistributions in binary form must reproduce the above
24: * copyright notice, this list of conditions and the
25: * following disclaimer in the documentation and/or other
26: * materials provided with the distribution.
27: * * Neither the name of the Alpha Framework nor the names
28: * of its contributors may be used to endorse or promote
29: * products derived from this software without specific
30: * prior written permission.
31: *
32: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
33: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
34: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
35: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45: * </pre>
46: */
47: class Validator
48: {
49: /**
50: * Allows any kind of input, including blanks.
51: *
52: * @var string
53: *
54: * @since 1.0
55: */
56: const ALLOW_ALL = '/.*/i';
57:
58: /**
59: * Required double value.
60: *
61: * @var string
62: *
63: * @since 1.0
64: */
65: const REQUIRED_DOUBLE = '/^-{0,1}[0-9\.]+$/';
66:
67: /**
68: * Required integer value.
69: *
70: * @var string
71: *
72: * @since 1.0
73: */
74: const REQUIRED_INTEGER = '/^-{0,1}[0-9]*$/';
75:
76: /**
77: * Required text value, accepts a maximum of 65536 characters.
78: *
79: * @var string
80: *
81: * @since 1.0
82: */
83: const REQUIRED_TEXT = '/^[\S]{1}.{0,65535}$/';
84:
85: /**
86: * Required string value, accepts a maximum of 255 characters.
87: *
88: * @var string
89: *
90: * @since 1.0
91: */
92: const REQUIRED_STRING = '/^[\S]{1}.{0,254}$/';
93:
94: /**
95: * Required alphabet string.
96: *
97: * @var string
98: *
99: * @since 1.0
100: */
101: const REQUIRED_ALPHA = '/^[a-zA-Z]+$/';
102:
103: /**
104: * Required uppercase alphabet string.
105: *
106: * @var string
107: *
108: * @since 1.0
109: */
110: const REQUIRED_ALPHA_UPPER = '/^[A-Z]+$/';
111:
112: /**
113: * Required alpha-numeric string.
114: *
115: * @var string
116: *
117: * @since 1.0
118: */
119: const REQUIRED_ALPHA_NUMERIC = '/^[a-zA-Z0-9]+$/';
120:
121: /**
122: * Required HTTP URL value.
123: *
124: * @var string
125: *
126: * @since 1.0
127: */
128: const REQUIRED_HTTP_URL = '/^((http|https):\/\/.*)$/i';
129:
130: /**
131: * Optional HTTP URL value.
132: *
133: * @var string
134: *
135: * @since 1.0
136: */
137: const OPTIONAL_HTTP_URL = '/(http|https).*|^$/i';
138:
139: /**
140: * Required IP address value.
141: *
142: * @var string
143: *
144: * @since 1.0
145: */
146: const REQUIRED_IP = '/^(((([1-9])|([1-9][\d])|(1[\d]{2})|(2[0-4][\d])|(25[0-4]))(\.(([\d])|([1-9][\d])|(1[\d]{2})|(2[0-4][\d])|(25[0-4]))){3})|(0(\.0){3}))$/';
147:
148: /**
149: * Required email address value.
150: *
151: * @var string
152: *
153: * @since 1.0
154: */
155: const REQUIRED_EMAIL = '/^[-_.a-zA-Z0-9]+@((([a-zA-Z0-9]|[-_.a-zA-Z0-9]*[a-zA-Z0-9])\.)+(ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$/i';
156:
157: /**
158: * Required username (allows a-z A-Z 0-9 and -_. characters).
159: *
160: * @var string
161: *
162: * @since 1.0
163: */
164: const REQUIRED_USERNAME = '/^[-_\.a-zA-Z0-9]+$/';
165:
166: /**
167: * Required sequence value.
168: *
169: * @var string
170: *
171: * @since 1.0
172: */
173: const REQUIRED_SEQUENCE = '/^[A-Z]*-[0-9]*$/';
174:
175: /**
176: * Validate that the provided value is a valid integer.
177: *
178: * @param $value
179: *
180: * @return bool
181: *
182: * @since 1.0
183: */
184: public static function isInteger($value)
185: {
186: if (preg_match(self::REQUIRED_INTEGER, $value)) {
187: return is_numeric($value) ? intval($value) == $value : false;
188: } else {
189: return false;
190: }
191: }
192:
193: /**
194: * Validate that the provided value is a valid double.
195: *
196: * @param $value
197: *
198: * @return bool
199: *
200: * @since 1.0
201: */
202: public static function isDouble($value)
203: {
204: if (preg_match(self::REQUIRED_DOUBLE, $value)) {
205: return is_numeric($value) ? doubleval($value) == $value : false;
206: } else {
207: return false;
208: }
209: }
210:
211: /**
212: * Validate that the provided value is a valid boolean (will accept 1 or 0 as valid booleans).
213: *
214: * @param $value
215: *
216: * @return bool
217: *
218: * @since 1.0
219: */
220: public static function isBoolean($value)
221: {
222: $acceptable = array(true, false, 'true', 'false', 1, 0, '1', '0', 'on', 'off');
223:
224: if (!in_array($value, $acceptable, true)) {
225: return false;
226: } else {
227: return true;
228: }
229: }
230:
231: /**
232: * Validate that the provided value is a valid boolean true or not (true, 'true', 1, '1', 'on').
233: *
234: * @param $value
235: *
236: * @return bool
237: *
238: * @since 2.0
239: */
240: public static function isBooleanTrue($value)
241: {
242: $acceptableTrue = array(true, 'true', 1, '1', 'on');
243:
244: if (!in_array($value, $acceptableTrue, true)) {
245: return false;
246: } else {
247: return true;
248: }
249: }
250:
251: /**
252: * Validate that the provided value is a valid alphabetic string (strictly a-zA-Z).
253: *
254: * @param $value
255: *
256: * @return bool
257: *
258: * @since 1.0
259: */
260: public static function isAlpha($value)
261: {
262: if (preg_match(self::REQUIRED_ALPHA, $value)) {
263: return true;
264: } else {
265: return false;
266: }
267: }
268:
269: /**
270: * Validate that the provided value is a valid alpha-numeric string (strictly a-zA-Z0-9).
271: *
272: * @param $value
273: *
274: * @return bool
275: *
276: * @since 1.0
277: */
278: public static function isAlphaNum($value)
279: {
280: if (preg_match(self::REQUIRED_ALPHA_NUMERIC, $value)) {
281: return true;
282: } else {
283: return false;
284: }
285: }
286:
287: /**
288: * Validate that the provided value is a valid Sequence string ([A-Z]-[0-9]).
289: *
290: * @param $value
291: *
292: * @return bool
293: *
294: * @since 1.0
295: */
296: public static function isSequence($value)
297: {
298: if (preg_match(self::REQUIRED_SEQUENCE, $value)) {
299: return true;
300: } else {
301: return false;
302: }
303: }
304:
305: /**
306: * Validate that the provided value is a valid URL.
307: *
308: * @param $value
309: *
310: * @return bool
311: *
312: * @since 1.0
313: */
314: public static function isURL($url)
315: {
316: if (preg_match(self::REQUIRED_HTTP_URL, $url)) {
317: if (!filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) {
318: return false;
319: } else {
320: return true;
321: }
322: } else {
323: return false;
324: }
325: }
326:
327: /**
328: * Validate that the provided value is a valid IP address.
329: *
330: * @param $value
331: *
332: * @return bool
333: *
334: * @since 1.0
335: */
336: public static function isIP($ip)
337: {
338: if (preg_match(self::REQUIRED_IP, $ip)) {
339: if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
340: return false;
341: } else {
342: return true;
343: }
344: } else {
345: return false;
346: }
347: }
348:
349: /**
350: * Validate that the provided value is a valid email address.
351: *
352: * @param $value
353: *
354: * @return bool
355: *
356: * @since 1.0
357: */
358: public static function isEmail($email)
359: {
360: if (preg_match(self::REQUIRED_EMAIL, $email)) {
361: if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
362: return false;
363: } else {
364: return true;
365: }
366: } else {
367: return false;
368: }
369: }
370:
371: /**
372: * Validate that the provided value is base64 encoded (best guess by regex).
373: *
374: * @param $value
375: *
376: * @return bool
377: *
378: * @since 1.2.2
379: */
380: public static function isBase64($value)
381: {
382: return (bool) preg_match('/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/', $value);
383: }
384:
385: /**
386: * Will return true if the value provided contains any HTML code that is stripable by
387: * the native strip_tags() function.
388: *
389: * @param $value
390: *
391: * @return bool
392: *
393: * @since 2.0.1
394: */
395: public static function isHTML($value)
396: {
397: return $value != strip_tags($value) ? true : false;
398: }
399: }
400: