Dotclear

source: inc/admin/class.dc.form.php @ 1156:92f840a91f98

Revision 1156:92f840a91f98, 26.0 KB checked in by Dsls <dsls@…>, 12 years ago (diff)

Commented code, small tuning

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14/**
15* dcFormNode Twig Node for Form handling
16*
17* @uses     Twig_Node
18*
19*/
20class dcFormNode extends Twig_Node
21{
22     public function __construct($name,Twig_NodeInterface $body,$attr,$lineno,$tag=null)
23     {
24          parent::__construct(array('body' => $body),array('name' => $name, 'attr' => $attr),$lineno,$tag);
25     }
26     
27     /**
28     * Compiles the node to PHP.
29     *
30     * @param Twig_Compiler A Twig_Compiler instance
31     */
32     public function compile(Twig_Compiler $compiler)
33     {
34          $compiler
35               ->addDebugInfo($this);
36          $compiler
37               ->write("\$context['dc_form']->beginForm(")
38               ->subcompile($this->getAttribute('name'));
39          if ($this->getAttribute('attr') !== null) {
40               $compiler
41                    ->write(',')
42                    ->subcompile($this->getAttribute('attr'));
43          }
44          $compiler
45               ->write(");\n");
46          $compiler
47               ->subcompile($this->getNode('body'))
48               ->write("\$context['dc_form']->renderHiddenWidgets();\n")
49               ->write("\$context['dc_form']->endForm();\n")
50          ;
51     }
52}
53
54/**
55 * Template form token parser
56 */
57class dcFormTokenParser extends Twig_TokenParser
58{
59    /**
60     * parse - parses form tag
61     * General syntax is :
62     *  {% form 'formname' %}
63     *  ... {{ form_field (...)}}
64     *  {% endform %}
65     * Specific attributes can be passed to the form, enabling to set
66     * attributes to the form template :
67     * {% form 'formname' with {'id':'myform'} %}
68     * @param mixed \Twig_Token Description.
69     *
70     * @access public
71     *
72     * @return mixed Value.
73     */
74     public function parse(Twig_Token $token)
75     {
76          $lineno = $token->getLine();
77          $stream = $this->parser->getStream();
78          $name = $this->parser->getExpressionParser()->parseExpression();
79          $attr = null;
80          /* parse optional context */
81          if ($stream->test(Twig_Token::NAME_TYPE, 'with')) {
82               $stream->next();
83               $attr = $this->parser->getExpressionParser()->parseExpression();
84          }
85          $stream->expect(Twig_Token::BLOCK_END_TYPE);
86          $body = $this->parser->subparse(array($this,'decideBlockEnd'),true);
87          $stream->expect(Twig_Token::BLOCK_END_TYPE);
88
89          return new dcFormNode($name,$body,$attr,$token->getLine(),$this->getTag());
90     }
91
92     public function decideBlockEnd(Twig_Token $token)
93     {
94          return $token->test('endform');
95     }
96
97     public function getTag()
98     {
99          return 'form';
100     }
101}
102
103/**
104 * Template form extension
105 */
106class dcFormExtension extends Twig_Extension
107{
108     protected $template;
109     protected $tpl;
110     protected $core;
111     protected $twig;
112     protected $forms;
113     protected $currentForm;
114     protected $blocks;
115
116     public function __construct($core)
117     {
118          $this->core = $core;
119          $this->tpl = array('@forms/form_layout.html.twig');
120          $this->forms = array();
121          $this->blocks = array();
122          $this->currentForm = null;
123     }
124
125     public function initRuntime(Twig_Environment $environment)
126     {
127          $this->twig = $environment;
128          $this->twig->getLoader()->addPath(dirname(__FILE__).'/default-templates/forms','forms');
129          foreach ($this->tpl as $tpl) {
130               $this->template = $this->twig->loadTemplate($tpl);
131               $this->blocks = array_merge($this->blocks,$this->template->getBlocks());
132          }
133     }
134
135     public function addTemplate($tpl) {
136          $this->tpl[]=$tpl;
137          if (isset($this->twig)) {
138               $this->template = $this->twig->loadTemplate($tpl);
139               $this->blocks = array_merge($this->blocks,$this->template->getBlocks());
140          }
141     }
142
143     public function getGlobals()
144     {
145          return array('dc_form' => $this);
146     }
147
148     public function getFunctions()
149     {
150          return array(
151               new Twig_SimpleFunction(
152                    'widget',
153                    array($this,'renderWidget'),
154                    array('is_safe' => array('html'))
155               ),
156               new Twig_SimpleFunction(
157                    'haswidget',
158                    array($this,'hasWidget'),
159                    array('is_safe' => array('html'))
160               ),
161               new Twig_SimpleFunction(
162                    'form_field',
163                    array($this,'renderField'),
164                    array('is_safe' => array('html'))
165               ),
166               new Twig_SimpleFunction(
167                    '_form_is_choice_group',
168                    array($this,'isChoiceGroup'),
169                    array('is_safe' => array('html'))
170               ),
171               new Twig_SimpleFunction(
172                    '_form_is_choice_selected',
173                    array($this,'isChoiceSelected'),
174                    array('is_safe' => array('html'))
175               )
176          );
177     }
178
179    /**
180     * isChoiceGroup - binding for twig function "_form_is_choice_group"
181     *                        returns whether a choice is a group or not
182     * @param mixed $choice the choice.
183     *
184     * @access public
185     *
186     * @return boolean true is choice is a group (optgroup).
187     */
188     public function isChoiceGroup($choice)
189     {
190          return is_array($choice);
191     }
192
193    /**
194     * isChoiceSelected - binding for twig function "_form_is_choice_selected"
195     *                        returns whether current choice matches a value or not
196     * @param mixed $choice the choixe.
197     * @param mixed $value  the value to check matching.
198     *
199     * @access public
200     *
201     * @return boolean if choice is matching the value.
202     */
203     public function isChoiceSelected($choice,$value)
204     {
205          return $choice == $value;
206     }
207
208    /**
209     * getTokenParsers returns token parsers
210     *
211     * @access public
212     *
213     * @return mixed Value.
214     */
215     public function getTokenParsers()
216     {
217          return array(new dcFormTokenParser());
218     }
219
220    /**
221     * hasWidget - binding for twig "haswidget" function
222     *    returns whether a widget is defined or not
223     *
224     * @param mixed $name the widget name.
225     *
226     * @access public
227     *
228     * @return boolean true if the widget exists.
229     */
230     public function hasWidget($name) {
231          return isset($this->blocks[$name]);
232     }
233
234    /**
235     * renderWidget - binding for 'widget' twig function
236     * behaves exactly like "block" function, except that a context
237     * can be passed to the function
238     *
239     * @param mixed $name the widget (block) name to render.
240     * @param mixed $attr Description the context for this block.
241     *
242     *
243     * @return mixed Value.
244     */
245     public function renderWidget($name,$attr) {
246          if (!isset($this->blocks[$name]))
247               return '';
248          echo $this->template->renderBlock(
249               $name,
250               $attr,
251               $this->blocks
252          );
253     }
254
255    /**
256     * getCurrentForm - returns current form if called within a {% form %} tag
257     *
258     * @access public
259     *
260     * @return string the current form.
261     */
262     public function getCurrentForm() {
263          return $this->currentForm;
264     }
265
266    /**
267     * renderField - binding for 'form_field' twig function; renders a field
268     *
269     * @param mixed $name       field name as defined on php side.
270     * @param array $attributes html attributes for field (ex : class, ...).
271     * @param array $extra      extra attributes that may be template specific.
272     *
273     * @access public
274     *
275     * @return mixed Value.
276     */
277     public function renderField($name,$attributes=array(),$extra=array())
278     {
279          $field = $this->currentForm->$name;
280          if ($field) {
281               $attr = $field->getAttributes($attributes);
282               if (isset($attr['attr'])) {
283                    $attr['attr'] = array_merge($attr['attr'],$attributes);
284               } else {
285                    $attr['attr'] = $attributes;
286               }
287               $this->renderWidget(
288                    $field->getWidgetBlock(),
289                    array_merge(
290                         $attr,
291                         $extra
292                    )
293               );
294          }
295     }
296
297    /**
298     * renderHiddenWidgets -- renders all form hidden fields
299     *
300     * @access public
301     *
302     * @return mixed Value.
303     */
304     public function renderHiddenWidgets()
305     {
306          foreach ($this->currentForm->getHiddenFields() as $h) {
307               $this->renderField($h->getName());
308          }
309     }
310
311     public function getName()
312     {
313          return 'dc_form';
314     }
315
316    /**
317     * addForm -- registers a new form
318     *
319     * @param mixed \dcForm Description.
320     *
321     * @access public
322     *
323     * @return mixed Value.
324     */
325     public function addForm(dcForm $form)
326     {
327          $this->forms[$form->getName()] = $form;
328     }
329
330    /**
331     * beginForm -- displays form beginning
332     *
333     * @param mixed $name form name.
334     * @param array $attr extra attributes.
335     *
336     * @access public
337     *
338     * @return mixed Value.
339     */
340     public function beginForm($name,$attr=array())
341     {
342          if (isset($this->forms[$name])) {
343               $this->currentForm = $this->forms[$name];
344               $this->currentForm->begin($attr);
345          }
346          else {
347               throw new Twig_Error_Runtime(sprintf(
348                    'Form "%s" does not exist',
349                    $name
350               ));
351          }
352     }
353
354    /**
355     * endForm -- displays form ending
356     *
357     * @access public
358     *
359     * @return mixed Value.
360     */
361     public function endForm()
362     {
363          $this->currentForm->end();
364          $this->currentForm = null;
365     }
366}
367
368/**
369 * Template form exception
370 */
371class InvalidFieldException extends Exception {
372}
373
374/**
375* dcForm - Template form
376*
377*/
378class dcForm
379{
380     /** @var string form id */
381     protected $id;
382     /** @var string form name */
383     protected $name;
384     /** @var dcCore dcCore instance */
385     protected $core;
386     /** @var string form action */
387     protected $action;
388     /** @var array(dcField) list of form fields */
389     protected $fields;
390     /** @var string form method (GET/POST) */
391     protected $method;
392     /** @var array(dcField) list of submit fields */
393     protected $submitfields;
394     /** @var array(dcField) list of hidden fields */
395     protected $hiddenfields;
396     /** @var array(dcField) list of form errors */
397     protected $errors;
398
399    /**
400     * Class constructor
401     *
402     * @param mixed  $core   dotclear core
403     * @param mixed  $name   form name - can be an array (name,id)
404     * @param mixed  $action form action
405     * @param string $method form method ('GET' or 'POST')
406     *
407     * @access public
408     *
409     * @return mixed Value.
410     */
411     public function __construct($core,$name,$action,$method='POST')
412     {
413          $this->core = $core;
414          $this->setNID($name);
415          $this->method = $method;
416          $this->action = $action;
417          $this->fields = array();
418          $this->core->tpl->getExtension('dc_form')->addForm($this);
419          $this->submitfields = array();
420          $this->hiddenfields = array();
421          $this->errors = array();
422          if ($method == 'POST') {
423               $this->addNonce();
424          }
425     }
426
427    /**
428     * addTemplate - Adds a template file to enrich form fields
429     *
430     * @param string $t the template file.
431     *
432     * @access public
433     */
434     public function addTemplate($t) {
435          $this->core->tpl->getExtension('dc_form')->addTemplate($t);
436     }
437
438    /**
439     * addNonce -- adds dc nonce to form fields
440     *
441     * @access protected
442     *
443     * @return nothing
444     */
445     protected function addNonce()
446     {
447          $this->addField(
448               new dcFieldHidden(array('xd_check'),
449               $this->core->getNonce())
450          );
451     }
452
453    /**
454     * Defines Name & ID from field
455     *
456     * @param mixed $nid either an array (name, id) or a string
457     *                   (name only, id will be set to null).
458     *
459     * @access protected
460     *
461     * @return nothing.
462     */
463     protected function setNID($nid)
464     {
465          if (is_array($nid)) {
466               $this->name = $nid[0];
467               $this->id = !empty($nid[1]) ? $nid[1] : null;
468          }
469          else {
470               $this->id = null;
471               $this->name = $nid;
472          }
473     }
474
475    /**
476     * getContext - returns form context (to fill-in twig context for instance),
477     *                   if any
478     *
479     * @access public
480     *
481     * @return array the form context.
482     */
483     public function getContext() {
484          return array();
485     }
486
487
488    /**
489     * Returns form name
490     *
491     * @access public
492     *
493     * @return mixed Value.
494     */
495     public function getName()
496     {
497          return $this->name;
498     }
499
500    /**
501     * getErrors - returns form errors
502     *
503     * @access public
504     *
505     * @return array the list of errors.
506     */
507     public function getErrors()
508     {
509          return $this->errors;
510     }
511
512    /**
513     * addField - adds a new field to form
514     *
515     * @param mixed \dcField the field to add.
516     *
517     * @access public
518     *
519     * @return dcForm the form instance (therefore addField can be chained)
520     */
521     public function addField(dcField $f)
522     {
523          if ($f instanceof dcFieldAction) {
524               $this->submitfields[$f->getName()] = $f;
525          }
526          if ($f instanceof dcFieldHidden) {
527               $this->hiddenfields[$f->getName()] = $f;
528          }
529          $this->fields[$f->getName()] = $f;
530
531          return $this;
532     }
533
534    /**
535     * removeField - removes a field
536     *
537     * @param mixed \dcField the field to remove.
538     *
539     * @access public
540     *
541     * @return dcForm the form instance (therefore addField can be chained)
542     */
543     public function removeField(dcField $f) {
544          $n = $f->getName();
545          if (isset($this->fields[$n])){
546               unset($this->fields[$n]);
547          }
548          return $this;
549     }
550
551
552    /**
553     * renameField - renames a field
554     *
555     * @param mixed $field   the field to rename.
556     * @param mixed $newname new field name
557     *
558     * @access public
559     *
560     *
561     * @return dcForm the form instance (therefore addField can be chained)
562     */
563     public function renameField($field,$newname) {
564          $oldname = $field->getName();
565          if (isset($this->fields[$oldname])) {
566               unset($this->fields[$oldname]);
567               $field->setName($newname);
568               $this->fields[$newname] = $field;
569          }
570          return $this;
571     }
572
573    /**
574     * begin - begins a form. Should be not be called directly, it is handled
575     *              by the Twig Form extension.
576     *
577     * @param array $attr form extra attributes, if any.
578     *
579     * @access public
580     *
581     * @return mixed Value.
582     */
583     public function begin($attr=array())
584     {
585          $attr['method'] = $this->method;
586          $attr['action'] = $this->action;
587          if (!empty($this->id)) {
588               $attr['id'] = $this->id;
589          }
590          $this->core->tpl->getExtension('dc_form')->renderWidget(
591               'beginform',
592               $attr);
593     }
594
595    /**
596     * end - ends a form. Should be not be called directly, it is handled
597     *              by the Twig Form extension.
598     *
599     * @access public
600     *
601     * @return mixed Value.
602     */
603     public function end()
604     {
605          $this->core->tpl->getExtension('dc_form')->renderWidget(
606               'endform');
607     }
608
609    /**
610     * __isset - magic method isset, checks whether a field exists
611     *                   example : if (isset($form->field1))
612     *
613     * @param mixed $name field name to check.
614     *
615     * @access public
616     *
617     * @return boolean true if the field exists.
618     */
619     public function __isset($name)
620     {
621          return isset($this->fields[$name]);
622     }
623
624    /**
625     * __get -- magic method, retrieves a field from a form
626     *              example : $f = $form->field1
627     *
628     * @param mixed $name Description.
629     *
630     * @access public
631     *
632     * @return mixed Value.
633     */
634     public function __get($name)
635     {
636          return isset($this->fields[$name]) ?
637               $this->fields[$name] : null;
638     }
639
640    /**
641     * __set -- magic method, sets a value for a given form field
642     *              example : $form->field1 = 'my value';
643     *
644     * @param mixed $name  the field name.
645     * @param mixed $value the field value.
646     *
647     * @access public
648     */
649     public function __set($name,$value)
650     {
651          if (isset($this->fields[$name])) {
652               $this->fields[$name]->setValue($value);
653          }
654     }
655
656/*   public function isSubmitted()
657     {
658          $from = $this->method == 'POST' ? $_POST : $_GET;
659     }
660*/
661
662    /**
663     * setupFields - initializes form & fields from $_GET or $_POST
664     *
665     * @access protected
666     */
667     protected function setupFields() {
668          $from = $this->method == 'POST' ? $_POST : $_GET;
669          foreach ($this->fields as $f) {
670               $f->setup($from);
671          }
672     }
673
674    /**
675     * handleActions - handle appropriate actions, according to submitted fields
676     *
677     * @param mixed $submitted the fields that have been submitted.
678     *
679     * @access protected
680     */
681     protected function handleActions($submitted) {
682          foreach ($submitted as $f) {
683               $action = $f->getAction();
684               if ($action != NULL) {
685                    $ret = call_user_func($action,$this);
686               }
687          }
688     }
689
690    /**
691     * getSubmittedFields - retrieves fields that have been submitted, if any
692     *
693     * @access protected
694     *
695     * @return array the list of submitted fields.
696     */
697     protected function getSubmittedFields() {
698          $s = array();
699          foreach ($this->submitfields as $f) {
700               if ($f->isDefined()) {
701                    $s[$f->getName()] = $f;
702               }
703          }
704          return $s;
705     }
706
707    /**
708     * setup - sets up the form, given the parameters given to the page
709     *              should be called after fields have been defined.
710     *
711     * @access public
712     *
713     * @return mixed Value.
714     */
715     public function setup()
716     {
717          $this->setupFields();
718          $submitted = $this->getSubmittedFields();
719          $this->handleActions($submitted);
720     }
721
722    /**
723     * check - checks if the form is valid, errors are filled in, in case of
724     *              incorrect fields
725     *
726     * @access public
727     */
728     public function check()
729     {
730          foreach ($this->fields as $f) {
731               try {
732                    $f->check();
733               }
734               catch (InvalidFieldException $e) {
735                    $this->errors[] = $e->getMessage();
736               }
737          }
738     }
739
740    /**
741     * getHiddenFields - returns the list of hidden fields
742     *
743     * @access public
744     *
745     * @return array the list of hidden fields.
746     */
747     public function getHiddenFields()
748     {
749          return $this->hiddenfields;
750     }
751}
752
753/**
754 * Template form field
755 */
756abstract class dcField implements Countable
757{
758     /** @var string field options */
759     protected $options;
760     /** @var string field name */
761     protected $name;
762     /** @var string field values */
763     protected $values;
764     /** @var string field id */
765     protected $id;
766     /** @var boolean true if field can contain multiple values */
767     protected $multiple;
768     /** @var boolean true if the field has been defined */
769     protected $defined;
770
771    /**
772     * __construct - constructor
773     *
774     * @param string $name   Name or array(name,id) for field.
775     * @param array $values  field values.
776     * @param array $options options
777     *
778     * Currently globally available options are :
779     *  * multiple : true/false. Enable multiple values for field
780     * @access public
781     *
782     * @return mixed Value.
783     */
784     public function __construct($name,$values,$options=array())
785     {
786          $this->setNID($name);
787          $this->options = new ArrayObject($options);
788          if ($values === NULL){
789               $values = array();
790          }
791          $this->setValues($values);
792          $this->defined = false;
793          $this->multiple = (isset($options['multiple']) && $options['multiple']);
794
795     }
796
797    /**
798     * setNID - defines fiels name & id
799     *
800     * @param mixed $nid field name (string) or an array containing  name (1st)
801     *                   and id (2nd field).
802     *
803     * @access protected
804     */
805     protected function setNID($nid)
806     {
807          if (is_array($nid)) {
808               $this->name = $nid[0];
809               $this->id = !empty($nid[1]) ? $nid[1] : null;
810          }
811          else {
812               $this->id = $this->name = $nid;
813          }
814     }
815
816    /**
817     * setValue - sets field value
818     *
819     * @param mixed $value  field value.
820     * @param int   $offset value offset to define (default 0).
821     *
822     * @access public
823     */
824     public function setValue($value,$offset=0) {
825          $this->values[$offset] = $value;
826     }
827
828    /**
829     * setValues - set field values
830     *
831     * @param mixed $values the array of values. If not an array, the parameter
832     *                      will be converted to an array containing the value
833     *
834     * @access public
835     */
836     public function setValues($values) {
837          if (is_array($values)) {
838               $this->values = $values;
839          } elseif ($values !== NULL) {
840               $this->values = array($values);
841          }
842
843     }
844
845    /**
846     * getValues - return field values
847     *
848     * @access public
849     *
850     * @return mixed the array of values.
851     */
852     public function getValues() {
853          return $this->values;
854     }
855
856    /**
857     * getValue - retrieves a field value
858     *
859     * @param int $offset value offset (by default 1st value is returned).
860     *
861     * @access public
862     *
863     * @return mixed the field value.
864     */
865     public function getValue($offset=0) {
866          if (isset($this->values[$offset])) {
867               return $this->values[$offset];
868          }
869     }
870
871    /**
872     * addValue -- Adds a value to the field values.
873     *
874     * @param mixed $value Description.
875     *
876     * @access public
877     *
878     * @return mixed Value.
879     */
880     public function addValue($value) {
881          $this->values[] = $value;
882     }
883     public function delValue($offset) {
884          if (isset($this->values[$offset])) {
885               array_splice($this->values,$offset,1);
886          }
887     }
888
889    /**
890     * count -- returns the number of field values
891     *
892     * @access public
893     *
894     * @return integer the number of values.
895     */
896     public function count() {
897          return count($this->values);
898     }
899
900     public function __toString()
901     {
902          return join(',',$this->values);
903     }
904     
905     abstract public function getWidgetBlock();
906     
907
908    /**
909     * getAttributes - retrieve field attributes that will be given to the
910     *                   twig widget
911     *
912     * @param array $options extra options given to the widget
913     *
914     * @access public
915     *
916     * @return array the attributes.
917     */
918     public function getAttributes($options)
919     {
920          $offset = isset($options['offset']) ? $options['offset'] : 0;
921
922          $attr = $this->options->getArrayCopy();
923          if (isset($this->values[$offset])) {
924               $attr['value'] = $this->values[$offset];
925          } else {
926               $attr['value'] = $this->getDefaultValue();
927          }
928          if ($offset==0) {
929               $attr['id']=$this->id;
930          }
931          $attr['name'] = $this->name;
932          if ($this->multiple) {
933               $attr['name'] = $attr['name'].'[]';
934          }
935          return $attr;
936     }
937
938    /**
939     * getDefaultValue - returns field default value
940     *
941     * @access public
942     *
943     * @return mixed the field default value.
944     */
945     public function getDefaultValue() {
946          return '';
947     }
948
949    /**
950     * getName - returns field name
951     *
952     * @access public
953     *
954     * @return string the field name.
955     */
956     public function getName()
957     {
958          return $this->name;
959     }
960
961    /**
962     * setName - defines field name and/or field id
963     *
964     * @param mixed $name the field name or an array containing name and id.
965     *
966     * @access public
967     */
968     public function setName($name) {
969          $this->setNID($name);
970     }
971
972    /**
973     * check - checks whether the field is valid or not - raises an exception
974     *              if not valid
975     * @access public
976     */
977     public function check()
978     {
979          if (!$this->defined && $this->options['mandatory']) {
980               throw new InvalidFieldException(sprintf(
981                    'Field "%s" is mandatory',
982                    $this->attributes['label'])
983               );
984          }
985     }
986
987    /**
988     * parseValues - parses field value from context (GET or POST)
989     *                   and returns parsed value(s)
990     *                   NOTE : the field is not updated with this method
991     *                   use setup() to also update the field.
992     * @param mixed $from the context (usually $_GET or $_POST).
993     *
994     * @access public
995     *
996     * @return array the list of values (empty array if no value).
997     */
998     public function parseValues($from) {
999          if (isset($from[$this->name])) {
1000               $n = $from[$this->name];
1001               if (!is_array($n)) {
1002                    $n = array($n);
1003               }
1004               return $n;
1005          }
1006          return array();
1007     }
1008
1009    /**
1010     * setup - sets up the field from conetxt (GET or $POST)
1011     *
1012     * @param mixed $from the context (usually $_GET or $_POST).
1013     *
1014     * @access public
1015     *
1016     * @return mixed Value.
1017     */
1018     public function setup($from)
1019     {
1020          $values = $this->parseValues($from);
1021          if (count($values)) {
1022               $this->setValues($values);
1023               $this->defined = true;
1024          }
1025     }
1026
1027    /**
1028     * isDefined - returns whether the field is defined or not
1029     *                   (a field is defined if some values are set after setup())
1030     * @access public
1031     *
1032     * @return mixed Value.
1033     */
1034     public function isDefined()
1035     {
1036          return $this->defined;
1037     }
1038}
1039
1040
1041/**
1042 * Template form field of type "password"
1043 */
1044class dcFieldPassword extends dcField
1045{
1046     public function getWidgetBlock()
1047     {
1048          return "field_password";
1049     }
1050}
1051
1052/**
1053 * Template form field of type "text"
1054 */
1055class dcFieldText extends dcField
1056{
1057     public function getWidgetBlock()
1058     {
1059     return "field_text";
1060     }
1061}
1062
1063/**
1064 * Template form field of type "textarea"
1065 */
1066class dcFieldTextArea extends dcField
1067{
1068     public function getWidgetBlock()
1069     {
1070          return "field_textarea";
1071     }
1072}
1073
1074/**
1075 * Template form field of type "hidden"
1076 */
1077class dcFieldHidden extends dcField
1078{
1079     public function getWidgetBlock()
1080     {
1081          return "field_hidden";
1082     }
1083}
1084
1085/**
1086 * Template form field of type "checkbox"
1087 */
1088class dcFieldCheckbox extends dcField
1089{
1090     public function getWidgetBlock()
1091     {
1092          return "field_checkbox";
1093     }
1094
1095     public function getDefaultValue() {
1096          return 0;
1097     }
1098}
1099
1100/**
1101 * Template form action
1102 */
1103abstract class dcFieldAction extends dcField
1104{
1105     protected $action;
1106
1107     public function __construct($name,$values,$options=array())
1108     {
1109          parent::__construct($name,$values,$options);
1110
1111          if (isset($options['action'])) {
1112               $this->action = $options['action'];
1113          } else {
1114               $this->action = NULL;
1115          }
1116     }
1117
1118     public function getAction()
1119     {
1120          return $this->action;
1121     }
1122}
1123
1124/**
1125 * Template form field of type "submit"
1126 */
1127class dcFieldSubmit extends dcFieldAction
1128{
1129     public function getWidgetBlock()
1130     {
1131          return "field_submit";
1132     }
1133}
1134
1135/**
1136 * Template form field of type "combo"
1137 */
1138class dcFieldCombo extends dcField
1139{
1140     protected $combo;
1141
1142     public function __construct($name,$value,$combo,$options=array())
1143     {
1144          $this->combo = $combo;
1145          parent::__construct($name,$value,$options);
1146     }
1147
1148     public function getWidgetBlock()
1149     {
1150          return "field_combo";
1151     }
1152
1153     public function getDefaultValue() {
1154          return current($this->combo);
1155     }
1156
1157     public function parseValues($from) {
1158          $values = parent::parseValues($from);
1159          if (!is_array($values)) {
1160               $values = array($values);
1161          }
1162          foreach ($values as &$v) {
1163               if (!isset($this->combo[$v]))
1164               $v = $this->getDefaultValue();
1165          }
1166          return $values;
1167     }
1168
1169     public function getAttributes($options) {
1170          $attr = parent::getAttributes($options);
1171          $attr['options'] = $this->combo;
1172          return $attr;
1173     }
1174}
1175
1176?>
Note: See TracBrowser for help on using the repository browser.

Sites map