Completed
Push — master ( 38a590...33903f )
by Shcherbak
06:56
created

Form::setData()   D

Complexity

Conditions 9
Paths 24

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 9.4453

Importance

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