PageRenderTime 591ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/fuel/core/classes/validation.php

https://bitbucket.org/codeyash/bootstrap
PHP | 947 lines | 543 code | 95 blank | 309 comment | 68 complexity | 91857640cfddf7f229f43bfb1a61c41c MD5 | raw file
Possible License(s): MIT, Apache-2.0
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * @package Fuel
  6. * @version 1.5
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2013 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. // ------------------------------------------------------------------------
  14. /**
  15. * Validation
  16. *
  17. * Static object to allow static usage of validation through singleton.
  18. *
  19. * @package Fuel
  20. * @subpackage Core
  21. * @category Core
  22. */
  23. class Validation
  24. {
  25. /**
  26. * @var Validation keeps a reference to an instance of Validation while it is being run
  27. */
  28. protected static $active;
  29. /**
  30. * @var Fieldset_Field keeps a reference to an instance of the Fieldset_Field validation is being run on
  31. */
  32. protected static $active_field;
  33. /**
  34. * Gets a new instance of the Validation class.
  35. *
  36. * @param string The name or instance of the Fieldset to link to
  37. * @return Validation
  38. */
  39. public static function forge($fieldset = 'default')
  40. {
  41. if (is_string($fieldset))
  42. {
  43. ($set = \Fieldset::instance($fieldset)) and $fieldset = $set;
  44. }
  45. if ($fieldset instanceof Fieldset)
  46. {
  47. if ($fieldset->validation(false) != null)
  48. {
  49. throw new \DomainException('Form instance already exists, cannot be recreated. Use instance() instead of forge() to retrieve the existing instance.');
  50. }
  51. }
  52. return new static($fieldset);
  53. }
  54. public static function instance($name = null)
  55. {
  56. $fieldset = \Fieldset::instance($name);
  57. return $fieldset === false ? false : $fieldset->validation();
  58. }
  59. /**
  60. * Fetch the currently active validation instance
  61. *
  62. * @return Validation
  63. */
  64. public static function active()
  65. {
  66. return static::$active;
  67. }
  68. /**
  69. * Set or unset the currently active validation instance
  70. */
  71. protected static function set_active($instance = null)
  72. {
  73. static::$active = $instance;
  74. }
  75. /**
  76. * Fetch the field currently being validated
  77. */
  78. public static function active_field()
  79. {
  80. return static::$active_field;
  81. }
  82. /**
  83. * Set or unset the current field being validated
  84. */
  85. protected static function set_active_field($instance = null)
  86. {
  87. static::$active_field = $instance;
  88. }
  89. /**
  90. * @var Fieldset the fieldset this instance validates
  91. */
  92. protected $fieldset;
  93. /**
  94. * @var array available after validation started running: contains given input values
  95. */
  96. protected $input = array();
  97. /**
  98. * @var array contains values of fields that validated successfully
  99. */
  100. protected $validated = array();
  101. /**
  102. * @var array contains Validation_Error instances of encountered errors
  103. */
  104. protected $errors = array();
  105. /**
  106. * @var array contains a list of classnames and objects that may contain validation methods
  107. */
  108. protected $callables = array();
  109. /**
  110. * @var bool $global_input_fallback wether to fall back to Input::param
  111. */
  112. protected $global_input_fallback = true;
  113. /**
  114. * @var array contains validation error messages, will overwrite those from lang files
  115. */
  116. protected $error_messages = array();
  117. protected function __construct($fieldset)
  118. {
  119. if ($fieldset instanceof Fieldset)
  120. {
  121. $fieldset->validation($this);
  122. $this->fieldset = $fieldset;
  123. }
  124. else
  125. {
  126. $this->fieldset = \Fieldset::forge($fieldset, array('validation_instance' => $this));
  127. }
  128. $this->callables = array($this);
  129. $this->global_input_fallback = \Config::get('validation.global_input_fallback', true);
  130. }
  131. /**
  132. * Returns the related fieldset
  133. *
  134. * @return Fieldset
  135. */
  136. public function fieldset()
  137. {
  138. return $this->fieldset;
  139. }
  140. /**
  141. * Simpler alias for Validation->add()
  142. *
  143. * @param string Field name
  144. * @param string Field label
  145. * @param string Rules as a piped string
  146. * @return Fieldset_Field $this to allow chaining
  147. * @depricated Remove in v2.0, passing rules as string is to be removed use add() instead
  148. */
  149. public function add_field($name, $label, $rules)
  150. {
  151. $field = $this->add($name, $label);
  152. is_array($rules) or $rules = explode('|', $rules);
  153. foreach ($rules as $rule)
  154. {
  155. if (($pos = strpos($rule, '[')) !== false)
  156. {
  157. preg_match('#\[(.*)\]#', $rule, $param);
  158. $rule = substr($rule, 0, $pos);
  159. // deal with rules that have comma's in the rule parameter
  160. if (in_array($rule, array('match_pattern')))
  161. {
  162. call_user_func_array(array($field, 'add_rule'), array_merge(array($rule), array($param[1])));
  163. }
  164. elseif (in_array($rule, array('valid_string')))
  165. {
  166. call_user_func_array(array($field, 'add_rule'), array_merge(array($rule), array(explode(',', $param[1]))));
  167. }
  168. else
  169. {
  170. call_user_func_array(array($field, 'add_rule'), array_merge(array($rule), explode(',', $param[1])));
  171. }
  172. }
  173. else
  174. {
  175. $field->add_rule($rule);
  176. }
  177. }
  178. return $field;
  179. }
  180. /**
  181. * This will overwrite lang file messages for this validation instance
  182. *
  183. * @param string
  184. * @param string
  185. * @return Validation this, to allow chaining
  186. */
  187. public function set_message($rule, $message)
  188. {
  189. if ($message !== null)
  190. {
  191. $this->error_messages[$rule] = $message;
  192. }
  193. else
  194. {
  195. unset($this->error_messages[$rule]);
  196. }
  197. return $this;
  198. }
  199. /**
  200. * Fetches a specific error message for this validation instance
  201. *
  202. * @param string
  203. * @return string
  204. */
  205. public function get_message($rule)
  206. {
  207. if ( ! array_key_exists($rule, $this->error_messages))
  208. {
  209. return false;
  210. }
  211. return $this->error_messages[$rule];
  212. }
  213. /**
  214. * Add Callable
  215. *
  216. * Adds an object for which you don't need to write a full callback, just
  217. * the method as a string will do. This also allows for overwriting functionality
  218. * from this object because the new class is prepended.
  219. *
  220. * @param string|Object Classname or object
  221. * @return Validation this, to allow chaining
  222. */
  223. public function add_callable($class)
  224. {
  225. if ( ! (is_object($class) || class_exists($class)))
  226. {
  227. throw new \InvalidArgumentException('Input for add_callable is not a valid object or class.');
  228. }
  229. // Prevent having the same class twice in the array, remove to re-add on top if...
  230. foreach ($this->callables as $key => $c)
  231. {
  232. // ...it already exists in callables
  233. if ($c === $class)
  234. {
  235. unset($this->callables[$key]);
  236. }
  237. // ...new object/class extends it or an instance of it
  238. elseif (is_string($c) and (is_subclass_of($class, $c) or (is_object($class) and is_a($class, $c))))
  239. {
  240. unset($this->callables[$key]);
  241. }
  242. // but if there's a subclass in there to the new one, put the subclass on top and forget the new
  243. elseif (is_string($class) and (is_subclass_of($c, $class) or (is_object($c) and is_a($c, $class))))
  244. {
  245. unset($this->callables[$key]);
  246. $class = $c;
  247. }
  248. }
  249. array_unshift($this->callables, $class);
  250. return $this;
  251. }
  252. /*
  253. * Remove Callable
  254. *
  255. * Removes an object from the callables array
  256. *
  257. * @param string|Object Classname or object
  258. * @return Validation this, to allow chaining
  259. */
  260. public function remove_callable($class)
  261. {
  262. if (($key = array_search($class, $this->callables, true)))
  263. {
  264. unset($this->callables[$key]);
  265. }
  266. return $this;
  267. }
  268. /**
  269. * Fetch the objects for which you don't need to add a full callback but
  270. * just the method name
  271. *
  272. * @return array
  273. */
  274. public function callables()
  275. {
  276. return $this->callables;
  277. }
  278. /**
  279. * Run validation
  280. *
  281. * Performs validation with current fieldset and on given input, will try POST
  282. * when input wasn't given.
  283. *
  284. * @param array input that overwrites POST values
  285. * @param bool will skip validation of values it can't find or are null
  286. * @return bool whether validation succeeded
  287. */
  288. public function run($input = null, $allow_partial = false, $temp_callables = array())
  289. {
  290. if (is_null($input) and \Input::method() != 'POST')
  291. {
  292. return false;
  293. }
  294. // Backup current state of callables so they can be restored after adding temp callables
  295. $callable_backup = $this->callables;
  296. // Add temporary callables, reversed so first ends on top
  297. foreach (array_reverse($temp_callables) as $temp_callable)
  298. {
  299. $this->add_callable($temp_callable);
  300. }
  301. static::set_active($this);
  302. $this->validated = array();
  303. $this->errors = array();
  304. $this->input = $input ?: array();
  305. $fields = $this->field(null, true);
  306. foreach($fields as $field)
  307. {
  308. static::set_active_field($field);
  309. // convert form field array's to Fuel dotted notation
  310. $name = str_replace(array('[',']'), array('.', ''), $field->name);
  311. $value = $this->input($name);
  312. if (($allow_partial === true and $value === null)
  313. or (is_array($allow_partial) and ! in_array($field->name, $allow_partial)))
  314. {
  315. continue;
  316. }
  317. try
  318. {
  319. foreach ($field->rules as $rule)
  320. {
  321. $callback = $rule[0];
  322. $params = $rule[1];
  323. $this->_run_rule($callback, $value, $params, $field);
  324. }
  325. if (strpos($name, '.') !== false)
  326. {
  327. \Arr::set($this->validated, $name, $value);
  328. }
  329. else
  330. {
  331. $this->validated[$name] = $value;
  332. }
  333. }
  334. catch (Validation_Error $v)
  335. {
  336. $this->errors[$field->name] = $v;
  337. if($field->fieldset())
  338. {
  339. $field->fieldset()->Validation()->add_error($field->name, $v);
  340. }
  341. }
  342. }
  343. static::set_active();
  344. static::set_active_field();
  345. // Restore callables
  346. $this->callables = $callable_backup;
  347. return empty($this->errors);
  348. }
  349. /**
  350. * Takes the rule input and formats it into a name & callback
  351. *
  352. * @param string|array short rule to be called on Validation callables array or full callback
  353. * @return array|bool rule array or false when it fails to find something callable
  354. */
  355. protected function _find_rule($callback)
  356. {
  357. // Rules are validated and only accepted when given as an array consisting of
  358. // array(callback, params) or just callbacks in an array.
  359. if (is_string($callback))
  360. {
  361. $callback_method = '_validation_'.$callback;
  362. foreach ($this->callables as $callback_class)
  363. {
  364. if (method_exists($callback_class, $callback_method))
  365. {
  366. return array($callback => array($callback_class, $callback_method));
  367. }
  368. }
  369. }
  370. // when no callable function was found, try regular callbacks
  371. if (is_callable($callback))
  372. {
  373. if ($callback instanceof \Closure)
  374. {
  375. $callback_name = 'closure';
  376. }
  377. elseif (is_array($callback))
  378. {
  379. $callback_name = preg_replace('#^([a-z_]*\\\\)*#i', '',
  380. is_object($callback[0]) ? get_class($callback[0]) : $callback[0]).':'.$callback[1];
  381. }
  382. else
  383. {
  384. $callback_name = preg_replace('#^([a-z_]*\\\\)*#i', '', str_replace('::', ':', $callback));
  385. }
  386. return array($callback_name => $callback);
  387. }
  388. elseif (is_array($callback) and is_callable(reset($callback)))
  389. {
  390. return $callback;
  391. }
  392. else
  393. {
  394. $string = ! is_array($callback)
  395. ? $callback
  396. : (is_object(@$callback[0])
  397. ? get_class(@$callback[0]).'->'.@$callback[1]
  398. : @$callback[0].'::'.@$callback[1]);
  399. \Error::notice('Invalid rule "'.$string.'" passed to Validation, not used.');
  400. return false;
  401. }
  402. }
  403. /**
  404. * Run rule
  405. *
  406. * Performs a single rule on a field and its value
  407. *
  408. * @param callback
  409. * @param mixed Value by reference, will be edited
  410. * @param array Extra parameters
  411. * @param array Validation field description
  412. * @throws Validation_Error
  413. */
  414. protected function _run_rule($rule, &$value, $params, $field)
  415. {
  416. if (($rule = $this->_find_rule($rule)) === false)
  417. {
  418. return;
  419. }
  420. $output = call_user_func_array(reset($rule), array_merge(array($value), $params));
  421. if ($output === false && $value !== false)
  422. {
  423. throw new \Validation_Error($field, $value, $rule, $params);
  424. }
  425. elseif ($output !== true)
  426. {
  427. $value = $output;
  428. }
  429. }
  430. /**
  431. * Fetches the input value from either post or given input
  432. *
  433. * @param string
  434. * @param mixed
  435. * @return mixed|array the input value or full input values array
  436. */
  437. public function input($key = null, $default = null)
  438. {
  439. if ($key === null)
  440. {
  441. return $this->input;
  442. }
  443. if ( ! array_key_exists($key, $this->input))
  444. {
  445. if (strpos($key,'[') !== false)
  446. {
  447. $this->input[$key] = $this->global_input_fallback ? \Arr::get(\Input::param(), str_replace(array('[', ']'),array('.', ''),$key), $default) : $default;
  448. }
  449. else
  450. {
  451. $this->input[$key] = $this->global_input_fallback ? \Input::param($key, $default) : $default;
  452. }
  453. }
  454. return $this->input[$key];
  455. }
  456. /**
  457. * Validated
  458. *
  459. * Returns specific validated value or all validated field=>value pairs
  460. *
  461. * @param string fieldname
  462. * @param mixed value to return when not validated
  463. * @return mixed|array the validated value or full validated values array
  464. */
  465. public function validated($field = null, $default = false)
  466. {
  467. if ($field === null)
  468. {
  469. return $this->validated;
  470. }
  471. return array_key_exists($field, $this->validated) ? $this->validated[$field] : $default;
  472. }
  473. /**
  474. * Error
  475. *
  476. * Return specific error or all errors thrown during validation
  477. *
  478. * @param string fieldname
  479. * @param mixed value to return when not validated
  480. * @return Validation_Error|array the validation error object or full array of error objects
  481. */
  482. public function error($field = null, $default = false)
  483. {
  484. if ($field === null)
  485. {
  486. return $this->errors;
  487. }
  488. return array_key_exists($field, $this->errors) ? $this->errors[$field] : $default;
  489. }
  490. /**
  491. * Show errors
  492. *
  493. * Returns all errors in a list or with set markup from $options param
  494. *
  495. * @param array uses keys open_list, close_list, open_error, close_error & no_errors
  496. * @return string
  497. */
  498. public function show_errors($options = array())
  499. {
  500. $default = array(
  501. 'open_list' => \Config::get('validation.open_list', '<ul>'),
  502. 'close_list' => \Config::get('validation.close_list', '</ul>'),
  503. 'open_error' => \Config::get('validation.open_error', '<li>'),
  504. 'close_error' => \Config::get('validation.close_error', '</li>'),
  505. 'no_errors' => \Config::get('validation.no_errors', '')
  506. );
  507. $options = array_merge($default, $options);
  508. if (empty($this->errors))
  509. {
  510. return $options['no_errors'];
  511. }
  512. $output = $options['open_list'];
  513. foreach($this->errors as $e)
  514. {
  515. $output .= $options['open_error'].$e->get_message().$options['close_error'];
  516. }
  517. $output .= $options['close_list'];
  518. return $output;
  519. }
  520. /**
  521. * Add error
  522. *
  523. * Adds an error for a given field.
  524. *
  525. * @param string field name for which to set the error
  526. * @param Validation_Error error for the field
  527. * @return Validation this, to allow chaining
  528. */
  529. protected function add_error($name = null, $error = null)
  530. {
  531. if($name !== null and $error !== null)
  532. {
  533. $this->errors[$name] = $error;
  534. }
  535. return $this;
  536. }
  537. /**
  538. * Alias for $this->fieldset->add()
  539. *
  540. * @return Fieldset_Field
  541. */
  542. public function add($name, $label = '', array $attributes = array(), array $rules = array())
  543. {
  544. return $this->fieldset->add($name, $label, $attributes, $rules);
  545. }
  546. /**
  547. * Alias for $this->fieldset->add_model()
  548. *
  549. * @return Validation this, to allow chaining
  550. */
  551. public function add_model($class, $instance = null, $method = 'set_form_fields')
  552. {
  553. $this->fieldset->add_model($class, $instance, $method);
  554. return $this;
  555. }
  556. /**
  557. * Alias for $this->fieldset->field()
  558. *
  559. * @return Fieldset_Field
  560. */
  561. public function field($name = null, $flatten = false)
  562. {
  563. return $this->fieldset->field($name, $flatten);
  564. }
  565. /* -------------------------------------------------------------------------------
  566. * The validation methods
  567. * ------------------------------------------------------------------------------- */
  568. /**
  569. * Required
  570. *
  571. * Value may not be empty
  572. *
  573. * @param mixed
  574. * @return bool
  575. */
  576. public function _validation_required($val)
  577. {
  578. return ! $this->_empty($val);
  579. }
  580. /**
  581. * Special empty method because 0 and '0' are non-empty values
  582. *
  583. * @param mixed
  584. * @return bool
  585. */
  586. public static function _empty($val)
  587. {
  588. return ($val === false or $val === null or $val === '' or $val === array());
  589. }
  590. /**
  591. * Match value against comparison input
  592. *
  593. * @param mixed
  594. * @param mixed
  595. * @param bool whether to do type comparison
  596. * @return bool
  597. */
  598. public function _validation_match_value($val, $compare, $strict = false)
  599. {
  600. // first try direct match
  601. if ($this->_empty($val) || $val === $compare || ( ! $strict && $val == $compare))
  602. {
  603. return true;
  604. }
  605. // allow multiple input for comparison
  606. if (is_array($compare))
  607. {
  608. foreach($compare as $c)
  609. {
  610. if ($val === $c || ( ! $strict && $val == $c))
  611. {
  612. return true;
  613. }
  614. }
  615. }
  616. // all is lost, return failure
  617. return false;
  618. }
  619. /**
  620. * Match PRCE pattern
  621. *
  622. * @param string
  623. * @param string a PRCE regex pattern
  624. * @return bool
  625. */
  626. public function _validation_match_pattern($val, $pattern)
  627. {
  628. return $this->_empty($val) || preg_match($pattern, $val) > 0;
  629. }
  630. /**
  631. * Match specific other submitted field string value
  632. * (must be both strings, check is type sensitive)
  633. *
  634. * @param string
  635. * @param string
  636. * @return bool
  637. */
  638. public function _validation_match_field($val, $field)
  639. {
  640. if ($this->input($field) !== $val)
  641. {
  642. $validating = $this->active_field();
  643. throw new \Validation_Error($validating, $val, array('match_field' => array($field)), array($this->field($field)->label));
  644. }
  645. return true;
  646. }
  647. /**
  648. * Minimum string length
  649. *
  650. * @param string
  651. * @param int
  652. * @return bool
  653. */
  654. public function _validation_min_length($val, $length)
  655. {
  656. return $this->_empty($val) || (MBSTRING ? mb_strlen($val) : strlen($val)) >= $length;
  657. }
  658. /**
  659. * Maximum string length
  660. *
  661. * @param string
  662. * @param int
  663. * @return bool
  664. */
  665. public function _validation_max_length($val, $length)
  666. {
  667. return $this->_empty($val) || (MBSTRING ? mb_strlen($val) : strlen($val)) <= $length;
  668. }
  669. /**
  670. * Exact string length
  671. *
  672. * @param string
  673. * @param int
  674. * @return bool
  675. */
  676. public function _validation_exact_length($val, $length)
  677. {
  678. return $this->_empty($val) || (MBSTRING ? mb_strlen($val) : strlen($val)) == $length;
  679. }
  680. /**
  681. * Validate email using PHP's filter_var()
  682. *
  683. * @param string
  684. * @return bool
  685. */
  686. public function _validation_valid_email($val)
  687. {
  688. return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_EMAIL);
  689. }
  690. /**
  691. * Validate email using PHP's filter_var()
  692. *
  693. * @param string
  694. * @return bool
  695. */
  696. public function _validation_valid_emails($val, $separator = ',')
  697. {
  698. if ($this->_empty($val))
  699. {
  700. return true;
  701. }
  702. $emails = explode($separator, $val);
  703. foreach ($emails as $e)
  704. {
  705. if ( ! filter_var(trim($e), FILTER_VALIDATE_EMAIL))
  706. {
  707. return false;
  708. }
  709. }
  710. return true;
  711. }
  712. /**
  713. * Validate URL using PHP's filter_var()
  714. *
  715. * @param string
  716. * @return bool
  717. */
  718. public function _validation_valid_url($val)
  719. {
  720. return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_URL);
  721. }
  722. /**
  723. * Validate IP using PHP's filter_var()
  724. *
  725. * @param string
  726. * @return bool
  727. */
  728. public function _validation_valid_ip($val)
  729. {
  730. return $this->_empty($val) || filter_var($val, FILTER_VALIDATE_IP);
  731. }
  732. /**
  733. * Validate input string with many options
  734. *
  735. * @param string
  736. * @param string|array either a named filter or combination of flags
  737. * @return bool
  738. */
  739. public function _validation_valid_string($val, $flags = array('alpha', 'utf8'))
  740. {
  741. if ($this->_empty($val))
  742. {
  743. return true;
  744. }
  745. if ( ! is_array($flags))
  746. {
  747. if ($flags == 'alpha')
  748. {
  749. $flags = array('alpha', 'utf8');
  750. }
  751. elseif ($flags == 'alpha_numeric')
  752. {
  753. $flags = array('alpha', 'utf8', 'numeric');
  754. }
  755. elseif ($flags == 'url_safe')
  756. {
  757. $flags = array('alpha', 'numeric', 'dashes');
  758. }
  759. elseif ($flags == 'integer' or $flags == 'numeric')
  760. {
  761. $flags = array('numeric');
  762. }
  763. elseif ($flags == 'float')
  764. {
  765. $flags = array('numeric', 'dots');
  766. }
  767. elseif ($flags == 'quotes')
  768. {
  769. $flags = array('singlequotes', 'doublequotes');
  770. }
  771. elseif ($flags == 'all')
  772. {
  773. $flags = array('alpha', 'utf8', 'numeric', 'spaces', 'newlines', 'tabs', 'punctuation', 'singlequotes', 'doublequotes', 'dashes');
  774. }
  775. else
  776. {
  777. return false;
  778. }
  779. }
  780. $pattern = ! in_array('uppercase', $flags) && in_array('alpha', $flags) ? 'a-z' : '';
  781. $pattern .= ! in_array('lowercase', $flags) && in_array('alpha', $flags) ? 'A-Z' : '';
  782. $pattern .= in_array('numeric', $flags) ? '0-9' : '';
  783. $pattern .= in_array('spaces', $flags) ? ' ' : '';
  784. $pattern .= in_array('newlines', $flags) ? "\n" : '';
  785. $pattern .= in_array('tabs', $flags) ? "\t" : '';
  786. $pattern .= in_array('dots', $flags) && ! in_array('punctuation', $flags) ? '\.' : '';
  787. $pattern .= in_array('commas', $flags) && ! in_array('punctuation', $flags) ? ',' : '';
  788. $pattern .= in_array('punctuation', $flags) ? "\.,\!\?:;\&" : '';
  789. $pattern .= in_array('dashes', $flags) ? '_\-' : '';
  790. $pattern .= in_array('singlequotes', $flags) ? "'" : '';
  791. $pattern .= in_array('doublequotes', $flags) ? "\"" : '';
  792. $pattern = empty($pattern) ? '/^(.*)$/' : ('/^(['.$pattern.'])+$/');
  793. $pattern .= in_array('utf8', $flags) ? 'u' : '';
  794. return preg_match($pattern, $val) > 0;
  795. }
  796. /**
  797. * Checks whether numeric input has a minimum value
  798. *
  799. * @param string|float|int
  800. * @param float|int
  801. * @return bool
  802. */
  803. public function _validation_numeric_min($val, $min_val)
  804. {
  805. return $this->_empty($val) || floatval($val) >= floatval($min_val);
  806. }
  807. /**
  808. * Checks whether numeric input has a maximum value
  809. *
  810. * @param string|float|int
  811. * @param float|int
  812. * @return bool
  813. */
  814. public function _validation_numeric_max($val, $max_val)
  815. {
  816. return $this->_empty($val) || floatval($val) <= floatval($max_val);
  817. }
  818. /**
  819. * Checks whether numeric input is between a minimum and a maximum value
  820. *
  821. * @param string|float|int
  822. * @param float|int
  823. * @param float|int
  824. * @return bool
  825. */
  826. public function _validation_numeric_between($val, $min_val, $max_val)
  827. {
  828. return $this->_empty($val) or (floatval($val) >= floatval($min_val) and floatval($val) <= floatval($max_val));
  829. }
  830. /**
  831. * Conditionally requires completion of current field based on completion of another field
  832. *
  833. * @param mixed
  834. * @param string
  835. * @return bool
  836. */
  837. public function _validation_required_with($val, $field)
  838. {
  839. if ( ! $this->_empty($this->input($field)) and $this->_empty($val))
  840. {
  841. $validating = $this->active_field();
  842. throw new \Validation_Error($validating, $val, array('required_with' => array($this->field($field))), array($this->field($field)->label));
  843. }
  844. return true;
  845. }
  846. }