Test Failed
Push — master ( e6640f...7ed858 )
by Gabor
02:12
created

ServiceAdapter::getElements()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2018 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
declare(strict_types = 1);
13
14
namespace WebHemi\Form\ServiceAdapter\Base;
15
16
use JsonSerializable;
17
use RuntimeException;
18
use InvalidArgumentException;
19
use WebHemi\Form\ElementInterface;
20
use WebHemi\Form\ServiceInterface;
21
use WebHemi\StringLib;
22
23
/**
24
 * Class ServiceAdapter.
25
 */
26
class ServiceAdapter implements ServiceInterface, JsonSerializable
27
{
28
    /**
29
     * @var string
30
     */
31
    private $identifier = '';
32
    /**
33
     * @var string
34
     */
35
    private $name;
36
    /**
37
     * @var string
38
     */
39
    private $action;
40
    /**
41
     * @var string
42
     */
43
    private $method;
44
    /**
45
     * @var string
46
     */
47
    private $enctype;
48
    /**
49
     * @var array
50
     */
51
    private $formElements = [];
52 9
53
    /**
54 9
     * ServiceAdapter constructor.
55 9
     *
56 9
     * @param string $name
57 9
     * @param string $action
58
     * @param string $method
59
     * @param string $enctype
60
     */
61
    public function __construct(
62
        string $name = '',
63
        string $action = '',
64
        string $method = 'POST',
65
        string $enctype = 'application/x-www-form-urlencoded'
66
    ) {
67
        $this->name = $name;
68 1
        $this->action = $action;
69
        $this->method = $method;
70 1
        $this->enctype = $enctype;
71 1
72
        if (!empty($this->name)) {
73
            $this->name = StringLib::convertCamelCaseToUnderscore($name);
74 1
            $this->identifier = StringLib::convertNonAlphanumericToUnderscore($this->name);
75 1
        }
76 1
    }
77
78 1
    /**
79
     * Initializes the form if it didn't happen in the constructor. (Used mostly in presets).
80
     *
81
     * @param  string $name
82
     * @param  string $action
83
     * @param  string $method
84
     * @param string $enctype
85
     *
86 1
     * @throws RuntimeException
87
     * @return ServiceInterface
88 1
     */
89
    public function initialize(
90
        string $name = '',
91
        string $action = '',
92
        string $method = 'POST',
93
        string $enctype = 'application/x-www-form-urlencoded'
94
    ) : ServiceInterface {
95
        if (!empty($this->name) || !empty($this->action)) {
96 1
            throw new RuntimeException('The form had been already initialized!', 1000);
97
        }
98 1
99
        $this->name = StringLib::convertCamelCaseToUnderscore($name);
100
        $this->identifier = StringLib::convertNonAlphanumericToUnderscore($this->name);
101
        $this->action = $action;
102
        $this->method = $method;
103
        $this->enctype = $enctype;
104
105
        return $this;
106 1
    }
107
108 1
    /**
109
     * Gets form name.
110
     *
111
     * @return string
112
     */
113
    public function getName() : string
114
    {
115
        return $this->name;
116
    }
117
118 4
    /**
119
     * Gets form ID.
120 4
     *
121 4
     * @return string
122
     */
123 4
    public function getId() : string
124 1
    {
125 1
        return $this->identifier;
126 1
    }
127
128
    /**
129
     * Gets form action.
130 4
     *
131 4
     * @return string
132
     */
133 4
    public function getAction() : string
134
    {
135
        return $this->action;
136
    }
137
138
    /**
139
     * Gets form method.
140
     *
141
     * @return string
142
     */
143 1
    public function getMethod() : string
144
    {
145 1
        return $this->method;
146 1
    }
147 1
148
    /**
149 1
     * Gets form enctype.
150 1
     *
151 1
     * @return string
152 1
     */
153
    public function getEnctype() : string
154
    {
155
        return $this->enctype;
156 1
    }
157
158
    /**
159
     * Adds an element to the form.
160
     *
161
     * @param  ElementInterface $formElement
162
     * @throws InvalidArgumentException
163
     * @return ServiceInterface
164 4
     */
165
    public function addElement(ElementInterface $formElement) : ServiceInterface
166 4
    {
167
        $elementName = $formElement->getName();
168
        $elementName = $this->name.'['.$elementName.']';
169
170
        if (isset($this->formElements[$elementName])) {
171
            throw new InvalidArgumentException(
172
                sprintf('The element "%s" in field list is ambiguous.', $elementName),
173
                1001
174
            );
175 1
        }
176
177 1
        $formElement->setName($elementName);
178
        $this->formElements[$elementName] = $formElement;
179 1
180 1
        return $this;
181
    }
182
183
    /**
184 1
     * Returns an element
185
     *
186 1
     * @param  string $elementName
187 1
     * @throws InvalidArgumentException
188 1
     * @return ElementInterface
189
     */
190 1
    public function getElement(string $elementName) : ElementInterface
191
    {
192
        $elementNames = array_keys($this->formElements);
193
        $elementName = StringLib::convertNonAlphanumericToUnderscore($elementName);
194 1
        $matchingElementNames = preg_grep('/.*\['.$elementName.'\]/', $elementNames);
195
196
        if (empty($matchingElementNames)) {
197
            throw new InvalidArgumentException(
198
                sprintf('The element "%s" does not exist in this form.', $elementName),
199
                1002
200
            );
201
        }
202 1
203
        return $this->formElements[current($matchingElementNames)];
204 1
    }
205
206
    /**
207
     * Returns all the elements assigned.
208
     *
209
     * @return ElementInterface[]
210 1
     */
211 1
    public function getElements() : array
212
    {
213 1
        return $this->formElements;
214 1
    }
215
216
    /**
217
     * Loads data into the form.
218 1
     *
219
     * @param  array $data
220
     * @return ServiceInterface
221
     */
222
    public function loadData(array $data) : ServiceInterface
223
    {
224
        $formData = $data[$this->name] ?? [];
225
226 1
        foreach ($formData as $elementName => $elementValue) {
227
            $fullName = $this->name.'['.$elementName.']';
228
            /**
229 1
             * @var ElementInterface $formElement
230 1
             */
231 1
            $formElement = $this->formElements[$fullName] ?? null;
232
233
            if ($formElement) {
234
                if (!is_array($elementValue)) {
235
                    $elementValue = [$elementValue];
236
                }
237
                $formElement->setValues($elementValue);
238
            }
239
        }
240 1
241 1
        return $this;
242
    }
243 1
244
    /**
245 1
     * Validates the form.
246 1
     *
247
     * @return bool
248
     */
249
    public function validate() : bool
250 1
    {
251
        $isValid = true;
252
253
        /**
254
         * @var string $index
255
         * @var ElementInterface $formElement
256
         */
257
        foreach ($this->formElements as $index => $formElement) {
258
            $this->formElements[$index] = $formElement->validate();
259
260
            if (!empty($formElement->getErrors())) {
261
                $isValid = false;
262
            }
263
        }
264
265
        return $isValid;
266
    }
267
268
    /**
269
     * Defines the data which are presented during the json serialization.
270
     *
271
     * @return array
272
     */
273
    public function jsonSerialize() : array
274
    {
275
        $formData = [
276
            'name' => $this->name,
277
            'action' => $this->action,
278
            'method' => $this->method,
279
            'data' => [],
280
            'errors' => []
281
        ];
282
283
        /**
284
         * @var string $elementName
285
         * @var ElementInterface $formElement
286
         */
287
        foreach ($this->formElements as $formElement) {
288
            $formData['data'][$formElement->getId()] = $formElement->getValues();
289
290
            $errors = $formElement->getErrors();
291
292
            if (!empty($errors)) {
293
                $formData['errors'][$formElement->getId()] = $errors;
294
            }
295
        }
296
297
        return $formData;
298
    }
299
}
300