TypeHandler::isScalarCollectionType()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Linio\Component\Input;
6
7
use Linio\Component\Input\Instantiator\InstantiatorInterface;
8
use Linio\Component\Input\Instantiator\SetInstantiator;
9
use Linio\Component\Input\Node\BaseNode;
10
use Linio\Component\Input\Node\BoolNode;
11
use Linio\Component\Input\Node\CollectionNode;
12
use Linio\Component\Input\Node\DateTimeNode;
13
use Linio\Component\Input\Node\FloatNode;
14
use Linio\Component\Input\Node\IntNode;
15
use Linio\Component\Input\Node\NumericNode;
16
use Linio\Component\Input\Node\ObjectNode;
17
use Linio\Component\Input\Node\ScalarCollectionNode;
18
use Linio\Component\Input\Node\StringNode;
19
20
class TypeHandler
21
{
22
    /**
23
     * @var array
24
     */
25
    protected $types;
26
27
    /**
28
     * @var InstantiatorInterface
29
     */
30
    protected $defaultInstantiator;
31
32
    public function __construct()
33
    {
34
        $this->types = [
35
            'bool' => BoolNode::class,
36
            'int' => IntNode::class,
37
            'float' => FloatNode::class,
38
            'double' => FloatNode::class,
39
            'numeric' => NumericNode::class,
40
            'string' => StringNode::class,
41
            'array' => BaseNode::class,
42
            'object' => ObjectNode::class,
43
            'datetime' => DateTimeNode::class,
44
        ];
45
46
        $this->defaultInstantiator = new SetInstantiator();
47
    }
48
49
    public function addType(string $name, string $class)
50
    {
51
        $this->types[$name] = $class;
52
    }
53
54
    public function getType(string $name): BaseNode
55
    {
56
        if (isset($this->types[$name])) {
57
            $type = new $this->types[$name]();
58
            $type->setTypeAlias($name);
59
            $type->setTypeHandler($this);
60
61
            return $type;
62
        }
63
64
        if ($this->isScalarCollectionType($name)) {
65
            $type = new ScalarCollectionNode();
66
            $type->setType($this->getCollectionType($name));
67
            $type->setTypeAlias($name);
68
            $type->setTypeHandler($this);
69
70
            return $type;
71
        }
72
73 View Code Duplication
        if ($this->isClassType($name)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74
            $type = new ObjectNode();
75
            $type->setType($name);
76
            $type->setTypeAlias('object');
77
            $type->setTypeHandler($this);
78
            $type->setInstantiator($this->defaultInstantiator);
79
80
            return $type;
81
        }
82
83 View Code Duplication
        if ($this->isCollectionType($name)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
            $type = new CollectionNode();
85
            $type->setType($this->getCollectionType($name));
86
            $type->setTypeAlias('object[]');
87
            $type->setTypeHandler($this);
88
            $type->setInstantiator($this->defaultInstantiator);
89
90
            return $type;
91
        }
92
93
        throw new \InvalidArgumentException('Unknown type name: ' . $name);
94
    }
95
96
    protected function isClassType(string $type): bool
97
    {
98
        return (class_exists($type) || interface_exists($type)) && $type != 'datetime';
99
    }
100
101
    protected function isCollectionType(string $type): bool
102
    {
103
        $collectionType = $this->getCollectionType($type);
104
105
        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...
106
            return false;
107
        }
108
109
        return true;
110
    }
111
112
    protected function isScalarCollectionType(string $type): bool
113
    {
114
        $collectionType = $this->getCollectionType($type);
115
116
        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...
117
            return false;
118
        }
119
120
        return true;
121
    }
122
123
    protected function getCollectionType(string $type): string
124
    {
125
        $pos = strrpos($type, '[]');
126
127
        if ($pos === false) {
128
            return $type;
129
        }
130
131
        return substr($type, 0, $pos);
132
    }
133
}
134