Overview

Packages

  • Form
  • None

Classes

  • Horde_Form
  • Horde_Form_Action
  • Horde_Form_Action_conditional_enable
  • Horde_Form_Action_conditional_setvalue
  • Horde_Form_Action_ConditionalEnable
  • Horde_Form_Action_ConditionalSetValue
  • Horde_Form_Action_reload
  • Horde_Form_Action_setcursorpos
  • Horde_Form_Action_submit
  • Horde_Form_Action_sum_fields
  • Horde_Form_Action_updatefield
  • Horde_Form_Renderer
  • Horde_Form_Translation
  • Horde_Form_Type
  • Horde_Form_Type_address
  • Horde_Form_Type_addresslink
  • Horde_Form_Type_assign
  • Horde_Form_Type_boolean
  • Horde_Form_Type_captcha
  • Horde_Form_Type_category
  • Horde_Form_Type_cellphone
  • Horde_Form_Type_colorpicker
  • Horde_Form_Type_countedtext
  • Horde_Form_Type_country
  • Horde_Form_Type_creditcard
  • Horde_Form_Type_date
  • Horde_Form_Type_datetime
  • Horde_Form_Type_dblookup
  • Horde_Form_Type_description
  • Horde_Form_Type_email
  • Horde_Form_Type_emailConfirm
  • Horde_Form_Type_enum
  • Horde_Form_Type_figlet
  • Horde_Form_Type_file
  • Horde_Form_Type_header
  • Horde_Form_Type_hourminutesecond
  • Horde_Form_Type_image
  • Horde_Form_Type_int
  • Horde_Form_Type_intlist
  • Horde_Form_Type_invalid
  • Horde_Form_Type_ip6address
  • Horde_Form_Type_ipaddress
  • Horde_Form_Type_keyval_multienum
  • Horde_Form_Type_link
  • Horde_Form_Type_longtext
  • Horde_Form_Type_matrix
  • Horde_Form_Type_mlenum
  • Horde_Form_Type_monthdayyear
  • Horde_Form_Type_monthyear
  • Horde_Form_Type_multienum
  • Horde_Form_Type_number
  • Horde_Form_Type_obrowser
  • Horde_Form_Type_octal
  • Horde_Form_Type_password
  • Horde_Form_Type_passwordconfirm
  • Horde_Form_Type_pgp
  • Horde_Form_Type_phone
  • Horde_Form_Type_radio
  • Horde_Form_Type_selectfiles
  • Horde_Form_Type_set
  • Horde_Form_Type_smime
  • Horde_Form_Type_sorter
  • Horde_Form_Type_sound
  • Horde_Form_Type_spacer
  • Horde_Form_Type_stringarray
  • Horde_Form_Type_stringlist
  • Horde_Form_Type_tableset
  • Horde_Form_Type_text
  • Horde_Form_Type_time
  • Horde_Form_Variable
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: require_once 'Horde/Form/Type.php';
  4: 
  5: /**
  6:  * Horde_Form Master Class.
  7:  *
  8:  * The Horde_Form:: package provides form rendering, validation, and
  9:  * other functionality for the Horde Application Framework.
 10:  *
 11:  * Copyright 2001-2007 Robert E. Coyle <robertecoyle@hotmail.com>
 12:  * Copyright 2001-2012 Horde LLC (http://www.horde.org/)
 13:  *
 14:  * See the enclosed file COPYING for license information (LGPL). If you
 15:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 16:  *
 17:  * @author  Robert E. Coyle <robertecoyle@hotmail.com>
 18:  * @author  Chuck Hagenbuch <chuck@horde.org>
 19:  * @package Form
 20:  */
 21: class Horde_Form {
 22: 
 23:     protected $_name = '';
 24:     protected $_title = '';
 25:     protected $_extra = '';
 26:     protected $_vars;
 27:     protected $_submit = array();
 28:     protected $_reset = false;
 29:     protected $_errors = array();
 30:     protected $_submitted = null;
 31:     public $_sections = array();
 32:     protected $_open_section = null;
 33:     protected $_currentSection = array();
 34:     protected $_variables = array();
 35:     protected $_hiddenVariables = array();
 36:     protected $_useFormToken = true;
 37:     protected $_autofilled = false;
 38:     protected $_enctype = null;
 39:     public $_help = false;
 40: 
 41:     function Horde_Form(&$vars, $title = '', $name = null)
 42:     {
 43:         if (empty($name)) {
 44:             $name = Horde_String::lower(get_class($this));
 45:         }
 46: 
 47:         $this->_vars = &$vars;
 48:         $this->_title = $title;
 49:         $this->_name = $name;
 50:     }
 51: 
 52:     function __construct($vars, $title = '', $name = null)
 53:     {
 54:         $this->Horde_Form($vars, $title, $name);
 55:     }
 56: 
 57:     function &singleton($form, &$vars, $title = '', $name = null)
 58:     {
 59:         static $instances = array();
 60: 
 61:         $signature = serialize(array($form, $vars, $title, $name));
 62:         if (!isset($instances[$signature])) {
 63:             if (class_exists($form)) {
 64:                 $instances[$signature] = new $form($vars, $title, $name);
 65:             } else {
 66:                 $instances[$signature] = new Horde_Form($vars, $title, $name);
 67:             }
 68:         }
 69: 
 70:         return $instances[$signature];
 71:     }
 72: 
 73:     function setVars(&$vars)
 74:     {
 75:         $this->_vars = &$vars;
 76:     }
 77: 
 78:     function getVars()
 79:     {
 80:         return $this->_vars;
 81:     }
 82: 
 83:     function getTitle()
 84:     {
 85:         return $this->_title;
 86:     }
 87: 
 88:     function setTitle($title)
 89:     {
 90:         $this->_title = $title;
 91:     }
 92: 
 93:     function getExtra()
 94:     {
 95:         return $this->_extra;
 96:     }
 97: 
 98:     function setExtra($extra)
 99:     {
100:         $this->_extra = $extra;
101:     }
102: 
103:     function getName()
104:     {
105:         return $this->_name;
106:     }
107: 
108:     /**
109:      * Sets or gets whether the form should be verified by tokens.
110:      * Tokens are used to verify that a form is only submitted once.
111:      *
112:      * @param boolean $token  If specified, sets whether to use form tokens.
113:      *
114:      * @return boolean  Whether form tokens are being used.
115:      */
116:     function useToken($token = null)
117:     {
118:         if (!is_null($token)) {
119:             $this->_useFormToken = $token;
120:         }
121:         return $this->_useFormToken;
122:     }
123: 
124:     /**
125:      * Get the renderer for this form, either a custom renderer or the
126:      * standard one.
127:      *
128:      * To use a custom form renderer, your form class needs to
129:      * override this function:
130:      * <code>
131:      * function &getRenderer()
132:      * {
133:      *     $r = new CustomFormRenderer();
134:      *     return $r;
135:      * }
136:      * </code>
137:      *
138:      * ... where CustomFormRenderer is the classname of the custom
139:      * renderer class, which should extend Horde_Form_Renderer.
140:      *
141:      * @param array $params  A hash of renderer-specific parameters.
142:      *
143:      * @return object Horde_Form_Renderer  The form renderer.
144:      */
145:     function getRenderer($params = array())
146:     {
147:         $renderer = new Horde_Form_Renderer($params);
148:         return $renderer;
149:     }
150: 
151:     /**
152:      * @throws Horde_Exception
153:      */
154:     function getType($type, $params = array())
155:     {
156:         if (strpos($type, ':') !== false) {
157:             list($app, $type) = explode(':', $type);
158:             $type_class = $app . '_Form_Type_' . $type;
159:         } else {
160:             $type_class = 'Horde_Form_Type_' . $type;
161:         }
162:         if (!class_exists($type_class)) {
163:             throw new Horde_Exception(sprintf('Nonexistant class "%s" for field type "%s"', $type_class, $type));
164:         }
165:         $type_ob = new $type_class();
166:         if (!$params) {
167:             $params = array();
168:         }
169:         call_user_func_array(array($type_ob, 'init'), $params);
170:         return $type_ob;
171:     }
172: 
173:     function setSection($section = '', $desc = '', $image = '', $expanded = true)
174:     {
175:         $this->_currentSection = $section;
176:         if (!count($this->_sections) && !$this->getOpenSection()) {
177:             $this->setOpenSection($section);
178:         }
179:         $this->_sections[$section]['desc'] = $desc;
180:         $this->_sections[$section]['expanded'] = $expanded;
181:         $this->_sections[$section]['image'] = $image;
182:     }
183: 
184:     function getSectionDesc($section)
185:     {
186:         return $this->_sections[$section]['desc'];
187:     }
188: 
189:     function getSectionImage($section)
190:     {
191:         return $this->_sections[$section]['image'];
192:     }
193: 
194:     function setOpenSection($section)
195:     {
196:         $this->_vars->set('__formOpenSection', $section);
197:     }
198: 
199:     function getOpenSection()
200:     {
201:         return $this->_vars->get('__formOpenSection');
202:     }
203: 
204:     function getSectionExpandedState($section, $boolean = false)
205:     {
206:         if ($boolean) {
207:             /* Only the boolean value is required. */
208:             return $this->_sections[$section]['expanded'];
209:         }
210: 
211:         /* Need to return the values for use in styles. */
212:         if ($this->_sections[$section]['expanded']) {
213:             return 'block';
214:         } else {
215:             return 'none';
216:         }
217:     }
218: 
219:     /**
220:      * TODO
221:      */
222:     function &addVariable($humanName, $varName, $type, $required,
223:                           $readonly = false, $description = null,
224:                           $params = array())
225:     {
226:         return $this->insertVariableBefore(null, $humanName, $varName, $type,
227:                                            $required, $readonly, $description,
228:                                            $params);
229:     }
230: 
231:     /**
232:      * TODO
233:      */
234:     function &insertVariableBefore($before, $humanName, $varName, $type,
235:                                    $required, $readonly = false,
236:                                    $description = null, $params = array())
237:     {
238:         $type = &$this->getType($type, $params);
239:         $var = new Horde_Form_Variable($humanName, $varName, $type,
240:                                        $required, $readonly, $description);
241: 
242:         /* Set the form object reference in the var. */
243:         $var->setFormOb($this);
244: 
245:         if ($var->getTypeName() == 'enum' &&
246:             !strlen($type->getPrompt()) &&
247:             count($var->getValues()) == 1) {
248:             $vals = array_keys($var->getValues());
249:             $this->_vars->add($var->varName, $vals[0]);
250:             $var->_autofilled = true;
251:         } elseif ($var->getTypeName() == 'file' ||
252:                   $var->getTypeName() == 'image') {
253:             $this->_enctype = 'multipart/form-data';
254:         }
255:         if (empty($this->_currentSection) && $this->_currentSection !== 0) {
256:             $this->_currentSection = '__base';
257:         }
258: 
259:         if (is_null($before)) {
260:             $this->_variables[$this->_currentSection][] = &$var;
261:         } else {
262:             $num = 0;
263:             while (isset($this->_variables[$this->_currentSection][$num]) &&
264:                    $this->_variables[$this->_currentSection][$num]->getVarName() != $before) {
265:                 $num++;
266:             }
267:             if (!isset($this->_variables[$this->_currentSection][$num])) {
268:                 $this->_variables[$this->_currentSection][] = &$var;
269:             } else {
270:                 $this->_variables[$this->_currentSection] = array_merge(
271:                     array_slice($this->_variables[$this->_currentSection], 0, $num),
272:                     array(&$var),
273:                     array_slice($this->_variables[$this->_currentSection], $num));
274:             }
275:         }
276: 
277:         return $var;
278:     }
279: 
280:     /**
281:      * Removes a variable from the form.
282:      *
283:      * As only variables can be passed by reference, you need to call this
284:      * method this way if want to pass a variable name:
285:      * <code>
286:      * $form->removeVariable($var = 'varname');
287:      * </code>
288:      *
289:      * @param Horde_Form_Variable|string $var  Either the variable's name or
290:      *                                         the variable to remove from the
291:      *                                         form.
292:      *
293:      * @return boolean  True if the variable was found (and deleted).
294:      */
295:     function removeVariable(&$var)
296:     {
297:         foreach (array_keys($this->_variables) as $section) {
298:             foreach (array_keys($this->_variables[$section]) as $i) {
299:                 if ((is_a($var, 'Horde_Form_Variable') && $this->_variables[$section][$i] === $var) ||
300:                     ($this->_variables[$section][$i]->getVarName() == $var)) {
301:                     // Slice out the variable to be removed.
302:                     $this->_variables[$this->_currentSection] = array_merge(
303:                         array_slice($this->_variables[$this->_currentSection], 0, $i),
304:                         array_slice($this->_variables[$this->_currentSection], $i + 1));
305: 
306:                     return true;
307:                 }
308:             }
309:         }
310: 
311:         return false;
312:     }
313: 
314:     /**
315:      * TODO
316:      */
317:     function &addHidden($humanName, $varName, $type, $required,
318:                         $readonly = false, $description = null,
319:                         $params = array())
320:     {
321:         $type = &$this->getType($type, $params);
322:         $var = new Horde_Form_Variable($humanName, $varName, $type,
323:                                        $required, $readonly, $description);
324:         $var->hide();
325:         $this->_hiddenVariables[] = &$var;
326:         return $var;
327:     }
328: 
329:     function &getVariables($flat = true, $withHidden = false)
330:     {
331:         if ($flat) {
332:             $vars = array();
333:             foreach ($this->_variables as $section) {
334:                 foreach ($section as $var) {
335:                     $vars[] = $var;
336:                 }
337:             }
338:             if ($withHidden) {
339:                 foreach ($this->_hiddenVariables as $var) {
340:                     $vars[] = $var;
341:                 }
342:             }
343:             return $vars;
344:         } else {
345:             return $this->_variables;
346:         }
347:     }
348: 
349:     function setButtons($submit, $reset = false)
350:     {
351:         if ($submit === true || is_null($submit) || empty($submit)) {
352:             /* Default to 'Submit'. */
353:             $submit = array(Horde_Form_Translation::t("Submit"));
354:         } elseif (!is_array($submit)) {
355:             /* Default to array if not passed. */
356:             $submit = array($submit);
357:         }
358:         /* Only if $reset is strictly true insert default 'Reset'. */
359:         if ($reset === true) {
360:             $reset = Horde_Form_Translation::t("Reset");
361:         }
362: 
363:         $this->_submit = $submit;
364:         $this->_reset = $reset;
365:     }
366: 
367:     function appendButtons($submit)
368:     {
369:         if (!is_array($submit)) {
370:             $submit = array($submit);
371:         }
372: 
373:         $this->_submit = array_merge($this->_submit, $submit);
374:     }
375: 
376:     function preserveVarByPost(&$vars, $varname, $alt_varname = '')
377:     {
378:         $value = $vars->getExists($varname, $wasset);
379: 
380:         /* If an alternate name is given under which to preserve use that. */
381:         if ($alt_varname) {
382:             $varname = $alt_varname;
383:         }
384: 
385:         if ($wasset) {
386:             $this->_preserveVarByPost($varname, $value);
387:         }
388:     }
389: 
390:     /**
391:      * @access private
392:      */
393:     function _preserveVarByPost($varname, $value)
394:     {
395:         if (is_array($value)) {
396:             foreach ($value as $id => $val) {
397:                 $this->_preserveVarByPost($varname . '[' . $id . ']', $val);
398:             }
399:         } else {
400:             $varname = htmlspecialchars($varname);
401:             $value = htmlspecialchars($value);
402:             printf('<input type="hidden" name="%s" value="%s" />' . "\n",
403:                    $varname,
404:                    $value);
405:         }
406:     }
407: 
408:     function open(&$renderer, &$vars, $action, $method = 'get', $enctype = null)
409:     {
410:         if (is_null($enctype) && !is_null($this->_enctype)) {
411:             $enctype = $this->_enctype;
412:         }
413:         $renderer->open($action, $method, $this->_name, $enctype);
414:         $renderer->listFormVars($this);
415: 
416:         if (!empty($this->_name)) {
417:             $this->_preserveVarByPost('formname', $this->_name);
418:         }
419: 
420:         if ($this->_useFormToken) {
421:             $token = Horde_Token::generateId($this->_name);
422:             $GLOBALS['session']->set('horde', 'form_secrets/' . $token, true);
423:             $this->_preserveVarByPost($this->_name . '_formToken', $token);
424:         }
425: 
426:         /* Loop through vars and check for any special cases to preserve. */
427:         $variables = $this->getVariables();
428:         foreach ($variables as $var) {
429:             /* Preserve value if change has to be tracked. */
430:             if ($var->getOption('trackchange')) {
431:                 $varname = $var->getVarName();
432:                 $this->preserveVarByPost($vars, $varname, '__old_' . $varname);
433:             }
434:         }
435: 
436:         foreach ($this->_hiddenVariables as $var) {
437:             $this->preserveVarByPost($vars, $var->getVarName());
438:         }
439:     }
440: 
441:     function close($renderer)
442:     {
443:         $renderer->close();
444:     }
445: 
446:     /**
447:      * Renders the form for editing.
448:      *
449:      * @param Horde_Form_Renderer $renderer  A renderer instance, optional
450:      *                                       since Horde 3.2.
451:      * @param Variables $vars                A Variables instance, optional
452:      *                                       since Horde 3.2.
453:      * @param string $action                 The form action (url).
454:      * @param string $method                 The form method, usually either
455:      *                                       'get' or 'post'.
456:      * @param string $enctype                The form encoding type. Determined
457:      *                                       automatically if null.
458:      * @param boolean $focus                 Focus the first form field?
459:      */
460:     function renderActive($renderer = null, $vars = null, $action = '',
461:                           $method = 'get', $enctype = null, $focus = true)
462:     {
463:         if (is_null($renderer)) {
464:             $renderer = $this->getRenderer();
465:         }
466:         if (is_null($vars)) {
467:             $vars = $this->_vars;
468:         }
469: 
470:         if (is_null($enctype) && !is_null($this->_enctype)) {
471:             $enctype = $this->_enctype;
472:         }
473:         $renderer->open($action, $method, $this->getName(), $enctype);
474:         $renderer->listFormVars($this);
475: 
476:         if (!empty($this->_name)) {
477:             $this->_preserveVarByPost('formname', $this->_name);
478:         }
479: 
480:         if ($this->_useFormToken) {
481:             $token = Horde_Token::generateId($this->_name);
482:             $GLOBALS['session']->set('horde', 'form_secrets/' . $token, true);
483:             $this->_preserveVarByPost($this->_name . '_formToken', $token);
484:         }
485: 
486:         if (count($this->_sections)) {
487:             $this->_preserveVarByPost('__formOpenSection', $this->getOpenSection());
488:         }
489: 
490:         /* Loop through vars and check for any special cases to
491:          * preserve. */
492:         $variables = $this->getVariables();
493:         foreach ($variables as $var) {
494:             /* Preserve value if change has to be tracked. */
495:             if ($var->getOption('trackchange')) {
496:                 $varname = $var->getVarName();
497:                 $this->preserveVarByPost($vars, $varname, '__old_' . $varname);
498:             }
499:         }
500: 
501:         foreach ($this->_hiddenVariables as $var) {
502:             $this->preserveVarByPost($vars, $var->getVarName());
503:         }
504: 
505:         $renderer->beginActive($this->getTitle(), $this->getExtra());
506:         $renderer->renderFormActive($this, $vars);
507:         $renderer->submit($this->_submit, $this->_reset);
508:         $renderer->end();
509:         $renderer->close($focus);
510:     }
511: 
512:     /**
513:      * Renders the form for displaying.
514:      *
515:      * @param Horde_Form_Renderer $renderer  A renderer instance, optional
516:      *                                       since Horde 3.2.
517:      * @param Variables $vars                A Variables instance, optional
518:      *                                       since Horde 3.2.
519:      */
520:     function renderInactive($renderer = null, $vars = null)
521:     {
522:         if (is_null($renderer)) {
523:             $renderer = $this->getRenderer();
524:         }
525:         if (is_null($vars)) {
526:             $vars = $this->_vars;
527:         }
528: 
529:         $renderer->_name = $this->_name;
530:         $renderer->beginInactive($this->getTitle(), $this->getExtra());
531:         $renderer->renderFormInactive($this, $vars);
532:         $renderer->end();
533:     }
534: 
535:     function preserve($vars)
536:     {
537:         if ($this->_useFormToken) {
538:             $token = Horde_Token::generateId($this->_name);
539:             $GLOBALS['session']->set('horde', 'form_secrets/' . $token, true);
540:             $this->_preserveVarByPost($this->_name . '_formToken', $token);
541:         }
542: 
543:         $variables = $this->getVariables();
544:         foreach ($variables as $var) {
545:             $varname = $var->getVarName();
546: 
547:             /* Save value of individual components. */
548:             switch ($var->getTypeName()) {
549:             case 'passwordconfirm':
550:             case 'emailconfirm':
551:                 $this->preserveVarByPost($vars, $varname . '[original]');
552:                 $this->preserveVarByPost($vars, $varname . '[confirm]');
553:                 break;
554: 
555:             case 'monthyear':
556:                 $this->preserveVarByPost($vars, $varname . '[month]');
557:                 $this->preserveVarByPost($vars, $varname . '[year]');
558:                 break;
559: 
560:             case 'monthdayyear':
561:                 $this->preserveVarByPost($vars, $varname . '[month]');
562:                 $this->preserveVarByPost($vars, $varname . '[day]');
563:                 $this->preserveVarByPost($vars, $varname . '[year]');
564:                 break;
565:             }
566: 
567:             $this->preserveVarByPost($vars, $varname);
568:         }
569:         foreach ($this->_hiddenVariables as $var) {
570:             $this->preserveVarByPost($vars, $var->getVarName());
571:         }
572:     }
573: 
574:     function unsetVars(&$vars)
575:     {
576:         foreach ($this->getVariables() as $var) {
577:             $vars->remove($var->getVarName());
578:         }
579:     }
580: 
581:     /**
582:      * Validates the form, checking if it really has been submitted by calling
583:      * isSubmitted() and if true does any onSubmit() calls for variable types
584:      * in the form. The _submitted variable is then rechecked.
585:      *
586:      * @param Variables $vars       A Variables instance, optional since Horde
587:      *                              3.2.
588:      * @param boolean $canAutofill  Can the form be valid without being
589:      *                              submitted?
590:      *
591:      * @return boolean  True if the form is valid.
592:      */
593:     function validate($vars = null, $canAutoFill = false)
594:     {
595:         if (is_null($vars)) {
596:             $vars = $this->_vars;
597:         }
598: 
599:         /* Get submitted status. */
600:         if ($this->isSubmitted() || $canAutoFill) {
601:             /* Form was submitted or can autofill; check for any variable
602:              * types' onSubmit(). */
603:             $this->onSubmit($vars);
604: 
605:             /* Recheck submitted status. */
606:             if (!$this->isSubmitted() && !$canAutoFill) {
607:                 return false;
608:             }
609:         } else {
610:             /* Form has not been submitted; return false. */
611:             return false;
612:         }
613: 
614:         $message = '';
615:         $this->_autofilled = true;
616: 
617:         if ($this->_useFormToken) {
618:             $tokenSource = $GLOBALS['injector']->getInstance('Horde_Token');
619:             $passedToken = $vars->get($this->_name . '_formToken');
620:             if (!empty($passedToken) && !$tokenSource->verify($passedToken)) {
621:                 $this->_errors['_formToken'] = Horde_Form_Translation::t("This form has already been processed.");
622:             }
623:             if (!$GLOBALS['session']->get('horde', 'form_secrets/' . $passedToken)) {
624:                 $this->_errors['_formSecret'] = Horde_Form_Translation::t("Required secret is invalid - potentially malicious request.");
625:             }
626:         }
627: 
628:         foreach ($this->getVariables() as $var) {
629:             $this->_autofilled = $var->_autofilled && $this->_autofilled;
630:             if (!$var->validate($vars, $message)) {
631:                 $this->_errors[$var->getVarName()] = $message;
632:             }
633:         }
634: 
635:         if ($this->_autofilled) {
636:             unset($this->_errors['_formToken']);
637:         }
638: 
639:         foreach ($this->_hiddenVariables as $var) {
640:             if (!$var->validate($vars, $message)) {
641:                 $this->_errors[$var->getVarName()] = $message;
642:             }
643:         }
644: 
645:         return $this->isValid();
646:     }
647: 
648:     function clearValidation()
649:     {
650:         $this->_errors = array();
651:     }
652: 
653:     function getErrors()
654:     {
655:         return $this->_errors;
656:     }
657: 
658:     function getError($var)
659:     {
660:         if (is_a($var, 'Horde_Form_Variable')) {
661:             $name = $var->getVarName();
662:         } else {
663:             $name = $var;
664:         }
665:         return isset($this->_errors[$name]) ? $this->_errors[$name] : null;
666:     }
667: 
668:     function setError($var, $message)
669:     {
670:         if (is_a($var, 'Horde_Form_Variable')) {
671:             $name = $var->getVarName();
672:         } else {
673:             $name = $var;
674:         }
675:         $this->_errors[$name] = $message;
676:     }
677: 
678:     function clearError($var)
679:     {
680:         if (is_a($var, 'Horde_Form_Variable')) {
681:             $name = $var->getVarName();
682:         } else {
683:             $name = $var;
684:         }
685:         unset($this->_errors[$name]);
686:     }
687: 
688:     function isValid()
689:     {
690:         return ($this->_autofilled || count($this->_errors) == 0);
691:     }
692: 
693:     function execute()
694:     {
695:         Horde::logMessage('Warning: Horde_Form::execute() called, should be overridden', 'DEBUG');
696:     }
697: 
698:     /**
699:      * Fetch the field values of the submitted form.
700:      *
701:      * @param Variables $vars  A Variables instance, optional since Horde 3.2.
702:      * @param array $info      Array to be filled with the submitted field
703:      *                         values.
704:      */
705:     function getInfo($vars, &$info)
706:     {
707:         if (is_null($vars)) {
708:             $vars = $this->_vars;
709:         }
710:         $this->_getInfoFromVariables($this->getVariables(), $vars, $info);
711:         $this->_getInfoFromVariables($this->_hiddenVariables, $vars, $info);
712:     }
713: 
714:     /**
715:      * Fetch the field values from a given array of variables.
716:      *
717:      * @access private
718:      *
719:      * @param array  $variables  An array of Horde_Form_Variable objects to
720:      *                           fetch from.
721:      * @param object $vars       The Variables object.
722:      * @param array  $info       The array to be filled with the submitted
723:      *                           field values.
724:      */
725:     function _getInfoFromVariables($variables, &$vars, &$info)
726:     {
727:         foreach ($variables as $var) {
728:             if ($var->isArrayVal()) {
729:                 $var->getInfo($vars, $values);
730:                 if (is_array($values)) {
731:                     $varName = str_replace('[]', '', $var->getVarName());
732:                     foreach ($values as $i => $val) {
733:                         $info[$i][$varName] = $val;
734:                     }
735:                 }
736:             } else {
737:                 if (Horde_Array::getArrayParts($var->getVarName(), $base, $keys)) {
738:                     if (!isset($info[$base])) {
739:                         $info[$base] = array();
740:                     }
741:                     $pointer = &$info[$base];
742:                     while (count($keys)) {
743:                         $key = array_shift($keys);
744:                         if (!isset($pointer[$key])) {
745:                             $pointer[$key] = array();
746:                         }
747:                         $pointer = &$pointer[$key];
748:                     }
749:                     $var->getInfo($vars, $pointer);
750:                 } else {
751:                     $var->getInfo($vars, $info[$var->getVarName()]);
752:                 }
753:             }
754:         }
755:     }
756: 
757:     function hasHelp()
758:     {
759:         return $this->_help;
760:     }
761: 
762:     /**
763:      * Determines if this form has been submitted or not. If the class
764:      * var _submitted is null then it will check for the presence of
765:      * the formname in the form variables.
766:      *
767:      * Other events can explicitly set the _submitted variable to
768:      * false to indicate a form submit but not for actual posting of
769:      * data (eg. onChange events to update the display of fields).
770:      *
771:      * @return boolean  True or false indicating if the form has been
772:      *                  submitted.
773:      */
774:     function isSubmitted()
775:     {
776:         if (is_null($this->_submitted)) {
777:             if ($this->_vars->get('formname') == $this->getName()) {
778:                 $this->_submitted = true;
779:             } else {
780:                 $this->_submitted = false;
781:             }
782:         }
783: 
784:         return $this->_submitted;
785:     }
786: 
787:     /**
788:      * Checks if there is anything to do on the submission of the form by
789:      * looping through each variable's onSubmit() function.
790:      *
791:      * @param Horde_Variables $vars
792:      */
793:     function onSubmit(&$vars)
794:     {
795:         /* Loop through all vars and check if there's anything to do on
796:          * submit. */
797:         $variables = $this->getVariables();
798:         foreach ($variables as $var) {
799:             $var->type->onSubmit($var, $vars);
800:             /* If changes to var being tracked don't register the form as
801:              * submitted if old value and new value differ. */
802:             if ($var->getOption('trackchange')) {
803:                 $varname = $var->getVarName();
804:                 if (!is_null($vars->get('formname')) &&
805:                     $vars->get($varname) != $vars->get('__old_' . $varname)) {
806:                     $this->_submitted = false;
807:                 }
808:             }
809:         }
810:     }
811: 
812:     /**
813:      * Explicitly sets the state of the form submit.
814:      *
815:      * An event can override the automatic determination of the submit state
816:      * in the isSubmitted() function.
817:      *
818:      * @param boolean $state  Whether to set the state of the form as being
819:      *                        submitted.
820:      */
821:     function setSubmitted($state = true)
822:     {
823:         $this->_submitted = $state;
824:     }
825: 
826: }
827: 
API documentation generated by ApiGen