diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-10-31 22:12:14 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-10-31 22:12:14 +0000 |
commit | eba717f95f586d2538007bd18da6e9b32b076c30 (patch) | |
tree | 15fc596a270f9de0d163c66c96e3c65fca5ee100 /modules/forge/libraries/Form_Input.php | |
parent | fff10f8b70376ef25722bd867df26bc5aefced43 (diff) |
Merge over vendor code.
git-svn-id: http://gallery.svn.sourceforge.net/svnroot/gallery/trunk/eval/gx/gallery3/trunk@18408 57fcd75e-5312-0410-8df3-f5eb6fbb1595
Diffstat (limited to 'modules/forge/libraries/Form_Input.php')
-rw-r--r-- | modules/forge/libraries/Form_Input.php | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/modules/forge/libraries/Form_Input.php b/modules/forge/libraries/Form_Input.php new file mode 100644 index 00000000..7dfc974d --- /dev/null +++ b/modules/forge/libraries/Form_Input.php @@ -0,0 +1,555 @@ +<?php +/** + * FORGE base input library. + * + * $Id$ + * + * @package Forge + * @author Kohana Team + * @copyright (c) 2007-2008 Kohana Team + * @license http://kohanaphp.com/license.html + */ +class Form_Input_Core { + + // Input method + public $method; + + // Element data + protected $data = array + ( + 'type' => 'text', + 'class' => 'textbox', + 'value' => '' + ); + + // Protected data keys + protected $protect = array(); + + // Validation rules, matches, and callbacks + protected $rules = array(); + protected $matches = array(); + protected $callbacks = array(); + + // Validation check + protected $is_valid; + + // Errors + protected $errors = array(); + protected $error_messages = array(); + + /** + * Sets the input element name. + */ + public function __construct($name) + { + $this->data['name'] = $name; + } + + /** + * Sets form attributes, or return rules. + */ + public function __call($method, $args) + { + if ($method == 'rules') + { + if (empty($args)) + return $this->rules; + + // Set rules and action + $rules = $args[0]; + $action = substr($rules, 0, 1); + + if (in_array($action, array('-', '+', '='))) + { + // Remove the action from the rules + $rules = substr($rules, 1); + } + else + { + // Default action is append + $action = ''; + } + + $this->add_rules(explode('|', $rules), $action); + } + elseif ($method == 'name') + { + // Do nothing. The name should stay static once it is set. + } + else + { + $this->data[$method] = $args[0]; + } + + return $this; + } + + /** + * Returns form attributes. + * + * @param string attribute name + * @return string + */ + public function __get($key) + { + if (isset($this->data[$key])) + { + return $this->data[$key]; + } + } + + /** + * Sets a form element that this element must match the value of. + * + * @chainable + * @param object another Forge input + * @return object + */ + public function matches($input) + { + if ( ! in_array($input, $this->matches, TRUE)) + { + $this->matches[] = $input; + } + + return $this; + } + + /** + * Sets a callback method as a rule for this input. + * + * @chainable + * @param callback + * @return object + */ + public function callback($callback) + { + if ( ! in_array($callback, $this->callbacks, TRUE)) + { + $this->callbacks[] = $callback; + } + + return $this; + } + + /** + * Sets or returns the input label. + * + * @chainable + * @param string label to set + * @return string|object + */ + public function label($val = NULL) + { + if ($val === NULL) + { + if (isset($this->data['name']) AND isset($this->data['label'])) + { + return form::label($this->data['name'], $this->data['label']); + } + return FALSE; + } + else + { + $this->data['label'] = ($val === TRUE) ? utf8::ucwords(inflector::humanize($this->name)) : $val; + return $this; + } + } + + /** + * Set or return the error message. + * + * @chainable + * @param string error message + * @return strong|object + */ + public function message($val = NULL) + { + if ($val === NULL) + { + if (isset($this->data['message'])) + return $this->data['message']; + } + else + { + $this->data['message'] = $val; + return $this; + } + } + + /** + * Runs validation and returns the element HTML. + * + * @return string + */ + public function render() + { + // Make sure validation runs + $this->validate(); + + return $this->html_element(); + } + + /** + * Returns the form input HTML. + * + * @return string + */ + protected function html_element() + { + $data = $this->data; + + unset($data['label']); + unset($data['message']); + + return form::input($data); + } + + /** + * Replace, remove, or append rules. + * + * @param array rules to change + * @param string action to use: replace, remove, append + */ + protected function add_rules( array $rules, $action) + { + if ($action === '=') + { + // Just replace the rules + $this->rules = $rules; + return; + } + + foreach ($rules as $rule) + { + if ($action === '-') + { + if (($key = array_search($rule, $this->rules)) !== FALSE) + { + // Remove the rule + unset($this->rules[$key]); + } + } + else + { + if ( ! in_array($rule, $this->rules)) + { + if ($action == '+') + { + array_unshift($this->rules, $rule); + } + else + { + $this->rules[] = $rule; + } + } + } + } + } + + /** + * Add an error to the input. + * + * @chainable + * @return object + */ + public function add_error($key, $val) + { + if ( ! isset($this->errors[$key])) + { + $this->errors[$key] = $val; + } + + return $this; + } + + /** + * Set or return the error messages. + * + * @chainable + * @param string|array failed validation function, or an array of messages + * @param string error message + * @return object|array + */ + public function error_messages($func = NULL, $message = NULL) + { + // Set custom error messages + if ( ! empty($func)) + { + if (is_array($func)) + { + // Replace all + $this->error_messages = $func; + } + else + { + if (empty($message)) + { + // Single error, replaces all others + $this->error_messages = $func; + } + else + { + // Add custom error + $this->error_messages[$func] = $message; + } + } + return $this; + } + + // Make sure validation runs + is_null($this->is_valid) and $this->validate(); + + // Return single error + if ( ! is_array($this->error_messages) AND ! empty($this->errors)) + return array($this->error_messages); + + $messages = array(); + foreach ($this->errors as $func => $args) + { + if (is_string($args)) + { + $error = $args; + } + else + { + // Force args to be an array + $args = is_array($args) ? $args : array(); + + // Add the label or name to the beginning of the args + array_unshift($args, $this->label ? utf8::strtolower($this->label) : $this->name); + + if (isset($this->error_messages[$func])) + { + // Use custom error message + $error = vsprintf($this->error_messages[$func], $args); + } + else + { + // Get the proper i18n entry, very hacky but it works + switch ($func) + { + case 'valid_url': + case 'valid_email': + case 'valid_ip': + // Fetch an i18n error message + $error = Kohana::lang('validation.'.$func, $args); + break; + case substr($func, 0, 6) === 'valid_': + // Strip 'valid_' from func name + $func = (substr($func, 0, 6) === 'valid_') ? substr($func, 6) : $func; + case 'alpha': + case 'alpha_dash': + case 'digit': + case 'numeric': + // i18n strings have to be inserted into valid_type + $args[] = Kohana::lang('validation.'.$func); + $error = Kohana::lang('validation.valid_type', $args); + break; + default: + $error = Kohana::lang('validation.'.$func, $args); + } + } + } + + // Add error to list + $messages[] = $error; + } + + return $messages; + } + + /** + * Get the global input value. + * + * @return string|bool + */ + protected function input_value($name = array()) + { + // Get the Input instance + $input = Input::instance(); + + // Fetch the method for this object + $method = $this->method; + + return $input->$method($name, NULL); + } + + /** + * Load the value of the input, if form data is present. + * + * @return void + */ + protected function load_value() + { + if (is_bool($this->is_valid)) + return; + + if ($name = $this->name) + { + // Load POSTed value, but only for named inputs + $this->data['value'] = $this->input_value($name); + } + + if (is_string($this->data['value'])) + { + // Trim string values + $this->data['value'] = trim($this->data['value']); + } + } + + /** + * Validate this input based on the set rules. + * + * @return bool + */ + public function validate() + { + // Validation has already run + if (is_bool($this->is_valid)) + return $this->is_valid; + + // No data to validate + if ($this->input_value() == FALSE) + return $this->is_valid = FALSE; + + // Load the submitted value + $this->load_value(); + + // No rules to validate + if (count($this->rules) == 0 AND count($this->matches) == 0 AND count($this->callbacks) == 0) + return $this->is_valid = TRUE; + + if ( ! empty($this->rules)) + { + foreach ($this->rules as $rule) + { + if (($offset = strpos($rule, '[')) !== FALSE) + { + // Get the args + $args = preg_split('/, ?/', trim(substr($rule, $offset), '[]')); + + // Remove the args from the rule + $rule = substr($rule, 0, $offset); + } + + if (substr($rule, 0, 6) === 'valid_' AND method_exists('valid', substr($rule, 6))) + { + $func = substr($rule, 6); + + if ($this->value AND ! valid::$func($this->value)) + { + $this->errors[$rule] = TRUE; + } + } + elseif (method_exists($this, 'rule_'.$rule)) + { + // The rule function is always prefixed with rule_ + $rule = 'rule_'.$rule; + + if (isset($args)) + { + // Manually call up to 2 args for speed + switch (count($args)) + { + case 1: + $this->$rule($args[0]); + break; + case 2: + $this->$rule($args[0], $args[1]); + break; + default: + call_user_func_array(array($this, $rule), $args); + break; + } + } + else + { + // Just call the rule + $this->$rule(); + } + + // Prevent args from being re-used + unset($args); + } + else + { + throw new Kohana_Exception('validation.invalid_rule', $rule); + } + + // Stop when an error occurs + if ( ! empty($this->errors)) + break; + } + } + + if ( ! empty($this->matches)) + { + foreach ($this->matches as $input) + { + if ($this->value != $input->value) + { + // Field does not match + $this->errors['matches'] = array($input->label ? utf8::strtolower($input->label) : $input->name); + break; + } + } + } + + if ( ! empty($this->callbacks)) + { + foreach ($this->callbacks as $callback) + { + call_user_func($callback, $this); + + // Stop when an error occurs + if ( ! empty($this->errors)) + break; + } + } + + // If there are errors, validation failed + return $this->is_valid = empty($this->errors); + } + + /** + * Validate required. + */ + protected function rule_required() + { + if ($this->value === '' OR $this->value === NULL) + { + $this->errors['required'] = TRUE; + } + } + + /** + * Validate length. + */ + protected function rule_length($min, $max = NULL) + { + // Get the length, return if zero + if (($length = utf8::strlen($this->value)) === 0) + return; + + if ($max == NULL) + { + if ($length != $min) + { + $this->errors['exact_length'] = array($min); + } + } + else + { + if ($length < $min) + { + $this->errors['min_length'] = array($min); + } + elseif ($length > $max) + { + $this->errors['max_length'] = array($max); + } + } + } + +} // End Form Input
\ No newline at end of file |