Completed
Push — master ( 1d0993...a92c21 )
by Klaus
03:01
created

TypeHandler::isInputHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Linio\Component\Input;
5
6
use Linio\Component\Input\Instantiator\InstantiatorInterface;
7
use Linio\Component\Input\Instantiator\SetInstantiator;
8
use Linio\Component\Input\Node\BaseNode;
9
use Linio\Component\Input\Node\BoolNode;
10
use Linio\Component\Input\Node\CollectionNode;
11
use Linio\Component\Input\Node\DateTimeNode;
12
use Linio\Component\Input\Node\FloatNode;
13
use Linio\Component\Input\Node\IntNode;
14
use Linio\Component\Input\Node\NumericNode;
15
use Linio\Component\Input\Node\ObjectNode;
16
use Linio\Component\Input\Node\ScalarCollectionNode;
17
use Linio\Component\Input\Node\StringNode;
18
19
class TypeHandler
20
{
21
    /**
22
     * @var array
23
     */
24
    protected $types;
25
26
    /**
27
     * @var InstantiatorInterface
28
     */
29
    protected $defaultInstantiator;
30
31
    public function __construct()
32
    {
33
        $this->types = [
34
            'bool' => BoolNode::class,
35
            'int' => IntNode::class,
36
            'float' => FloatNode::class,
37
            'double' => FloatNode::class,
38
            'numeric' => NumericNode::class,
39
            'string' => StringNode::class,
40
            'array' => BaseNode::class,
41
            'object' => ObjectNode::class,
42
            'datetime' => DateTimeNode::class,
43
        ];
44
45
        $this->defaultInstantiator = new SetInstantiator();
46
    }
47
48
    public function addType(string $name, string $class)
49
    {
50
        $this->types[$name] = $class;
51
    }
52
53
    public function getType(string $name): BaseNode
54
    {
55
        if (isset($this->types[$name])) {
56
            $type = new $this->types[$name]();
57
            $type->setTypeHandler($this);
58
59
            return $type;
60
        }
61
62
        if ($this->isScalarCollectionType($name)) {
63
            $type = new ScalarCollectionNode();
64
            $type->setType($this->getCollectionType($name));
65
            $type->setTypeHandler($this);
66
67
            return $type;
68
        }
69
70
        if ($this->isClassType($name)) {
71
            $type = new ObjectNode();
72
            $type->setType($name);
73
            $type->setTypeHandler($this);
74
            $type->setInstantiator($this->defaultInstantiator);
75
76
            return $type;
77
        }
78
79
        if ($this->isCollectionType($name)) {
80
            $type = new CollectionNode();
81
            $type->setType($this->getCollectionType($name));
82
            $type->setTypeHandler($this);
83
            $type->setInstantiator($this->defaultInstantiator);
84
85
            return $type;
86
        }
87
88
        throw new \InvalidArgumentException('Unknown type name: ' . $name);
89
    }
90
91
    protected function isClassType(string $type): bool
92
    {
93
        return (class_exists($type) || interface_exists($type)) && $type != 'datetime';
94
    }
95
96
    protected function isCollectionType(string $type): bool
97
    {
98
        $collectionType = $this->getCollectionType($type);
99
100
        if (!class_exists($collectionType)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return class_exists($collectionType);.
Loading history...
101
            return false;
102
        }
103
104
        return true;
105
    }
106
107
    protected function isScalarCollectionType(string $type): bool
108
    {
109
        $collectionType = $this->getCollectionType($type);
110
111
        if (!function_exists('is_' . $collectionType)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return function_exists('is_' . $collectionType);.
Loading history...
112
            return false;
113
        }
114
115
        return true;
116
    }
117
118
    protected function getCollectionType(string $type): string
119
    {
120
        $pos = strrpos($type, '[]');
121
122
        if ($pos === false) {
123
            return $type;
124
        }
125
126
        return substr($type, 0, $pos);
127
    }
128
}
129