* @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);
}
}