Completed
Push — master ( 39d3cf...40a686 )
by Gabor
05:31
created

AbstractForm::setAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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