a6a021774a593aeff4302e55d231bd438b50be08
[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 */
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|Tx_[a-zA-Z0-9_]+|[A-Z][a-zA-Z0-9\\\\_]+|object|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage|Tx_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 static protected $collectionTypes = array('array', 'ArrayObject', 'SplObjectStorage', 'TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage', 'Tx_Extbase_Persistence_ObjectStorage');
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 static public function parseType($type) {
44 $matches = array();
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 array(
54 'type' => $type,
55 'elementType' => $elementType
56 );
57 } else {
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 /**
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 static public function normalizeType($type) {
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 boolean
91 */
92 static public function isLiteral($type) {
93 return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
94 }
95
96 /**
97 * Returns TRUE if the $type is a simple type.
98 *
99 * @param string $type
100 * @return boolean
101 */
102 static public function isSimpleType($type) {
103 return in_array(self::normalizeType($type), array('array', 'string', 'float', 'integer', 'boolean'), TRUE);
104 }
105
106 /**
107 * Returns TRUE if the $type is a CMS core type object.
108 *
109 * @param string $type
110 * @return boolean
111 */
112 static public function isCoreType($type) {
113 return is_subclass_of($type, 'TYPO3\\CMS\\Core\\Type\\TypeInterface');
114 }
115
116 /**
117 * Returns TRUE if the $type is a collection type.
118 *
119 * @param string $type
120 * @return boolean
121 */
122 static public function isCollectionType($type) {
123 if (in_array($type, self::$collectionTypes, TRUE)) {
124 return TRUE;
125 }
126
127 if (class_exists($type) === TRUE || interface_exists($type) === TRUE) {
128 foreach (self::$collectionTypes as $collectionType) {
129 if (is_subclass_of($type, $collectionType) === TRUE) {
130 return TRUE;
131 }
132 }
133 }
134
135 return FALSE;
136 }
137
138 /**
139 * Converts a hex encoded string into binary data
140 *
141 * @param string $hexadecimalData A hex encoded string of data
142 * @return string A binary string decoded from the input
143 */
144 static public function hex2bin($hexadecimalData) {
145 $binaryData = '';
146 $length = strlen($hexadecimalData);
147 for ($i = 0; $i < $length; $i += 2) {
148 $binaryData .= pack('C', hexdec(substr($hexadecimalData, $i, 2)));
149 }
150 return $binaryData;
151 }
152 }