* @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2014 PradoSoft * @license http://www.pradosoft.com/license/ * @package Prado\Data\SqlMap\DataMapper */ namespace Prado\Data\SqlMap\DataMapper; use Prado\Exceptions\TInvalidDataValueException; /** * TPropertyAccess class provides dot notation stype property access and setting. * * Access object's properties (and subproperties) using dot path notation. * The following are equivalent. * * echo $obj->property1; * echo $obj->getProperty1(); * echo $obj['property1']; //$obj may be an array or object * echo TPropertyAccess($obj, 'property1'); * * * Setting a property value. * * $obj1->propert1 = 'hello'; * $obj->setProperty('hello'); * $obj['property1'] = 'hello'; //$obj may be an array or object * TPropertyAccess($obj, 'property1', 'hello'); * * * Subproperties are supported using the dot notation. E.g. * * echo $obj->property1->property2->property3 * echo TPropertyAccess::get($obj, 'property1.property2.property3'); * * * @author Wei Zhuo * @package Prado\Data\SqlMap\DataMapper * @since 3.1 */ class TPropertyAccess { /** * Gets the property value. * @param mixed object or path. * @param string property path. * @return mixed property value. * @throws TInvalidDataValueException if property path 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(array_key_exists($prop, $object)) $object = $object[$prop]; else throw new TInvalidPropertyException('sqlmap_invalid_property',$path); } else if(is_object($object)) { $getter = 'get'.$prop; if(method_exists($object, $getter) && is_callable(array($object, $getter))) $object = $object->{$getter}(); else if(in_array($prop, array_keys(get_object_vars($object)))) $object = $object->{$prop}; elseif(method_exists($object, '__get') && is_callable(array($object, '__get'))) $object = $object->{$prop}; else throw new TInvalidPropertyException('sqlmap_invalid_property',$path); } else throw new TInvalidPropertyException('sqlmap_invalid_property',$path); } return $object; } /** * @param mixed object or array * @param string property path. * @return boolean true if property path is valid */ 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(array_key_exists($prop, $object)) $object = $object[$prop]; else return false; } else if(is_object($object)) { $getter = 'get'.$prop; if(method_exists($object, $getter) && is_callable(array($object, $getter))) $object = $object->{$getter}(); else if(in_array($prop, array_keys(get_object_vars($object)))) $object = $object->{$prop}; elseif(method_exists($object, '__get') && is_callable(array($object, '__get'))) $object = $object->{$prop}; else return false; } else return false; } return true; } /** * Sets the property value. * @param mixed object or array * @param string property path. * @param mixed new property value. * @throws TInvalidDataValueException if property path is invalid. */ public static function set(&$originalObject, $path, $value) { $properties = explode('.', $path); $prop = array_pop($properties); if(count($properties) > 0) $object = self::get($originalObject, implode('.',$properties)); else $object = &$originalObject; if(is_array($object) || $object instanceof \ArrayAccess) { $object[$prop] = $value; } else if(is_object($object)) { $setter = 'set'.$prop; if (method_exists($object, $setter) && is_callable(array($object, $setter))) $object->{$setter}($value); else $object->{$prop} = $value; } else throw new TInvalidPropertyException('sqlmap_invalid_property_type',$path); } }