Completed
Push — master ( 8507e2...2d694e )
by Lars
01:39
created

AbstractTypeCheck::valueToString()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 9.4924

Importance

Changes 0
Metric Value
cc 8
nc 8
nop 1
dl 0
loc 33
ccs 10
cts 14
cp 0.7143
crap 9.4924
rs 8.1475
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arrayy\TypeCheck;
6
7
abstract class AbstractTypeCheck implements TypeCheckInterface
8
{
9
    /**
10
     * @var bool
11
     */
12
    protected $isNullable = false;
13
14
    /**
15
     * @var array
16
     */
17
    protected $types = [];
18
19
    /**
20
     * @var array
21
     */
22
    private static $typeMapping = [
23
        'int'   => 'integer',
24
        'bool'  => 'boolean',
25
        'float' => 'double',
26
    ];
27
28
    /**
29
     * @return array
30
     */
31 25
    public function getTypes(): array
32
    {
33 25
        return $this->types;
34
    }
35
36
    /**
37
     * @param mixed $value
38
     *
39
     * @return bool
40
     */
41 81
    public function checkType(&$value): bool
42
    {
43 81
        if ($this->isNullable && $value === null) {
44 11
            return true;
45
        }
46
47 81
        foreach ($this->types as $currentType) {
48 81
            $isValidType = $this->assertTypeEquals($currentType, $value);
49
50 81
            if ($isValidType) {
51 79
                return true;
52
            }
53
        }
54
55 25
        $type = \gettype($value);
56
57 25
        $expectedTypes = \implode('|', $this->getTypes());
58
59 25
        $this->throwException($expectedTypes, $value, $type);
60
61
        return false;
62
    }
63
64
    /**
65
     * @param string $type
66
     * @param mixed  $value
67
     *
68
     * @return bool
69
     */
70 81
    protected function assertTypeEquals(string $type, &$value): bool
71
    {
72 81
        if (\strpos($type, '[]') !== false) {
73 14
            return $this->isValidGenericCollection($type, $value);
74
        }
75
76 81
        if ($type === 'mixed' && $value !== null) {
77 4
            return true;
78
        }
79
80 81
        return $value instanceof $type
81
               ||
82 81
               \gettype($value) === (self::$typeMapping[$type] ?? $type);
83
    }
84
85
    /**
86
     * @param mixed $value
87
     *
88
     * @return string
89
     */
90 4
    protected function valueToString($value): string
91
    {
92
        // null
93 4
        if ($value === null) {
94
            return 'NULL';
95
        }
96
97
        // bool
98 4
        if (\is_bool($value)) {
99
            return $value ? 'TRUE' : 'FALSE';
100
        }
101
102
        // array
103 4
        if (\is_array($value)) {
104 1
            return 'Array';
105
        }
106
107
        // scalar types (integer, float, string)
108 3
        if (\is_scalar($value)) {
109 2
            return (string) $value;
110
        }
111
112
        // resource
113 1
        if (\is_resource($value)) {
114
            return \get_resource_type($value) . ' resource #' . (int) $value;
115
        }
116
117 1
        if (\is_object($value)) {
118 1
            return \get_class($value) . ' Object';
119
        }
120
121
        return '';
122
    }
123
124
    /**
125
     * @param string $type
126
     * @param mixed  $collection
127
     *
128
     * @return bool
129
     */
130 14
    private function isValidGenericCollection(string $type, &$collection): bool
131
    {
132 14
        if (!\is_array($collection)) {
133 1
            return false;
134
        }
135
136 13
        $valueType = \str_replace('[]', '', $type);
137
138 13
        foreach ($collection as $value) {
139 13
            if (!$this->assertTypeEquals($valueType, $value)) {
140 2
                return false;
141
            }
142
        }
143
144 11
        return true;
145
    }
146
}
147