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