Completed
Push — master ( effe34...d8cca3 )
by Kirill
10s
created

Declaration::getTypesFromDeclaration()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 7
nc 4
nop 1
1
<?php
2
/**
3
 * This file is part of Properties package.
4
 *
5
 * @author Serafim <[email protected]>
6
 * @date 14.04.2016 13:29
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Serafim\Properties\Support;
12
13
/**
14
 * Class Declaration
15
 * @package Serafim\Properties\Support
16
 */
17
class Declaration
18
{
19
    /**
20
     * @var array|string[]
21
     */
22
    private $types = [];
23
24
    /**
25
     * @var string
26
     */
27
    private $field;
28
29
    /**
30
     * @var string
31
     */
32
    private $access;
33
34
    /**
35
     * @var string
36
     */
37
    private $originalTypesDeclaration = '';
38
39
    /**
40
     * Declaration constructor.
41
     * @param string $types
42
     * @param string $field
43
     * @param string $accessType
44
     */
45
    public function __construct($types, $field, $accessType = Parser::ACCESS_BOTH)
46
    {
47
        $this->originalTypesDeclaration = trim($types);
48
        $this->types = $this->getTypesFromDeclaration($this->originalTypesDeclaration);
49
        $this->field = $field;
50
        $this->access = $accessType;
51
    }
52
53
    /**
54
     * @param string $originalTypesDeclaration
55
     * @return array
56
     */
57
    private function getTypesFromDeclaration($originalTypesDeclaration)
58
    {
59
        $types = explode('|', mb_strtolower($originalTypesDeclaration));
60
61
        // Some[] to array
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
62
        foreach ($types as $typeKey => $typeName) {
63
            $types[$typeKey] = preg_replace("/(.+)\[\]/i", "array", $typeName);
64
        }
65
66
        // Some<Type> to Some
67
        foreach ($types as $typeKey => $typeName) {
68
            $types[$typeKey] = preg_replace("/(.+)\<(.+)\>/i", "$1", $typeName);
69
        }
70
71
        return $types;
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    public function getAvailableTypes()
78
    {
79
        return $this->originalTypesDeclaration;
80
    }
81
82
    /**
83
     * @param string $type
84
     * @return bool
85
     */
86
    public function typeOf($type)
87
    {
88
89
        if ($this->inTypesArray($type)) {
90
            return true;
91
        }
92
93
        $typeAliases = $this->getVarTypeAliases($type);
94
95
        foreach ($typeAliases as $typeAliase) {
96
            if ($this->inTypesArray($typeAliase)) {
97
                return true;
98
            }
99
        }
100
101
        return $this->classOf($type);
102
    }
103
104
    /**
105
     * @param $type
106
     * @return bool
107
     */
108
    private function inTypesArray($type)
109
    {
110
        return in_array(mb_strtolower($type), $this->types, true);
111
    }
112
113
    /**
114
     * @param $typeName
115
     * @return array
116
     */
117
    private function getVarTypeAliases($typeName)
118
    {
119
        $typeName = strtolower($typeName);
120
121
        $types = [
122
            'integer'  => [
123
                'int',
124
            ],
125
            'boolean'  => [
126
                'bool',
127
            ],
128
            'closure'  => [
129
                'callable',
130
            ],
131
            'double'   => [
132
                'float',
133
            ],
134
            'string'   => [],
135
            'null'     => [],
136
            'resource' => [],
137
        ];
138
139
        return isset($types[$typeName]) ? $types[$typeName] : [];
140
    }
141
142
    /**
143
     * @param string $type
144
     * @return bool
145
     */
146
    private function classOf($type)
147
    {
148
        foreach ($this->types as $class) {
149
            if (is_subclass_of($type, $class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if $class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
150
                return true;
151
            }
152
        }
153
154
        return false;
155
    }
156
157
    /**
158
     * @return bool
159
     */
160
    public function isReadable()
161
    {
162
        return $this->access === Parser::ACCESS_READ || $this->access === Parser::ACCESS_BOTH;
163
    }
164
165
    /**
166
     * @return bool
167
     */
168
    public function isWritable()
169
    {
170
        return $this->access === Parser::ACCESS_WRITE || $this->access === Parser::ACCESS_BOTH;
171
    }
172
173
    /**
174
     * @return string
175
     */
176
    public function getName()
177
    {
178
        return $this->field;
179
    }
180
}
181