/halogy/libraries/Validation.php

https://bitbucket.org/haloweb/halogy-1.0/ · PHP · 875 lines · 403 code · 121 blank · 351 comment · 78 complexity · ddc03af713c1cb380c4556e756a04c54 MD5 · raw file

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 4.3.2 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * Validation Class
  18. *
  19. * @package CodeIgniter
  20. * @subpackage Libraries
  21. * @category Validation
  22. * @author ExpressionEngine Dev Team
  23. * @link http://codeigniter.com/user_guide/libraries/validation.html
  24. */
  25. class CI_Validation {
  26. var $CI;
  27. var $error_string = '';
  28. var $_error_array = array();
  29. var $_rules = array();
  30. var $_fields = array();
  31. var $_error_messages = array();
  32. var $_current_field = '';
  33. var $_safe_form_data = FALSE;
  34. var $_error_prefix = '<p>';
  35. var $_error_suffix = '</p>';
  36. /**
  37. * Constructor
  38. *
  39. */
  40. function CI_Validation()
  41. {
  42. $this->CI =& get_instance();
  43. if (function_exists('mb_internal_encoding'))
  44. {
  45. mb_internal_encoding($this->CI->config->item('charset'));
  46. }
  47. log_message('debug', "Validation Class Initialized");
  48. }
  49. // --------------------------------------------------------------------
  50. /**
  51. * Set Fields
  52. *
  53. * This function takes an array of field names as input
  54. * and generates class variables with the same name, which will
  55. * either be blank or contain the $_POST value corresponding to it
  56. *
  57. * @access public
  58. * @param string
  59. * @param string
  60. * @return void
  61. */
  62. function set_fields($data = '', $field = '')
  63. {
  64. if ($data == '')
  65. {
  66. if (count($this->_fields) == 0)
  67. {
  68. return FALSE;
  69. }
  70. }
  71. else
  72. {
  73. if ( ! is_array($data))
  74. {
  75. $data = array($data => $field);
  76. }
  77. if (count($data) > 0)
  78. {
  79. $this->_fields = $data;
  80. }
  81. }
  82. foreach($this->_fields as $key => $val)
  83. {
  84. $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
  85. $error = $key.'_error';
  86. if ( ! isset($this->$error))
  87. {
  88. $this->$error = '';
  89. }
  90. }
  91. }
  92. // --------------------------------------------------------------------
  93. /**
  94. * Set Rules
  95. *
  96. * This function takes an array of field names and validation
  97. * rules as input ad simply stores is for use later.
  98. *
  99. * @access public
  100. * @param mixed
  101. * @param string
  102. * @return void
  103. */
  104. function set_rules($data, $rules = '')
  105. {
  106. if ( ! is_array($data))
  107. {
  108. if ($rules == '')
  109. return;
  110. $data = array($data => $rules);
  111. }
  112. foreach ($data as $key => $val)
  113. {
  114. $this->_rules[$key] = $val;
  115. }
  116. }
  117. // --------------------------------------------------------------------
  118. /**
  119. * Set Error Message
  120. *
  121. * Lets users set their own error messages on the fly. Note: The key
  122. * name has to match the function name that it corresponds to.
  123. *
  124. * @access public
  125. * @param string
  126. * @param string
  127. * @return string
  128. */
  129. function set_message($lang, $val = '')
  130. {
  131. if ( ! is_array($lang))
  132. {
  133. $lang = array($lang => $val);
  134. }
  135. $this->_error_messages = array_merge($this->_error_messages, $lang);
  136. }
  137. // --------------------------------------------------------------------
  138. /**
  139. * Set The Error Delimiter
  140. *
  141. * Permits a prefix/suffix to be added to each error message
  142. *
  143. * @access public
  144. * @param string
  145. * @param string
  146. * @return void
  147. */
  148. function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
  149. {
  150. $this->_error_prefix = $prefix;
  151. $this->_error_suffix = $suffix;
  152. }
  153. // --------------------------------------------------------------------
  154. /**
  155. * Run the Validator
  156. *
  157. * This function does all the work.
  158. *
  159. * @access public
  160. * @return bool
  161. */
  162. function run()
  163. {
  164. // Do we even have any data to process? Mm?
  165. if (count($_POST) == 0 OR count($this->_rules) == 0)
  166. {
  167. return FALSE;
  168. }
  169. // Load the language file containing error messages
  170. $this->CI->lang->load('validation');
  171. // Cycle through the rules and test for errors
  172. foreach ($this->_rules as $field => $rules)
  173. {
  174. //Explode out the rules!
  175. $ex = explode('|', $rules);
  176. // Is the field required? If not, if the field is blank we'll move on to the next test
  177. if ( ! in_array('required', $ex, TRUE))
  178. {
  179. if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
  180. {
  181. continue;
  182. }
  183. }
  184. /*
  185. * Are we dealing with an "isset" rule?
  186. *
  187. * Before going further, we'll see if one of the rules
  188. * is to check whether the item is set (typically this
  189. * applies only to checkboxes). If so, we'll
  190. * test for it here since there's not reason to go
  191. * further
  192. */
  193. if ( ! isset($_POST[$field]))
  194. {
  195. if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
  196. {
  197. if ( ! isset($this->_error_messages['isset']))
  198. {
  199. if (FALSE === ($line = $this->CI->lang->line('isset')))
  200. {
  201. $line = 'The field was not set';
  202. }
  203. }
  204. else
  205. {
  206. $line = $this->_error_messages['isset'];
  207. }
  208. // Build the error message
  209. $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
  210. $message = sprintf($line, $mfield);
  211. // Set the error variable. Example: $this->username_error
  212. $error = $field.'_error';
  213. $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
  214. $this->_error_array[] = $message;
  215. }
  216. continue;
  217. }
  218. /*
  219. * Set the current field
  220. *
  221. * The various prepping functions need to know the
  222. * current field name so they can do this:
  223. *
  224. * $_POST[$this->_current_field] == 'bla bla';
  225. */
  226. $this->_current_field = $field;
  227. // Cycle through the rules!
  228. foreach ($ex As $rule)
  229. {
  230. // Is the rule a callback?
  231. $callback = FALSE;
  232. if (substr($rule, 0, 9) == 'callback_')
  233. {
  234. $rule = substr($rule, 9);
  235. $callback = TRUE;
  236. }
  237. // Strip the parameter (if exists) from the rule
  238. // Rules can contain a parameter: max_length[5]
  239. $param = FALSE;
  240. if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
  241. {
  242. $rule = $match[1];
  243. $param = $match[2];
  244. }
  245. // Call the function that corresponds to the rule
  246. if ($callback === TRUE)
  247. {
  248. if ( ! method_exists($this->CI, $rule))
  249. {
  250. continue;
  251. }
  252. $result = $this->CI->$rule($_POST[$field], $param);
  253. // If the field isn't required and we just processed a callback we'll move on...
  254. if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
  255. {
  256. continue 2;
  257. }
  258. }
  259. else
  260. {
  261. if ( ! method_exists($this, $rule))
  262. {
  263. /*
  264. * Run the native PHP function if called for
  265. *
  266. * If our own wrapper function doesn't exist we see
  267. * if a native PHP function does. Users can use
  268. * any native PHP function call that has one param.
  269. */
  270. if (function_exists($rule))
  271. {
  272. $_POST[$field] = $rule($_POST[$field]);
  273. $this->$field = $_POST[$field];
  274. }
  275. continue;
  276. }
  277. $result = $this->$rule($_POST[$field], $param);
  278. }
  279. // Did the rule test negatively? If so, grab the error.
  280. if ($result === FALSE)
  281. {
  282. if ( ! isset($this->_error_messages[$rule]))
  283. {
  284. if (FALSE === ($line = $this->CI->lang->line($rule)))
  285. {
  286. $line = 'Unable to access an error message corresponding to your field name.';
  287. }
  288. }
  289. else
  290. {
  291. $line = $this->_error_messages[$rule];
  292. }
  293. // Build the error message
  294. $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
  295. $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
  296. $message = sprintf($line, $mfield, $mparam);
  297. // Set the error variable. Example: $this->username_error
  298. $error = $field.'_error';
  299. $this->$error = $this->_error_prefix.$message.$this->_error_suffix;
  300. // Add the error to the error array
  301. $this->_error_array[] = $message;
  302. continue 2;
  303. }
  304. }
  305. }
  306. $total_errors = count($this->_error_array);
  307. /*
  308. * Recompile the class variables
  309. *
  310. * If any prepping functions were called the $_POST data
  311. * might now be different then the corresponding class
  312. * variables so we'll set them anew.
  313. */
  314. if ($total_errors > 0)
  315. {
  316. $this->_safe_form_data = TRUE;
  317. }
  318. $this->set_fields();
  319. // Did we end up with any errors?
  320. if ($total_errors == 0)
  321. {
  322. return TRUE;
  323. }
  324. // Generate the error string
  325. foreach ($this->_error_array as $val)
  326. {
  327. $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
  328. }
  329. return FALSE;
  330. }
  331. // --------------------------------------------------------------------
  332. /**
  333. * Required
  334. *
  335. * @access public
  336. * @param string
  337. * @return bool
  338. */
  339. function required($str)
  340. {
  341. if ( ! is_array($str))
  342. {
  343. return (trim($str) == '') ? FALSE : TRUE;
  344. }
  345. else
  346. {
  347. return ( ! empty($str));
  348. }
  349. }
  350. // --------------------------------------------------------------------
  351. /**
  352. * Match one field to another
  353. *
  354. * @access public
  355. * @param string
  356. * @param field
  357. * @return bool
  358. */
  359. function matches($str, $field)
  360. {
  361. if ( ! isset($_POST[$field]))
  362. {
  363. return FALSE;
  364. }
  365. return ($str !== $_POST[$field]) ? FALSE : TRUE;
  366. }
  367. // --------------------------------------------------------------------
  368. /**
  369. * Minimum Length
  370. *
  371. * @access public
  372. * @param string
  373. * @param value
  374. * @return bool
  375. */
  376. function min_length($str, $val)
  377. {
  378. if (preg_match("/[^0-9]/", $val))
  379. {
  380. return FALSE;
  381. }
  382. if (function_exists('mb_strlen'))
  383. {
  384. return (mb_strlen($str) < $val) ? FALSE : TRUE;
  385. }
  386. return (strlen($str) < $val) ? FALSE : TRUE;
  387. }
  388. // --------------------------------------------------------------------
  389. /**
  390. * Max Length
  391. *
  392. * @access public
  393. * @param string
  394. * @param value
  395. * @return bool
  396. */
  397. function max_length($str, $val)
  398. {
  399. if (preg_match("/[^0-9]/", $val))
  400. {
  401. return FALSE;
  402. }
  403. if (function_exists('mb_strlen'))
  404. {
  405. return (mb_strlen($str) > $val) ? FALSE : TRUE;
  406. }
  407. return (strlen($str) > $val) ? FALSE : TRUE;
  408. }
  409. // --------------------------------------------------------------------
  410. /**
  411. * Exact Length
  412. *
  413. * @access public
  414. * @param string
  415. * @param value
  416. * @return bool
  417. */
  418. function exact_length($str, $val)
  419. {
  420. if (preg_match("/[^0-9]/", $val))
  421. {
  422. return FALSE;
  423. }
  424. if (function_exists('mb_strlen'))
  425. {
  426. return (mb_strlen($str) != $val) ? FALSE : TRUE;
  427. }
  428. return (strlen($str) != $val) ? FALSE : TRUE;
  429. }
  430. // --------------------------------------------------------------------
  431. /**
  432. * Valid Email
  433. *
  434. * @access public
  435. * @param string
  436. * @return bool
  437. */
  438. function valid_email($str)
  439. {
  440. return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
  441. }
  442. // --------------------------------------------------------------------
  443. /**
  444. * Valid Emails
  445. *
  446. * @access public
  447. * @param string
  448. * @return bool
  449. */
  450. function valid_emails($str)
  451. {
  452. if (strpos($str, ',') === FALSE)
  453. {
  454. return $this->valid_email(trim($str));
  455. }
  456. foreach(explode(',', $str) as $email)
  457. {
  458. if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
  459. {
  460. return FALSE;
  461. }
  462. }
  463. return TRUE;
  464. }
  465. // --------------------------------------------------------------------
  466. /**
  467. * Validate IP Address
  468. *
  469. * @access public
  470. * @param string
  471. * @return string
  472. */
  473. function valid_ip($ip)
  474. {
  475. return $this->CI->input->valid_ip($ip);
  476. }
  477. // --------------------------------------------------------------------
  478. /**
  479. * Alpha
  480. *
  481. * @access public
  482. * @param string
  483. * @return bool
  484. */
  485. function alpha($str)
  486. {
  487. return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
  488. }
  489. // --------------------------------------------------------------------
  490. /**
  491. * Alpha-numeric
  492. *
  493. * @access public
  494. * @param string
  495. * @return bool
  496. */
  497. function alpha_numeric($str)
  498. {
  499. return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
  500. }
  501. // --------------------------------------------------------------------
  502. /**
  503. * Alpha-numeric with underscores and dashes
  504. *
  505. * @access public
  506. * @param string
  507. * @return bool
  508. */
  509. function alpha_dash($str)
  510. {
  511. return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
  512. }
  513. // --------------------------------------------------------------------
  514. /**
  515. * Numeric
  516. *
  517. * @access public
  518. * @param string
  519. * @return bool
  520. */
  521. function numeric($str)
  522. {
  523. return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
  524. }
  525. // --------------------------------------------------------------------
  526. /**
  527. * Is Numeric
  528. *
  529. * @access public
  530. * @param string
  531. * @return bool
  532. */
  533. function is_numeric($str)
  534. {
  535. return ( ! is_numeric($str)) ? FALSE : TRUE;
  536. }
  537. // --------------------------------------------------------------------
  538. /**
  539. * Integer
  540. *
  541. * @access public
  542. * @param string
  543. * @return bool
  544. */
  545. function integer($str)
  546. {
  547. return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
  548. }
  549. // --------------------------------------------------------------------
  550. /**
  551. * Is a Natural number (0,1,2,3, etc.)
  552. *
  553. * @access public
  554. * @param string
  555. * @return bool
  556. */
  557. function is_natural($str)
  558. {
  559. return (bool)preg_match( '/^[0-9]+$/', $str);
  560. }
  561. // --------------------------------------------------------------------
  562. /**
  563. * Is a Natural number, but not a zero (1,2,3, etc.)
  564. *
  565. * @access public
  566. * @param string
  567. * @return bool
  568. */
  569. function is_natural_no_zero($str)
  570. {
  571. if ( ! preg_match( '/^[0-9]+$/', $str))
  572. {
  573. return FALSE;
  574. }
  575. if ($str == 0)
  576. {
  577. return FALSE;
  578. }
  579. return TRUE;
  580. }
  581. // --------------------------------------------------------------------
  582. /**
  583. * Valid Base64
  584. *
  585. * Tests a string for characters outside of the Base64 alphabet
  586. * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
  587. *
  588. * @access public
  589. * @param string
  590. * @return bool
  591. */
  592. function valid_base64($str)
  593. {
  594. return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
  595. }
  596. // --------------------------------------------------------------------
  597. /**
  598. * Set Select
  599. *
  600. * Enables pull-down lists to be set to the value the user
  601. * selected in the event of an error
  602. *
  603. * @access public
  604. * @param string
  605. * @param string
  606. * @return string
  607. */
  608. function set_select($field = '', $value = '')
  609. {
  610. if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
  611. {
  612. return '';
  613. }
  614. if ($_POST[$field] == $value)
  615. {
  616. return ' selected="selected"';
  617. }
  618. }
  619. // --------------------------------------------------------------------
  620. /**
  621. * Set Radio
  622. *
  623. * Enables radio buttons to be set to the value the user
  624. * selected in the event of an error
  625. *
  626. * @access public
  627. * @param string
  628. * @param string
  629. * @return string
  630. */
  631. function set_radio($field = '', $value = '')
  632. {
  633. if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
  634. {
  635. return '';
  636. }
  637. if ($_POST[$field] == $value)
  638. {
  639. return ' checked="checked"';
  640. }
  641. }
  642. // --------------------------------------------------------------------
  643. /**
  644. * Set Checkbox
  645. *
  646. * Enables checkboxes to be set to the value the user
  647. * selected in the event of an error
  648. *
  649. * @access public
  650. * @param string
  651. * @param string
  652. * @return string
  653. */
  654. function set_checkbox($field = '', $value = '')
  655. {
  656. if ($field == '' OR $value == '' OR ! isset($_POST[$field]))
  657. {
  658. return '';
  659. }
  660. if ($_POST[$field] == $value)
  661. {
  662. return ' checked="checked"';
  663. }
  664. }
  665. // --------------------------------------------------------------------
  666. /**
  667. * Prep data for form
  668. *
  669. * This function allows HTML to be safely shown in a form.
  670. * Special characters are converted.
  671. *
  672. * @access public
  673. * @param string
  674. * @return string
  675. */
  676. function prep_for_form($data = '')
  677. {
  678. if (is_array($data))
  679. {
  680. foreach ($data as $key => $val)
  681. {
  682. $data[$key] = $this->prep_for_form($val);
  683. }
  684. return $data;
  685. }
  686. if ($this->_safe_form_data == FALSE OR $data == '')
  687. {
  688. return $data;
  689. }
  690. return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
  691. }
  692. // --------------------------------------------------------------------
  693. /**
  694. * Prep URL
  695. *
  696. * @access public
  697. * @param string
  698. * @return string
  699. */
  700. function prep_url($str = '')
  701. {
  702. if ($str == 'http://' OR $str == '')
  703. {
  704. $_POST[$this->_current_field] = '';
  705. return;
  706. }
  707. if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
  708. {
  709. $str = 'http://'.$str;
  710. }
  711. $_POST[$this->_current_field] = $str;
  712. }
  713. // --------------------------------------------------------------------
  714. /**
  715. * Strip Image Tags
  716. *
  717. * @access public
  718. * @param string
  719. * @return string
  720. */
  721. function strip_image_tags($str)
  722. {
  723. $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str);
  724. }
  725. // --------------------------------------------------------------------
  726. /**
  727. * XSS Clean
  728. *
  729. * @access public
  730. * @param string
  731. * @return string
  732. */
  733. function xss_clean($str)
  734. {
  735. $_POST[$this->_current_field] = $this->CI->input->xss_clean($str);
  736. }
  737. // --------------------------------------------------------------------
  738. /**
  739. * Convert PHP tags to entities
  740. *
  741. * @access public
  742. * @param string
  743. * @return string
  744. */
  745. function encode_php_tags($str)
  746. {
  747. $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
  748. }
  749. }
  750. // END Validation Class
  751. /* End of file Validation.php */
  752. /* Location: ./system/libraries/Validation.php */