75c017a3d536c57678a64f22cdc2420ad3a40981
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Reflection / ObjectAccess.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Christopher Hlubek <hlubek@networkteam.com>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Provides methods to call appropriate getter/setter on an object given the
27 * property name. It does this following these rules:
28 * - if the target object is an instance of ArrayAccess, it gets/sets the property
29 * - if public getter/setter method exists, call it.
30 * - if public property exists, return/set the value of it.
31 * - else, throw exception
32 *
33 * @package Extbase
34 * @subpackage Reflection
35 * @version $Id$
36 */
37 class Tx_Extbase_Reflection_ObjectAccess {
38
39 const ACCESS_GET = 0;
40 const ACCESS_SET = 1;
41 const ACCESS_PUBLIC = 2;
42
43 /**
44 * Get a property of a given object.
45 * Tries to get the property the following ways:
46 * - if the target object is an instance of ArrayAccess, it gets the property
47 * on it if it exists.
48 * - if public getter method exists, call it.
49 * - if public property exists, return the value of it.
50 * - else, throw exception
51 *
52 * @param object $object Object to get the property from
53 * @param string $propertyName name of the property to retrieve
54 * @return object Value of the property.
55 */
56 static public function getProperty($object, $propertyName) {
57 if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301367);
58 if (!is_string($propertyName)) throw new InvalidArgumentException('Given property name is not of type string.', 1231178303);
59
60 if (is_callable(array($object, $getterMethodName = self::buildGetterMethodName($propertyName)))) {
61 return call_user_func(array($object, $getterMethodName));
62 } elseif ($object instanceof ArrayAccess && isset($object[$propertyName])) {
63 return $object[$propertyName];
64 } elseif (array_key_exists($propertyName, get_object_vars($object))) {
65 return $object->$propertyName;
66 }
67 return NULL;
68 }
69
70 /**
71 * Set a property for a given object.
72 * Tries to set the property the following ways:
73 * - if public setter method exists, call it.
74 * - if public property exists, set it directly.
75 * - if the target object is an instance of ArrayAccess, it sets the property
76 * on it without checking if it existed.
77 * - else, return FALSE
78 *
79 * @param object $object The target object
80 * @param string $propertyName Name of the property to set
81 * @param object $propertyValue Value of the property
82 * @return void
83 * @throws Tx_Extbase_Reflection_Exception if property was could not be set
84 */
85 static public function setProperty($object, $propertyName, $propertyValue) {
86 if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301368);
87 if (!is_string($propertyName)) throw new InvalidArgumentException('Given property name is not of type string.', 1231178878);
88
89 if (is_callable(array($object, $setterMethodName = self::buildSetterMethodName($propertyName)))) {
90 call_user_func(array($object, $setterMethodName), $propertyValue);
91 } elseif ($object instanceof ArrayAccess) {
92 $object[$propertyName] = $propertyValue;
93 } elseif (array_key_exists($propertyName, get_object_vars($object))) {
94 $object->$propertyName = $propertyValue;
95 } else {
96 return FALSE;
97 }
98 return TRUE;
99 }
100
101 /**
102 * Returns an array of properties which can be get/set with the getProperty
103 * and setProperty methods.
104 * Includes the following properties:
105 * - which can be set through a public setter method.
106 * - public properties which can be directly set.
107 *
108 * @param object $object Object to receive property names for
109 * @return array Array of all declared property names
110 * @todo What to do with ArrayAccess
111 */
112 static public function getAccessiblePropertyNames($object) {
113 if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301369);
114 $declaredPropertyNames = array_keys(get_class_vars(get_class($object)));
115
116 foreach (get_class_methods($object) as $methodName) {
117 if (substr($methodName, 0, 3) === 'get') {
118 $declaredPropertyNames[] = t3lib_div::lcfirst(substr($methodName, 3));
119 }
120 }
121
122 $propertyNames = array_unique($declaredPropertyNames);
123 sort($propertyNames);
124 return $propertyNames;
125 }
126
127 /**
128 * Get all properties (names and their current values) of the current
129 * $object that are accessible through this class.
130 *
131 * @param object $object Object to get all properties from.
132 * @return array Associative array of all properties.
133 * @todo What to do with ArrayAccess
134 */
135 static public function getAccessibleProperties($object) {
136 if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301370);
137 $properties = array();
138 foreach (self::getAccessiblePropertyNames($object) as $propertyName) {
139 $properties[$propertyName] = self::getProperty($object, $propertyName);
140 }
141 return $properties;
142 }
143
144 /**
145 * Build the getter method name for a given property by capitalizing the
146 * first letter of the property, and prepending it with "get".
147 *
148 * @param string $property Name of the property
149 * @return string Name of the getter method name
150 */
151 static protected function buildGetterMethodName($property) {
152 return 'get' . ucfirst($property);
153 }
154
155 /**
156 * Build the setter method name for a given property by capitalizing the
157 * first letter of the property, and prepending it with "set".
158 *
159 * @param string $property Name of the property
160 * @return string Name of the setter method name
161 */
162 static protected function buildSetterMethodName($property) {
163 return 'set' . ucfirst($property);
164 }
165 }
166
167
168 ?>