Passed
Branch master (30ae21)
by Gabor
03:15
created

AbstractForm::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 5.6
6
 *
7
 * @copyright 2012 - 2016 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
namespace WebHemi\Form;
13
14
use Iterator;
15
use WebHemi\Form\Element\NestedElementInterface;
16
use WebHemi\Form\Traits\CamelCaseToUnderScoreTrait;
17
use WebHemi\Form\Traits\IteratorTrait;
18
19
/**
20
 * Class AbstractForm
21
 */
22
abstract class AbstractForm implements FormInterface, Iterator
23
{
24
    /** @var NestedElementInterface */
25
    protected $form;
26
    /** @var string */
27
    protected $salt;
28
29
    // The implementation of the Iterator interface.
30
    use IteratorTrait;
31
    // CamelCase to under_score converter
32
    use CamelCaseToUnderScoreTrait;
33
34
    /**
35
     * AbstractForm constructor.
36
     *
37
     * @param string $name
38
     * @param string $action
39
     * @param string $method
40
     */
41 8
    final public function __construct($name = '', $action = '', $method = 'POST')
42
    {
43 8
        if (empty($name)) {
44 1
            $name = $this->camelCaseToUnderscore(get_called_class());
45 1
        }
46
47 8
        $this->form = $this->getFormContainer();
48 8
        $this->form->setName($name)
49 8
            ->setAttributes(
50
                [
51 8
                    'action' => $action,
52 8
                    'method' => strtoupper($method)
53 8
                ]
54 8
            );
55
56
        // For simplicity in rendering (twig macro), we store it in an array.
57 8
        $this->nodes[0] =& $this->form;
58
        // Set a default salt for the form name. If the AutoComplete attribute is 'off', it will be added to the form's
59
        // name attribute. The default salt will change every hour.
60 8
        $this->salt = md5(gmdate('YmdH'));
61
62 8
        $this->initForm();
63 8
    }
64
65
    /**
66
     * Returns the form container element. E.g.: for HTML forms it is the <form> tag.
67
     *
68
     * @return NestedElementInterface
69
     */
70
    abstract protected function getFormContainer();
71
72
    /**
73
     * Initialize form.
74
     *
75
     * @return void
76
     */
77
    abstract protected function initForm();
78
79
    /**
80
     * Sets form name.
81
     *
82
     * @param string $name
83
     * @return FormInterface
84
     */
85 2
    public function setName($name)
86
    {
87 2
        $this->form->setName($name);
88
89 2
        $formAttributes = $this->form->getAttributes();
90
91 2
        if (isset($formAttributes['autocomplete'])) {
92 1
            $this->setAutoComplete($formAttributes['autocomplete']);
93 1
        }
94 2
    }
95
96
    /**
97
     * Gets form name.
98
     *
99
     * @return string
100
     */
101 3
    public function getName()
102
    {
103 3
        return $this->form->getName();
104
    }
105
106
    /**
107
     * Set unique identifier for the form.
108
     *
109
     * @param string $salt
110
     * @return AbstractForm
111
     */
112 3
    public function setNameSalt($salt)
113
    {
114 3
        $this->salt = md5($salt);
115
116 3
        return $this;
117
    }
118
119
    /**
120
     * Sets form action.
121
     *
122
     * @param string $action
123
     * @return AbstractForm
124
     */
125 1
    final public function setAction($action)
126
    {
127 1
        $this->setAttribute('action', $action);
128
129 1
        return $this;
130
    }
131
132
    /**
133
     * Sets form submit.
134
     *
135
     * @param string $method
136
     * @return AbstractForm
137
     */
138 1
    final public function setMethod($method = 'POST')
139
    {
140 1
        $this->setAttribute('method', $method);
141
142 1
        return $this;
143
    }
144
145
    /**
146
     * Sets form encoding type.
147
     *
148
     * @param string $encodingType
149
     * @return AbstractForm
150
     */
151 1
    final protected function setEnctype($encodingType = 'application/x-www-form-urlencoded')
152
    {
153 1
        $this->setAttribute('enctype', $encodingType);
154
155 1
        return $this;
156
    }
157
158
    /**
159
     * Sets form auto-complete option.
160
     *
161
     * @param bool $autoComplete
162
     * @return AbstractForm
163
     */
164 3
    final public function setAutoComplete($autoComplete = true)
165
    {
166 3
        $name = $this->form->getName(false);
167 3
        $md5Match = [];
168
169
        // Search for the unique form prefix.
170 3
        preg_match('/^[a-z0-9\_\-\[\]]+\_(?P<md5>[a-f0-9]{32}).*$/', $name, $md5Match);
171
172
        // When it's necessary, add/remove the salt to/from the name
173 3
        if ($autoComplete && !empty($md5Match)) {
174 1
            $name = str_replace('_'.$md5Match['md5'], '', $name);
175 3
        } elseif (!$autoComplete && empty($md5Match)) {
176 3
            $name = $name.'_'.$this->salt;
177 3
        }
178
179 3
        $this->form->setName($name);
180
181 3
        $this->setAttribute('autocomplete', $autoComplete);
182
183 3
        return $this;
184
    }
185
186
    /**
187
     * Sets specific form attributes.
188
     *
189
     * @param $name
190
     * @param $value
191
     */
192 4
    private function setAttribute($name, $value)
193
    {
194 4
        $attributes = $this->form->getAttributes();
195 4
        $attributes[$name] = $value;
196
197 4
        $this->form->setAttributes($attributes);
198 4
    }
199
200
    /**
201
     * Adds a form element to the form.
202
     *
203
     * @param array<FormElementInterface> $nodes
204
     * @return AbstractForm
205
     */
206 8
    protected function setNodes(array $nodes)
207
    {
208 8
        $this->form->setNodes($nodes);
209
210 8
        return $this;
211
    }
212
213
    /**
214
     * Gets the form elements.
215
     *
216
     * @return array<FormElementInterface>
217
     */
218 1
    protected function getNodes()
219
    {
220 1
        return $this->form->getNodes();
221
    }
222
223
    /**
224
     * Validates the form.
225
     *
226
     * @param bool $reValidate
227
     * @return bool
228
     */
229 2
    public function isValid($reValidate = false)
230
    {
231 2
        return $this->form->isValid($reValidate);
232
    }
233
234
    /**
235
     * Gets validation errors.
236
     *
237
     * @return array
238
     */
239 1
    public function getErrors()
240
    {
241 1
        return $this->form->getErrors();
242
    }
243
244
    /**
245
     * Sets form data.
246
     *
247
     * @param array $data
248
     * @return FormInterface
249
     */
250 1
    public function setData(array $data)
251
    {
252 1
        if (isset($data[$this->form->getName()])) {
253 1
            $data = $data[$this->form->getName()];
254 1
        }
255
256 1
        $this->form->setValue($data);
257
258 1
        return $this;
259
    }
260
261
    /**
262
     * Returns the form data.
263
     *
264
     * @return array
265
     */
266 1
    public function getData()
267
    {
268 1
        return $this->form->getValue();
269
    }
270
}
271