TYPO3 CMS  TYPO3_6-2
ObjectAccess.php
Go to the documentation of this file.
1 <?php
3 
17 
26 class ObjectAccess {
27 
28  const ACCESS_GET = 0;
29 
30  const ACCESS_SET = 1;
31 
32  const ACCESS_PUBLIC = 2;
33 
53  static public function getProperty($subject, $propertyName, $forceDirectAccess = FALSE) {
54  if (!is_object($subject) && !is_array($subject)) {
55  throw new \InvalidArgumentException('$subject must be an object or array, ' . gettype($subject) . ' given.', 1237301367);
56  }
57  if (!is_string($propertyName) && (!is_array($subject) && !$subject instanceof \ArrayAccess)) {
58  throw new \InvalidArgumentException('Given property name is not of type string.', 1231178303);
59  }
60  $propertyExists = FALSE;
61  $propertyValue = self::getPropertyInternal($subject, $propertyName, $forceDirectAccess, $propertyExists);
62  if ($propertyExists === TRUE) {
63  return $propertyValue;
64  }
65  throw new \TYPO3\CMS\Extbase\Reflection\Exception\PropertyNotAccessibleException('The property "' . $propertyName . '" on the subject was not accessible.', 1263391473);
66  }
67 
84  static public function getPropertyInternal($subject, $propertyName, $forceDirectAccess, &$propertyExists) {
85  if ($subject === NULL || is_scalar($subject)) {
86  return NULL;
87  }
88  $propertyExists = TRUE;
89  if (is_array($subject)) {
90  if (array_key_exists($propertyName, $subject)) {
91  return $subject[$propertyName];
92  }
93  $propertyExists = FALSE;
94  return NULL;
95  }
96  if ($forceDirectAccess === TRUE) {
97  if (property_exists(get_class($subject), $propertyName)) {
98  $propertyReflection = new \TYPO3\CMS\Extbase\Reflection\PropertyReflection(get_class($subject), $propertyName);
99  return $propertyReflection->getValue($subject);
100  } elseif (property_exists($subject, $propertyName)) {
101  return $subject->{$propertyName};
102  } else {
103  throw new \TYPO3\CMS\Extbase\Reflection\Exception\PropertyNotAccessibleException('The property "' . $propertyName . '" on the subject does not exist.', 1302855001);
104  }
105  }
106  if ($subject instanceof \SplObjectStorage || $subject instanceof \TYPO3\CMS\Extbase\Persistence\ObjectStorage) {
107  if (MathUtility::canBeInterpretedAsInteger($propertyName)) {
108  $index = 0;
109  foreach ($subject as $value) {
110  if ($index === (int)$propertyName) {
111  return $value;
112  }
113  $index++;
114  }
115  $propertyExists = FALSE;
116  return NULL;
117  }
118  } elseif ($subject instanceof \ArrayAccess && isset($subject[$propertyName])) {
119  return $subject[$propertyName];
120  }
121  $getterMethodName = 'get' . ucfirst($propertyName);
122  if (is_callable(array($subject, $getterMethodName))) {
123  return $subject->{$getterMethodName}();
124  }
125  $getterMethodName = 'is' . ucfirst($propertyName);
126  if (is_callable(array($subject, $getterMethodName))) {
127  return $subject->{$getterMethodName}();
128  }
129  if (is_object($subject) && array_key_exists($propertyName, get_object_vars($subject))) {
130  return $subject->{$propertyName};
131  }
132  $propertyExists = FALSE;
133  return NULL;
134  }
135 
149  static public function getPropertyPath($subject, $propertyPath) {
150  $propertyPathSegments = explode('.', $propertyPath);
151  foreach ($propertyPathSegments as $pathSegment) {
152  $propertyExists = FALSE;
153  $subject = self::getPropertyInternal($subject, $pathSegment, FALSE, $propertyExists);
154  if (!$propertyExists || $subject === NULL) {
155  return $subject;
156  }
157  }
158  return $subject;
159  }
160 
180  static public function setProperty(&$subject, $propertyName, $propertyValue, $forceDirectAccess = FALSE) {
181  if (is_array($subject)) {
182  $subject[$propertyName] = $propertyValue;
183  return TRUE;
184  }
185  if (!is_object($subject)) {
186  throw new \InvalidArgumentException('subject must be an object or array, ' . gettype($subject) . ' given.', 1237301368);
187  }
188  if (!is_string($propertyName)) {
189  throw new \InvalidArgumentException('Given property name is not of type string.', 1231178878);
190  }
191  if ($forceDirectAccess === TRUE) {
192  if (property_exists(get_class($subject), $propertyName)) {
193  $propertyReflection = new \TYPO3\CMS\Extbase\Reflection\PropertyReflection(get_class($subject), $propertyName);
194  $propertyReflection->setAccessible(TRUE);
195  $propertyReflection->setValue($subject, $propertyValue);
196  } else {
197  $subject->{$propertyName} = $propertyValue;
198  }
199  } elseif (is_callable(array($subject, $setterMethodName = self::buildSetterMethodName($propertyName)))) {
200  $subject->{$setterMethodName}($propertyValue);
201  } elseif ($subject instanceof \ArrayAccess) {
202  $subject[$propertyName] = $propertyValue;
203  } elseif (array_key_exists($propertyName, get_object_vars($subject))) {
204  $subject->{$propertyName} = $propertyValue;
205  } else {
206  return FALSE;
207  }
208  return TRUE;
209  }
210 
223  static public function getGettablePropertyNames($object) {
224  if (!is_object($object)) {
225  throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1237301369);
226  }
227  if ($object instanceof \stdClass) {
228  $declaredPropertyNames = array_keys(get_object_vars($object));
229  } else {
230  $declaredPropertyNames = array_keys(get_class_vars(get_class($object)));
231  }
232  foreach (get_class_methods($object) as $methodName) {
233  if (is_callable(array($object, $methodName))) {
234  if (substr($methodName, 0, 2) === 'is') {
235  $declaredPropertyNames[] = lcfirst(substr($methodName, 2));
236  }
237  if (substr($methodName, 0, 3) === 'get') {
238  $declaredPropertyNames[] = lcfirst(substr($methodName, 3));
239  }
240  }
241  }
242  $propertyNames = array_unique($declaredPropertyNames);
243  sort($propertyNames);
244  return $propertyNames;
245  }
246 
259  static public function getSettablePropertyNames($object) {
260  if (!is_object($object)) {
261  throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1264022994);
262  }
263  if ($object instanceof \stdClass) {
264  $declaredPropertyNames = array_keys(get_object_vars($object));
265  } else {
266  $declaredPropertyNames = array_keys(get_class_vars(get_class($object)));
267  }
268  foreach (get_class_methods($object) as $methodName) {
269  if (substr($methodName, 0, 3) === 'set' && is_callable(array($object, $methodName))) {
270  $declaredPropertyNames[] = lcfirst(substr($methodName, 3));
271  }
272  }
273  $propertyNames = array_unique($declaredPropertyNames);
274  sort($propertyNames);
275  return $propertyNames;
276  }
277 
287  static public function isPropertySettable($object, $propertyName) {
288  if (!is_object($object)) {
289  throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1259828920);
290  }
291  if ($object instanceof \stdClass && array_search($propertyName, array_keys(get_object_vars($object))) !== FALSE) {
292  return TRUE;
293  } elseif (array_search($propertyName, array_keys(get_class_vars(get_class($object)))) !== FALSE) {
294  return TRUE;
295  }
296  return is_callable(array($object, self::buildSetterMethodName($propertyName)));
297  }
298 
308  static public function isPropertyGettable($object, $propertyName) {
309  if (!is_object($object)) {
310  throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1259828921);
311  }
312  if ($object instanceof \ArrayAccess && isset($object[$propertyName]) === TRUE) {
313  return TRUE;
314  } elseif ($object instanceof \stdClass && array_search($propertyName, array_keys(get_object_vars($object))) !== FALSE) {
315  return TRUE;
316  } elseif ($object instanceof \ArrayAccess && isset($object[$propertyName]) === TRUE) {
317  return TRUE;
318  }
319  if (is_callable(array($object, 'get' . ucfirst($propertyName)))) {
320  return TRUE;
321  }
322  if (is_callable(array($object, 'is' . ucfirst($propertyName)))) {
323  return TRUE;
324  }
325  return array_search($propertyName, array_keys(get_class_vars(get_class($object)))) !== FALSE;
326  }
327 
338  static public function getGettableProperties($object) {
339  if (!is_object($object)) {
340  throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1237301370);
341  }
342  $properties = array();
343  foreach (self::getGettablePropertyNames($object) as $propertyName) {
344  $propertyExists = FALSE;
345  $propertyValue = self::getPropertyInternal($object, $propertyName, FALSE, $propertyExists);
346  if ($propertyExists === TRUE) {
347  $properties[$propertyName] = $propertyValue;
348  }
349  }
350  return $properties;
351  }
352 
361  static public function buildSetterMethodName($propertyName) {
362  return 'set' . ucfirst($propertyName);
363  }
364 }
static getPropertyInternal($subject, $propertyName, $forceDirectAccess, &$propertyExists)
static isPropertyGettable($object, $propertyName)
static isPropertySettable($object, $propertyName)
static setProperty(&$subject, $propertyName, $propertyValue, $forceDirectAccess=FALSE)
static getPropertyPath($subject, $propertyPath)
static getProperty($subject, $propertyName, $forceDirectAccess=FALSE)