Test Failed
Push — master ( 539796...4ba9a1 )
by Gabor
04:03
created

ServiceAdapter::jsonSerialize()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

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