Passed
Push — master ( 042e95...d37488 )
by Chris
02:46
created

FormSubmissionManager::processField()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2.0023

Importance

Changes 0
Metric Value
cc 2
eloc 12
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 18
ccs 11
cts 12
cp 0.9167
crap 2.0023
rs 9.8666
1
<?php
2
3
namespace WebTheory\Saveyour\Controllers;
4
5
use Psr\Http\Message\ServerRequestInterface;
6
use WebTheory\Saveyour\Contracts\FieldOperationCacheInterface;
7
use WebTheory\Saveyour\Contracts\FormDataProcessorInterface;
8
use WebTheory\Saveyour\Contracts\FormFieldControllerInterface;
9
use WebTheory\Saveyour\Contracts\FormFieldRepositoryInterface;
10
use WebTheory\Saveyour\Contracts\FormProcessingCacheInterface;
11
use WebTheory\Saveyour\Contracts\FormSubmissionManagerInterface;
12
use WebTheory\Saveyour\Contracts\FormValidatorInterface;
13
use WebTheory\Saveyour\Request;
14
15
class FormSubmissionManager implements FormSubmissionManagerInterface
16
{
17
    /**
18
     * Array of FormFieldControllerInterface instances
19
     *
20
     * @var FormFieldControllerInterface[]
21
     */
22
    protected $fields = [];
23
24
    /**
25
     * @var FormFieldRepositoryInterface
26
     */
27
    protected $fieldRepository;
28
29
    /**
30
     * Array of FormDataProcessorInterface instances
31
     *
32
     * @var FormDataProcessorInterface[]
33
     */
34
    protected $processors = [];
35
36
    /**
37
     * Array of form FormValidatorInterface instances
38
     *
39
     * @var FormValidatorInterface[]
40
     */
41
    protected $validators = [];
42
43
    /**
44
     * @var FieldOperationCacheInterface[]
45
     */
46
    protected $results = [];
47
48
    /**
49
     * Array of alerts to display in after form submission
50
     *
51
     * @var string[]
52
     */
53
    protected $alerts = [];
54
55
    /**
56
     * Get the value of validators
57
     *
58
     * @return mixed
59
     */
60 6
    public function getValidators()
61
    {
62 6
        return $this->validators;
63
    }
64
65
    /**
66
     * Set array of form FormValidatorInterface instances
67
     *
68
     * @param array $validators Array of form FormValidatorInterface instances
69
     *
70
     * @return self
71
     */
72 9
    public function setValidators(array $validators)
73
    {
74 9
        $this->validators = [];
75
76 9
        foreach ($validators as $rule => $validator) {
77
78 9
            if (is_array($validator)) {
79 3
                $alert = $validator['alert'] ?? null;
80 3
                $validator = $validator['validator'];
81
            }
82
83 9
            $this->addValidator($rule, $validator, $alert ?? null);
84
        }
85
86 9
        return $this;
87
    }
88
89
    /**
90
     *
91
     */
92 18
    public function addValidator(string $rule, FormValidatorInterface $validator, ?string $alert = null)
93
    {
94 18
        $this->validators[$rule] = $validator;
95
96 18
        if ($alert) {
97 6
            $this->addAlert($rule, $alert);
98
        }
99
100 18
        return $this;
101
    }
102
103
    /**
104
     * Get array of alerts to display in after form submission
105
     *
106
     * @return string[]
107
     */
108 6
    public function getAlerts(): array
109
    {
110 6
        return $this->alerts;
111
    }
112
113
    /**
114
     *
115
     */
116 6
    public function getAlert(string $rule): string
117
    {
118 6
        return $this->alerts[$rule];
119
    }
120
121
    /**
122
     * Set array of alerts to display in after form submission
123
     *
124
     * @param string[] $alert Array of alerts to display in after form submission
125
     *
126
     * @return self
127
     */
128 3
    public function setAlerts(array $alerts)
129
    {
130 3
        $this->alerts = [];
131
132 3
        foreach ($alerts as $rule => $alert) {
133 3
            $this->addAlert($rule, $alert);
134
        }
135 3
    }
136
137
    /**
138
     *
139
     */
140 12
    public function addAlert(string $rule, string $alert)
141
    {
142 12
        $this->alerts[$rule] = $alert;
143
144 12
        return $this;
145
    }
146
147
    /**
148
     * Get the value of fields
149
     *
150
     * @return mixed
151
     */
152 6
    public function getFields()
153
    {
154 6
        return $this->fields;
155
    }
156
157
    /**
158
     * Set the value of fields
159
     *
160
     * @param FormFieldControllerInterface[] $fields
161
     *
162
     * @return self
163
     */
164 9
    public function setFields(FormFieldControllerInterface ...$fields)
165
    {
166 9
        $this->fields = $fields;
167
168 9
        return $this;
169
    }
170
171
    /**
172
     * @param FormFieldControllerInterface $field
173
     */
174 6
    public function addField(FormFieldControllerInterface $field)
175
    {
176 6
        $this->fields[] = $field;
177
178 6
        return $this;
179
    }
180
181
    /**
182
     * Get the value of fieldRepository
183
     *
184
     * @return FormFieldRepositoryInterface
185
     */
186
    public function getFieldRepository(): FormFieldRepositoryInterface
187
    {
188
        return $this->fieldRepository;
189
    }
190
191
    /**
192
     * Set the value of fieldRepository
193
     *
194
     * @param FormFieldRepositoryInterface $fieldRepository
195
     *
196
     * @return self
197
     */
198
    public function setFieldRepository(FormFieldRepositoryInterface $fieldRepository)
199
    {
200
        $this->fieldRepository = $fieldRepository;
201
202
        return $this;
203
    }
204
205
    /**
206
     * Get the value of groups
207
     *
208
     * @return array
209
     */
210 6
    public function getProcessors(): array
211
    {
212 6
        return $this->processors;
213
    }
214
215
    /**
216
     * Set the value of groups
217
     *
218
     * @param FormDataProcessorInterface[] $processors
219
     *
220
     * @return self
221
     */
222 3
    public function setProcessors(FormDataProcessorInterface ...$processors)
223
    {
224 3
        $this->processors = $processors;
225
226 3
        return $this;
227
    }
228
229
    /**
230
     * Add a group
231
     *
232
     * @param string $groups
233
     *
234
     * @return self
235
     */
236 6
    public function addProcessor(FormDataProcessorInterface $processor)
237
    {
238 6
        $this->processors[] = $processor;
239
240 6
        return $this;
241
    }
242
243
    /**
244
     *
245
     */
246 12
    public function process(ServerRequestInterface $request): FormProcessingCacheInterface
247
    {
248 12
        $cache = new FormProcessingCache();
249
250 12
        if ($this->isSafe($request, $cache)) {
251 9
            $this->processFields($request, $cache);
252 9
            $this->runProcessors($request, $cache);
253 9
            $this->processResults($request, $cache);
254
        }
255
256 12
        return $cache;
257
    }
258
259
    /**
260
     *
261
     */
262 12
    protected function isSafe(ServerRequestInterface $request, FormProcessingCache $cache): bool
263
    {
264 12
        $violations = [];
265
266 12
        foreach ($this->validators as $rule => $validator) {
267 3
            if (!$validator->isValid($request)) {
268 3
                $violations[$rule] = $this->alerts[$rule] ?? '';
269
            }
270
        }
271
272 12
        $cache->withRequestViolations($violations);
273
274 12
        return empty($violations);
275
    }
276
277
    /**
278
     *
279
     */
280 9
    protected function sortFieldsForProcessing()
281
    {
282
        usort($this->fields, function (FormFieldControllerInterface $a, FormFieldControllerInterface $b) {
283
            // because usort will not compare values that it infers from
284
            // previous comparisons to be equal, 0 should never be returned. all
285
            // that matters is that dependent fields are positioned after their
286
            // dependencies.
287 6
            return in_array($a->getRequestVar(), $b->mustAwait()) ? -1 : 1;
288 9
        });
289 9
    }
290
291
    /**
292
     *
293
     */
294 9
    protected function fieldPresentInRequest(FormFieldControllerInterface $field, ServerRequestInterface $request): bool
295
    {
296 9
        return Request::has($request, $field->getRequestVar());
297
    }
298
299
    /**
300
     *
301
     */
302 9
    protected function processFields(ServerRequestInterface $request, FormProcessingCache $cache)
303
    {
304 9
        $inputResults = [];
305 9
        $inputViolations = [];
306
307 9
        $this->sortFieldsForProcessing();
308
309 9
        foreach ($this->fields as $field) {
310 9
            $name = $field->getRequestVar();
311 9
            $results = $this->processField($field, $request);
312
313 9
            $inputResults[$name] = $results;
314 9
            $inputViolations[$name] = $results->ruleViolations();
315
        }
316
317 9
        $cache->withInputResults($inputResults);
318 9
        $cache->withInputViolations(array_filter($inputViolations));
319
320 9
        return $this;
321
    }
322
323
    /**
324
     *
325
     */
326 9
    protected function processField(FormFieldControllerInterface $field, ServerRequestInterface $request): FieldOperationCacheInterface
327
    {
328 9
        $requestVarPresent = $this->fieldPresentInRequest($field, $request);
329
330 9
        if ($requestVarPresent) {
331 9
            $base = $field->process($request);
332 9
            $results = new FieldOperationCache(
333 9
                true,
334 9
                $base->sanitizedInputValue(),
335 9
                $base->updateAttempted(),
336 9
                $base->updateSuccessful(),
337 9
                $base->ruleViolations()
338
            );
339
        } else {
340
            $results = new FieldOperationCache(false, null, false, false, []);
341
        }
342
343 9
        return $results;
344
    }
345
346
    /**
347
     *
348
     */
349 9
    protected function runProcessors(ServerRequestInterface $request, FormProcessingCache $cache)
350
    {
351 9
        $fields = $cache->inputResults();
352 9
        $responses = [];
353
354 9
        foreach ($this->processors as $processor) {
355 3
            $results = [];
356
357 3
            foreach ($processor->getFields() as $field) {
358 3
                $results[$field] = $fields[$field];
359
            }
360
361 3
            $responses[] = $processor->process($request, $results);
362
        }
363
364 9
        $cache->withProcessingResults(array_filter($responses));
365
366 9
        return $this;
367
    }
368
369
    /**
370
     *
371
     */
372 9
    protected function processResults(ServerRequestInterface $request, FormProcessingCache $cache)
0 ignored issues
show
Unused Code introduced by
The parameter $cache is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

372
    protected function processResults(ServerRequestInterface $request, /** @scrutinizer ignore-unused */ FormProcessingCache $cache)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

372
    protected function processResults(/** @scrutinizer ignore-unused */ ServerRequestInterface $request, FormProcessingCache $cache)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
373
    {
374 9
        return $this;
375
    }
376
}
377