InputHandler::bind()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Linio\Component\Input;
6
7
use Linio\Component\Input\Exception\RequiredFieldException;
8
use Linio\Component\Input\Node\BaseNode;
9
10
abstract class InputHandler
0 ignored issues
show
Coding Style introduced by
InputHandler does not seem to conform to the naming convention (^Abstract|Factory$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
11
{
12
    /**
13
     * @var BaseNode
14
     */
15
    protected $root;
16
17
    /**
18
     * @var TypeHandler
19
     */
20
    protected $typeHandler;
21
22
    /**
23
     * @var array
24
     */
25
    protected $output = [];
26
27
    /**
28
     * @var array
29
     */
30
    protected $errors = [];
31
32
    public function __construct(TypeHandler $typeHandler = null)
33
    {
34
        $this->root = new BaseNode();
35
        $this->typeHandler = $typeHandler ?? new TypeHandler();
36
        $this->root->setTypeHandler($this->typeHandler);
37
    }
38
39
    public function add(string $key, string $type, array $options = []): BaseNode
40
    {
41
        return $this->root->add($key, $type, $options);
42
    }
43
44
    public function remove(string $key)
45
    {
46
        $this->root->remove($key);
47
    }
48
49
    public function getRoot(): BaseNode
50
    {
51
        return $this->root;
52
    }
53
54
    public function setRootType(string $type)
55
    {
56
        $this->root = $this->typeHandler->getType($type);
57
    }
58
59
    public function bind(array $input)
60
    {
61
        $this->define();
62
63
        try {
64
            $this->output = $this->root->getValue('root', $this->root->walk($input));
65
        } catch (RequiredFieldException $exception) {
66
            $this->errors[] = 'Missing required field: ' . $exception->getField();
67
        } catch (\RuntimeException $exception) {
68
            $this->errors[] = $exception->getMessage();
69
        }
70
    }
71
72
    public function getData($index = null)
73
    {
74
        if (!$this->isValid()) {
75
            throw new \RuntimeException($this->getErrorsAsString());
76
        }
77
78
        if ($index) {
79
            return $this->output[$index];
80
        }
81
82
        return $this->output;
83
    }
84
85
    public function hasData($index)
86
    {
87
        return isset($this->output[$index]);
88
    }
89
90
    public function isValid(): bool
91
    {
92
        return empty($this->errors);
93
    }
94
95
    public function getErrors(): array
96
    {
97
        return $this->errors;
98
    }
99
100
    public function getErrorsAsString(): string
101
    {
102
        return implode(', ', $this->errors);
103
    }
104
105
    abstract public function define();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
106
}
107