Dotclear

source: inc/admin/class.dc.form.php @ 1053:96e69ef76fc9

Revision 1053:96e69ef76fc9, 8.6 KB checked in by Dsls <dsls@…>, 13 years ago (diff)
  • Added page errors & informations in context and default layout page.
  • Added submit actions and hidden fields.
  • cleaned up code in admin/post.php, all actions need to be recoded.
Line 
1<?php
2
3
4class dcFormNode extends Twig_Node {
5    public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
6    {
7        parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
8    }
9
10    /**
11     * Compiles the node to PHP.
12     *
13     * @param Twig_Compiler A Twig_Compiler instance
14     */
15    public function compile(Twig_Compiler $compiler)
16    {
17        $compiler
18            ->addDebugInfo($this)
19            ->write("\$context['dc_form']->beginForm('".
20                $this->getAttribute('name')."');\n")
21            ->subcompile($this->getNode('body'))
22            ->write("\$context['dc_form']->renderHiddenWidgets();\n")
23            ->write("\$context['dc_form']->endForm();\n")
24        ;
25    }
26
27}
28
29class dcFormTokenParser extends Twig_TokenParser {
30
31     public function parse(Twig_Token $token) {
32        $lineno = $token->getLine();
33        $stream = $this->parser->getStream();
34        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
35        $stream->expect(Twig_Token::BLOCK_END_TYPE);
36        $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
37        $stream->expect(Twig_Token::BLOCK_END_TYPE);
38        return new dcFormNode ($name, $body, $token->getLine(), $this->getTag());
39     }
40
41     public function decideBlockEnd(Twig_Token $token)
42    {
43        return $token->test('endform');
44    }
45
46
47    public function getTag()
48    {
49        return 'form';
50    }
51
52}
53
54class dcFormExtension extends Twig_Extension {
55     protected $template;
56     protected $tpl;
57     protected $core;
58     protected $twig;
59     protected $blocks;
60     protected $forms;
61     protected $currentForm;
62
63     public function __construct($core){
64          $this->core = $core;
65          $this->tpl = 'form_layout.html.twig';
66          $this->forms = array();
67          $this->currentForm = null;
68     }
69
70    public function initRuntime(Twig_Environment $environment)
71    {
72     $this->twig = $environment;
73          $this->template = $this->twig->loadTemplate($this->tpl);
74     $this->blocks = $this->template->getBlocks();
75    }
76
77    public function getGlobals() {
78     return array('dc_form' => $this);
79    }
80
81     public function getFunctions() {
82          return array(
83               'form_field' => new Twig_Function_Method($this, 'renderWidget', array('is_safe' => array('html'))),
84            '_form_is_choice_group'    => new \Twig_Function_Method($this, 'isChoiceGroup', array('is_safe' => array('html'))),
85            '_form_is_choice_selected' => new \Twig_Function_Method($this, 'isChoiceSelected', array('is_safe' => array('html')))
86
87          );
88     }
89
90     public function isChoiceGroup($choice) {
91          return is_array($choice);
92     }
93     public function isChoiceSelected($choice,$value) {
94          return $choice == $value;
95
96     }
97
98     public function getTokenParsers() {
99          return array(new dcFormTokenParser());
100     }
101
102     public function renderWidget($name,$attributes=array()) {
103          $field = $this->currentForm->$name;
104          if ($field) {
105               echo $this->template->renderBlock(
106                    $field->getWidgetBlock(),
107                    array_merge($field->getAttributes(),array('attr'=>$attributes)),
108                    $this->blocks);
109          }
110     }
111
112     public function renderHiddenWidgets() {
113          foreach ($this->currentForm->getHiddenFields() as $h) {
114               $this->renderWidget($h->getName());
115          }
116     }
117
118     public function getName() {
119          return 'dc_form';
120     }
121
122     public function addForm(dcForm $form) {
123          $this->forms[$form->getName()]=$form;
124     }
125
126     public function beginForm($name) {
127          if (isset($this->forms[$name])) {
128               $this->currentForm = $this->forms[$name];
129               $this->currentForm->begin();
130          } else {
131               throw new Twig_Error_Runtime("Form '".$name."' does not exist");
132          }
133     }
134     public function endForm() {
135          $this->currentForm->end();
136          $this->currentForm = null;
137     }
138
139}
140
141class InvalidFieldException extends Exception {
142}
143
144
145class dcForm {
146     protected $name;
147     protected $core;
148     protected $action;
149     protected $fields;
150     protected $method;
151     protected $submitfields;
152     protected $hiddenfields;
153     protected $errors;
154     
155     private function addNonce() {
156          $this->addField(new dcFieldHidden(array('xd_check'), $this->core->getNonce()));
157     }
158     
159     public function __construct($core,$name,$action, $method='POST') {
160          $this->core = $core;
161          $this->name = $name;
162          $this->method = $method;
163          $this->action = $action;
164          $this->fields = array();
165          $this->core->page->getExtension('dc_form')->addForm($this);
166          $this->submitfields = array();
167          $this->hiddenfields = array();
168          $this->errors = array();
169          if ($method == 'POST') {
170               $this->addNonce();
171          }
172     }
173
174     public function getName() {
175          return $this->name;
176     }
177
178     public function getErrors() {
179          return $this->errors;
180     }
181     
182     public function addField(dcField $f) {
183         
184          if ($f instanceof dcFieldAction) {
185               $this->submitfields[$f->getName()]=$f;
186          }
187          if ($f instanceof dcFieldHidden) {
188               $this->hiddenfields[$f->getName()]=$f;
189          }
190
191          $this->fields[$f->getName()]=$f;
192          return $this;
193     }
194
195     public function begin() {
196          echo '<form method="'.$this->method.'" action="'.$this->action.'">';
197     }
198
199     public function end() {
200          echo '</form>';
201     }
202
203
204    public function __isset($name) {
205          return isset($this->fields[$name]);
206    }
207
208    public function __get($name) {
209          if (isset($this->fields[$name])) {
210               return $this->fields[$name];
211          } else {
212               return null;
213          }
214    }
215
216    public function __set($name,$value) {
217          if (isset($this->fields[$name])) {
218               $this->fields[$name]->setAttribute('value',$value);
219          }
220    }
221
222     public function isSubmitted() {
223          $from = ($this->method == 'POST')?$_POST:$_GET;
224          echo "form fields :\n";
225     }
226     
227     public function setup() {
228          $from = ($this->method=='POST')?$_POST:$_GET;
229          foreach ($this->fields as $f) {
230               $f->setup($from);
231          }
232          foreach ($this->submitfields as $f) {
233               if ($f->isDefined()) {
234                    $ret = call_user_func ($f->getAction(),$this);
235                    return;
236               }
237          }
238     }
239     
240     public function check() {
241          foreach ($this->fields as $f) {
242               try {
243                    $f->check();
244               } catch (InvalidFieldException $e) {
245                    $this->errors[]=$e->getMessage();
246               }
247          }
248     }
249     
250     public function getHiddenFields() {
251          return $this->hiddenfields;
252     }
253     
254}
255
256abstract class dcField {
257     protected $attributes;
258     protected $name;
259     protected $value;
260     protected $id;
261     protected $defined;
262     
263     protected function getNID($nid) {
264          if (is_array($nid)) {
265               $this->name = $nid[0];
266               $this->id = !empty($nid[1]) ? $nid[1] : null;
267          } else {
268               $this->id = $this->name = $nid;
269          }
270     }
271
272     public function __construct($name, $value, $attributes = array()) {
273          $this->getNID($name);
274          $this->attributes = $attributes;
275          $this->value = $value;
276          $this->attributes['name'] = $this->name;
277          $this->attributes['id'] = $this->id;
278          $this->attributes['value'] = $this->value;
279          $this->defined = false;
280
281     }
282
283     abstract public function getWidgetBlock();
284
285     public function setAttribute ($name,$value) {
286          $this->attributes[$name] = $value;
287     }
288
289     public function getAttributes() {
290          return $this->attributes;
291
292     }
293
294     public function getName(){
295          return $this->name;
296     }
297
298     public function check() {
299          if (!$this->defined && $this->attributes['defined']) {
300               throw new InvalidFieldException(sprintf('Field "%s" is mandatory'),$this->attributes['label']);
301          }
302
303     }
304     
305     public function setup($from) {
306          if (isset($from[$this->id])) {
307               $this->value = $from[$this->id];
308               $this->defined = true;
309          }
310     }
311     
312     public function isDefined() {
313          return $this->defined;
314     }
315     
316}
317
318
319class dcFieldText extends dcField {
320
321     public function getWidgetBlock() {
322          return "field_text";
323     }
324
325}
326
327class dcFieldTextArea extends dcField {
328
329     public function getWidgetBlock() {
330          return "field_textarea";
331     }
332
333}
334
335class dcFieldHidden extends dcField {
336
337     public function getWidgetBlock() {
338          return "field_hidden";
339     }
340
341}
342
343class dcFieldCheckbox extends dcField {
344
345     public function getWidgetBlock() {
346          return "field_checkbox";
347     }
348
349}
350
351abstract class dcFieldAction extends dcField {
352     protected $action;
353     public function __construct($name, $value, $attributes = array()) {
354          parent::__construct($name, $value, $attributes);
355          if (isset($attributes['action'])) {
356               $this->action = $attributes['action'];
357          }
358     }
359     public function getAction() {
360          return $this->action;
361     }
362}
363
364class dcFieldSubmit extends dcFieldAction {
365
366     public function getWidgetBlock() {
367          return "field_submit";
368     }
369
370}
371
372class dcFieldCombo extends dcField {
373     protected $options;
374
375     public function __construct($name, $value, $options, $attributes = array()) {
376          $this->options = $options;
377          parent::__construct($name,$value,$attributes);
378          $this->attributes['options']=$options;
379     }
380
381     public function getWidgetBlock() {
382          return "field_combo";
383     }
384
385}
386
387?>
Note: See TracBrowser for help on using the repository browser.

Sites map