Completed
Push — master ( e6e5ff...3738e1 )
by
unknown
30:28 queued 15:43
created

TypeHandlingUtility::hex2bin()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Extbase\Utility;
19
20
use TYPO3\CMS\Core\Type\TypeInterface;
21
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
22
use TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException;
23
24
/**
25
 * PHP type handling functions
26
 * @internal only to be used within Extbase, not part of TYPO3 Core API.
27
 */
28
class TypeHandlingUtility
29
{
30
    /**
31
     * A property type parse pattern.
32
     */
33
    const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTimeImmutable|DateTime|[A-Z][a-zA-Z0-9\\\\]+|object|resource|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage)(?:<\\\\?(?P<elementType>[a-zA-Z0-9\\\\]+)>)?/';
34
35
    /**
36
     * A type pattern to detect literal types.
37
     */
38
    const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
39
40
    /**
41
     * @var array
42
     */
43
    protected static $collectionTypes = ['array', \ArrayObject::class, \SplObjectStorage::class, ObjectStorage::class];
44
45
    /**
46
     * Returns an array with type information, including element type for
47
     * collection types (array, SplObjectStorage, ...)
48
     *
49
     * @param string $type Type of the property (see PARSE_TYPE_PATTERN)
50
     * @return array An array with information about the type
51
     * @throws \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException
52
     */
53
    public static function parseType(string $type): array
54
    {
55
        $matches = [];
56
        if (preg_match(self::PARSE_TYPE_PATTERN, $type, $matches)) {
57
            $type = self::normalizeType($matches['type']);
58
            $elementType = isset($matches['elementType']) ? self::normalizeType($matches['elementType']) : null;
59
60
            if ($elementType !== null && !self::isCollectionType($type)) {
61
                throw new InvalidTypeException('Found an invalid element type declaration in %s. Type "' . $type . '" must not have an element type hint (' . $elementType . ').', 1264093642);
62
            }
63
64
            return [
65
                'type' => $type,
66
                'elementType' => $elementType
67
            ];
68
        }
69
        throw new InvalidTypeException('Found an invalid element type declaration in %s. A type "' . var_export($type, true) . '" does not exist.', 1264093630);
70
    }
71
72
    /**
73
     * Normalize data types so they match the PHP type names:
74
     *  int -> integer
75
     *  double -> float
76
     *  bool -> boolean
77
     *
78
     * @param string $type Data type to unify
79
     * @return string unified data type
80
     */
81
    public static function normalizeType(string $type): string
82
    {
83
        switch ($type) {
84
            case 'int':
85
                $type = 'integer';
86
                break;
87
            case 'bool':
88
                $type = 'boolean';
89
                break;
90
            case 'double':
91
                $type = 'float';
92
                break;
93
        }
94
        return $type;
95
    }
96
97
    /**
98
     * Returns TRUE if the $type is a literal.
99
     *
100
     * @param string $type
101
     * @return bool
102
     */
103
    public static function isLiteral(string $type): bool
104
    {
105
        return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
106
    }
107
108
    /**
109
     * Returns TRUE if the $type is a simple type.
110
     *
111
     * @param string $type
112
     * @return bool
113
     */
114
    public static function isSimpleType(string $type): bool
115
    {
116
        return in_array(self::normalizeType($type), ['array', 'string', 'float', 'integer', 'boolean'], true);
117
    }
118
119
    /**
120
     * Returns TRUE if the $type is a CMS core type object.
121
     *
122
     * @param string|object $type
123
     * @return bool
124
     */
125
    public static function isCoreType($type): bool
126
    {
127
        return is_subclass_of($type, TypeInterface::class);
128
    }
129
130
    /**
131
     * Returns TRUE if the $type is a collection type.
132
     *
133
     * @param string $type
134
     * @return bool
135
     */
136
    public static function isCollectionType(string $type): bool
137
    {
138
        if (in_array($type, self::$collectionTypes, true)) {
139
            return true;
140
        }
141
142
        if (class_exists($type) === true || interface_exists($type) === true) {
143
            foreach (self::$collectionTypes as $collectionType) {
144
                if (is_subclass_of($type, $collectionType) === true) {
145
                    return true;
146
                }
147
            }
148
        }
149
150
        return false;
151
    }
152
153
    /**
154
     * Returns TRUE when the given value can be used in an "in" comparison in a query.
155
     *
156
     * @param mixed $value
157
     * @return bool
158
     */
159
    public static function isValidTypeForMultiValueComparison($value): bool
160
    {
161
        return is_iterable($value);
162
    }
163
}
164