Completed
Push — master ( 15d409...38a590 )
by Shcherbak
05:57 queued 13s
created

Form::submit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 7
rs 9.4285
c 1
b 0
f 0
ccs 6
cts 6
cp 1
cc 1
eloc 6
nc 1
nop 2
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
   * @method Form setMethod($method)
14
   *
15
   * @author Ivan Shcherbak <[email protected]>
16
   */
17
  class Form extends Element\Html {
18
19
    /**
20
     * @var null
21
     */
22
    protected $uid = null;
23
24
    /**
25
     * @var mixed
26
     */
27
    protected $validResultCache = 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->flushCacheFlags();
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] : array();
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']) == 'post') {
114 1
        return 'post';
115
      } else {
116 1
        return 'get';
117
      }
118
    }
119
120
121
    /**
122
     *
123
     */
124 13
    protected function flushCacheFlags() {
125 13
      $this->validResultCache = 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->validResultCache !== null) {
136
        return $this->validResultCache;
137
      }
138
139 7
      if (!$this->isSubmitted()) {
140 1
        return false;
141
      }
142
143 6
      $this->validResultCache = true;
144 6
      foreach ($this->elements as $element) {
145 6
        if (!$element->validate()) {
146 6
          $this->validResultCache = false;
147
        }
148
      }
149
150 6
      return $this->validResultCache;
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());
0 ignored issues
show
Documentation Bug introduced by
It seems like md5(get_called_class()) of type string is incompatible with the declared type null of property $uid.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
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        $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        $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
     * Connect element to block and to form
219
     *
220
     * @param Element\Base $element
221
     * @return $this
222
     */
223 12
    protected function setElement(\Fiv\Form\Element\Base $element) {
224 12
      $this->flushCacheFlags();
225 12
      $this->elements[$element->getName()] = $element;
226 12
      return $this;
227
    }
228
229
230
    /**
231
     * @param      $name
232
     * @param null $text
233
     * @return Select
234
     */
235
    public function select($name, $text = null) {
236
      $select = new Select();
237
      $select->setName($name);
238
      $select->setText($text);
239
      $this->setElement($select);
240
      return $select;
241
    }
242
243
244
    /**
245
     * @param        $name
246
     * @param string $text
247
     * @return RadioList
248
     */
249
    public function radioList($name, $text = null) {
250
      $radio = new RadioList();
251
      $radio->setName($name);
252
      $radio->setText($text);
253
      $this->setElement($radio);
254
      return $radio;
255
    }
256
257
258
    /**
259
     * @param      $name
260
     * @param null $text
261
     * @return TextArea
262
     */
263 3
    public function textarea($name, $text = null) {
264 3
      $input = new TextArea();
265 3
      $input->setName($name);
266 3
      $input->setText($text);
267 3
      $this->setElement($input);
268 3
      return $input;
269
    }
270
271
272
    /**
273
     * ```
274
     * $form->hidden('key', md5($this-user->id . HASH_A);
275
     * ```
276
     * @param      $name
277
     * @param null $value
278
     * @return \Fiv\Form\Element\Input
279
     */
280 2
    public function hidden($name, $value = null) {
281 2
      $hidden = new  \Fiv\Form\Element\Input();
282 2
      $hidden->setType('hidden');
283 2
      $hidden->setName($name);
284 2
      $hidden->setValue($value);
285 2
      $this->setElement($hidden);
286 2
      return $hidden;
287
    }
288
289
290
    /**
291
     * ```
292
     * $form->submit('register', 'зареєструватись');
293
     * ```
294
     * @param      $name
295
     * @param null $value
296
     * @return Submit
297
     */
298 1
    public function submit($name, $value = null) {
299 1
      $input = new Submit();
300 1
      $input->setName($name);
301 1
      $input->setValue($value);
302 1
      $this->setElement($input);
303 1
      return $input;
304
    }
305
306
307
    /**
308
     * ```
309
     * $form->checkbox('subscribe', 'Підписка на новини');
310
     * ```
311
     * @param string $name
312
     * @param string|null $label
313
     * @return Checkbox
314
     */
315
    public function checkbox($name, $label = null) {
316
      $checkbox = new Checkbox();
317
      $checkbox->setName($name);
318
      $checkbox->setLabel($label);
319
      $this->setElement($checkbox);
320
      return $checkbox;
321
    }
322
323
324
    /**
325
     * @param string $name
326
     * @param null $text
327
     * @return CheckboxList
328
     */
329
    public function checkboxList($name, $text = null) {
330
      $checkbox = new CheckboxList();
331
      $checkbox->setName($name);
332
      $checkbox->setText($text);
333
      $this->setElement($checkbox);
334
      return $checkbox;
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(array(
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
  }