1 <?php
2
3 /**
4 * Class for var casting.
5 *
6 * @author gharlan
7 *
8 * @package redaxo\core
9 */
10 class rex_type
11 {
12 /**
13 * Casts the variable $var to $vartype.
14 *
15 * Possible types:
16 * - 'bool' (or 'boolean')
17 * - 'int' (or 'integer')
18 * - 'double'
19 * - 'string'
20 * - 'float'
21 * - 'real'
22 * - 'object'
23 * - 'array'
24 * - 'array[<type>]', e.g. 'array[int]'
25 * - '' (don't cast)
26 * - a callable
27 * - array(
28 * array(<key>, <vartype>, <default>),
29 * array(<key>, <vartype>, <default>),
30 * ...
31 * )
32 *
33 * @param mixed $var Variable to cast
34 * @param mixed $vartype Variable type
35 *
36 * @throws InvalidArgumentException
37 *
38 * @return mixed Castet value
39 */
40 public static function cast($var, $vartype)
41 {
42 if (is_string($vartype)) {
43 $casted = true;
44 switch ($vartype) {
45 // ---------------- PHP types
46 case 'bool':
47 case 'boolean':
48 $var = (bool) $var;
49 break;
50 case 'int':
51 case 'integer':
52 $var = (int) $var;
53 break;
54 case 'double':
55 $var = (float) $var;
56 break;
57 case 'float':
58 case 'real':
59 $var = (float) $var;
60 break;
61 case 'string':
62 $var = (string) $var;
63 break;
64 case 'object':
65 $var = (object) $var;
66 break;
67 case 'array':
68 if ('' === $var) {
69 $var = [];
70 } else {
71 $var = (array) $var;
72 }
73 break;
74
75 // kein Cast, nichts tun
76 case '': break;
77
78 default:
79 // check for array with generic type
80 if (strpos($vartype, 'array[') === 0) {
81 if (empty($var)) {
82 $var = [];
83 } else {
84 $var = (array) $var;
85 }
86
87 // check if every element in the array is from the generic type
88 $matches = [];
89 if (preg_match('@array\[([^\]]*)\]@', $vartype, $matches)) {
90 foreach ($var as $key => $value) {
91 try {
92 $var[$key] = self::cast($value, $matches[1]);
93 } catch (InvalidArgumentException $e) {
94 // Evtl Typo im vartype, mit urspr. typ als fehler melden
95 throw new InvalidArgumentException('Unexpected vartype "' . $vartype . '" in cast()!');
96 }
97 }
98 } else {
99 throw new InvalidArgumentException('Unexpected vartype "' . $vartype . '" in cast()!');
100 }
101 } else {
102 $casted = false;
103 }
104 }
105 if ($casted) {
106 return $var;
107 }
108 }
109
110 if (is_callable($vartype)) {
111 $var = call_user_func($vartype, $var);
112 } elseif (is_array($vartype)) {
113 $var = self::cast($var, 'array');
114 $newVar = [];
115 foreach ($vartype as $cast) {
116 if (!is_array($cast) || !isset($cast[0])) {
117 throw new InvalidArgumentException('Unexpected vartype in cast()!');
118 }
119 $key = $cast[0];
120 $innerVartype = isset($cast[1]) ? $cast[1] : '';
121 if (array_key_exists($key, $var)) {
122 $newVar[$key] = self::cast($var[$key], $innerVartype);
123 } elseif (!isset($cast[2])) {
124 $newVar[$key] = self::cast('', $innerVartype);
125 } else {
126 $newVar[$key] = $cast[2];
127 }
128 }
129 $var = $newVar;
130 } elseif (is_string($vartype)) {
131 throw new InvalidArgumentException('Unexpected vartype "' . $vartype . '" in cast()!');
132 } else {
133 throw new InvalidArgumentException('Unexpected vartype in cast()!');
134 }
135
136 return $var;
137 }
138 }
139