9d1c98664f60b57db6b3a8f32d43bb732a6a08f2
[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 */
17 class TypeHandlingUtility
18 {
19 /**
20 * A property type parse pattern.
21 */
22 const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTime|Tx_[a-zA-Z0-9_]+|[A-Z][a-zA-Z0-9\\\\_]+|object|resource|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage)(?:<\\\\?(?P<elementType>[a-zA-Z0-9\\\\_]+)>)?/';
23
24 /**
25 * A type pattern to detect literal types.
26 */
27 const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
28
29 /**
30 * @var array
31 */
32 protected static $collectionTypes = ['array', 'ArrayObject', 'SplObjectStorage', \TYPO3\CMS\Extbase\Persistence\ObjectStorage::class];
33
34 /**
35 * Returns an array with type information, including element type for
36 * collection types (array, SplObjectStorage, ...)
37 *
38 * @param string $type Type of the property (see PARSE_TYPE_PATTERN)
39 * @return array An array with information about the type
40 * @throws \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException
41 */
42 public static function parseType($type)
43 {
44 $matches = [];
45 if (preg_match(self::PARSE_TYPE_PATTERN, $type, $matches)) {
46 $type = self::normalizeType($matches['type']);
47 $elementType = isset($matches['elementType']) ? self::normalizeType($matches['elementType']) : null;
48
49 if ($elementType !== null && !self::isCollectionType($type)) {
50 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);
51 }
52
53 return [
54 'type' => $type,
55 'elementType' => $elementType
56 ];
57 }
58 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);
59 }
60
61 /**
62 * Normalize data types so they match the PHP type names:
63 * int -> integer
64 * double -> float
65 * bool -> boolean
66 *
67 * @param string $type Data type to unify
68 * @return string unified data type
69 */
70 public static function normalizeType($type)
71 {
72 switch ($type) {
73 case 'int':
74 $type = 'integer';
75 break;
76 case 'bool':
77 $type = 'boolean';
78 break;
79 case 'double':
80 $type = 'float';
81 break;
82 }
83 return $type;
84 }
85
86 /**
87 * Returns TRUE if the $type is a literal.
88 *
89 * @param string $type
90 * @return bool
91 */
92 public static function isLiteral($type)
93 {
94 return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
95 }
96
97 /**
98 * Returns TRUE if the $type is a simple type.
99 *
100 * @param string $type
101 * @return bool
102 */
103 public static function isSimpleType($type)
104 {
105 return in_array(self::normalizeType($type), ['array', 'string', 'float', 'integer', 'boolean'], true);
106 }
107
108 /**
109 * Returns TRUE if the $type is a CMS core type object.
110 *
111 * @param string|object $type
112 * @return bool
113 */
114 public static function isCoreType($type)
115 {
116 return is_subclass_of($type, \TYPO3\CMS\Core\Type\TypeInterface::class);
117 }
118
119 /**
120 * Returns TRUE if the $type is a collection type.
121 *
122 * @param string $type
123 * @return bool
124 */
125 public static function isCollectionType($type)
126 {
127 if (in_array($type, self::$collectionTypes, true)) {
128 return true;
129 }
130
131 if (class_exists($type) === true || interface_exists($type) === true) {
132 foreach (self::$collectionTypes as $collectionType) {
133 if (is_subclass_of($type, $collectionType) === true) {
134 return true;
135 }
136 }
137 }
138
139 return false;
140 }
141
142 /**
143 * Returns TRUE when the given value can be used in an "in" comparison in a query.
144 *
145 * @param mixed $value
146 * @return bool
147 */
148 public static function isValidTypeForMultiValueComparison($value)
149 {
150 return is_array($value) || $value instanceof \Traversable;
151 }
152
153 /**
154 * Converts a hex encoded string into binary data
155 *
156 * @param string $hexadecimalData A hex encoded string of data
157 * @return string A binary string decoded from the input
158 */
159 public static function hex2bin($hexadecimalData)
160 {
161 $binaryData = '';
162 $length = strlen($hexadecimalData);
163 for ($i = 0; $i < $length; $i += 2) {
164 $binaryData .= pack('C', hexdec(substr($hexadecimalData, $i, 2)));
165 }
166 return $binaryData;
167 }
168 }