Passed
Push — master ( d26101...1eb4af )
by Gabor
03:11
created

AbstractForm   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 19
c 0
b 0
f 0
lcom 1
cbo 3
dl 0
loc 228
ccs 60
cts 60
cp 1
rs 10

16 Methods

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