Completed
Push — master ( 1aee73...d60b75 )
by Shcherbak
05:52
created

Form::setMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
4
  namespace Fiv\Form;
5
6
  use Fiv\Form\Element;
7
  use Fiv\Form\Element\Submit;
8
9
  /**
10
   * @method Form setAction($action);
11
   * @method string|null getAction();
12
   *
13
   * @author Ivan Shcherbak <[email protected]>
14
   */
15
  class Form extends Element\Html {
16
17
    /**
18
     * @var null|string
19
     */
20
    protected $uid = null;
21
22
    /**
23
     * @var boolean|null
24
     */
25
    protected $validationResult = null;
26
27
    /**
28
     * @var array|null
29
     */
30
    protected $data = null;
31
32
    /**
33
     * @var Element\BaseElement[]
34
     */
35
    protected $elements = [];
36
37
    /**
38
     * Default form attributes
39
     *
40
     * @var array
41
     */
42
    protected $attributes = [
43
      'method' => 'post',
44
    ];
45
46
47
    /**
48
     * @param $name
49
     * @return $this
50
     */
51 6
    public function setName($name) {
52 6
      $this->uid = $name;
53 6
      $this->attributes['name'] = $name;
54 6
      return $this;
55
    }
56
57
58
    /**
59
     * @return array
60
     * @throws \Exception
61
     */
62 11
    public function getData() {
63 11
      if (!isset($this->data)) {
64 1
        throw new \Exception("Data does not exist!");
65
      }
66
67 10
      return $this->data;
68
    }
69
70
71
    /**
72
     * @param array|\Iterator $data
73
     * @throws \Exception
74
     */
75 11
    public function setData($data) {
76 11
      if ($data instanceof \Iterator) {
77
        $data = iterator_to_array($data);
78
      }
79
80 11
      if (!is_array($data)) {
81 1
        throw new \Exception('Data should be an array');
82
      }
83
84
85 10
      $this->cleanValidationFlag();
86
87 10
      foreach ($this->elements as $element) {
88 9
        $name = $element->getName();
89
90 9
        if ($element instanceof Checkbox) {
91
          $data[$name] = isset($data[$name]) ? 1 : 0;
92 9
        } elseif ($element instanceof CheckboxList) {
93
          $data[$name] = isset($data[$name]) ? $data[$name] : [];
94
        }
95
96 9
        if (array_key_exists($name, $data)) {
97 8
          $element->setValue($data[$name]);
98 9
          $data[$name] = $element->getValue();
99
        }
100
101
      }
102
103 10
      $this->data = $data;
104 10
    }
105
106
107
    /**
108
     * @return string
109
     */
110 2
    public function getMethod() {
111 2
      if (!empty($this->attributes['method'])) {
112 2
        return strtolower($this->attributes['method']);
113
      }
114
115 1
      return null;
116
    }
117
118
119
    /**
120
     * @param string $method
121
     * @return $this
122
     */
123 2
    public function setMethod($method) {
124 2
      $this->attributes['method'] = $method;
125
126 2
      return $this;
127
    }
128
129
130
    /**
131
     *
132
     */
133 17
    protected function cleanValidationFlag() {
134 17
      $this->validationResult = null;
135 17
    }
136
137
138
    /**
139
     * Check if form is submitted and all elements are valid
140
     *
141
     * @return boolean
142
     */
143 9
    public function isValid() {
144 9
      if ($this->validationResult !== null) {
145 1
        return $this->validationResult;
146
      }
147
148 9
      if (!$this->isSubmitted()) {
149 1
        return false;
150
      }
151
152 8
      $this->validationResult = true;
153 8
      foreach ($this->elements as $element) {
154 8
        if (!$element->validate()) {
155 8
          $this->validationResult = false;
156
        }
157
      }
158
159 8
      return $this->validationResult;
160
    }
161
162
163
    /**
164
     * Check if form is submitted
165
     *
166
     * @return bool
167
     */
168 11
    public function isSubmitted() {
169 11
      $data = $this->getData();
170
171 10
      return isset($data[$this->getUid()]);
172
    }
173
174
175
    /**
176
     * Return unique id of form
177
     *
178
     * @return string
179
     */
180 12
    public function getUid() {
181 12
      if (empty($this->uid)) {
182 10
        $this->uid = md5(get_called_class());
183
      }
184
185 12
      return $this->uid;
186
    }
187
188
189
    /**
190
     * @return Element\BaseElement[]
191
     */
192 4
    public function getElements() {
193 4
      return $this->elements;
194
    }
195
196
197
    /**
198
     * @param string $name
199
     * @param string|null $text
200
     * @return \Fiv\Form\Element\Input
201
     */
202 7
    public function input($name, $text = null) {
203 7
      $input = new Element\Input();
204 7
      $input->setName($name);
205 7
      $input->setText($text);
206 7
      $this->addElement($input);
207 7
      return $input;
208
    }
209
210
211
    /**
212
     * @param string $name
213
     * @param string|null $text
214
     * @return \Fiv\Form\Element\Input
215
     */
216
    public function password($name, $text = null) {
217
      $input = new Element\Password();
218
      $input->setName($name);
219
      $input->setText($text);
220
      $this->addElement($input);
221
      return $input;
222
    }
223
224
225
    /**
226
     * @param string $name
227
     * @param null $text
228
     * @return Select
229
     */
230
    public function select($name, $text = null) {
231
      $select = new Select();
232
      $select->setName($name);
233
      $select->setText($text);
234
      $this->addElement($select);
235
      return $select;
236
    }
237
238
239
    /**
240
     * @param        $name
241
     * @param string $text
242
     * @return RadioList
243
     */
244
    public function radioList($name, $text = null) {
245
      $radio = new RadioList();
246
      $radio->setName($name);
247
      $radio->setText($text);
248
      $this->addElement($radio);
249
      return $radio;
250
    }
251
252
253
    /**
254
     * @param string $name
255
     * @param null $text
256
     * @return TextArea
257
     */
258 3
    public function textarea($name, $text = null) {
259 3
      $input = new TextArea();
260 3
      $input->setName($name);
261 3
      $input->setText($text);
262 3
      $this->addElement($input);
263 3
      return $input;
264
    }
265
266
267
    /**
268
     * ```
269
     * $form->hidden('key', md5($this-user->id . HASH_A);
270
     * ```
271
     * @param string $name
272
     * @param null $value
273
     * @return \Fiv\Form\Element\Input
274
     */
275 2
    public function hidden($name, $value = null) {
276 2
      $hidden = new  \Fiv\Form\Element\Input();
277 2
      $hidden->setType('hidden');
278 2
      $hidden->setName($name);
279 2
      $hidden->setValue($value);
280 2
      $this->addElement($hidden);
281 2
      return $hidden;
282
    }
283
284
285
    /**
286
     * ```
287
     * $form->submit('register', 'зареєструватись');
288
     * ```
289
     * @param string $name
290
     * @param null $value
291
     * @return Submit
292
     */
293 1
    public function submit($name, $value = null) {
294 1
      $input = new Submit();
295 1
      $input->setName($name);
296 1
      $input->setValue($value);
297 1
      $this->addElement($input);
298 1
      return $input;
299
    }
300
301
302
    /**
303
     * ```
304
     * $form->checkbox('subscribe', 'Підписка на новини');
305
     * ```
306
     * @param string $name
307
     * @param string|null $label
308
     * @return Checkbox
309
     */
310
    public function checkbox($name, $label = null) {
311
      $checkbox = new Checkbox();
312
      $checkbox->setName($name);
313
      $checkbox->setLabel($label);
314
      $this->addElement($checkbox);
315
      return $checkbox;
316
    }
317
318
319
    /**
320
     * @param string $name
321
     * @param null $text
322
     * @return CheckboxList
323
     */
324
    public function checkboxList($name, $text = null) {
325
      $checkbox = new CheckboxList();
326
      $checkbox->setName($name);
327
      $checkbox->setText($text);
328
      $this->addElement($checkbox);
329
      return $checkbox;
330
    }
331
332
333
    /**
334
     * Attach element to this form. Overwrite element with same name
335
     *
336
     * @param Element\BaseElement $element
337
     * @return $this
338
     */
339 2
    public function setElement(Element\BaseElement $element) {
340 2
      $this->cleanValidationFlag();
341 2
      $this->elements[$element->getName()] = $element;
342 2
      return $this;
343
    }
344
345
346
    /**
347
     * @param Element\BaseElement $element
348
     * @return $this
349
     * @throws \Exception
350
     */
351 14
    public function addElement(Element\BaseElement $element) {
352 14
      if (isset($this->elements[$element->getName()])) {
353 1
        throw new \Exception('Element with name ' . $element->getName() . ' is already added. Use setElement to overwrite it or change name');
354
      }
355
356 14
      $this->cleanValidationFlag();
357 14
      $this->elements[$element->getName()] = $element;
358 14
      return $this;
359
    }
360
361
362
    /**
363
     * Render full form
364
     *
365
     * @return string
366
     */
367 1
    public function render() {
368 1
      return $this->renderStart() . $this->renderElements() . $this->renderEnd();
369
    }
370
371
372
    /**
373
     * You can easy rewrite this method for custom design of your forms
374
     *
375
     * @return string
376
     */
377 1
    protected function renderElements() {
378 1
      $formHtml = '<dl>';
379
380 1
      foreach ($this->elements as $element) {
381
        $formHtml .=
382
          '<dt>' . $element->getText() . '</dt>' .
383
          '<dd>' . $element->render() . '</dd>';
384
      }
385
386 1
      $formHtml .= '</dl>';
387 1
      return $formHtml;
388
    }
389
390
391
    /**
392
     * @return string
393
     */
394 1
    public function renderStart() {
395 1
      $hidden = new Element\Input();
396 1
      $hidden->setType('hidden');
397 1
      $hidden->addAttributes([
398 1
        'name' => $this->getUid(),
399
      ]);
400 1
      $hidden->setValue(1);
401
402
403
      # get default attribute
404 1
      $method = $this->getMethod();
405 1
      $this->setAttribute('method', $method);
406
407 1
      return '<form ' . $this->getAttributesAsString() . '>' . $hidden->render();
408
    }
409
410
411
    /**
412
     * @return string
413
     */
414 1
    public function renderEnd() {
415 1
      return '</form> ';
416
    }
417
418
  }