PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/class.error.php

http://github.com/tylerhall/simple-php-framework
PHP | 273 lines | 203 code | 40 blank | 30 comment | 45 complexity | c962f3e6c90a59403744474fa3623325 MD5 | raw file
  1. <?PHP
  2. class Error
  3. {
  4. // Singleton object. Leave $me alone.
  5. private static $me;
  6. public $errors; // Array of errors
  7. public $style; // CSS rules to apply to error elements
  8. private function __construct($style = "border:1px solid red;")
  9. {
  10. $this->errors = array();
  11. $this->style = $style;
  12. }
  13. // Get Singleton object
  14. public static function getError()
  15. {
  16. if(is_null(self::$me))
  17. self::$me = new Error();
  18. return self::$me;
  19. }
  20. // Returns an unordered list of error messages
  21. public function __tostring()
  22. {
  23. return $this->alert();
  24. }
  25. // Returns true if there are no errors
  26. public function ok()
  27. {
  28. return count($this->errors) == 0;
  29. }
  30. // Manually add an error
  31. public function add($id, $msg)
  32. {
  33. if(isset($this->errors[$id]) && !is_array($this->errors[$id]))
  34. $this->errors[$id] = array($msg);
  35. else
  36. $this->errors[$id][] = $msg;
  37. }
  38. // Delete all errors associated with an element's id
  39. public function delete($id)
  40. {
  41. unset($this->errors[$id]);
  42. }
  43. // Returns the error message associated with an element.
  44. // This may return a string or an array - so be sure to test before echoing!
  45. public function msg($id)
  46. {
  47. return $this->errors[$id];
  48. }
  49. // Outputs the CSS to style the error elements
  50. public function css($header = true)
  51. {
  52. $out = '';
  53. if(count($this->errors) > 0)
  54. {
  55. if($header) $out .= '<style type="text/css" media="screen">';
  56. $out .= "#" . implode(", #", array_keys($this->errors)) . " { {$this->style} }";
  57. if($header) $out .= '</style>';
  58. }
  59. echo $out;
  60. }
  61. // Returns an unordered list of error messages
  62. public function ul($class = 'warn')
  63. {
  64. if(count($this->errors) == 0) return '';
  65. $out = "<ul class='$class'>";
  66. foreach($this->errors as $error)
  67. $out .= "<li>" . implode("</li><li>", $error) . "</li>";
  68. $out .= "</ul>";
  69. return $out;
  70. }
  71. // Returns error alerts
  72. public function alert()
  73. {
  74. if(count($this->errors) == 0)
  75. return '';
  76. $out = '';
  77. foreach($this->errors as $error)
  78. $out .= "<p class='alert error'>" . implode(' ', $error) . "</p>";
  79. return $out;
  80. }
  81. // Below are a collection of tests for error conditions in your user's input...
  82. // Be sure to customize these to suit your app's needs. Especially the error messages.
  83. // Is the (string) value empty?
  84. public function blank($val, $id, $name = null)
  85. {
  86. if(trim($val) == '')
  87. {
  88. if(is_null($name)) $name = ucwords($id);
  89. $this->add($id, "$name cannot be left blank.");
  90. return false;
  91. }
  92. return true;
  93. }
  94. // Is a number between a given range? (inclusive)
  95. public function range($val, $lower, $upper, $id, $name = null)
  96. {
  97. if($val < $lower || $val > $upper)
  98. {
  99. if(is_null($name)) $name = ucwords($id);
  100. $this->add($id, "$name must be between $lower and $upper.");
  101. return false;
  102. }
  103. return true;
  104. }
  105. // Is a string an appropriate length?
  106. public function length($val, $lower, $upper, $id, $name = null)
  107. {
  108. if(strlen($val) < $lower)
  109. {
  110. if(is_null($name)) $name = ucwords($id);
  111. $this->add($id, "$name must be at least $lower characters.");
  112. return false;
  113. }
  114. elseif(strlen($val) > $upper)
  115. {
  116. if(is_null($name)) $name = ucwords($id);
  117. $this->add($id, "$name cannot be more than $upper characters long.");
  118. return false;
  119. }
  120. return true;
  121. }
  122. // Do the passwords match?
  123. public function passwords($pass1, $pass2, $id)
  124. {
  125. if($pass1 !== $pass2)
  126. {
  127. $this->add($id, 'The passwords you entered do not match.');
  128. return false;
  129. }
  130. return true;
  131. }
  132. // Does a value match a given regex?
  133. public function regex($val, $regex, $id, $msg)
  134. {
  135. if(preg_match($regex, $val) === 0)
  136. {
  137. $this->add($id, $msg);
  138. return false;
  139. }
  140. return true;
  141. }
  142. // Is an email address valid?
  143. public function email($val, $id = 'email')
  144. {
  145. if(!preg_match("/^([_a-z0-9+-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i", $val))
  146. {
  147. $this->add($id, 'The email address you entered is not valid.');
  148. return false;
  149. }
  150. return true;
  151. }
  152. // Is a string a parseable and valid date?
  153. public function date($val, $id)
  154. {
  155. if(chkdate($val) === false)
  156. {
  157. $this->add($id, 'Please enter a valid date');
  158. return false;
  159. }
  160. return true;
  161. }
  162. // Is a birth date at least 18 years old?
  163. public function adult($val, $id)
  164. {
  165. if( dater_utc($val) > ( (date('Y') - 18) . date('-m-d H:i:s') ) )
  166. {
  167. $this->add($id, 'You must be at least 18 years old.');
  168. return false;
  169. }
  170. return true;
  171. }
  172. // Is a string a valid phone number?
  173. public function phone($val, $id)
  174. {
  175. $val = preg_replace('/[^0-9]/', '', $val);
  176. if(strlen($val) != 7 && strlen($val) != 10)
  177. {
  178. $this->add($id, 'Please enter a valid 7 or 10 digit phone number.');
  179. return false;
  180. }
  181. return true;
  182. }
  183. // Did we get a successful file upload?
  184. // Typically, you'd pass in $_FILES['file']
  185. public function upload($val, $id)
  186. {
  187. if(!is_uploaded_file($val['tmp_name']) || !is_readable($val['tmp_name']))
  188. {
  189. $this->add($id, 'Your file was not uploaded successfully. Please try again.');
  190. return false;
  191. }
  192. return true;
  193. }
  194. // Valid 5 digit zip code?
  195. public function zip($val, $id, $name = null)
  196. {
  197. // From http://www.zend.com//code/codex.php?ozid=991&single=1
  198. $ranges = array(array('99500', '99929'), array('35000', '36999'), array('71600', '72999'), array('75502', '75505'), array('85000', '86599'), array('90000', '96199'), array('80000', '81699'), array('06000', '06999'), array('20000', '20099'), array('20200', '20599'), array('19700', '19999'), array('32000', '33999'), array('34100', '34999'), array('30000', '31999'), array('96700', '96798'), array('96800', '96899'), array('50000', '52999'), array('83200', '83899'), array('60000', '62999'), array('46000', '47999'), array('66000', '67999'), array('40000', '42799'), array('45275', '45275'), array('70000', '71499'), array('71749', '71749'), array('01000', '02799'), array('20331', '20331'), array('20600', '21999'), array('03801', '03801'), array('03804', '03804'), array('03900', '04999'), array('48000', '49999'), array('55000', '56799'), array('63000', '65899'), array('38600', '39799'), array('59000', '59999'), array('27000', '28999'), array('58000', '58899'), array('68000', '69399'), array('03000', '03803'), array('03809', '03899'), array('07000', '08999'), array('87000', '88499'), array('89000', '89899'), array('00400', '00599'), array('06390', '06390'), array('09000', '14999'), array('43000', '45999'), array('73000', '73199'), array('73400', '74999'), array('97000', '97999'), array('15000', '19699'), array('02800', '02999'), array('06379', '06379'), array('29000', '29999'), array('57000', '57799'), array('37000', '38599'), array('72395', '72395'), array('73300', '73399'), array('73949', '73949'), array('75000', '79999'), array('88501', '88599'), array('84000', '84799'), array('20105', '20199'), array('20301', '20301'), array('20370', '20370'), array('22000', '24699'), array('05000', '05999'), array('98000', '99499'), array('49936', '49936'), array('53000', '54999'), array('24700', '26899'), array('82000', '83199'));
  199. foreach($ranges as $r)
  200. {
  201. if($val >= $r[0] && $val <= $r[1])
  202. return true;
  203. }
  204. if(is_null($name)) $name = ucwords($id);
  205. $this->add($id, "Please enter a valid, 5-digit zip code.");
  206. return false;
  207. }
  208. // Test if string $val is a valid, decimal number.
  209. public function nan($val, $id, $name = null)
  210. {
  211. if(preg_match('/^-?[0-9]+(\.[0-9]+)?$/', $val) == 0)
  212. {
  213. if(is_null($name)) $name = ucwords($id);
  214. $this->add($id, "$name must be a number.");
  215. return false;
  216. }
  217. return true;
  218. }
  219. // Valid URL?
  220. // This is hardly perfect, but it's good enough for now...
  221. // TODO: Make URL validation more robust
  222. public function url($val, $id, $name = null)
  223. {
  224. $info = @parse_url($val);
  225. if(($info === false) || ($info['scheme'] != 'http' && $info['scheme'] != 'https') || ($info['host'] == ''))
  226. {
  227. if(is_null($name)) $name = ucwords($id);
  228. $this->add($id, "$name is not a valid URL.");
  229. return false;
  230. }
  231. return true;
  232. }
  233. }