/horde-3.3.13/lib/Horde/Form.php
PHP | 4908 lines | 3112 code | 652 blank | 1144 comment | 469 complexity | f4355879d9388b0d21ca68251e904d7e MD5 | raw file
Possible License(s): LGPL-2.0
- <?php
- /**
- * @package Horde_Form
- */
- /** String */
- include_once 'Horde/String.php';
- /**
- * Horde_Form Master Class.
- *
- * The Horde_Form:: package provides form rendering, validation, and
- * other functionality for the Horde Application Framework.
- *
- * $Horde: framework/Form/Form.php,v 1.306.2.81 2012/02/03 15:17:31 jan Exp $
- *
- * Copyright 2001-2007 Robert E. Coyle <robertecoyle@hotmail.com>
- * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Robert E. Coyle <robertecoyle@hotmail.com>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @since Horde 3.0
- * @package Horde_Form
- */
- class Horde_Form {
- var $_name = '';
- var $_title = '';
- var $_extra = '';
- var $_vars;
- var $_submit = array();
- var $_reset = false;
- var $_errors = array();
- var $_submitted = null;
- var $_sections = array();
- var $_open_section = null;
- var $_currentSection = array();
- var $_variables = array();
- var $_hiddenVariables = array();
- var $_useFormToken = true;
- var $_autofilled = false;
- var $_enctype = null;
- var $_help = false;
- function Horde_Form(&$vars, $title = '', $name = null)
- {
- if (empty($name)) {
- $name = String::lower(get_class($this));
- }
- $this->_vars = &$vars;
- $this->_title = $title;
- $this->_name = $name;
- }
- function __construct($vars, $title = '', $name = null)
- {
- $this->Horde_Form($vars, $title, $name);
- }
- function &singleton($form, &$vars, $title = '', $name = null)
- {
- static $instances = array();
- $signature = serialize(array($form, $vars, $title, $name));
- if (!isset($instances[$signature])) {
- if (class_exists($form)) {
- $instances[$signature] = new $form($vars, $title, $name);
- } else {
- $instances[$signature] = new Horde_Form($vars, $title, $name);
- }
- }
- return $instances[$signature];
- }
- function setVars(&$vars)
- {
- $this->_vars = &$vars;
- }
- function getTitle()
- {
- return $this->_title;
- }
- function setTitle($title)
- {
- $this->_title = $title;
- }
- function getExtra()
- {
- return $this->_extra;
- }
- function setExtra($extra)
- {
- $this->_extra = $extra;
- }
- function getName()
- {
- return $this->_name;
- }
- /**
- * Sets or gets whether the form should be verified by tokens.
- * Tokens are used to verify that a form is only submitted once.
- *
- * @param boolean $token If specified, sets whether to use form tokens.
- *
- * @return boolean Whether form tokens are being used.
- */
- function useToken($token = null)
- {
- if (!is_null($token)) {
- $this->_useFormToken = $token;
- }
- return $this->_useFormToken;
- }
- /**
- * Get the renderer for this form, either a custom renderer or the
- * standard one.
- *
- * To use a custom form renderer, your form class needs to
- * override this function:
- * <code>
- * function &getRenderer()
- * {
- * $r = new CustomFormRenderer();
- * return $r;
- * }
- * </code>
- *
- * ... where CustomFormRenderer is the classname of the custom
- * renderer class, which should extend Horde_Form_Renderer.
- *
- * @param array $params A hash of renderer-specific parameters.
- *
- * @return object Horde_Form_Renderer The form renderer.
- */
- function &getRenderer($params = array())
- {
- require_once 'Horde/Form/Renderer.php';
- $renderer = new Horde_Form_Renderer($params);
- return $renderer;
- }
- function &getType($type, $params = array())
- {
- $type_class = 'Horde_Form_Type_' . $type;
- if (!class_exists($type_class)) {
- require_once 'PEAR.php';
- Horde::fatal(PEAR::raiseError(sprintf('Nonexistant class "%s" for field type "%s"', $type_class, $type)), __FILE__, __LINE__);
- }
- $type_ob = new $type_class();
- if (!$params) {
- $params = array();
- }
- call_user_func_array(array(&$type_ob, 'init'), $params);
- return $type_ob;
- }
- function setSection($section = '', $desc = '', $image = '', $expanded = true)
- {
- $this->_currentSection = $section;
- if (!count($this->_sections) && !$this->getOpenSection()) {
- $this->setOpenSection($section);
- }
- $this->_sections[$section]['desc'] = $desc;
- $this->_sections[$section]['expanded'] = $expanded;
- $this->_sections[$section]['image'] = $image;
- }
- function getSectionDesc($section)
- {
- return $this->_sections[$section]['desc'];
- }
- function getSectionImage($section)
- {
- return $this->_sections[$section]['image'];
- }
- function setOpenSection($section)
- {
- $this->_vars->set('__formOpenSection', $section);
- }
- function getOpenSection()
- {
- return $this->_vars->get('__formOpenSection');
- }
- function getSectionExpandedState($section, $boolean = false)
- {
- if ($boolean) {
- /* Only the boolean value is required. */
- return $this->_sections[$section]['expanded'];
- }
- /* Need to return the values for use in styles. */
- if ($this->_sections[$section]['expanded']) {
- return 'block';
- } else {
- return 'none';
- }
- }
- /**
- * TODO
- */
- function &addVariable($humanName, $varName, $type, $required,
- $readonly = false, $description = null,
- $params = array())
- {
- return $this->insertVariableBefore(null, $humanName, $varName, $type,
- $required, $readonly, $description,
- $params);
- }
- /**
- * TODO
- */
- function &insertVariableBefore($before, $humanName, $varName, $type,
- $required, $readonly = false,
- $description = null, $params = array())
- {
- $type = &$this->getType($type, $params);
- $var = new Horde_Form_Variable($humanName, $varName, $type,
- $required, $readonly, $description);
- /* Set the form object reference in the var. */
- $var->setFormOb($this);
- if ($var->getTypeName() == 'enum' &&
- !strlen($type->getPrompt()) &&
- count($var->getValues()) == 1) {
- $vals = array_keys($var->getValues());
- $this->_vars->add($var->varName, $vals[0]);
- $var->_autofilled = true;
- } elseif ($var->getTypeName() == 'file' ||
- $var->getTypeName() == 'image') {
- $this->_enctype = 'multipart/form-data';
- }
- if (empty($this->_currentSection)) {
- $this->_currentSection = '__base';
- }
- if (is_null($before)) {
- $this->_variables[$this->_currentSection][] = &$var;
- } else {
- $num = 0;
- while (isset($this->_variables[$this->_currentSection][$num]) &&
- $this->_variables[$this->_currentSection][$num]->getVarName() != $before) {
- $num++;
- }
- if (!isset($this->_variables[$this->_currentSection][$num])) {
- $this->_variables[$this->_currentSection][] = &$var;
- } else {
- $this->_variables[$this->_currentSection] = array_merge(
- array_slice($this->_variables[$this->_currentSection], 0, $num),
- array(&$var),
- array_slice($this->_variables[$this->_currentSection], $num));
- }
- }
- return $var;
- }
- /**
- * Removes a variable from the form.
- *
- * As only variables can be passed by reference, you need to call this
- * method this way if want to pass a variable name:
- * <code>
- * $form->removeVariable($var = 'varname');
- * </code>
- *
- * @param Horde_Form_Variable|string $var Either the variable's name or
- * the variable to remove from the
- * form.
- *
- * @return boolean True if the variable was found (and deleted).
- */
- function removeVariable(&$var)
- {
- foreach (array_keys($this->_variables) as $section) {
- foreach (array_keys($this->_variables[$section]) as $i) {
- if ((is_a($var, 'Horde_Form_Variable') && $this->_variables[$section][$i] === $var) ||
- ($this->_variables[$section][$i]->getVarName() == $var)) {
- // Slice out the variable to be removed.
- $this->_variables[$this->_currentSection] = array_merge(
- array_slice($this->_variables[$this->_currentSection], 0, $i),
- array_slice($this->_variables[$this->_currentSection], $i + 1));
- return true;
- }
- }
- }
- return false;
- }
- /**
- * TODO
- */
- function &addHidden($humanName, $varName, $type, $required,
- $readonly = false, $description = null,
- $params = array())
- {
- $type = &$this->getType($type, $params);
- $var = new Horde_Form_Variable($humanName, $varName, $type,
- $required, $readonly, $description);
- $var->hide();
- $this->_hiddenVariables[] = &$var;
- return $var;
- }
- function &getVariables($flat = true, $withHidden = false)
- {
- if ($flat) {
- $vars = array();
- foreach ($this->_variables as $section) {
- foreach ($section as $var) {
- $vars[] = $var;
- }
- }
- if ($withHidden) {
- foreach ($this->_hiddenVariables as $var) {
- $vars[] = $var;
- }
- }
- return $vars;
- } else {
- return $this->_variables;
- }
- }
- function setButtons($submit, $reset = false)
- {
- if ($submit === true || is_null($submit) || empty($submit)) {
- /* Default to 'Submit'. */
- $submit = array(_("Submit"));
- } elseif (!is_array($submit)) {
- /* Default to array if not passed. */
- $submit = array($submit);
- }
- /* Only if $reset is strictly true insert default 'Reset'. */
- if ($reset === true) {
- $reset = _("Reset");
- }
- $this->_submit = $submit;
- $this->_reset = $reset;
- }
- function appendButtons($submit)
- {
- if (!is_array($submit)) {
- $submit = array($submit);
- }
- $this->_submit = array_merge($this->_submit, $submit);
- }
- function preserveVarByPost(&$vars, $varname, $alt_varname = '')
- {
- $value = $vars->getExists($varname, $wasset);
- /* If an alternate name is given under which to preserve use that. */
- if ($alt_varname) {
- $varname = $alt_varname;
- }
- if ($wasset) {
- $this->_preserveVarByPost($varname, $value);
- }
- }
- /**
- * @access private
- */
- function _preserveVarByPost($varname, $value)
- {
- if (is_array($value)) {
- foreach ($value as $id => $val) {
- $this->_preserveVarByPost($varname . '[' . $id . ']', $val);
- }
- } else {
- $varname = htmlspecialchars($varname);
- $value = htmlspecialchars($value);
- printf('<input type="hidden" name="%s" value="%s" />' . "\n",
- $varname,
- $value);
- }
- }
- function open(&$renderer, &$vars, $action, $method = 'get', $enctype = null)
- {
- if (is_null($enctype) && !is_null($this->_enctype)) {
- $enctype = $this->_enctype;
- }
- $renderer->open($action, $method, $this->_name, $enctype);
- $renderer->listFormVars($this);
- if (!empty($this->_name)) {
- $this->_preserveVarByPost('formname', $this->_name);
- }
- if ($this->_useFormToken) {
- require_once 'Horde/Token.php';
- $token = Horde_Token::generateId($this->_name);
- $_SESSION['horde_form_secrets'][$token] = true;
- $this->_preserveVarByPost($this->_name . '_formToken', $token);
- }
- /* Loop through vars and check for any special cases to preserve. */
- $variables = $this->getVariables();
- foreach ($variables as $var) {
- /* Preserve value if change has to be tracked. */
- if ($var->getOption('trackchange')) {
- $varname = $var->getVarName();
- $this->preserveVarByPost($vars, $varname, '__old_' . $varname);
- }
- }
- foreach ($this->_hiddenVariables as $var) {
- $this->preserveVarByPost($vars, $var->getVarName());
- }
- }
- function close($renderer)
- {
- $renderer->close();
- }
- /**
- * Renders the form for editing.
- *
- * @param Horde_Form_Renderer $renderer A renderer instance, optional
- * since Horde 3.2.
- * @param Variables $vars A Variables instance, optional
- * since Horde 3.2.
- * @param string $action The form action (url).
- * @param string $method The form method, usually either
- * 'get' or 'post'.
- * @param string $enctype The form encoding type. Determined
- * automatically if null.
- * @param boolean $focus Focus the first form field?
- */
- function renderActive($renderer = null, $vars = null, $action = '',
- $method = 'get', $enctype = null, $focus = true)
- {
- if (is_null($renderer)) {
- $renderer = $this->getRenderer();
- }
- if (is_null($vars)) {
- $vars = $this->_vars;
- }
- if (is_null($enctype) && !is_null($this->_enctype)) {
- $enctype = $this->_enctype;
- }
- $renderer->open($action, $method, $this->getName(), $enctype);
- $renderer->listFormVars($this);
- if (!empty($this->_name)) {
- $this->_preserveVarByPost('formname', $this->_name);
- }
- if ($this->_useFormToken) {
- require_once 'Horde/Token.php';
- $token = Horde_Token::generateId($this->_name);
- $_SESSION['horde_form_secrets'][$token] = true;
- $this->_preserveVarByPost($this->_name . '_formToken', $token);
- }
- if (count($this->_sections)) {
- $this->_preserveVarByPost('__formOpenSection', $this->getOpenSection());
- }
- /* Loop through vars and check for any special cases to
- * preserve. */
- $variables = $this->getVariables();
- foreach ($variables as $var) {
- /* Preserve value if change has to be tracked. */
- if ($var->getOption('trackchange')) {
- $varname = $var->getVarName();
- $this->preserveVarByPost($vars, $varname, '__old_' . $varname);
- }
- }
- foreach ($this->_hiddenVariables as $var) {
- $this->preserveVarByPost($vars, $var->getVarName());
- }
- $renderer->beginActive($this->getTitle(), $this->getExtra());
- $renderer->renderFormActive($this, $vars);
- $renderer->submit($this->_submit, $this->_reset);
- $renderer->end();
- $renderer->close($focus);
- }
- /**
- * Renders the form for displaying.
- *
- * @param Horde_Form_Renderer $renderer A renderer instance, optional
- * since Horde 3.2.
- * @param Variables $vars A Variables instance, optional
- * since Horde 3.2.
- */
- function renderInactive($renderer = null, $vars = null)
- {
- if (is_null($renderer)) {
- $renderer = $this->getRenderer();
- }
- if (is_null($vars)) {
- $vars = $this->_vars;
- }
- $renderer->_name = $this->_name;
- $renderer->beginInactive($this->getTitle(), $this->getExtra());
- $renderer->renderFormInactive($this, $vars);
- $renderer->end();
- }
- function preserve($vars)
- {
- if ($this->_useFormToken) {
- require_once 'Horde/Token.php';
- $token = Horde_Token::generateId($this->_name);
- $_SESSION['horde_form_secrets'][$token] = true;
- $this->_preserveVarByPost($this->_name . '_formToken', $token);
- }
- $variables = $this->getVariables();
- foreach ($variables as $var) {
- $varname = $var->getVarName();
- /* Save value of individual components. */
- switch ($var->getTypeName()) {
- case 'passwordconfirm':
- case 'emailconfirm':
- $this->preserveVarByPost($vars, $varname . '[original]');
- $this->preserveVarByPost($vars, $varname . '[confirm]');
- break;
- case 'monthyear':
- $this->preserveVarByPost($vars, $varname . '[month]');
- $this->preserveVarByPost($vars, $varname . '[year]');
- break;
- case 'monthdayyear':
- $this->preserveVarByPost($vars, $varname . '[month]');
- $this->preserveVarByPost($vars, $varname . '[day]');
- $this->preserveVarByPost($vars, $varname . '[year]');
- break;
- }
- $this->preserveVarByPost($vars, $varname);
- }
- foreach ($this->_hiddenVariables as $var) {
- $this->preserveVarByPost($vars, $var->getVarName());
- }
- }
- function unsetVars(&$vars)
- {
- foreach ($this->getVariables() as $var) {
- $vars->remove($var->getVarName());
- }
- }
- /**
- * Validates the form, checking if it really has been submitted by calling
- * isSubmitted() and if true does any onSubmit() calls for variable types
- * in the form. The _submitted variable is then rechecked.
- *
- * @param Variables $vars A Variables instance, optional since Horde
- * 3.2.
- * @param boolean $canAutofill Can the form be valid without being
- * submitted?
- *
- * @return boolean True if the form is valid.
- */
- function validate($vars = null, $canAutoFill = false)
- {
- if (is_null($vars)) {
- $vars = $this->_vars;
- }
- /* Get submitted status. */
- if ($this->isSubmitted() || $canAutoFill) {
- /* Form was submitted or can autofill; check for any variable
- * types' onSubmit(). */
- $this->onSubmit($vars);
- /* Recheck submitted status. */
- if (!$this->isSubmitted() && !$canAutoFill) {
- return false;
- }
- } else {
- /* Form has not been submitted; return false. */
- return false;
- }
- $message = '';
- $this->_autofilled = true;
- if ($this->_useFormToken) {
- global $conf;
- require_once 'Horde/Token.php';
- if (isset($conf['token'])) {
- /* If there is a configured token system, set it up. */
- $tokenSource = &Horde_Token::singleton($conf['token']['driver'], Horde::getDriverConfig('token', $conf['token']['driver']));
- } else {
- /* Default to the file system if no config. */
- $tokenSource = &Horde_Token::singleton('file');
- }
- $passedToken = $vars->get($this->_name . '_formToken');
- if (!empty($passedToken) && !$tokenSource->verify($passedToken)) {
- $this->_errors['_formToken'] = _("This form has already been processed.");
- }
- if (empty($_SESSION['horde_form_secrets'][$passedToken])) {
- $this->_errors['_formSecret'] = _("Required secret is invalid - potentially malicious request.");
- }
- }
- foreach ($this->getVariables() as $var) {
- $this->_autofilled = $var->_autofilled && $this->_autofilled;
- if (!$var->validate($vars, $message)) {
- $this->_errors[$var->getVarName()] = $message;
- }
- }
- if ($this->_autofilled) {
- unset($this->_errors['_formToken']);
- }
- foreach ($this->_hiddenVariables as $var) {
- if (!$var->validate($vars, $message)) {
- $this->_errors[$var->getVarName()] = $message;
- }
- }
- return $this->isValid();
- }
- function clearValidation()
- {
- $this->_errors = array();
- }
- function getError($var)
- {
- if (is_a($var, 'Horde_Form_Variable')) {
- $name = $var->getVarName();
- } else {
- $name = $var;
- }
- return isset($this->_errors[$name]) ? $this->_errors[$name] : null;
- }
- function setError($var, $message)
- {
- if (is_a($var, 'Horde_Form_Variable')) {
- $name = $var->getVarName();
- } else {
- $name = $var;
- }
- $this->_errors[$name] = $message;
- }
- function clearError($var)
- {
- if (is_a($var, 'Horde_Form_Variable')) {
- $name = $var->getVarName();
- } else {
- $name = $var;
- }
- unset($this->_errors[$name]);
- }
- function isValid()
- {
- return ($this->_autofilled || count($this->_errors) == 0);
- }
- function execute()
- {
- Horde::logMessage('Warning: Horde_Form::execute() called, should be overridden', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- }
- /**
- * Fetch the field values of the submitted form.
- *
- * @param Variables $vars A Variables instance, optional since Horde 3.2.
- * @param array $info Array to be filled with the submitted field
- * values.
- */
- function getInfo($vars, &$info)
- {
- if (is_null($vars)) {
- $vars = $this->_vars;
- }
- $this->_getInfoFromVariables($this->getVariables(), $vars, $info);
- $this->_getInfoFromVariables($this->_hiddenVariables, $vars, $info);
- }
- /**
- * Fetch the field values from a given array of variables.
- *
- * @access private
- *
- * @param array $variables An array of Horde_Form_Variable objects to
- * fetch from.
- * @param object $vars The Variables object.
- * @param array $info The array to be filled with the submitted
- * field values.
- */
- function _getInfoFromVariables($variables, &$vars, &$info)
- {
- foreach ($variables as $var) {
- if ($var->isArrayVal()) {
- $var->getInfo($vars, $values);
- if (is_array($values)) {
- $varName = str_replace('[]', '', $var->getVarName());
- foreach ($values as $i => $val) {
- $info[$i][$varName] = $val;
- }
- }
- } else {
- require_once 'Horde/Array.php';
- if (Horde_Array::getArrayParts($var->getVarName(), $base, $keys)) {
- if (!isset($info[$base])) {
- $info[$base] = array();
- }
- $pointer = &$info[$base];
- while (count($keys)) {
- $key = array_shift($keys);
- if (!isset($pointer[$key])) {
- $pointer[$key] = array();
- }
- $pointer = &$pointer[$key];
- }
- $var->getInfo($vars, $pointer);
- } else {
- $var->getInfo($vars, $info[$var->getVarName()]);
- }
- }
- }
- }
- function hasHelp()
- {
- return $this->_help;
- }
- /**
- * Determines if this form has been submitted or not. If the class
- * var _submitted is null then it will check for the presence of
- * the formname in the form variables.
- *
- * Other events can explicitly set the _submitted variable to
- * false to indicate a form submit but not for actual posting of
- * data (eg. onChange events to update the display of fields).
- *
- * @return boolean True or false indicating if the form has been
- * submitted.
- */
- function isSubmitted()
- {
- if (is_null($this->_submitted)) {
- if ($this->_vars->get('formname') == $this->getName()) {
- $this->_submitted = true;
- } else {
- $this->_submitted = false;
- }
- }
- return $this->_submitted;
- }
- /**
- * Checks if there is anything to do on the submission of the form by
- * looping through each variable's onSubmit() function.
- *
- * @param Horde_Variables $vars
- */
- function onSubmit(&$vars)
- {
- /* Loop through all vars and check if there's anything to do on
- * submit. */
- $variables = $this->getVariables();
- foreach ($variables as $var) {
- $var->type->onSubmit($var, $vars);
- /* If changes to var being tracked don't register the form as
- * submitted if old value and new value differ. */
- if ($var->getOption('trackchange')) {
- $varname = $var->getVarName();
- if (!is_null($vars->get('formname')) &&
- $vars->get($varname) != $vars->get('__old_' . $varname)) {
- $this->_submitted = false;
- }
- }
- }
- }
- /**
- * Explicitly sets the state of the form submit.
- *
- * An event can override the automatic determination of the submit state
- * in the isSubmitted() function.
- *
- * @param boolean $state Whether to set the state of the form as being
- * submitted.
- */
- function setSubmitted($state = true)
- {
- $this->_submitted = $state;
- }
- }
- /**
- * Horde_Form_Type Class
- *
- * @author Robert E. Coyle <robertecoyle@hotmail.com>
- * @package Horde_Form
- */
- class Horde_Form_Type {
- function Horde_Form_Type()
- {
- }
- function getProperty($property)
- {
- $prop = '_' . $property;
- return isset($this->$prop) ? $this->$prop : null;
- }
- function __get($property)
- {
- return $this->getProperty($property);
- }
- function setProperty($property, $value)
- {
- $prop = '_' . $property;
- $this->$prop = $value;
- }
- function __set($property, $value)
- {
- return $this->setProperty($property, $value);
- }
- function init()
- {
- }
- function onSubmit()
- {
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $message = '<strong>Error:</strong> Horde_Form_Type::isValid() called - should be overridden<br />';
- return false;
- }
- function getTypeName()
- {
- return str_replace('horde_form_type_', '', String::lower(get_class($this)));
- }
- function getValues()
- {
- return null;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $info = $var->getValue($vars);
- }
- }
- class Horde_Form_Type_spacer extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Spacer"));
- }
- }
- class Horde_Form_Type_header extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Header"));
- }
- }
- class Horde_Form_Type_description extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Description"));
- }
- }
- /**
- * Simply renders its raw value in both active and inactive rendering.
- */
- class Horde_Form_Type_html extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("HTML"));
- }
- }
- class Horde_Form_Type_number extends Horde_Form_Type {
- var $_fraction;
- function init($fraction = null)
- {
- $this->_fraction = $fraction;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value) && ((string)(double)$value !== $value)) {
- $message = _("This field is required.");
- return false;
- } elseif (empty($value)) {
- return true;
- }
- /* If matched, then this is a correct numeric value. */
- if (preg_match($this->_getValidationPattern(), $value)) {
- return true;
- }
- $message = _("This field must be a valid number.");
- return false;
- }
- function _getValidationPattern()
- {
- static $pattern = '';
- if (!empty($pattern)) {
- return $pattern;
- }
- /* Get current locale information. */
- $linfo = NLS::getLocaleInfo();
- /* Build the pattern. */
- $pattern = '(-)?';
- /* Only check thousands separators if locale has any. */
- if (!empty($linfo['mon_thousands_sep'])) {
- /* Regex to check for correct thousands separators (if any). */
- $pattern .= '((\d+)|((\d{0,3}?)([' . $linfo['mon_thousands_sep'] . ']\d{3})*?))';
- } else {
- /* No locale thousands separator, check for only digits. */
- $pattern .= '(\d+)';
- }
- /* If no decimal point specified default to dot. */
- if (empty($linfo['mon_decimal_point'])) {
- $linfo['mon_decimal_point'] = '.';
- }
- /* Regex to check for correct decimals (if any). */
- if (empty($this->_fraction)) {
- $fraction = '*';
- } else {
- $fraction = '{0,' . $this->_fraction . '}';
- }
- $pattern .= '([' . $linfo['mon_decimal_point'] . '](\d' . $fraction . '))?';
- /* Put together the whole regex pattern. */
- $pattern = '/^' . $pattern . '$/';
- return $pattern;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $value = $vars->get($var->getVarName());
- $linfo = NLS::getLocaleInfo();
- $value = str_replace($linfo['mon_thousands_sep'], '', $value);
- $info = str_replace($linfo['mon_decimal_point'], '.', $value);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Number"));
- }
- }
- class Horde_Form_Type_int extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value) && ((string)(int)$value !== $value)) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || preg_match('/^[0-9]+$/', $value)) {
- return true;
- }
- $message = _("This field may only contain integers.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Integer"));
- }
- }
- class Horde_Form_Type_octal extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value) && ((string)(int)$value !== $value)) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || preg_match('/^[0-7]+$/', $value)) {
- return true;
- }
- $message = _("This field may only contain octal values.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Octal"));
- }
- }
- class Horde_Form_Type_intlist extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (empty($value) && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || preg_match('/^[0-9 ,]+$/', $value)) {
- return true;
- }
- $message = _("This field must be a comma or space separated list of integers");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Integer list"));
- }
- }
- class Horde_Form_Type_text extends Horde_Form_Type {
- var $_regex;
- var $_size;
- var $_maxlength;
- /**
- * The initialisation function for the text variable type.
- *
- * @access private
- *
- * @param string $regex Any valid PHP PCRE pattern syntax that
- * needs to be matched for the field to be
- * considered valid. If left empty validity
- * will be checked only for required fields
- * whether they are empty or not.
- * If using this regex test it is advisable
- * to enter a description for this field to
- * warn the user what is expected, as the
- * generated error message is quite generic
- * and will not give any indication where
- * the regex failed.
- * @param integer $size The size of the input field.
- * @param integer $maxlength The max number of characters.
- */
- function init($regex = '', $size = 40, $maxlength = null)
- {
- $this->_regex = $regex;
- $this->_size = $size;
- $this->_maxlength = $maxlength;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $valid = true;
- if (!empty($this->_maxlength) && String::length($value) > $this->_maxlength) {
- $valid = false;
- $message = sprintf(_("Value is over the maximum length of %d."), $this->_maxlength);
- } elseif ($var->isRequired() && empty($this->_regex)) {
- $valid = strlen(trim($value)) > 0;
- if (!$valid) {
- $message = _("This field is required.");
- }
- } elseif (!empty($this->_regex)) {
- $valid = preg_match($this->_regex, $value);
- if (!$valid) {
- $message = _("You must enter a valid value.");
- }
- }
- return $valid;
- }
- function getSize()
- {
- return $this->_size;
- }
- function getMaxLength()
- {
- return $this->_maxlength;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Text"),
- 'params' => array(
- 'regex' => array('label' => _("Regex"),
- 'type' => 'text'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'),
- 'maxlength' => array('label' => _("Maximum length"),
- 'type' => 'int')));
- }
- }
- class Horde_Form_Type_stringlist extends Horde_Form_Type_text {
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("String list"),
- 'params' => array(
- 'regex' => array('label' => _("Regex"),
- 'type' => 'text'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'),
- 'maxlength' => array('label' => _("Maximum length"),
- 'type' => 'int')),
- );
- }
- }
- /**
- * @since Horde 3.3
- */
- class Horde_Form_Type_stringarray extends Horde_Form_Type_stringlist {
- function getInfo(&$vars, &$var, &$info)
- {
- $info = array_map('trim', explode(',', $vars->get($var->getVarName())));
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("String list returning an array"),
- 'params' => array(
- 'regex' => array('label' => _("Regex"),
- 'type' => 'text'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'),
- 'maxlength' => array('label' => _("Maximum length"),
- 'type' => 'int')),
- );
- }
- }
- /**
- * @since Horde 3.2
- */
- class Horde_Form_Type_phone extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (!strlen(trim($value))) {
- if ($var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- } elseif (!preg_match('/^\+?[\d()\-\/. ]*$/', $value)) {
- $message = _("You must enter a valid phone number, digits only with an optional '+' for the international dialing prefix.");
- return false;
- }
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Phone number"));
- }
- }
- class Horde_Form_Type_cellphone extends Horde_Form_Type_phone {
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Mobile phone number"));
- }
- }
- class Horde_Form_Type_ipaddress extends Horde_Form_Type_text {
- function isValid(&$var, &$vars, $value, &$message)
- {
- $valid = true;
- if (strlen(trim($value)) > 0) {
- $ip = explode('.', $value);
- $valid = (count($ip) == 4);
- if ($valid) {
- foreach ($ip as $part) {
- if (!is_numeric($part) ||
- $part > 255 ||
- $part < 0) {
- $valid = false;
- break;
- }
- }
- }
- if (!$valid) {
- $message = _("Please enter a valid IP address.");
- }
- } elseif ($var->isRequired()) {
- $valid = false;
- $message = _("This field is required.");
- }
- return $valid;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("IP address"));
- }
- }
- class Horde_Form_Type_longtext extends Horde_Form_Type_text {
- var $_rows;
- var $_cols;
- var $_helper = array();
- function init($rows = 8, $cols = 80, $helper = array())
- {
- if (!is_array($helper)) {
- $helper = array($helper);
- }
- $this->_rows = $rows;
- $this->_cols = $cols;
- $this->_helper = $helper;
- }
- function getRows()
- {
- return $this->_rows;
- }
- function getCols()
- {
- return $this->_cols;
- }
- function hasHelper($option = '')
- {
- if (empty($option)) {
- /* No option specified, check if any helpers have been
- * activated. */
- return !empty($this->_helper);
- } elseif (empty($this->_helper)) {
- /* No helpers activated at all, return false. */
- return false;
- } else {
- /* Check if given helper has been activated. */
- return in_array($option, $this->_helper);
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Long text"),
- 'params' => array(
- 'rows' => array('label' => _("Number of rows"),
- 'type' => 'int'),
- 'cols' => array('label' => _("Number of columns"),
- 'type' => 'int'),
- 'helper' => array('label' => _("Helpers"),
- 'type' => 'stringarray')));
- }
- }
- class Horde_Form_Type_countedtext extends Horde_Form_Type_longtext {
- var $_chars;
- function init($rows = null, $cols = null, $chars = 1000)
- {
- parent::init($rows, $cols);
- $this->_chars = $chars;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $valid = true;
- $length = String::length(trim($value));
- if ($var->isRequired() && $length <= 0) {
- $valid = false;
- $message = _("This field is required.");
- } elseif ($length > $this->_chars) {
- $valid = false;
- $message = sprintf(ngettext("There are too many characters in this field. You have entered %d character; ", "There are too many characters in this field. You have entered %d characters; ", $length), $length)
- . sprintf(_("you must enter less than %d."), $this->_chars);
- }
- return $valid;
- }
- function getChars()
- {
- return $this->_chars;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Counted text"),
- 'params' => array(
- 'rows' => array('label' => _("Number of rows"),
- 'type' => 'int'),
- 'cols' => array('label' => _("Number of columns"),
- 'type' => 'int'),
- 'chars' => array('label' => _("Number of characters"),
- 'type' => 'int')));
- }
- }
- class Horde_Form_Type_address extends Horde_Form_Type_longtext {
- function parse($address)
- {
- $info = array();
- $aus_state_regex = '(?:ACT|NSW|NT|QLD|SA|TAS|VIC|WA)';
- if (preg_match('/(?s)(.*?)(?-s)\r?\n(?:(.*?)\s+)?((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])? \d[A-Z]{2})/', $address, $addressParts)) {
- /* UK postcode detected. */
- $info = array('country' => 'uk', 'zip' => $addressParts[3]);
- if (!empty($addressParts[1])) {
- $info['street'] = $addressParts[1];
- }
- if (!empty($addressParts[2])) {
- $info['city'] = $addressParts[2];
- }
- } elseif (preg_match('/\b' . $aus_state_regex . '\b/', $address)) {
- /* Australian state detected. */
- /* Split out the address, line-by-line. */
- $addressLines = preg_split('/\r?\n/', $address);
- $info = array('country' => 'au');
- for ($i = 0; $i < count($addressLines); $i++) {
- /* See if it's the street number & name. */
- if (preg_match('/(\d+\s*\/\s*)?(\d+|\d+[a-zA-Z])\s+([a-zA-Z ]*)/', $addressLines[$i], $lineParts)) {
- $info['street'] = $addressLines[$i];
- $info['streetNumber'] = $lineParts[2];
- $info['streetName'] = $lineParts[3];
- }
- /* Look for "Suburb, State". */
- if (preg_match('/([a-zA-Z ]*),?\s+(' . $aus_state_regex . ')/', $addressLines[$i], $lineParts)) {
- $info['city'] = $lineParts[1];
- $info['state'] = $lineParts[2];
- }
- /* Look for "State <4 digit postcode>". */
- if (preg_match('/(' . $aus_state_regex . ')\s+(\d{4})/', $addressLines[$i], $lineParts)) {
- $info['state'] = $lineParts[1];
- $info['zip'] = $lineParts[2];
- }
- }
- } elseif (preg_match('/(?s)(.*?)(?-s)\r?\n(.*)\s*,\s*(\w+)\.?\s+(\d+|[a-zA-Z]\d[a-zA-Z]\s?\d[a-zA-Z]\d)/', $address, $addressParts)) {
- /* American/Canadian address style. */
- $info = array('country' => 'us');
- if (!empty($addressParts[4]) &&
- preg_match('|[a-zA-Z]\d[a-zA-Z]\s?\d[a-zA-Z]\d|', $addressParts[4])) {
- $info['country'] = 'ca';
- }
- if (!empty($addressParts[1])) {
- $info['street'] = $addressParts[1];
- }
- if (!empty($addressParts[2])) {
- $info['city'] = $addressParts[2];
- }
- if (!empty($addressParts[3])) {
- $info['state'] = $addressParts[3];
- }
- if (!empty($addressParts[4])) {
- $info['zip'] = $addressParts[4];
- }
- } elseif (preg_match('/(?:(?s)(.*?)(?-s)(?:\r?\n|,\s*))?(?:([A-Z]{1,3})-)?(\d{4,5})\s+(.*)(?:\r?\n(.*))?/i', $address, $addressParts)) {
- /* European address style. */
- $info = array();
- if (!empty($addressParts[1])) {
- $info['street'] = $addressParts[1];
- }
- if (!empty($addressParts[2])) {
- include 'Horde/NLS/carsigns.php';
- $country = array_search(String::upper($addressParts[2]), $carsigns);
- if ($country) {
- $info['country'] = $country;
- }
- }
- if (!empty($addressParts[5])) {
- include 'Horde/NLS/countries.php';
- $country = array_search($addressParts[5], $countries);
- if ($country) {
- $info['country'] = String::lower($country);
- } elseif (!isset($info['street'])) {
- $info['street'] = trim($addressParts[5]);
- } else {
- $info['street'] .= "\n" . $addressParts[5];
- }
- }
- if (!empty($addressParts[3])) {
- $info['zip'] = $addressParts[3];
- }
- if (!empty($addressParts[4])) {
- $info['city'] = trim($addressParts[4]);
- }
- }
- return $info;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Address"),
- 'params' => array(
- 'rows' => array('label' => _("Number of rows"),
- 'type' => 'int'),
- 'cols' => array('label' => _("Number of columns"),
- 'type' => 'int')));
- }
- }
- class Horde_Form_Type_addresslink extends Horde_Form_Type_address {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Address Link"));
- }
- }
- /**
- * @since Horde 3.3
- */
- class Horde_Form_Type_pgp extends Horde_Form_Type_longtext {
- /**
- * Path to the GnuPG binary.
- *
- * @var string
- */
- var $_gpg;
- /**
- * A temporary directory.
- *
- * @var string
- */
- var $_temp;
- function init($gpg, $temp_dir = null, $rows = null, $cols = null)
- {
- $this->_gpg = $gpg;
- $this->_temp = $temp_dir;
- parent::init($rows, $cols);
- }
- /**
- * Returns a parameter hash for the Horde_Crypt_pgp constructor.
- *
- * @return array A parameter hash.
- */
- function getPGPParams()
- {
- return array('program' => $this->_gpg, 'temp' => $this->_temp);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("PGP Key"),
- 'params' => array(
- 'gpg' => array('label' => _("Path to the GnuPG binary"),
- 'type' => 'string'),
- 'temp_dir' => array('label' => _("A temporary directory"),
- 'type' => 'string'),
- 'rows' => array('label' => _("Number of rows"),
- 'type' => 'int'),
- 'cols' => array('label' => _("Number of columns"),
- 'type' => 'int')));
- }
- }
- /**
- * @since Horde 3.3
- */
- class Horde_Form_Type_smime extends Horde_Form_Type_longtext {
- /**
- * A temporary directory.
- *
- * @var string
- */
- var $_temp;
- function init($temp_dir = null, $rows = null, $cols = null)
- {
- $this->_temp = $temp_dir;
- parent::init($rows, $cols);
- }
- /**
- * Returns a parameter hash for the Horde_Crypt_smime constructor.
- *
- * @return array A parameter hash.
- */
- function getSMIMEParams()
- {
- return array('temp' => $this->_temp);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("S/MIME Key"),
- 'params' => array(
- 'temp_dir' => array('label' => _("A temporary directory"),
- 'type' => 'string'),
- 'rows' => array('label' => _("Number of rows"),
- 'type' => 'int'),
- 'cols' => array('label' => _("Number of columns"),
- 'type' => 'int')));
- }
- }
- /**
- * @since Horde 3.2
- */
- class Horde_Form_Type_country extends Horde_Form_Type_enum {
- function init($prompt = null)
- {
- include 'Horde/NLS/countries.php';
- parent::init($countries, $prompt);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Country drop down list"),
- 'params' => array(
- 'prompt' => array('label' => _("Prompt text"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_file extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired()) {
- $uploaded = Browser::wasFileUploaded($var->getVarName());
- if (is_a($uploaded, 'PEAR_Error')) {
- $message = $uploaded->getMessage();
- return false;
- }
- }
- return true;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $name = $var->getVarName();
- $uploaded = Browser::wasFileUploaded($name);
- if ($uploaded === true) {
- $info['name'] = Util::dispelMagicQuotes($_FILES[$name]['name']);
- $info['type'] = $_FILES[$name]['type'];
- $info['tmp_name'] = $_FILES[$name]['tmp_name'];
- $info['file'] = $_FILES[$name]['tmp_name'];
- $info['error'] = $_FILES[$name]['error'];
- $info['size'] = $_FILES[$name]['size'];
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("File upload"));
- }
- }
- class Horde_Form_Type_image extends Horde_Form_Type {
- /**
- * Has a file been uploaded on this form submit?
- *
- * @var boolean
- */
- var $_uploaded = null;
- /**
- * Show the upload button?
- *
- * @var boolean
- */
- var $_show_upload = true;
- /**
- * Show the option to upload also original non-modified image?
- *
- * @var boolean
- */
- var $_show_keeporig = false;
- /**
- * Limit the file size?
- *
- * @var integer
- */
- var $_max_filesize = null;
- /**
- * Hash containing the previously uploaded image info.
- *
- * @var array
- */
- var $_img;
- /**
- * A random id that identifies the image information in the session data.
- *
- * @var string
- */
- var $_random;
- function init($show_upload = true, $show_keeporig = false, $max_filesize = null)
- {
- $this->_show_upload = $show_upload;
- $this->_show_keeporig = $show_keeporig;
- $this->_max_filesize = $max_filesize;
- }
- function onSubmit(&$var, &$vars)
- {
- /* Get the upload. */
- $this->getImage($vars, $var);
- /* If this was done through the upload button override the submitted
- * value of the form. */
- if ($vars->get('_do_' . $var->getVarName())) {
- $var->form->setSubmitted(false);
- if (is_a($this->_uploaded, 'PEAR_Error')) {
- $this->_img = array('hash' => $this->getRandomId(),
- 'error' => $this->_uploaded->getMessage());
- }
- }
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- /* Get the upload. */
- $this->getImage($vars, $var);
- $field = $vars->get($var->getVarName());
- /* The upload generated a PEAR Error. */
- if (is_a($this->_uploaded, 'PEAR_Error')) {
- /* Not required and no image upload attempted. */
- if (!$var->isRequired() && empty($field['hash']) &&
- $this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) {
- return true;
- }
- if (($this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) &&
- empty($field['hash'])) {
- /* Nothing uploaded and no older upload. */
- $message = _("This field is required.");
- return false;
- } elseif (!empty($field['hash'])) {
- if ($this->_img && isset($this->_img['error'])) {
- $message = $this->_img['error'];
- return false;
- }
- /* Nothing uploaded but older upload present. */
- return true;
- } else {
- /* Some other error message. */
- $message = $this->_uploaded->getMessage();
- return false;
- }
- } elseif (empty($this->_img['img']['size'])) {
- $message = _("The image file size could not be determined or it was 0 bytes. The upload may have been interrupted.");
- return false;
- } elseif ($this->_max_filesize &&
- $this->_img['img']['size'] > $this->_max_filesize) {
- $message = sprintf(_("The image file was larger than the maximum allowed size (%d bytes)."), $this->_max_filesize);
- return false;
- }
- return true;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- /* Get the upload. */
- $this->getImage($vars, $var);
- /* Get image params stored in the hidden field. */
- $value = $var->getValue($vars);
- $info = $this->_img['img'];
- if (empty($info['file'])) {
- unset($info['file']);
- return;
- }
- if ($this->_show_keeporig) {
- $info['keep_orig'] = !empty($value['keep_orig']);
- }
- /* Set the uploaded value (either true or PEAR_Error). */
- $info['uploaded'] = &$this->_uploaded;
- /* If a modified file exists move it over the original. */
- if ($this->_show_keeporig && $info['keep_orig']) {
- /* Requested the saving of original file also. */
- $info['orig_file'] = Horde::getTempDir() . '/' . $info['file'];
- $info['file'] = Horde::getTempDir() . '/mod_' . $info['file'];
- /* Check if a modified file actually exists. */
- if (!file_exists($info['file'])) {
- $info['file'] = $info['orig_file'];
- unset($info['orig_file']);
- }
- } else {
- /* Saving of original not required. */
- $mod_file = Horde::getTempDir() . '/mod_' . $info['file'];
- $info['file'] = Horde::getTempDir() . '/' . $info['file'];
- if (file_exists($mod_file)) {
- /* Unlink first (has to be done on Windows machines?) */
- unlink($info['file']);
- rename($mod_file, $info['file']);
- }
- }
- }
- /**
- * Gets the upload and sets up the upload data array. Either
- * fetches an upload done with this submit or retries stored
- * upload info.
- */
- function _getUpload(&$vars, &$var)
- {
- /* Don't bother with this function if already called and set
- * up vars. */
- if (!empty($this->_img)) {
- return true;
- }
- /* Check if file has been uploaded. */
- $varname = $var->getVarName();
- $this->_uploaded = Browser::wasFileUploaded($varname . '[new]');
- if ($this->_uploaded === true) {
- /* A file has been uploaded on this submit. Save to temp dir for
- * preview work. */
- $this->_img['img']['type'] = $this->getUploadedFileType($varname . '[new]');
- /* Get the other parts of the upload. */
- require_once 'Horde/Array.php';
- Horde_Array::getArrayParts($varname . '[new]', $base, $keys);
- /* Get the temporary file name. */
- $keys_path = array_merge(array($base, 'tmp_name'), $keys);
- $this->_img['img']['file'] = Horde_Array::getElement($_FILES, $keys_path);
- /* Get the actual file name. */
- $keys_path = array_merge(array($base, 'name'), $keys);
- $this->_img['img']['name'] = Horde_Array::getElement($_FILES, $keys_path);
- /* Get the file size. */
- $keys_path = array_merge(array($base, 'size'), $keys);
- $this->_img['img']['size'] = Horde_Array::getElement($_FILES, $keys_path);
- /* Get any existing values for the image upload field. */
- $upload = $vars->get($var->getVarName());
- if (!empty($upload['hash'])) {
- $upload['img'] = $_SESSION['horde_form'][$upload['hash']];
- unset($_SESSION['horde_form'][$upload['hash']]);
- }
- /* Get the temp file if already one uploaded, otherwise create a
- * new temporary file. */
- if (!empty($upload['img']['file'])) {
- $tmp_file = Horde::getTempDir() . '/' . $upload['img']['file'];
- } else {
- $tmp_file = Horde::getTempFile('Horde', false);
- }
- /* Move the browser created temp file to the new temp file. */
- move_uploaded_file($this->_img['img']['file'], $tmp_file);
- $this->_img['img']['file'] = basename($tmp_file);
- } elseif ($this->_uploaded) {
- /* File has not been uploaded. */
- $upload = $vars->get($var->getVarName());
- if ($this->_uploaded->getCode() == 4 &&
- !empty($upload['hash']) &&
- isset($_SESSION['horde_form'][$upload['hash']])) {
- $this->_img['img'] = $_SESSION['horde_form'][$upload['hash']];
- unset($_SESSION['horde_form'][$upload['hash']]);
- if (isset($this->_img['error'])) {
- $this->_uploaded = PEAR::raiseError($this->_img['error']);
- }
- }
- }
- if (isset($this->_img['img'])) {
- $_SESSION['horde_form'][$this->getRandomId()] = $this->_img['img'];
- }
- }
- function getUploadedFileType($field)
- {
- /* Get any index on the field name. */
- require_once 'Horde/Array.php';
- $index = Horde_Array::getArrayParts($field, $base, $keys);
- if ($index) {
- /* Index present, fetch the mime type var to check. */
- $keys_path = array_merge(array($base, 'type'), $keys);
- $type = Horde_Array::getElement($_FILES, $keys_path);
- $keys_path= array_merge(array($base, 'tmp_name'), $keys);
- $tmp_name = Horde_Array::getElement($_FILES, $keys_path);
- } else {
- /* No index, simple set up of vars to check. */
- $type = $_FILES[$field]['type'];
- $tmp_name = $_FILES[$field]['tmp_name'];
- }
- if (empty($type) || ($type == 'application/octet-stream')) {
- /* Type wasn't set on upload, try analising the upload. */
- global $conf;
- require_once 'Horde/MIME/Magic.php';
- if (!($type = MIME_Magic::analyzeFile($tmp_name, isset($conf['mime']['magic_db']) ? $conf['mime']['magic_db'] : null))) {
- if ($index) {
- /* Get the name value. */
- $keys_path = array_merge(array($base, 'name'), $keys);
- $name = Horde_Array::getElement($_FILES, $keys_path);
- /* Work out the type from the file name. */
- $type = MIME_Magic::filenameToMIME($name);
- /* Set the type. */
- $keys_path = array_merge(array($base, 'type'), $keys);
- Horde_Array::getElement($_FILES, $keys_path, $type);
- } else {
- /* Work out the type from the file name. */
- $type = MIME_Magic::filenameToMIME($_FILES[$field]['name']);
- /* Set the type. */
- $_FILES[$field]['type'] = MIME_Magic::filenameToMIME($_FILES[$field]['name']);
- }
- }
- }
- return $type;
- }
- /**
- * Returns the current image information.
- *
- * @return array The current image hash.
- */
- function getImage($vars, $var)
- {
- $this->_getUpload($vars, $var);
- if (!isset($this->_img)) {
- $image = $vars->get($var->getVarName());
- if ($image) {
- $this->loadImageData($image);
- if (isset($image['img'])) {
- $this->_img = $image;
- $_SESSION['horde_form'][$this->getRandomId()] = $this->_img['img'];
- }
- }
- }
- return $this->_img;
- }
- /**
- * Loads any existing image data into the image field. Requires that the
- * array $image passed to it contains the structure:
- * $image['load']['file'] - the filename of the image;
- * $image['load']['data'] - the raw image data.
- *
- * @param array $image The image array.
- */
- function loadImageData(&$image)
- {
- /* No existing image data to load. */
- if (!isset($image['load'])) {
- return;
- }
- /* Save the data to the temp dir. */
- $tmp_file = Horde::getTempDir() . '/' . $image['load']['file'];
- if ($fd = fopen($tmp_file, 'w')) {
- fwrite($fd, $image['load']['data']);
- fclose($fd);
- }
- $image['img'] = array('file' => $image['load']['file']);
- unset($image['load']);
- }
- function getRandomId()
- {
- if (!isset($this->_random)) {
- $this->_random = uniqid(mt_rand());
- }
- return $this->_random;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Image upload"),
- 'params' => array(
- 'show_upload' => array('label' => _("Show upload?"),
- 'type' => 'boolean'),
- 'show_keeporig' => array('label' => _("Show option to keep original?"),
- 'type' => 'boolean'),
- 'max_filesize' => array('label' => _("Maximum file size in bytes"),
- 'type' => 'int')));
- }
- }
- class Horde_Form_Type_boolean extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $info = String::lower($vars->get($var->getVarName())) == 'on';
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("True or false"));
- }
- }
- class Horde_Form_Type_link extends Horde_Form_Type {
- /**
- * List of hashes containing link parameters. Possible keys: 'url', 'text',
- * 'target', 'onclick', 'title', 'accesskey'.
- *
- * @var array
- */
- var $values;
- function init($values)
- {
- $this->values = $values;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Link"),
- 'params' => array(
- 'url' => array(
- 'label' => _("Link URL"),
- 'type' => 'text'),
- 'text' => array(
- 'label' => _("Link text"),
- 'type' => 'text'),
- 'target' => array(
- 'label' => _("Link target"),
- 'type' => 'text'),
- 'onclick' => array(
- 'label' => _("Onclick event"),
- 'type' => 'text'),
- 'title' => array(
- 'label' => _("Link title attribute"),
- 'type' => 'text'),
- 'accesskey' => array(
- 'label' => _("Link access key"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_email extends Horde_Form_Type {
- /**
- * Allow multiple addresses?
- *
- * @var boolean
- */
- var $_allow_multi = false;
- /**
- * Protect address from spammers?
- *
- * @var boolean
- */
- var $_strip_domain = false;
- /**
- * Link the email address to the compose page when displaying?
- *
- * @var boolean
- */
- var $_link_compose = false;
- /**
- * Whether to check the domain's SMTP server whether the address exists.
- *
- * @var boolean
- */
- var $_check_smtp = false;
- /**
- * The name to use when linking to the compose page
- *
- * @var boolean
- */
- var $_link_name;
- /**
- * A string containing valid delimiters (default is just comma).
- *
- * @var string
- */
- var $_delimiters = ',';
- /**
- * @param boolean $allow_multi Allow multiple addresses?
- * @param boolean $strip_domain Protect address from spammers?
- * @param boolean $link_compose Link the email address to the compose page
- * when displaying?
- * @param string $link_name The name to use when linking to the
- compose page.
- * @param string $delimiters Character to split multiple addresses with.
- */
- function init($allow_multi = false, $strip_domain = false,
- $link_compose = false, $link_name = null,
- $delimiters = ',')
- {
- $this->_allow_multi = $allow_multi;
- $this->_strip_domain = $strip_domain;
- $this->_link_compose = $link_compose;
- $this->_link_name = $link_name;
- $this->_delimiters = $delimiters;
- }
- /**
- */
- function isValid(&$var, &$vars, $value, &$message)
- {
- // Split into individual addresses.
- $emails = $this->splitEmailAddresses($value);
- // Check for too many.
- if (!$this->_allow_multi && count($emails) > 1) {
- $message = _("Only one email address is allowed.");
- return false;
- }
- // Check for all valid and at least one non-empty.
- $nonEmpty = 0;
- foreach ($emails as $email) {
- if (!strlen($email)) {
- continue;
- }
- if (!$this->validateEmailAddress($email)) {
- $message = sprintf(_("\"%s\" is not a valid email address."), htmlspecialchars($email));
- return false;
- }
- ++$nonEmpty;
- }
- if (!$nonEmpty && $var->isRequired()) {
- if ($this->_allow_multi) {
- $message = _("You must enter at least one email address.");
- } else {
- $message = _("You must enter an email address.");
- }
- return false;
- }
- return true;
- }
- /**
- * Explodes an RFC 2822 string, ignoring a delimiter if preceded
- * by a "\" character, or if the delimiter is inside single or
- * double quotes.
- *
- * @param string $string The RFC 822 string.
- *
- * @return array The exploded string in an array.
- */
- function splitEmailAddresses($string)
- {
- $quotes = array('"', "'");
- $emails = array();
- $pos = 0;
- $in_quote = null;
- $in_group = false;
- $prev = null;
- if (!strlen($string)) {
- return array();
- }
- $char = $string[0];
- if (in_array($char, $quotes)) {
- $in_quote = $char;
- } elseif ($char == ':') {
- $in_group = true;
- } elseif (strpos($this->_delimiters, $char) !== false) {
- $emails[] = '';
- $pos = 1;
- }
- for ($i = 1, $iMax = strlen($string); $i < $iMax; ++$i) {
- $char = $string[$i];
- if (in_array($char, $quotes)) {
- if ($prev !== '\\') {
- if ($in_quote === $char) {
- $in_quote = null;
- } elseif (is_null($in_quote)) {
- $in_quote = $char;
- }
- }
- } elseif ($in_group) {
- if ($char == ';') {
- $emails[] = substr($string, $pos, $i - $pos + 1);
- $pos = $i + 1;
- $in_group = false;
- }
- } elseif ($char == ':') {
- $in_group = true;
- } elseif (strpos($this->_delimiters, $char) !== false &&
- $prev !== '\\' &&
- is_null($in_quote)) {
- $emails[] = substr($string, $pos, $i - $pos);
- $pos = $i + 1;
- }
- $prev = $char;
- }
- if ($pos != $i) {
- /* The string ended without a delimiter. */
- $emails[] = substr($string, $pos, $i - $pos);
- }
- return $emails;
- }
- /**
- * RFC(2)822 Email Parser.
- *
- * By Cal Henderson <cal@iamcal.com>
- * This code is licensed under a Creative Commons Attribution-ShareAlike 2.5 License
- * http://creativecommons.org/licenses/by-sa/2.5/
- *
- * http://code.iamcal.com/php/rfc822/
- *
- * http://iamcal.com/publish/articles/php/parsing_email
- *
- * Revision 4
- *
- * @param string $email An individual email address to validate.
- *
- * @return boolean
- */
- function validateEmailAddress($email)
- {
- static $comment_regexp, $email_regexp;
- if ($comment_regexp === null) {
- $this->_defineValidationRegexps($comment_regexp, $email_regexp);
- }
- // We need to strip comments first (repeat until we can't find
- // any more).
- while (true) {
- $new = preg_replace("!$comment_regexp!", '', $email);
- if (strlen($new) == strlen($email)){
- break;
- }
- $email = $new;
- }
- // Now match what's left.
- $result = (bool)preg_match("!^$email_regexp$!", $email);
- if ($result && $this->_check_smtp) {
- $result = $this->validateEmailAddressSmtp($email);
- }
- return $result;
- }
- /**
- * Attempt partial delivery of mail to an address to validate it.
- *
- * @param string $email An individual email address to validate.
- *
- * @return boolean
- */
- function validateEmailAddressSmtp($email)
- {
- list(, $maildomain) = explode('@', $email, 2);
- // Try to get the real mailserver from MX records.
- if (function_exists('getmxrr') &&
- @getmxrr($maildomain, $mxhosts, $mxpriorities)) {
- // MX record found.
- array_multisort($mxpriorities, $mxhosts);
- $mailhost = $mxhosts[0];
- } else {
- // No MX record found, try the root domain as the mail
- // server.
- $mailhost = $maildomain;
- }
- $fp = @fsockopen($mailhost, 25, $errno, $errstr, 5);
- if (!$fp) {
- return false;
- }
- // Read initial response.
- fgets($fp, 4096);
- // HELO
- fputs($fp, "HELO $mailhost\r\n");
- fgets($fp, 4096);
- // MAIL FROM
- fputs($fp, "MAIL FROM: <root@example.com>\r\n");
- fgets($fp, 4096);
- // RCPT TO - gets the result we want.
- fputs($fp, "RCPT TO: <$email>\r\n");
- $result = trim(fgets($fp, 4096));
- // QUIT
- fputs($fp, "QUIT\r\n");
- fgets($fp, 4096);
- fclose($fp);
- return substr($result, 0, 1) == '2';
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Email"),
- 'params' => array(
- 'allow_multi' => array(
- 'label' => _("Allow multiple addresses?"),
- 'type' => 'boolean'),
- 'strip_domain' => array(
- 'label' => _("Protect address from spammers?"),
- 'type' => 'boolean'),
- 'link_compose' => array(
- 'label' => _("Link the email address to the compose page when displaying?"),
- 'type' => 'boolean'),
- 'link_name' => array(
- 'label' => _("The name to use when linking to the compose page"),
- 'type' => 'text'),
- 'delimiters' => array(
- 'label' => _("Character to split multiple addresses with"),
- 'type' => 'text'),
- ),
- );
- }
- /**
- * RFC(2)822 Email Parser.
- *
- * By Cal Henderson <cal@iamcal.com>
- * This code is licensed under a Creative Commons Attribution-ShareAlike 2.5 License
- * http://creativecommons.org/licenses/by-sa/2.5/
- *
- * http://code.iamcal.com/php/rfc822/
- *
- * http://iamcal.com/publish/articles/php/parsing_email
- *
- * Revision 4
- *
- * @param string &$comment The regexp for comments.
- * @param string &$addr_spec The regexp for email addresses.
- */
- function _defineValidationRegexps(&$comment, &$addr_spec)
- {
- /**
- * NO-WS-CTL = %d1-8 / ; US-ASCII control characters
- * %d11 / ; that do not include the
- * %d12 / ; carriage return, line feed,
- * %d14-31 / ; and white space characters
- * %d127
- * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
- * DIGIT = %x30-39
- */
- $no_ws_ctl = "[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]";
- $alpha = "[\\x41-\\x5a\\x61-\\x7a]";
- $digit = "[\\x30-\\x39]";
- $cr = "\\x0d";
- $lf = "\\x0a";
- $crlf = "($cr$lf)";
- /**
- * obs-char = %d0-9 / %d11 / ; %d0-127 except CR and
- * %d12 / %d14-127 ; LF
- * obs-text = *LF *CR *(obs-char *LF *CR)
- * text = %d1-9 / ; Characters excluding CR and LF
- * %d11 /
- * %d12 /
- * %d14-127 /
- * obs-text
- * obs-qp = "\" (%d0-127)
- * quoted-pair = ("\" text) / obs-qp
- */
- $obs_char = "[\\x00-\\x09\\x0b\\x0c\\x0e-\\x7f]";
- $obs_text = "($lf*$cr*($obs_char$lf*$cr*)*)";
- $text = "([\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f]|$obs_text)";
- $obs_qp = "(\\x5c[\\x00-\\x7f])";
- $quoted_pair = "(\\x5c$text|$obs_qp)";
- /**
- * obs-FWS = 1*WSP *(CRLF 1*WSP)
- * FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space
- * obs-FWS
- * ctext = NO-WS-CTL / ; Non white space controls
- * %d33-39 / ; The rest of the US-ASCII
- * %d42-91 / ; characters not including "(",
- * %d93-126 ; ")", or "\"
- * ccontent = ctext / quoted-pair / comment
- * comment = "(" *([FWS] ccontent) [FWS] ")"
- * CFWS = *([FWS] comment) (([FWS] comment) / FWS)
- *
- * @note: We translate ccontent only partially to avoid an
- * infinite loop. Instead, we'll recursively strip comments
- * before processing the input.
- */
- $wsp = "[\\x20\\x09]";
- $obs_fws = "($wsp+($crlf$wsp+)*)";
- $fws = "((($wsp*$crlf)?$wsp+)|$obs_fws)";
- $ctext = "($no_ws_ctl|[\\x21-\\x27\\x2A-\\x5b\\x5d-\\x7e])";
- $ccontent = "($ctext|$quoted_pair)";
- $comment = "(\\x28($fws?$ccontent)*$fws?\\x29)";
- $cfws = "(($fws?$comment)*($fws?$comment|$fws))";
- $cfws = "$fws*";
- /**
- * atext = ALPHA / DIGIT / ; Any character except controls,
- * "!" / "#" / ; SP, and specials.
- * "$" / "%" / ; Used for atoms
- * "&" / "'" /
- * "*" / "+" /
- * "-" / "/" /
- * "=" / "?" /
- * "^" / "_" /
- * "`" / "{" /
- * "|" / "}" /
- * "~"
- * atom = [CFWS] 1*atext [CFWS]
- */
- $atext = "($alpha|$digit|[\\x21\\x23-\\x27\\x2a\\x2b\\x2d\\x2e\\x3d\\x3f\\x5e\\x5f\\x60\\x7b-\\x7e])";
- $atom = "($cfws?$atext+$cfws?)";
- /**
- * qtext = NO-WS-CTL / ; Non white space controls
- * %d33 / ; The rest of the US-ASCII
- * %d35-91 / ; characters not including "\"
- * %d93-126 ; or the quote character
- * qcontent = qtext / quoted-pair
- * quoted-string = [CFWS]
- * DQUOTE *([FWS] qcontent) [FWS] DQUOTE
- * [CFWS]
- * word = atom / quoted-string
- */
- $qtext = "($no_ws_ctl|[\\x21\\x23-\\x5b\\x5d-\\x7e])";
- $qcontent = "($qtext|$quoted_pair)";
- $quoted_string = "($cfws?\\x22($fws?$qcontent)*$fws?\\x22$cfws?)";
- $word = "($atom|$quoted_string)";
- /**
- * obs-local-part = word *("." word)
- * obs-domain = atom *("." atom)
- */
- $obs_local_part = "($word(\\x2e$word)*)";
- $obs_domain = "($atom(\\x2e$atom)*)";
- /**
- * dot-atom-text = 1*atext *("." 1*atext)
- * dot-atom = [CFWS] dot-atom-text [CFWS]
- */
- $dot_atom_text = "($atext+(\\x2e$atext+)*)";
- $dot_atom = "($cfws?$dot_atom_text$cfws?)";
- /**
- * domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
- * dcontent = dtext / quoted-pair
- * dtext = NO-WS-CTL / ; Non white space controls
- *
- * %d33-90 / ; The rest of the US-ASCII
- * %d94-126 ; characters not including "[",
- * ; "]", or "\"
- */
- $dtext = "($no_ws_ctl|[\\x21-\\x5a\\x5e-\\x7e])";
- $dcontent = "($dtext|$quoted_pair)";
- $domain_literal = "($cfws?\\x5b($fws?$dcontent)*$fws?\\x5d$cfws?)";
- /**
- * local-part = dot-atom / quoted-string / obs-local-part
- * domain = dot-atom / domain-literal / obs-domain
- * addr-spec = local-part "@" domain
- */
- $local_part = "($dot_atom|$quoted_string|$obs_local_part)";
- $domain = "($dot_atom|$domain_literal|$obs_domain)";
- $addr_spec = "($local_part\\x40$domain)";
- }
- }
- class Horde_Form_Type_matrix extends Horde_Form_Type {
- var $_cols;
- var $_rows;
- var $_matrix;
- var $_new_input;
- /**
- * Initializes the variable.
- *
- * Example:
- * <code>
- * init(array('Column A', 'Column B'),
- * array(1 => 'Row One', 2 => 'Row 2', 3 => 'Row 3'),
- * array(array(true, true, false),
- * array(true, false, true),
- * array(fasle, true, false)),
- * array('Row 4', 'Row 5'));
- * </code>
- *
- * @param array $cols A list of column headers.
- * @param array $rows A hash with row IDs as the keys and row
- * labels as the values.
- * @param array $matrix A two dimensional hash with the field
- * values.
- * @param boolean|array $new_input If true, a free text field to add a new
- * row is displayed on the top, a select
- * box if this parameter is a value.
- */
- function init($cols, $rows = array(), $matrix = array(), $new_input = false)
- {
- $this->_cols = $cols;
- $this->_rows = $rows;
- $this->_matrix = $matrix;
- $this->_new_input = $new_input;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- function getCols() { return $this->_cols; }
- function getRows() { return $this->_rows; }
- function getMatrix() { return $this->_matrix; }
- function getNewInput() { return $this->_new_input; }
- function getInfo(&$vars, &$var, &$info)
- {
- $values = $vars->get($var->getVarName());
- if (!empty($values['n']['r']) && isset($values['n']['v'])) {
- $new_row = $values['n']['r'];
- $values['r'][$new_row] = $values['n']['v'];
- unset($values['n']);
- }
- $info = (isset($values['r']) ? $values['r'] : array());
- }
- function about()
- {
- return array(
- 'name' => _("Field matrix"),
- 'params' => array(
- 'cols' => array('label' => _("Column titles"),
- 'type' => 'stringarray')));
- }
- }
- class Horde_Form_Type_emailConfirm extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value['original'])) {
- $message = _("This field is required.");
- return false;
- }
- if ($value['original'] != $value['confirm']) {
- $message = _("Email addresses must match.");
- return false;
- } else {
- require_once 'Horde/MIME.php';
- $parsed_email = MIME::parseAddressList($value['original'], false,
- true);
- if (is_a($parsed_email, 'PEAR_Error')) {
- $message = $parsed_email->getMessage();
- return false;
- }
- if (count($parsed_email) > 1) {
- $message = _("Only one email address allowed.");
- return false;
- }
- if (empty($parsed_email[0]->mailbox)) {
- $message = _("You did not enter a valid email address.");
- return false;
- }
- }
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Email with confirmation"));
- }
- }
- class Horde_Form_Type_password extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- $valid = true;
- if ($var->isRequired()) {
- $valid = strlen(trim($value)) > 0;
- if (!$valid) {
- $message = _("This field is required.");
- }
- }
- return $valid;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Password"));
- }
- }
- class Horde_Form_Type_passwordconfirm extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value['original'])) {
- $message = _("This field is required.");
- return false;
- }
- if ($value['original'] != $value['confirm']) {
- $message = _("Passwords must match.");
- return false;
- }
- return true;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $value = $vars->get($var->getVarName());
- $info = $value['original'];
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Password with confirmation"));
- }
- }
- class Horde_Form_Type_enum extends Horde_Form_Type {
- var $_values;
- var $_prompt;
- function init($values, $prompt = null)
- {
- $this->setValues($values);
- if ($prompt === true) {
- $this->_prompt = _("-- select --");
- } else {
- $this->_prompt = $prompt;
- }
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && $value == '' && !isset($this->_values[$value])) {
- $message = _("This field is required.");
- return false;
- }
- if (count($this->_values) == 0 || isset($this->_values[$value]) ||
- ($this->_prompt && empty($value))) {
- return true;
- }
- $message = _("Invalid data submitted.");
- return false;
- }
- function getValues()
- {
- return $this->_values;
- }
- /**
- * @since Horde 3.2
- */
- function setValues($values)
- {
- $this->_values = $values;
- }
- function getPrompt()
- {
- return $this->_prompt;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Drop down list"),
- 'params' => array(
- 'values' => array('label' => _("Values to select from"),
- 'type' => 'stringarray'),
- 'prompt' => array('label' => _("Prompt text"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_mlenum extends Horde_Form_Type {
- var $_values;
- var $_prompts;
- function init(&$values, $prompts = null)
- {
- $this->_values = &$values;
- if ($prompts === true) {
- $this->_prompts = array(_("-- select --"), _("-- select --"));
- } elseif (!is_array($prompts)) {
- $this->_prompts = array($prompts, $prompts);
- } else {
- $this->_prompts = $prompts;
- }
- }
- function onSubmit(&$var, &$vars)
- {
- $varname = $var->getVarName();
- $value = $vars->get($varname);
- if ($value['1'] != $value['old']) {
- $var->form->setSubmitted(false);
- }
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && (empty($value['1']) || empty($value['2']))) {
- $message = _("This field is required.");
- return false;
- }
- if (!count($this->_values) || isset($this->_values[$value['1']]) ||
- (!empty($this->_prompts) && empty($value['1']))) {
- return true;
- }
- $message = _("Invalid data submitted.");
- return false;
- }
- function getValues()
- {
- return $this->_values;
- }
- function getPrompts()
- {
- return $this->_prompts;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $info = $vars->get($var->getVarName());
- return $info['2'];
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Multi-level drop down lists"),
- 'params' => array(
- 'values' => array('label' => _("Values to select from"),
- 'type' => 'stringarray'),
- 'prompt' => array('label' => _("Prompt text"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_multienum extends Horde_Form_Type_enum {
- var $size = 5;
- function init($values, $size = null)
- {
- if (!is_null($size)) {
- $this->size = (int)$size;
- }
- parent::init($values);
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (is_array($value)) {
- foreach ($value as $val) {
- if (!$this->isValid($var, $vars, $val, $message)) {
- return false;
- }
- }
- return true;
- }
- if (empty($value) && ((string)(int)$value !== $value)) {
- if ($var->isRequired()) {
- $message = _("This field is required.");
- return false;
- } else {
- return true;
- }
- }
- if (count($this->_values) == 0 || isset($this->_values[$value])) {
- return true;
- }
- $message = _("Invalid data submitted.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Multiple selection"),
- 'params' => array(
- 'values' => array('label' => _("Values"),
- 'type' => 'stringarray'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'))
- );
- }
- }
- class Horde_Form_Type_keyval_multienum extends Horde_Form_Type_multienum {
- function getInfo(&$vars, &$var, &$info)
- {
- $value = $vars->get($var->getVarName());
- $info = array();
- foreach ($value as $key) {
- $info[$key] = $this->_values[$key];
- }
- }
- }
- class Horde_Form_Type_radio extends Horde_Form_Type_enum {
- /* Entirely implemented by Horde_Form_Type_enum; just a different
- * view. */
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Radio selection"),
- 'params' => array(
- 'values' => array('label' => _("Values"),
- 'type' => 'stringarray')));
- }
- }
- class Horde_Form_Type_set extends Horde_Form_Type {
- var $_values;
- var $_checkAll = false;
- function init($values, $checkAll = false)
- {
- $this->_values = $values;
- $this->_checkAll = $checkAll;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (count($this->_values) == 0 || count($value) == 0) {
- return true;
- }
- foreach ($value as $item) {
- if (!isset($this->_values[$item])) {
- $error = true;
- break;
- }
- }
- if (!isset($error)) {
- return true;
- }
- $message = _("Invalid data submitted.");
- return false;
- }
- function getValues()
- {
- return $this->_values;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Set"),
- 'params' => array(
- 'values' => array('label' => _("Values"),
- 'type' => 'stringarray')));
- }
- }
- class Horde_Form_Type_date extends Horde_Form_Type {
- var $_format;
- function init($format = '%a %d %B')
- {
- $this->_format = $format;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $valid = true;
- if ($var->isRequired()) {
- $valid = strlen(trim($value)) > 0;
- if (!$valid) {
- $message = sprintf(_("%s is required"), $var->getHumanName());
- }
- }
- return $valid;
- }
- /**
- * @static
- *
- * @param mixed $date The date to calculate the difference from. Can be
- * either a timestamp integer value, or an array
- * with date parts: 'day', 'month', 'year'.
- *
- * @return string
- */
- function getAgo($date)
- {
- if ($date === null) {
- return '';
- } elseif (!is_array($date)) {
- /* Date is not array, so assume timestamp. Work out the component
- * parts using date(). */
- $date = array('day' => date('j', $date),
- 'month' => date('n', $date),
- 'year' => date('Y', $date));
- }
- require_once 'Date/Calc.php';
- $diffdays = Date_Calc::dateDiff((int)$date['day'],
- (int)$date['month'],
- (int)$date['year'],
- date('j'), date('n'), date('Y'));
- /* An error occured. */
- if ($diffdays == -1) {
- return;
- }
- $ago = $diffdays * Date_Calc::compareDates((int)$date['day'],
- (int)$date['month'],
- (int)$date['year'],
- date('j'), date('n'),
- date('Y'));
- if ($ago < -1) {
- return sprintf(_(" (%s days ago)"), $diffdays);
- } elseif ($ago == -1) {
- return _(" (yesterday)");
- } elseif ($ago == 0) {
- return _(" (today)");
- } elseif ($ago == 1) {
- return _(" (tomorrow)");
- } else {
- return sprintf(_(" (in %s days)"), $diffdays);
- }
- }
- function getFormattedTime($timestamp, $format = null, $showago = true)
- {
- if (empty($format)) {
- $format = $this->_format;
- }
- if (!empty($timestamp)) {
- return strftime($format, $timestamp) . ($showago ? Horde_Form_Type_date::getAgo($timestamp) : '');
- } else {
- return '';
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Date"));
- }
- }
- class Horde_Form_Type_time extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value) && ((string)(double)$value !== $value)) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || preg_match('/^[0-2]?[0-9]:[0-5][0-9]$/', $value)) {
- return true;
- }
- $message = _("This field may only contain numbers and the colon.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Time"));
- }
- }
- class Horde_Form_Type_hourminutesecond extends Horde_Form_Type {
- var $_show_seconds;
- function init($show_seconds = false)
- {
- $this->_show_seconds = $show_seconds;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $time = $vars->get($var->getVarName());
- if (!$this->_show_seconds && count($time) && !isset($time['second'])) {
- $time['second'] = 0;
- }
- if (!$this->emptyTimeArray($time) && !$this->checktime($time['hour'], $time['minute'], $time['second'])) {
- $message = _("Please enter a valid time.");
- return false;
- } elseif ($this->emptyTimeArray($time) && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- return true;
- }
- function checktime($hour, $minute, $second)
- {
- if (!isset($hour) || $hour == '' || ($hour < 0 || $hour > 23)) {
- return false;
- }
- if (!isset($minute) || $minute == '' || ($minute < 0 || $minute > 60)) {
- return false;
- }
- if (!isset($second) || $second === '' || ($second < 0 || $second > 60)) {
- return false;
- }
- return true;
- }
- /**
- * Return the time supplied as a Horde_Date object.
- *
- * @param string $time_in Date in one of the three formats supported by
- * Horde_Form and Horde_Date (ISO format
- * YYYY-MM-DD HH:MM:SS, timestamp YYYYMMDDHHMMSS and
- * UNIX epoch).
- *
- * @return Date The time object.
- */
- function getTimeOb($time_in)
- {
- require_once 'Horde/Date.php';
- if (is_array($time_in)) {
- if (!$this->emptyTimeArray($time_in)) {
- $time_in = sprintf('1970-01-01 %02d:%02d:%02d', $time_in['hour'], $time_in['minute'], $this->_show_seconds ? $time_in['second'] : 0);
- }
- }
- return new Horde_Date($time_in);
- }
- /**
- * Return the time supplied split up into an array.
- *
- * @param string $time_in Time in one of the three formats supported by
- * Horde_Form and Horde_Date (ISO format
- * YYYY-MM-DD HH:MM:SS, timestamp YYYYMMDDHHMMSS and
- * UNIX epoch).
- *
- * @return array Array with three elements - hour, minute and seconds.
- */
- function getTimeParts($time_in)
- {
- if (is_array($time_in)) {
- /* This is probably a failed isValid input so just return the
- * parts as they are. */
- return $time_in;
- } elseif (empty($time_in)) {
- /* This is just an empty field so return empty parts. */
- return array('hour' => '', 'minute' => '', 'second' => '');
- }
- $time = $this->getTimeOb($time_in);
- return array('hour' => $time->hour,
- 'minute' => $time->min,
- 'second' => $time->sec);
- }
- function emptyTimeArray($time)
- {
- return (is_array($time)
- && (!isset($time['hour']) || !strlen($time['hour']))
- && (!isset($time['minute']) || !strlen($time['minute']))
- && (!$this->_show_seconds || !strlen($time['second'])));
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Time selection"),
- 'params' => array(
- 'seconds' => array('label' => _("Show seconds?"),
- 'type' => 'boolean')));
- }
- }
- class Horde_Form_Type_monthyear extends Horde_Form_Type {
- var $_start_year;
- var $_end_year;
- function init($start_year = null, $end_year = null)
- {
- if (empty($start_year)) {
- $start_year = 1920;
- }
- if (empty($end_year)) {
- $end_year = date('Y');
- }
- $this->_start_year = $start_year;
- $this->_end_year = $end_year;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (!$var->isRequired()) {
- return true;
- }
- if (!$vars->get($this->getMonthVar($var)) ||
- !$vars->get($this->getYearVar($var))) {
- $message = _("Please enter a month and a year.");
- return false;
- }
- return true;
- }
- function getMonthVar($var)
- {
- return $var->getVarName() . '[month]';
- }
- function getYearVar($var)
- {
- return $var->getVarName() . '[year]';
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Month and year"),
- 'params' => array(
- 'start_year' => array('label' => _("Start year"),
- 'type' => 'int'),
- 'end_year' => array('label' => _("End year"),
- 'type' => 'int')));
- }
- }
- class Horde_Form_Type_monthdayyear extends Horde_Form_Type {
- var $_start_year;
- var $_end_year;
- var $_picker;
- var $_format_in = null;
- var $_format_out = '%x';
- /**
- * Return the date supplied as a Horde_Date object.
- *
- * @param integer $start_year The first available year for input.
- * @param integer $end_year The last available year for input.
- * @param boolean $picker Do we show the DHTML calendar?
- * @param integer $format_in The format to use when sending the date
- * for storage. Defaults to Unix epoch.
- * Similar to the strftime() function.
- * @param integer $format_out The format to use when displaying the
- * date. Similar to the strftime() function.
- */
- function init($start_year = '', $end_year = '', $picker = true,
- $format_in = null, $format_out = '%x')
- {
- if (empty($start_year)) {
- $start_year = date('Y');
- }
- if (empty($end_year)) {
- $end_year = date('Y') + 10;
- }
- $this->_start_year = $start_year;
- $this->_end_year = $end_year;
- $this->_picker = $picker;
- $this->_format_in = $format_in;
- $this->_format_out = $format_out;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $date = $vars->get($var->getVarName());
- $empty = $this->emptyDateArray($date);
- if ($empty == 1 && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- } elseif ($empty == 0 && !checkdate($date['month'],
- $date['day'],
- $date['year'])) {
- $message = _("Please enter a valid date, check the number of days in the month.");
- return false;
- } elseif ($empty == -1) {
- $message = _("Select all date components.");
- return false;
- }
- return true;
- }
- /**
- * Determine if the provided date value is completely empty, partially empty
- * or non-empty.
- *
- * @param mixed $date String or date part array representation of date.
- *
- * @return integer 0 for non-empty, 1 for completely empty or -1 for
- * partially empty.
- */
- function emptyDateArray($date)
- {
- if (!is_array($date)) {
- return (int)empty($date);
- }
- $empty = 0;
- /* Check each date array component. */
- foreach (array('day', 'month', 'year') as $key) {
- if (empty($date[$key])) {
- $empty++;
- }
- }
- /* Check state of empty. */
- if ($empty == 0) {
- /* If no empty parts return 0. */
- return 0;
- } elseif ($empty == 3) {
- /* If all empty parts return 1. */
- return 1;
- } else {
- /* If some empty parts return -1. */
- return -1;
- }
- }
- /**
- * Return the date supplied split up into an array.
- *
- * @param string $date_in Date in one of the three formats supported by
- * Horde_Form and Horde_Date (ISO format
- * YYYY-MM-DD HH:MM:SS, timestamp YYYYMMDDHHMMSS
- * and UNIX epoch) plus the fourth YYYY-MM-DD.
- *
- * @return array Array with three elements - year, month and day.
- */
- function getDateParts($date_in)
- {
- if (is_array($date_in)) {
- /* This is probably a failed isValid input so just return
- * the parts as they are. */
- return $date_in;
- } elseif (empty($date_in)) {
- /* This is just an empty field so return empty parts. */
- return array('year' => '', 'month' => '', 'day' => '');
- }
- $date = $this->getDateOb($date_in);
- return array('year' => $date->year,
- 'month' => $date->month,
- 'day' => $date->mday);
- }
- /**
- * Return the date supplied as a Horde_Date object.
- *
- * @param string $date_in Date in one of the three formats supported by
- * Horde_Form and Horde_Date (ISO format
- * YYYY-MM-DD HH:MM:SS, timestamp YYYYMMDDHHMMSS
- * and UNIX epoch) plus the fourth YYYY-MM-DD.
- *
- * @return Date The date object.
- */
- function getDateOb($date_in)
- {
- require_once 'Horde/Date.php';
- if (is_array($date_in)) {
- /* If passed an array change it to the ISO format. */
- if ($this->emptyDateArray($date_in) == 0) {
- $date_in = sprintf('%04d-%02d-%02d 00:00:00',
- $date_in['year'],
- $date_in['month'],
- $date_in['day']);
- }
- } elseif (preg_match('/^\d{4}-?\d{2}-?\d{2}$/', $date_in)) {
- /* Fix the date if it is the shortened ISO. */
- $date_in = $date_in . ' 00:00:00';
- }
- return new Horde_Date($date_in);
- }
- /**
- * Return the date supplied as a Horde_Date object.
- *
- * @param string $date Either an already set up Horde_Date object or a
- * string date in one of the three formats supported
- * by Horde_Form and Horde_Date (ISO format
- * YYYY-MM-DD HH:MM:SS, timestamp YYYYMMDDHHMMSS and
- * UNIX epoch) plus the fourth YYYY-MM-DD.
- *
- * @return string The date formatted according to the $format_out
- * parameter when setting up the monthdayyear field.
- */
- function formatDate($date)
- {
- if (!is_a($date, 'Date')) {
- $date = $this->getDateOb($date);
- }
- return $date->strftime($this->_format_out);
- }
- /**
- * Insert the date input through the form into $info array, in the format
- * specified by the $format_in parameter when setting up monthdayyear
- * field.
- */
- function getInfo(&$vars, &$var, &$info)
- {
- $info = $this->_validateAndFormat($var->getValue($vars), $var);
- }
- /**
- * Validate/format a date submission.
- */
- function _validateAndFormat($value, &$var)
- {
- /* If any component is empty consider it a bad date and return the
- * default. */
- if ($this->emptyDateArray($value) == 1) {
- return $var->getDefault();
- } else {
- $date = $this->getDateOb($value);
- if ($this->_format_in === null) {
- return $date->timestamp();
- } else {
- return $date->strftime($this->_format_in);
- }
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Date selection"),
- 'params' => array(
- 'start_year' => array('label' => _("Start year"),
- 'type' => 'int'),
- 'end_year' => array('label' => _("End year"),
- 'type' => 'int'),
- 'picker' => array('label' => _("Show picker?"),
- 'type' => 'boolean'),
- 'format_in' => array('label' => _("Storage format"),
- 'type' => 'text'),
- 'format_out' => array('label' => _("Display format"),
- 'type' => 'text')));
- }
- }
- /**
- * @since Horde 3.2
- */
- class Horde_Form_Type_datetime extends Horde_Form_Type {
- var $_mdy;
- var $_hms;
- var $_show_seconds;
- /**
- * Return the date supplied as a Horde_Date object.
- *
- * @param integer $start_year The first available year for input.
- * @param integer $end_year The last available year for input.
- * @param boolean $picker Do we show the DHTML calendar?
- * @param integer $format_in The format to use when sending the date
- * for storage. Defaults to Unix epoch.
- * Similar to the strftime() function.
- * @param integer $format_out The format to use when displaying the
- * date. Similar to the strftime() function.
- * @param boolean $show_seconds Include a form input for seconds.
- */
- function init($start_year = '', $end_year = '', $picker = true,
- $format_in = null, $format_out = '%x', $show_seconds = false)
- {
- $this->_mdy = new Horde_Form_Type_monthdayyear();
- $this->_mdy->init($start_year, $end_year, $picker, $format_in, $format_out);
- $this->_hms = new Horde_Form_Type_hourminutesecond();
- $this->_hms->init($show_seconds);
- $this->_show_seconds = $show_seconds;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- $date = $vars->get($var->getVarName());
- if (!$this->_show_seconds && !isset($date['second'])) {
- $date['second'] = '';
- }
- $mdy_empty = $this->emptyDateArray($date);
- $hms_empty = $this->emptyTimeArray($date);
- $valid = true;
- /* Require all fields if one field is not empty */
- if ($var->isRequired() || $mdy_empty != 1 || !$hms_empty) {
- $old_required = $var->required;
- $var->required = true;
- $mdy_valid = $this->_mdy->isValid($var, $vars, $value, $message);
- $hms_valid = $this->_hms->isValid($var, $vars, $value, $message);
- $var->required = $old_required;
- $valid = $mdy_valid && $hms_valid;
- if ($mdy_valid && !$hms_valid) {
- $message = _("You must choose a time.");
- } elseif ($hms_valid && !$mdy_valid) {
- $message = _("You must choose a date.");
- }
- }
- return $valid;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- /* If any component is empty consider it a bad date and return the
- * default. */
- $value = $var->getValue($vars);
- if ($this->emptyDateArray($value) == 1 || $this->emptyTimeArray($value)) {
- $info = $var->getDefault();
- return;
- }
- $date = $this->getDateOb($value);
- $time = $this->getTimeOb($value);
- $date->hour = $time->hour;
- $date->min = $time->min;
- $date->sec = $time->sec;
- if ($this->getProperty('format_in') === null) {
- $info = $date->timestamp();
- } else {
- $info = $date->strftime($this->getProperty('format_in'));
- }
- }
- function getProperty($property)
- {
- if ($property == 'show_seconds') {
- return $this->_hms->getProperty($property);
- } else {
- return $this->_mdy->getProperty($property);
- }
- }
- function setProperty($property, $value)
- {
- if ($property == 'show_seconds') {
- $this->_hms->setProperty($property, $value);
- } else {
- $this->_mdy->setProperty($property, $value);
- }
- }
- function checktime($hour, $minute, $second)
- {
- return $this->_hms->checktime($hour, $minute, $second);
- }
- function getTimeOb($time_in)
- {
- return $this->_hms->getTimeOb($time_in);
- }
- function getTimeParts($time_in)
- {
- return $this->_hms->getTimeParts($time_in);
- }
- function emptyTimeArray($time)
- {
- return $this->_hms->emptyTimeArray($time);
- }
- function emptyDateArray($date)
- {
- return $this->_mdy->emptyDateArray($date);
- }
- function getDateParts($date_in)
- {
- return $this->_mdy->getDateParts($date_in);
- }
- function getDateOb($date_in)
- {
- return $this->_mdy->getDateOb($date_in);
- }
- function formatDate($date)
- {
- if ($this->_mdy->emptyDateArray($date)) {
- return '';
- }
- return $this->_mdy->formatDate($date);
- }
- function about()
- {
- return array(
- 'name' => _("Date and time selection"),
- 'params' => array(
- 'start_year' => array('label' => _("Start year"),
- 'type' => 'int'),
- 'end_year' => array('label' => _("End year"),
- 'type' => 'int'),
- 'picker' => array('label' => _("Show picker?"),
- 'type' => 'boolean'),
- 'format_in' => array('label' => _("Storage format"),
- 'type' => 'text'),
- 'format_out' => array('label' => _("Display format"),
- 'type' => 'text'),
- 'seconds' => array('label' => _("Show seconds?"),
- 'type' => 'boolean')));
- }
- }
- class Horde_Form_Type_colorpicker extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value)) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || preg_match('/^#([0-9a-z]){6}$/i', $value)) {
- return true;
- }
- $message = _("This field must contain a color code in the RGB Hex format, for example '#1234af'.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Colour selection"));
- }
- }
- class Horde_Form_Type_sound extends Horde_Form_Type {
- var $_sounds = array();
- function init()
- {
- foreach (glob($GLOBALS['registry']->get('themesfs', 'horde') . '/sounds/*.wav') as $sound) {
- $this->_sounds[] = basename($sound);
- }
- }
- function getSounds()
- {
- return $this->_sounds;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if ($var->isRequired() && empty($value)) {
- $message = _("This field is required.");
- return false;
- }
- if (empty($value) || in_array($value, $this->_sounds)) {
- return true;
- }
- $message = _("Please choose a sound.");
- return false;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Sound selection"));
- }
- }
- class Horde_Form_Type_sorter extends Horde_Form_Type {
- var $_instance;
- var $_values;
- var $_size;
- var $_header;
- function init($values, $size = 8, $header = '')
- {
- static $horde_sorter_instance = 0;
- /* Get the next progressive instance count for the horde
- * sorter so that multiple sorters can be used on one page. */
- $horde_sorter_instance++;
- $this->_instance = 'horde_sorter_' . $horde_sorter_instance;
- $this->_values = $values;
- $this->_size = $size;
- $this->_header = $header;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- function getValues()
- {
- return $this->_values;
- }
- function getSize()
- {
- return $this->_size;
- }
- function getHeader()
- {
- if (!empty($this->_header)) {
- return $this->_header;
- }
- return '';
- }
- function getOptions($keys = null)
- {
- $html = '';
- if ($this->_header) {
- $html .= '<option value="">' . htmlspecialchars($this->_header) . '</option>';
- }
- if (empty($keys)) {
- $keys = array_keys($this->_values);
- } else {
- $keys = explode("\t", $keys['array']);
- }
- foreach ($keys as $sl_key) {
- $html .= '<option value="' . $sl_key . '">' . htmlspecialchars($this->_values[$sl_key]) . '</option>';
- }
- return $html;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $value = $vars->get($var->getVarName());
- $info = explode("\t", $value['array']);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Sort order selection"),
- 'params' => array(
- 'values' => array('label' => _("Values"),
- 'type' => 'stringarray'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'),
- 'header' => array('label' => _("Header"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_selectfiles extends Horde_Form_Type {
- /**
- * The text to use in the link.
- *
- * @var string
- */
- var $_link_text;
- /**
- * The style to use for the link.
- *
- * @var string
- */
- var $_link_style;
- /**
- * Create the link with an icon instead of text?
- *
- * @var boolean
- */
- var $_icon;
- /**
- * Contains gollem selectfile selectionID
- *
- * @var string
- */
- var $_selectid;
- function init($selectid, $link_text = null, $link_style = '',
- $icon = false)
- {
- $this->_selectid = $selectid;
- if (is_null($link_text)) {
- $link_text = _("Select Files");
- }
- $this->_link_text = $link_text;
- $this->_link_style = $link_style;
- $this->_icon = $icon;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- function getInfo(&$var, &$vars, &$info)
- {
- $value = $vars->getValue($var);
- $info = $GLOBALS['registry']->call('files/selectlistResults', array($value));
- }
- function about()
- {
- return array(
- 'name' => _("File selection"),
- 'params' => array(
- 'selectid' => array('label' => _("Id"),
- 'type' => 'text'),
- 'link_text' => array('label' => _("Link text"),
- 'type' => 'text'),
- 'link_style' => array('label' => _("Link style"),
- 'type' => 'text'),
- 'icon' => array('label' => _("Show icon?"),
- 'type' => 'boolean')));
- }
- }
- class Horde_Form_Type_assign extends Horde_Form_Type {
- var $_leftValues;
- var $_rightValues;
- var $_leftHeader;
- var $_rightHeader;
- var $_size;
- var $_width;
- function init($leftValues, $rightValues, $leftHeader = '',
- $rightHeader = '', $size = 8, $width = '200px')
- {
- $this->_leftValues = $leftValues;
- $this->_rightValues = $rightValues;
- $this->_leftHeader = $leftHeader;
- $this->_rightHeader = $rightHeader;
- $this->_size = $size;
- $this->_width = $width;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- function getValues($side)
- {
- return $side ? $this->_rightValues : $this->_leftValues;
- }
- function setValues($side, $values)
- {
- if ($side) {
- $this->_rightValues = $values;
- } else {
- $this->_leftValues = $values;
- }
- }
- function getHeader($side)
- {
- return $side ? $this->_rightHeader : $this->_leftHeader;
- }
- function getSize()
- {
- return $this->_size;
- }
- function getWidth()
- {
- return $this->_width;
- }
- function getOptions($side, $formname, $varname)
- {
- $html = '';
- $headers = false;
- if ($side) {
- $values = $this->_rightValues;
- if (!empty($this->_rightHeader)) {
- $values = array('' => $this->_rightHeader) + $values;
- $headers = true;
- }
- } else {
- $values = $this->_leftValues;
- if (!empty($this->_leftHeader)) {
- $values = array('' => $this->_leftHeader) + $values;
- $headers = true;
- }
- }
- foreach ($values as $key => $val) {
- $html .= '<option value="' . htmlspecialchars($key) . '"';
- if ($headers) {
- $headers = false;
- } else {
- $html .= ' ondblclick="Horde_Form_Assign.move(\'' . $formname . '\', \'' . $varname . '\', ' . (int)$side . ');"';
- }
- $html .= '>' . htmlspecialchars($val) . '</option>';
- }
- return $html;
- }
- function getInfo(&$vars, &$var, &$info)
- {
- $value = $vars->get($var->getVarName() . '__values');
- if (strpos($value, "\t\t") === false) {
- $left = $value;
- $right = '';
- } else {
- list($left, $right) = explode("\t\t", $value);
- }
- if (empty($left)) {
- $info['left'] = array();
- } else {
- $info['left'] = explode("\t", $left);
- }
- if (empty($right)) {
- $info['right'] = array();
- } else {
- $info['right'] = explode("\t", $right);
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Assignment columns"),
- 'params' => array(
- 'leftValues' => array('label' => _("Left values"),
- 'type' => 'stringarray'),
- 'rightValues' => array('label' => _("Right values"),
- 'type' => 'stringarray'),
- 'leftHeader' => array('label' => _("Left header"),
- 'type' => 'text'),
- 'rightHeader' => array('label' => _("Right header"),
- 'type' => 'text'),
- 'size' => array('label' => _("Size"),
- 'type' => 'int'),
- 'width' => array('label' => _("Width in CSS units"),
- 'type' => 'text')));
- }
- }
- class Horde_Form_Type_creditcard extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (empty($value) && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- if (!empty($value)) {
- /* getCardType() will also verify the checksum. */
- $type = $this->getCardType($value);
- if ($type === false || $type == 'unknown') {
- $message = _("This does not seem to be a valid card number.");
- return false;
- }
- }
- return true;
- }
- function getChecksum($ccnum)
- {
- $len = strlen($ccnum);
- if (!is_long($len / 2)) {
- $weight = 2;
- $digit = $ccnum[0];
- } elseif (is_long($len / 2)) {
- $weight = 1;
- $digit = $ccnum[0] * 2;
- }
- if ($digit > 9) {
- $digit = $digit - 9;
- }
- $i = 1;
- $checksum = $digit;
- while ($i < $len) {
- if ($ccnum[$i] != ' ') {
- $digit = $ccnum[$i] * $weight;
- $weight = ($weight == 1) ? 2 : 1;
- if ($digit > 9) {
- $digit = $digit - 9;
- }
- $checksum += $digit;
- }
- $i++;
- }
- return $checksum;
- }
- function getCardType($ccnum)
- {
- $sum = $this->getChecksum($ccnum);
- $l = strlen($ccnum);
- // Screen checksum.
- if (($sum % 10) != 0) {
- return false;
- }
- // Check for Visa.
- if ((($l == 16) || ($l == 13)) &&
- ($ccnum[0] == 4)) {
- return 'visa';
- }
- // Check for MasterCard.
- if (($l == 16) &&
- ($ccnum[0] == 5) &&
- ($ccnum[1] >= 1) &&
- ($ccnum[1] <= 5)) {
- return 'mastercard';
- }
- // Check for Amex.
- if (($l == 15) &&
- ($ccnum[0] == 3) &&
- (($ccnum[1] == 4) || ($ccnum[1] == 7))) {
- return 'amex';
- }
- // Check for Discover (Novus).
- if (strlen($ccnum) == 16 &&
- substr($ccnum, 0, 4) == '6011') {
- return 'discover';
- }
- // If we got this far, then no card matched.
- return 'unknown';
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Credit card number"));
- }
- }
- class Horde_Form_Type_obrowser extends Horde_Form_Type {
- function isValid(&$var, &$vars, $value, &$message)
- {
- return true;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Relationship browser"));
- }
- }
- class Horde_Form_Type_dblookup extends Horde_Form_Type_enum {
- function init($dsn, $sql, $prompt = null)
- {
- require_once 'DB.php';
- $values = array();
- $db = DB::connect($dsn);
- if (!is_a($db, 'PEAR_Error')) {
- // Set DB portability options.
- switch ($db->phptype) {
- case 'mssql':
- $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
- default:
- $db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
- $col = $db->getCol($sql);
- if (!is_a($col, 'PEAR_Error')) {
- require_once 'Horde/Array.php';
- $values = Horde_Array::combine($col, $col);
- }
- }
- parent::init($values, $prompt);
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Database lookup"),
- 'params' => array(
- 'dsn' => array('label' => _("DSN (see http://pear.php.net/manual/en/package.database.db.intro-dsn.php)"),
- 'type' => 'text'),
- 'sql' => array('label' => _("SQL statement for value lookups"),
- 'type' => 'text'),
- 'prompt' => array('label' => _("Prompt text"),
- 'type' => 'text'))
- );
- }
- }
- class Horde_Form_Type_figlet extends Horde_Form_Type {
- var $_text;
- var $_font;
- function init($text, $font)
- {
- $this->_text = $text;
- $this->_font = $font;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (empty($value) && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- if (String::lower($value) != String::lower($this->_text)) {
- $message = _("The text you entered did not match the text on the screen.");
- return false;
- }
- return true;
- }
- function getFont()
- {
- return $this->_font;
- }
- function getText()
- {
- return $this->_text;
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Figlet CAPTCHA"),
- 'params' => array(
- 'text' => array('label' => _("Text"),
- 'type' => 'text'),
- 'font' => array('label' => _("Figlet font"),
- 'type' => 'text'))
- );
- }
- }
- class Horde_Form_Type_captcha extends Horde_Form_Type_figlet {
- /**
- * Return info about field type.
- */
- function about()
- {
- return array(
- 'name' => _("Image CAPTCHA"),
- 'params' => array(
- 'text' => array('label' => _("Text"),
- 'type' => 'text'),
- 'font' => array('label' => _("Font"),
- 'type' => 'text'))
- );
- }
- }
- /**
- * @since Horde 3.2
- */
- class Horde_Form_Type_category extends Horde_Form_Type {
- function getInfo(&$vars, &$var, &$info)
- {
- $info = $var->getValue($vars);
- if ($info == '*new*') {
- $info = array('new' => true,
- 'value' => $vars->get('new_category'));
- } else {
- $info = array('new' => false,
- 'value' => $info);
- }
- }
- /**
- * Return info about field type.
- */
- function about()
- {
- return array('name' => _("Category"));
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- if (empty($value) && $var->isRequired()) {
- $message = _("This field is required.");
- return false;
- }
- return true;
- }
- }
- class Horde_Form_Type_invalid extends Horde_Form_Type {
- var $message;
- function init($message)
- {
- $this->message = $message;
- }
- function isValid(&$var, &$vars, $value, &$message)
- {
- return false;
- }
- }
- /**
- * This class represents a single form variable that may be rendered as one or
- * more form fields.
- *
- * @author Robert E. Coyle <robertecoyle@hotmail.com>
- * @package Horde_Form
- */
- class Horde_Form_Variable {
- /**
- * The form instance this variable is assigned to.
- *
- * @var Horde_Form
- */
- var $form;
- /**
- * A short description of this variable's purpose.
- *
- * @var string
- */
- var $humanName;
- /**
- * The internally used name.
- *
- * @var string
- */
- var $varName;
- /**
- * A {@link Horde_Form_Type} instance.
- *
- * @var Horde_Form_Type
- */
- var $type;
- /**
- * Whether this is a required variable.
- *
- * @var boolean
- */
- var $required;
- /**
- * Whether this is a readonly variable.
- *
- * @var boolean
- */
- var $readonly;
- /**
- * A long description of the variable's purpose, special instructions, etc.
- *
- * @var string
- */
- var $description;
- /**
- * The variable help text.
- *
- * @var string
- */
- var $help;
- /**
- * Whether this is an array variable.
- *
- * @var boolean
- */
- var $_arrayVal;
- /**
- * The default value.
- *
- * @var mixed
- */
- var $_defValue = null;
- /**
- * A {@link Horde_Form_Action} instance.
- *
- * @var Horde_Form_Action
- */
- var $_action;
- /**
- * Whether this variable is disabled.
- *
- * @var boolean
- */
- var $_disabled = false;
- /**
- * TODO
- *
- * @var boolean
- */
- var $_autofilled = false;
- /**
- * Whether this is a hidden variable.
- *
- * @var boolean
- */
- var $_hidden = false;
- /**
- * TODO
- *
- * @var array
- */
- var $_options = array();
- /**
- * Variable constructor.
- *
- * @param string $humanName A short description of the variable's
- * purpose.
- * @param string $varName The internally used name.
- * @param Horde_Form_Type $type A {@link Horde_Form_Type} instance.
- * @param boolean $required Whether this is a required variable.
- * @param boolean $readonly Whether this is a readonly variable.
- * @param string $description A long description of the variable's
- * purpose, special instructions, etc.
- */
- function Horde_Form_Variable($humanName, $varName, &$type, $required,
- $readonly = false, $description = null)
- {
- $this->humanName = $humanName;
- $this->varName = $varName;
- $this->type = &$type;
- $this->required = $required;
- $this->readonly = $readonly;
- $this->description = $description;
- $this->_arrayVal = (strpos($varName, '[]') !== false);
- }
- /**
- * Assign this variable to the specified form.
- *
- * @param Horde_Form $form The form instance to assign this variable to.
- */
- function setFormOb(&$form)
- {
- $this->form = &$form;
- }
- /**
- * Sets a default value for this variable.
- *
- * @param mixed $value A variable value.
- */
- function setDefault($value)
- {
- $this->_defValue = $value;
- }
- /**
- * Returns this variable's default value.
- *
- * @return mixed This variable's default value.
- */
- function getDefault()
- {
- return $this->_defValue;
- }
- /**
- * Assigns an action to this variable.
- *
- * Example:
- * <code>
- * $v = &$form->addVariable('My Variable', 'var1', 'text', false);
- * $v->setAction(Horde_Form_Action::factory('submit'));
- * </code>
- *
- * @param Horde_Form_Action $action A {@link Horde_Form_Action} instance.
- */
- function setAction($action)
- {
- $this->_action = $action;
- }
- /**
- * Returns whether this variable has an attached action.
- *
- * @return boolean True if this variable has an attached action.
- */
- function hasAction()
- {
- return !is_null($this->_action);
- }
- /**
- * Makes this a hidden variable.
- */
- function hide()
- {
- $this->_hidden = true;
- }
- /**
- * Returns whether this is a hidden variable.
- *
- * @return boolean True if this a hidden variable.
- */
- function isHidden()
- {
- return $this->_hidden;
- }
- /**
- * Disables this variable.
- */
- function disable()
- {
- $this->_disabled = true;
- }
- /**
- * Returns whether this variable is disabled.
- *
- * @return boolean True if this variable is disabled.
- */
- function isDisabled()
- {
- return $this->_disabled;
- }
- /**
- * Return the short description of this variable.
- *
- * @return string A short description
- */
- function getHumanName()
- {
- return $this->humanName;
- }
- /**
- * Returns the internally used variable name.
- *
- * @return string This variable's internal name.
- */
- function getVarName()
- {
- return $this->varName;
- }
- /**
- * Returns this variable's type.
- *
- * @return Horde_Form_Type This variable's {@link Horde_Form_Type}
- * instance.
- */
- function &getType()
- {
- return $this->type;
- }
- /**
- * Returns the name of this variable's type.
- *
- * @return string This variable's {@link Horde_Form_Type} name.
- */
- function getTypeName()
- {
- return $this->type->getTypeName();
- }
- /**
- * Returns whether this is a required variable.
- *
- * @return boolean True if this is a required variable.
- */
- function isRequired()
- {
- return $this->required;
- }
- /**
- * Returns whether this is a readonly variable.
- *
- * @return boolean True if this a readonly variable.
- */
- function isReadonly()
- {
- return $this->readonly;
- }
- /**
- * Returns the possible values of this variable.
- *
- * @return array The possible values of this variable or null.
- */
- function getValues()
- {
- return $this->type->getValues();
- }
- /**
- * Returns whether this variable has a long description.
- *
- * @return boolean True if this variable has a long description.
- */
- function hasDescription()
- {
- return !empty($this->description);
- }
- /**
- * Returns this variable's long description.
- *
- * @return string This variable's long description.
- */
- function getDescription()
- {
- return $this->description;
- }
- /**
- * Returns whether this is an array variable.
- *
- * @return boolean True if this an array variable.
- */
- function isArrayVal()
- {
- return $this->_arrayVal;
- }
- /**
- * Returns whether this variable is to upload a file.
- *
- * @return boolean True if variable is to upload a file.
- */
- function isUpload()
- {
- return ($this->type->getTypeName() == 'file');
- }
- /**
- * Assigns a help text to this variable.
- *
- * @param string $help The variable help text.
- */
- function setHelp($help)
- {
- $this->form->_help = true;
- $this->help = $help;
- }
- /**
- * Returns whether this variable has some help text assigned.
- *
- * @return boolean True if this variable has a help text.
- */
- function hasHelp()
- {
- return !empty($this->help);
- }
- /**
- * Returns the help text of this variable.
- *
- * @return string This variable's help text.
- */
- function getHelp()
- {
- return $this->help;
- }
- /**
- * Sets a variable option.
- *
- * @param string $option The option name.
- * @param mixed $val The option's value.
- */
- function setOption($option, $val)
- {
- $this->_options[$option] = $val;
- }
- /**
- * Returns a variable option's value.
- *
- * @param string $option The option name.
- *
- * @return mixed The option's value.
- */
- function getOption($option)
- {
- return isset($this->_options[$option]) ? $this->_options[$option] : null;
- }
- /**
- * Processes the submitted value of this variable according to the rules of
- * the variable type.
- *
- * @param Variables $vars The {@link Variables} instance of the submitted
- * form.
- * @param mixed $info A variable passed by reference that will be
- * assigned the processed value of the submitted
- * variable value.
- *
- * @return mixed Depending on the variable type.
- */
- function getInfo(&$vars, &$info)
- {
- return $this->type->getInfo($vars, $this, $info);
- }
- /**
- * Returns whether this variable if it had the "trackchange" option set
- * has actually been changed.
- *
- * @param Variables $vars The {@link Variables} instance of the submitted
- * form.
- *
- * @return boolean Null if this variable doesn't have the "trackchange"
- * option set or the form wasn't submitted yet. A boolean
- * indicating whether the variable was changed otherwise.
- */
- function wasChanged(&$vars)
- {
- if (!$this->getOption('trackchange')) {
- return null;
- }
- $old = $vars->get('__old_' . $this->getVarName());
- if (is_null($old)) {
- return null;
- }
- return $old != $vars->get($this->getVarName());
- }
- /**
- * Validates this variable.
- *
- * @param Variables $vars The {@link Variables} instance of the submitted
- * form.
- * @param string $message A variable passed by reference that will be
- * assigned a descriptive error message if
- * validation failed.
- *
- * @return boolean True if the variable validated.
- */
- function validate(&$vars, &$message)
- {
- if ($this->_arrayVal) {
- $vals = $this->getValue($vars);
- if (!is_array($vals)) {
- if ($this->required) {
- $message = _("This field is required.");
- return false;
- } else {
- return true;
- }
- }
- foreach ($vals as $i => $value) {
- if ($value === null && $this->required) {
- $message = _("This field is required.");
- return false;
- } else {
- if (!$this->type->isValid($this, $vars, $value, $message)) {
- return false;
- }
- }
- }
- } else {
- $value = $this->getValue($vars);
- return $this->type->isValid($this, $vars, $value, $message);
- }
- return true;
- }
- /**
- * Returns the submitted or default value of this variable.
- * If an action is attached to this variable, the value will get passed to
- * the action object.
- *
- * @param Variables $vars The {@link Variables} instance of the submitted
- * form.
- * @param integer $index If the variable is an array variable, this
- * specifies the array element to return.
- *
- * @return mixed The variable or element value.
- */
- function getValue(&$vars, $index = null)
- {
- if ($this->_arrayVal) {
- $name = str_replace('[]', '', $this->varName);
- } else {
- $name = $this->varName;
- }
- $value = $vars->getExists($name, $wasset);
- if (!$wasset) {
- $value = $this->getDefault();
- }
- if ($this->_arrayVal && !is_null($index)) {
- if (!$wasset && !is_array($value)) {
- $return = $value;
- } else {
- $return = isset($value[$index]) ? $value[$index] : null;
- }
- } else {
- $return = $value;
- }
- if ($this->hasAction()) {
- $this->_action->setValues($vars, $return, $this->_arrayVal);
- }
- return $return;
- }
- }