summaryrefslogtreecommitdiff
path: root/framework/DataAccess/SQLMap/DataMapper/TPropertyAccess.php
blob: dbd4d6e71c818c8a3c2765a3bd38639daa57466e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php

class TPropertyAccess
{
	private $_obj;
	private $_performance=false;

	public function __construct($obj,$performance=false)
	{
		$this->_obj = $obj;
		$this->_performance=$performance;
	}

	public function __get($name)
	{
		return self::get($this->_obj,$name,$this->_performance);
	}

	public function __set($name,$value)
	{
		self::set($this->_obj,$name,$value,$this->_performance);
	}

	/**
	 * Evaluates the data value at the specified field.
	 * - If the data is an array, then the field is treated as an array index
	 *   and the corresponding element value is returned;
	 * - If the data is a TMap or TList object, then the field is treated as a key
	 *   into the map or list, and the corresponding value is returned.
	 * - If the data is an object, the field is treated as a property or subproperty
	 *   defined with getter methods. For example, if the object has a method called
	 *   getMyValue(), then field 'MyValue' will retrive the result of this method call.
	 *   If getMyValue() returns an object which contains a method getMySubValue(),
	 *   then field 'MyValue.MySubValue' will return that method call result.
	 * @param mixed data containing the field value, can be an array, TMap, TList or object.
	 * @param mixed field value
	 * @return mixed value at the specified field
	 * @throw TInvalidDataValueException if field or data is invalid
	 */
	public static function get($object,$path)
	{
		if(!is_array($object) && !is_object($object))
			return $object;
		$properties = explode('.', $path);
		foreach($properties as $prop)
		{	
			if(is_array($object) || $object instanceof ArrayAccess)
			{
				if(isset($object[$prop]))
					$object = $object[$prop];
				else
					throw new TInvalidPropertyException('sqlmap_invalid_property',$path);					
			}
			else if(is_object($object))
			{
				$getter = 'get'.$prop;
				if(is_callable(array($object,$getter)))
					$object = $object->{$getter}();
				else if(in_array($prop, array_keys(get_object_vars($object))))
					$object = $object->{$prop};
				else
					throw new TInvalidPropertyException('sqlmap_invalid_property',$path);
			}
			else
				throw new TInvalidPropertyException('sqlmap_invalid_property',$path);
		}
		return $object;
	}

	public static function has($object, $path)
	{
		if(!is_array($object) && !is_object($object))
			return false;
		$properties = explode('.', $path);
		foreach($properties as $prop)
		{	
			if(is_array($object) || $object instanceof ArrayAccess)
			{
				if(isset($object[$prop]))
					$object = $object[$prop];
				else
					return false;
			}
			else if(is_object($object))
			{
				$getter = 'get'.$prop;
				if(is_callable(array($object,$getter)))
					$object = $object->{$getter}();
				else if(in_array($prop, array_keys(get_object_vars($object))))
					$object = $object->{$prop};
				return false;
			}
			else
				return false;
		}
		return true;
	}

	public static function set(&$object, $path, $value)
	{
		$properties = explode('.', $path);
		$prop = array_pop($properties);
		if(count($properties) > 0)
			$object = self::get($object, implode('.',$properties));
		if(is_array($object) || $object instanceof ArrayAccess)
		{
			$object[$prop] = $value;
		}
		else if(is_object($object))
		{
			$setter = 'set'.$prop;
			if(is_callable(array($object, $setter)))
				$object->{$setter}($value);
			else
				$object->{$prop} = $value;
		}
		else
			throw new TInvalidPropertyException('sqlmap_invalid_property_type',$path);
	}

}

?>