1 <?php
4 /*! \brief This class represents a server side object.
5 * All actions preformed on this object will be executed
6 * on the server using RPC calls.
7 * Properties will bestored directly (directStorage=TRUE) or when commit() is called.
8 */
9 class remoteObject
10 {
11 private $rpcHandle;
12 private $properties;
13 private $methods;
14 private $type;
15 private $object_id;
16 private $ref_id;
17 private $values;
18 private $success;
19 private $lastError;
21 private $cache = array();
23 // When set to true, property modifications will be
24 // transfered to the server, immediately.
25 // If it is false, changes will be transfered when
26 // commit() is called.
27 private $directStorage=FALSE;
30 /*!\brief Constructs the remoteObject.
31 * @param jsonRPC The rpc connection handle.
32 * @param String The type of the object, e.g. 'user'.
33 * @param Array A list of available properties.
34 * @param Array A list of values for the properties.
35 * @param Array A list of methods provided by this object.
36 * @param String A string that represents the object call.
37 * @return String The server side object ID, used to identify the object.
38 */
39 function __construct(&$rpcHandle, $type, $properties, $values, $methods, $object_id, $ref_id)
40 {
41 $this->rpcHandle = $rpcHandle;
42 $this->properties = $properties;
43 $this->methods = $methods;
44 $this->type = $type;
45 $this->ref_id = $ref_id;
46 $this->object_id = $object_id;
47 $this->values = $values;
48 $this->cache = $values;
49 }
52 /*!\brief Returns the object type.
53 * @return String The type of the object. E.g. 'user'.
54 */
55 function getType()
56 {
57 return($this->type);
58 }
61 /*!\brief Returns a list of available property names.
62 * @return Array A list of property names.
63 */
64 function getProperties()
65 {
66 return($this->properties);
67 }
70 /*!\brief Returns the objects reference ID.
71 * @return String the server side object id.
72 */
73 function getReferenceId()
74 {
75 return($this->ref_id);
76 }
79 /*!\brief Clears all object modification when in not in
80 * 'directStorage' mode.
81 */
82 function clearCache()
83 {
84 $this->__clearCache();
85 }
88 /*!\brief Catch all method for undefined function calls.
89 * This method detects setter, getter and methods calls
90 * and forwards them to the right object method.
91 * @param String The name of the function to call.
92 * @param Array A list of parameters.
93 * @return Mixed E.g. The answer from the server.
94 */
95 function __call($name, $args)
96 {
98 // Check if such an attribute is registered
99 if(preg_match("/^get/", $name)){
100 $varName = ucfirst(preg_replace("/^get/","", $name));
101 $varName2 = lcfirst($varName);
102 if(in_array($varName, $this->properties)){
103 $force = isset($args[0]) && $args[0];
104 return($this->__getProperty($varName, $force));
105 }elseif(in_array($varName2, $this->properties)){
106 $force = isset($args[0]) && $args[0];
107 return($this->__getProperty($varName2, $force));
108 }
109 }elseif(preg_match("/^set/", $name)){
110 $varName = ucfirst(preg_replace("/^set/","", $name));
111 $varName2 = lcfirst($varName);
112 if(in_array($varName, $this->properties)){
113 return($this->__setProperty($varName, $args[0]));
114 }elseif(in_array($varName2, $this->properties)){
115 return($this->__setProperty($varName2, $args[0]));
116 }
117 }
119 // Forward to the call to the backend.
120 if(in_array($name, $this->methods)){
121 $this->lastError = "";
122 $this->success = TRUE;
123 $fArgs = array();
124 $fArgs[] = $this->ref_id;
125 $fArgs[] = $name;
126 $fArgs = array_merge($fArgs, $args);
127 $res = call_user_func_array(array($this->rpcHandle,"dispatchObjectMethod"), $fArgs);
129 if(!$this->rpcHandle->success()){
130 $this->success = FALSE;
131 $this->lastError = $this->rpcHandle->get_error();
132 trigger_error($this->lastError);
133 }
135 return($res);
136 }
138 // Show an error, we do not know what to to with this..
139 trigger_error("Unknown method '{$name}' called for {$this->object_id}!");
140 }
143 function success()
144 {
145 return($this->success);
146 }
149 /*!\brief A catch all method for setter calls.
150 *
151 * @param String The name of the property to set.
152 * @param String The value to use.
153 * @return
154 */
155 function __set($varName, $value)
156 {
157 // Set property value
158 if(in_array($varName, $this->properties)){
159 return($this->__setProperty($varName, $value));
160 }
162 // Set class member value
163 if(isset($this->$varName)){
164 $this->$varName = $value;
165 return(TRUE);
166 }
168 trigger_error("No attribute '{$varName}' defined!");
169 return(FALSE);
170 }
173 /*!\brief A catch all method for getter calls.
174 * @param String The name of the requested property.
175 * @return Mixed.
176 */
177 function __get($varName)
178 {
179 if(in_array($varName, $this->properties)){
180 return($this->__getProperty($varName));
181 }
183 // Set class member value
184 if(isset($this->$varName)){
185 return($this->$varName);
186 }
188 trigger_error("No attribute '{$varName}' defined!");
189 return(NULL);
190 }
193 /*!\brief Internal method used to set properties.
194 * @param String The name of property to set.
195 * @param Mixed The new value for the property.
196 * @return Boolean true on success else false.
197 */
198 function __setProperty($name, $value, $forceSave = FALSE)
199 {
200 if($this->directStorage || $forceSave){
201 $this->rpcHandle->setObjectProperty($this->ref_id, $name,$value);
202 if($this->rpcHandle->success()){
203 $this->__addPropValueToCache($name, $value);
204 return(TRUE);
205 }else{
206 return(FALSE);
207 }
208 }else{
209 $this->__addPropValueToCache($name, $value);
210 return(TRUE);
211 }
212 }
215 /*!\brief Internal method used to get property values.
216 * @param String The name of the property.
217 * @return Mixed.
218 */
219 function __getProperty($name, $force = FALSE)
220 {
221 if(!$force && $this->__propIsCached($name)){
222 return($this->__getPropFromCache($name));
223 }
225 $res = $this->rpcHandle->getObjectProperty($this->ref_id, $name);
226 if(!$this->rpcHandle->success()){
227 return(NULL);
228 }else{
229 $this->__addPropValueToCache($name, $res);
230 $this->values[$name] = $res;
231 return($res);
232 }
233 }
236 /*!\brief Closes the object on the server side.
237 * @return The closing status.
238 */
239 function close()
240 {
241 $res = $this->rpcHandle->closeObject($this->ref_id);
242 if($this->success){
243 $this->ref_id = "";
244 }
245 return($this->rpcHandle->success());
246 }
249 /*!\brief Internal method used to add property values to the cache.
250 * @param String The name of the propterty to add.
251 * @param String The value of the property to add.
252 */
253 function __addPropValueToCache($name, $value)
254 {
255 $this->cache[$name] = $value;
256 }
259 /*!\brief Internal method used to fetch property values from the cache.
260 * @param String The name of the property to fetch.
261 * @return Mixed.
262 */
263 function __getPropFromCache($name)
264 {
265 return($this->cache[$name]);
266 }
269 /*!\brief Internal method to check whether a property value is cached or not.
270 * @param String The name of the property.
271 * @return Boolean True on success else false
272 */
273 function __propIsCached($name)
274 {
275 return(isset($this->cache[$name]));
276 }
279 /*!\brief Clears the internal property cache.
280 */
281 function __clearCache()
282 {
283 $this->cache = array();
284 }
287 /* \brief See commit();
288 */
289 function save()
290 {
291 return($this->commit());
292 }
295 /*! \brief Saves property modifications back to the server.
296 * This is only necessary in directStorage mode.
297 * @param Boolean If set to true all attributes will be saved, even not modified.
298 */
299 function commit($saveUntouchedPropertiesToo = FALSE)
300 {
301 foreach($this->properties as $prop){
302 if(!$this->__propIsCached($prop)) continue;
303 if($saveUntouchedPropertiesToo || $this->values[$prop] != $this->__getPropFromCache($prop)){
304 $this->__setProperty($prop, $this->__getPropFromCache($prop), TRUE);
305 }
306 }
307 }
310 /*!\brief Internal method which removes a property from the cache.
311 * @param String The name of the property.
312 * @return
313 */
314 function __removePropFromCache($name)
315 {
316 if($this->__propIsCached($name)){
317 unset($this->cache[$name]);
318 }
319 }
320 }
322 ?>