PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/demo/scalr_newui/app/src/LibWebta/library/Data/Validation/class.Validator.php

https://github.com/kennethjiang/Wolke
PHP | 528 lines | 256 code | 68 blank | 204 comment | 56 complexity | 70026ae0de1899747a91a2b3de515ec3 MD5 | raw file
  1. <?
  2. /**
  3. * This file is a part of LibWebta, PHP class library.
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to version 2 of the GPL license,
  8. * that is bundled with this package in the file license.txt and is
  9. * available through the world-wide-web at the following url:
  10. * http://www.gnu.org/copyleft/gpl.html
  11. *
  12. * @category LibWebta
  13. * @package Data
  14. * @subpackage Validation
  15. * @copyright Copyright (c) 2003-2007 Webta Inc, http://www.gnu.org/licenses/gpl.html
  16. * @license http://www.gnu.org/licenses/gpl.html
  17. */
  18. // A simple checkdnsrr for Windows. Needed for Validator::IsEmail()
  19. if(!function_exists('checkdnsrr'))
  20. {
  21. function checkdnsrr($hostName, $recType = '')
  22. {
  23. if(!empty($hostName)) {
  24. if( $recType == '' ) $recType = "MX";
  25. exec("nslookup -type=$recType $hostName", $result);
  26. // check each line to find the one that starts with the host
  27. // name. If it exists then the function succeeded.
  28. foreach ($result as $line) {
  29. if(eregi("^$hostName",$line)) {
  30. return true;
  31. }
  32. }
  33. // otherwise there was no mail handler for the domain
  34. return false;
  35. }
  36. return false;
  37. }
  38. }
  39. /**
  40. * @name Validator
  41. * @version 1.0
  42. * @category LibWebta
  43. * @package Data
  44. * @subpackage Validation
  45. * @author Alex Kovalyov <http://webta.net/company.html>
  46. * @author Igor Savchenko <http://webta.net/company.html>
  47. */
  48. class Validator extends Core
  49. {
  50. const ERROR_EMPTY = "%s cannot be empty";
  51. const ERROR_NUMERIC = "%s must be a number";
  52. const ERROR_NUMERIC_RANGE = "%s must be a number between %s and %s";
  53. const ERROR_ALPHA = "%s must contain english letters only";
  54. const ERROR_EQUAL = "%s must be equal";
  55. const ERROR_PATTERN = "%s is invalid";
  56. const ERROR_IP = "%s must be valid IP addres";
  57. const ERROR_URL = "%s must be valid URL";
  58. const ERROR_DOMAIN = "%s must be valid domain name";
  59. const ERROR_EMAIL = "%s must be valid E-mail address";
  60. const ERROR_ALPHANUM = "%s must contain english letters or numbers only";
  61. const ERROR_XSS = "%s contains disallowed characters";
  62. const ERROR_LENGTH = "%s must be longer than %s characters";
  63. const ERROR_DATE = "%s must be valid date";
  64. const ERROR_E164PHONE = "%s must be in XXX-XXX-XXXX format. Minimum length of last field is 4, maximum: 12";
  65. /**
  66. * Errors
  67. *
  68. * @var array
  69. */
  70. public $Errors;
  71. /**
  72. * Validator constructor
  73. *
  74. */
  75. function __construct()
  76. {
  77. $this->Errors = array();
  78. }
  79. /**
  80. * Scan strings for debug code
  81. *
  82. * @param string $string
  83. * @return bool
  84. */
  85. public static function ScanForDebugCode($string)
  86. {
  87. return preg_match("/((apd_[A-Za-z]*\()|(xdebug_[A-Za-z]*\()|(eval\()|(var_dump\()|(print_r\()|(classkit_[a-zA-Z_]*\()|(create_function)|(call_user_func)|(Reflection[A-Za-z]+\())/si", $string, $matches);
  88. }
  89. /**
  90. * Return true if $var is empty
  91. *
  92. * @param mixed $var
  93. * @param string $name
  94. * @param string $error
  95. * @return bool
  96. */
  97. public function IsNotEmpty($var, $name = null, $error = null)
  98. {
  99. $retval = !empty($var);
  100. if (!$retval)
  101. $this->AddError(self::ERROR_EMPTY, $var, $name, $error);
  102. return $retval;
  103. }
  104. /**
  105. * Return true if $var is numeric
  106. *
  107. * @param mixed $var
  108. * @param string $name
  109. * @param string $error
  110. * @return bool
  111. */
  112. public function IsNumeric($var, $name = null, $error = null)
  113. {
  114. $retval = is_numeric($var);
  115. if (!$retval)
  116. $this->AddError(self::ERROR_NUMERIC, $var, $name, $error);
  117. return $retval;
  118. }
  119. /**
  120. * Return true if $var is numeric
  121. *
  122. * @param mixed $var
  123. * @param string $name
  124. * @param string $error
  125. * @return bool
  126. */
  127. public function IsInRange($var, $min = null, $max = null, $strict, $name = null, $error = null)
  128. {
  129. $retval = $this->IsNumeric($var);
  130. if (!is_null($min))
  131. $retval &= $strict ? ($var > $min) : ($var >= $min);
  132. if (!is_null($max))
  133. $retval &= $strict ? ($var < $man) : ($var <= $max);
  134. if (!$retval)
  135. {
  136. $this->AddError(self::ERROR_NUMERIC_RANGE, $var, $name, $error);
  137. }
  138. return $retval;
  139. }
  140. /**
  141. * Return true if $var is alpha
  142. *
  143. * @param mixed $var
  144. * @param string $name
  145. * @param string $error
  146. * @return bool
  147. */
  148. public function IsAlpha($var, $name = null, $error = null)
  149. {
  150. $retval = preg_match("/^[[:alpha:]]+$/", $var);
  151. if (!$retval)
  152. $this->AddError(self::ERROR_ALPHA, $var, $name, $error);
  153. return $retval;
  154. }
  155. public function IsE164Phone($var, $name = null, $error = null)
  156. {
  157. $retval = preg_match("/^[0-9]{3}-[0-9]{3}-[0-9]{4,12}$/", $var);
  158. if (!$retval)
  159. $this->AddError(self::ERROR_E164PHONE, $var, $name, $error);
  160. return $retval;
  161. }
  162. /**
  163. * Return true if $var1 equal $var2
  164. *
  165. * @param mixed $var1
  166. * @param mixed $var2
  167. * @param sting $name
  168. * @param string $error
  169. * @return bool
  170. */
  171. public function AreEqual($var1, $var2, $name = null, $error = null)
  172. {
  173. $retval = ($var1 === $var2);
  174. if (!$retval)
  175. $this->AddError(self::ERROR_EQUAL, "{$var1} and {$var2}", $name, $error);
  176. return $retval;
  177. }
  178. /**
  179. * Return true if $var matches pattern $pattern
  180. *
  181. * @param mixed $var
  182. * @param string $pattern
  183. * @param string $name
  184. * @param string $error
  185. * @return bool
  186. */
  187. public function MatchesPattern($var, $pattern, $name = null, $error = null)
  188. {
  189. $retval = preg_match($pattern, $var);
  190. if (!$retval)
  191. $this->AddError(self::ERROR_PATTERN, $var, $name, $error);
  192. return $retval;
  193. }
  194. /**
  195. * Return true is $var is valid Date
  196. * (allowed date formats: Y-m-d, Y/m/d, Y m d or Y.m.d)
  197. *
  198. * @param mixed $var
  199. * @param string $name
  200. * @param string $error
  201. * @return array
  202. */
  203. public function IsDate($var, $name = null, $error = null)
  204. {
  205. $retval = preg_match("/^(19|20)\d\d[\.\s\/\-](0[1-9]|1[012])[\.\s\/\-](0[1-9]|[12][0-9]|3[01])$/", $var);
  206. if (!$retval)
  207. $this->AddError(self::ERROR_DATE, $var, $name, $error);
  208. return $retval;
  209. }
  210. /**
  211. * Return true if $var is valid IP address
  212. *
  213. * @param mixed $var
  214. * @param string $name
  215. * @param string $error
  216. * @return array
  217. */
  218. public function IsIPAddress($var, $name = null, $error = null)
  219. {
  220. $retval = (ip2long($var) === false) ? false : true;
  221. if (!$retval)
  222. $this->AddError(self::ERROR_IP, $var, $name, $error);
  223. return $retval;
  224. }
  225. /**
  226. * Checks either a $var is a local network IP address or broadcast IP address.
  227. *
  228. * @param mixed $var
  229. * @param string $name
  230. * @param string $error
  231. * @return array
  232. */
  233. public function IsExternalIPAddress($var, $name = null, $error = null)
  234. {
  235. $internal_classA = (bool)preg_match('/^10(\.[0-9]{1,3}){3}$/', $var);
  236. $internal_classB = (bool)preg_match('/^172\.(1[6-9]|2[0-9]|31){1}(\.[0-9]{1,3}){2}$/', $var);
  237. $internal_classC = (bool)preg_match('/^192.168(\.[0-9]{1,3}){2}$/', $var);
  238. $bcast = (bool)preg_match('/^([0-9]{1,3}\.){3}(255|0)$/', $var);
  239. $retval = !($internal_classA || $internal_classB || $internal_classC || $bcast);
  240. if (!$retval)
  241. $this->AddError(self::ERROR_IP, $var, $name, $error);
  242. return $retval;
  243. }
  244. /**
  245. * Returns true if $var is valid URL
  246. *
  247. * @param mixed $var
  248. * @param string $name
  249. * @param string $error
  250. * @return bool
  251. */
  252. public function IsURL($var, $name = null, $error = null)
  253. {
  254. $retval = preg_match("/^(http:\/\/)?(www\.)?([A-Za-z0-9]+[A-Za-z0-9-]*[A-Za-z0-9]+[\.]){2,}$/", $var.".");
  255. if (!$retval)
  256. $this->AddError(self::ERROR_URL, $var, $name, $error);
  257. return $retval;
  258. }
  259. /**
  260. * Returns true if $var is valid domain name
  261. *
  262. * @param mixed $var
  263. * @param string $name
  264. * @param string $error
  265. * @return bool
  266. */
  267. public function IsDomain($var, $name = null, $error = null, $allowed_utf8_chars = "", $disallowed_utf8_chars = "")
  268. {
  269. // Remove trailing dot if its there. FQDN may contain dot at the end!
  270. $var = rtrim($var, ".");
  271. $retval = (bool)preg_match('/^([a-zA-Z0-9'.$allowed_utf8_chars.']+[a-zA-Z0-9-'.$allowed_utf8_chars.']*\.[a-zA-Z0-9'.$allowed_utf8_chars.']*?)+$/usi', $var);
  272. if ($disallowed_utf8_chars != '')
  273. $retval &= !(bool)preg_match("/[{$disallowed_utf8_chars}]+/siu", $var);
  274. if (!$retval)
  275. $this->AddError(self::ERROR_DOMAIN, $var, $name, $error);
  276. return $retval;
  277. }
  278. /**
  279. * Return true if $var is valid e-mail. RFC-compliant.
  280. *
  281. * @param mixed $var
  282. * @param string $name
  283. * @param string $error
  284. * @return bool
  285. * @link http://www.linuxjournal.com/article/9585
  286. */
  287. function IsEmail($var, $name = null, $error = null, $check_dns = false)
  288. {
  289. $email = $var;
  290. $isValid = true;
  291. $atIndex = strrpos($email, "@");
  292. if (is_bool($atIndex) && !$atIndex)
  293. {
  294. $isValid = false;
  295. }
  296. else
  297. {
  298. $domain = substr($email, $atIndex+1);
  299. $local = substr($email, 0, $atIndex);
  300. $localLen = strlen($local);
  301. $domainLen = strlen($domain);
  302. if ($localLen < 1 || $localLen > 64)
  303. {
  304. // local part length exceeded
  305. $isValid = false;
  306. }
  307. else if ($domainLen < 1 || $domainLen > 255)
  308. {
  309. // domain part length exceeded
  310. $isValid = false;
  311. }
  312. else if ($local[0] == '.' || $local[$localLen-1] == '.')
  313. {
  314. // local part starts or ends with '.'
  315. $isValid = false;
  316. }
  317. else if (preg_match('/\\.\\./', $local))
  318. {
  319. // local part has two consecutive dots
  320. $isValid = false;
  321. }
  322. else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
  323. {
  324. // character not valid in domain part
  325. $isValid = false;
  326. }
  327. else if (preg_match('/\\.\\./', $domain))
  328. {
  329. // domain part has two consecutive dots
  330. $isValid = false;
  331. }
  332. else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',
  333. str_replace("\\\\","",$local)))
  334. {
  335. // character not valid in local part unless
  336. // local part is quoted
  337. if (!preg_match('/^"(\\\\"|[^"])+"$/',
  338. str_replace("\\\\","",$local)))
  339. {
  340. $isValid = false;
  341. }
  342. }
  343. if ($check_dns)
  344. {
  345. if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A")))
  346. {
  347. // domain not found in DNS
  348. $isValid = false;
  349. }
  350. }
  351. }
  352. return $isValid;
  353. }
  354. /**
  355. * Return true if $var is valid e-mail. RFC-compliant. Also checks in DNS.
  356. *
  357. * @param mixed $var
  358. * @param string $name
  359. * @param string $error
  360. * @return bool
  361. * @link http://www.linuxjournal.com/article/9585
  362. */
  363. function IsEmailPlusDNS($var, $name = null, $error = null)
  364. {
  365. Validator::IsEmail($var, $name, $error, true);
  366. }
  367. /**
  368. * Return true if $var is valid e-mail
  369. *
  370. * @param mixed $var
  371. * @param string $name
  372. * @param string $error
  373. * @return bool
  374. */
  375. public function IsEmailRestrictive($var, $name = null, $error = null)
  376. {
  377. $retval = preg_match("/^[a-zA-Z0-9]+([a-zA-Z0-9_\.-]*[a-zA-Z0-9])*?@([a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+\.)+[a-zA-Z]{2,5}$/i", $var);
  378. if (!$retval)
  379. $this->AddError(self::ERROR_EMAIL, $var, $name, $error);
  380. return $retval;
  381. }
  382. /**
  383. * Return true if $var is alphanumeric
  384. *
  385. * @param mixed $var
  386. * @param string $name
  387. * @param string $error
  388. * @return bool
  389. */
  390. public function IsAlphaNumeric($var, $name = null, $error = null)
  391. {
  392. $retval = preg_match("/^[A-Za-z0-9]+$/si", $var);
  393. if (!$retval)
  394. $this->AddError(self::ERROR_ALPHANUM, $var, $name, $error);
  395. return $retval;
  396. }
  397. public function IsXSSClean()
  398. {
  399. //TODO: I don't know what i can write here!
  400. }
  401. /**
  402. * Add error to errors stack
  403. *
  404. * @param string $error_template
  405. * @param string $var
  406. * @param string $name
  407. * @param string $error_str
  408. */
  409. public function AddError($error_template, $var, $name = null, $error_str = null)
  410. {
  411. if ($error_str)
  412. array_push($this->Errors, $error_str);
  413. elseif ($name)
  414. array_push($this->Errors, sprintf($error_template, $name));
  415. else
  416. array_push($this->Errors, sprintf($error_template, "'{$var}'"));
  417. }
  418. /**
  419. * Validate all data in array
  420. *
  421. * @param array $array
  422. * @return bool or array of errors
  423. */
  424. public function ValidateAll($array)
  425. {
  426. $this->Errors = array();
  427. foreach($array as $var=>$method)
  428. {
  429. if (method_exists($this, $method))
  430. {
  431. eval("\$this->{$method}('{$var}');");
  432. }
  433. else
  434. Core::RaiseWarning("{$method} is not valid method of Validator class.");
  435. }
  436. if ($this->HasErrors())
  437. return $this->Errors;
  438. else
  439. return true;
  440. }
  441. /**
  442. * Return true if we have errors
  443. *
  444. * @return bool
  445. */
  446. public function HasErrors()
  447. {
  448. return (count($this->Errors) > 0);
  449. }
  450. /**
  451. * Return last error message
  452. *
  453. * @return bool
  454. */
  455. public function GetLastError()
  456. {
  457. return $this->Errors[count($this->Errors) -1];
  458. }
  459. }
  460. ?>