Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Hydration Strategies #2072

Merged
merged 17 commits into from Aug 1, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
117 changes: 117 additions & 0 deletions library/Zend/Stdlib/Hydrator/AbstractHydrator.php
@@ -0,0 +1,117 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Stdlib
*/

namespace Zend\Stdlib\Hydrator;

use ArrayObject;
use Zend\Stdlib\Hydrator\StrategyEnabledInterface;
use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;

/**
* @category Zend
* @package Zend_Stdlib
* @subpackage Hydrator
*/
abstract class AbstractHydrator implements HydratorInterface, StrategyEnabledInterface
{
/**
* The list with strategies that this hydrator has.
*
* @var ArrayObject
*/
protected $strategies;

/**
* Initializes a new instance of this class.
*/
public function __construct()
{
$this->strategies = new ArrayObject();
}

/**
* Gets the strategy with the given name.
*
* @param string $name The name of the strategy to get.
* @return StrategyInterface
*/
public function getStrategy($name)
{
return $this->strategies[$name];
}

/**
* Checks if the strategy with the given name exists.
*
* @param string $name The name of the strategy to check for.
* @return bool
*/
public function hasStrategy($name)
{
return array_key_exists($name, $this->strategies);
}

/**
* Adds the given strategy under the given name.
*
* @param string $name The name of the strategy to register.
* @param StrategyInterface $strategy The strategy to register.
* @return HydratorInterface
*/
public function addStrategy($name, StrategyInterface $strategy)
{
$this->strategies[$name] = $strategy;
return $this;
}

/**
* Removes the strategy with the given name.
*
* @param string $name The name of the strategy to remove.
* @return HydratorInterface
*/
public function removeStrategy($name)
{
unset($this->strategies[$name]);
return $this;
}

/**
* Converts a value for extraction. If no strategy exists the plain value is returned.
*
* @param string $name The name of the strategy to use.
* @param mixed $value The value that should be converted.
* @return mixed
*/
public function extractValue($name, $value)
{
if ($this->hasStrategy($name)) {
$strategy = $this->getStrategy($name);
$value = $strategy->extract($value);
}
return $value;
}

/**
* Converts a value for hydration. If no strategy exists the plain value is returned.
*
* @param string $name The name of the strategy to use.
* @param mixed $value The value that should be converted.
* @return mixed
*/
public function hydrateValue($name, $value)
{
if ($this->hasStrategy($name)) {
$strategy = $this->getStrategy($name);
$value = $strategy->hydrate($value);
}
return $value;
}
}
20 changes: 14 additions & 6 deletions library/Zend/Stdlib/Hydrator/ArraySerializable.php
Expand Up @@ -17,8 +17,9 @@
* @package Zend_Stdlib
* @subpackage Hydrator
*/
class ArraySerializable implements HydratorInterface
class ArraySerializable extends AbstractHydrator
{

/**
* Extract values from the provided object
*
Expand All @@ -32,11 +33,15 @@ public function extract($object)
{
if (!is_callable(array($object, 'getArrayCopy'))) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided object to implement getArrayCopy()',
__METHOD__
'%s expects the provided object to implement getArrayCopy()', __METHOD__
));
}
return $object->getArrayCopy();

$data = $object->getArrayCopy();
array_walk($data, function(&$value, $name) {
$value = $this->extractValue($name, $value);
});
return $data;
}

/**
Expand All @@ -52,14 +57,17 @@ public function extract($object)
*/
public function hydrate(array $data, $object)
{
array_walk($data, function(&$value, $name) {
$value = $this->hydrateValue($name, $value);
});

if (is_callable(array($object, 'exchangeArray'))) {
$object->exchangeArray($data);
} elseif (is_callable(array($object, 'populate'))) {
$object->populate($data);
} else {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided object to implement exchangeArray() or populate()',
__METHOD__
'%s expects the provided object to implement exchangeArray() or populate()', __METHOD__
));
}
return $object;
Expand Down
20 changes: 10 additions & 10 deletions library/Zend/Stdlib/Hydrator/ClassMethods.php
Expand Up @@ -17,7 +17,7 @@
* @package Zend_Stdlib
* @subpackage Hydrator
*/
class ClassMethods implements HydratorInterface
class ClassMethods extends AbstractHydrator
{
/**
* Flag defining whether array keys are underscore-separated (true) or camel case (false)
Expand All @@ -31,6 +31,7 @@ class ClassMethods implements HydratorInterface
*/
public function __construct($underscoreSeparatedKeys = true)
{
parent::__construct();
$this->underscoreSeparatedKeys = $underscoreSeparatedKeys;
}

Expand All @@ -47,8 +48,7 @@ public function extract($object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
'%s expects the provided $object to be a PHP object)', __METHOD__
));
}

Expand All @@ -58,20 +58,19 @@ public function extract($object)
};
$attributes = array();
$methods = get_class_methods($object);
foreach($methods as $method) {
if(preg_match('/^get[A-Z]\w*/', $method)) {
foreach ($methods as $method) {
if (preg_match('/^get[A-Z]\w*/', $method)) {
// setter verification
$setter = preg_replace('/^get/', 'set', $method);
if(!in_array($setter, $methods)) {
if (!in_array($setter, $methods)) {
continue;
}
$attribute = substr($method, 3);
$attribute = lcfirst($attribute);
if ($this->underscoreSeparatedKeys) {
$attribute = preg_replace_callback('/([A-Z])/', $transform, $attribute);
}

$attributes[$attribute] = $object->$method();
$attributes[$attribute] = $this->extractValue($attribute, $object->$method());
}
}

Expand All @@ -92,8 +91,7 @@ public function hydrate(array $data, $object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
'%s expects the provided $object to be a PHP object)', __METHOD__
));
}

Expand All @@ -108,6 +106,8 @@ public function hydrate(array $data, $object)
}
$method = 'set' . ucfirst($property);
if (method_exists($object, $method)) {
$value = $this->hydrateValue($property, $value);

$object->$method($value);
}
}
Expand Down
16 changes: 9 additions & 7 deletions library/Zend/Stdlib/Hydrator/ObjectProperty.php
Expand Up @@ -17,7 +17,7 @@
* @package Zend_Stdlib
* @subpackage Hydrator
*/
class ObjectProperty implements HydratorInterface
class ObjectProperty extends AbstractHydrator
{
/**
* Extract values from an object
Expand All @@ -32,12 +32,15 @@ public function extract($object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
'%s expects the provided $object to be a PHP object)', __METHOD__
));
}

return get_object_vars($object);
$data = get_object_vars($object);
array_walk($data, function(&$value, $name) {
$value = $this->extractValue($name, $value);
});
return $data;
}

/**
Expand All @@ -54,12 +57,11 @@ public function hydrate(array $data, $object)
{
if (!is_object($object)) {
throw new Exception\BadMethodCallException(sprintf(
'%s expects the provided $object to be a PHP object)',
__METHOD__
'%s expects the provided $object to be a PHP object)', __METHOD__
));
}
foreach ($data as $property => $value) {
$object->$property = $value;
$object->$property = $this->hydrateValue($property, $value);
}
return $object;
}
Expand Down
9 changes: 6 additions & 3 deletions library/Zend/Stdlib/Hydrator/Reflection.php
Expand Up @@ -14,7 +14,7 @@
use Zend\Stdlib\Exception;
use Zend\Stdlib\Hydrator\HydratorInterface;

class Reflection implements HydratorInterface
class Reflection extends AbstractHydrator
{
/**
* Simple in-memory array cache of ReflectionProperties used.
Expand All @@ -32,7 +32,10 @@ public function extract($object)
{
$result = array();
foreach(self::getReflProperties($object) as $property) {
$result[$property->getName()] = $property->getValue($object);
$propertyName = $property->getName();

$value = $property->getValue($object);
$result[$propertyName] = $this->extractValue($propertyName, $value);
}

return $result;
Expand All @@ -50,7 +53,7 @@ public function hydrate(array $data, $object)
$reflProperties = self::getReflProperties($object);
foreach($data as $key => $value) {
if (isset($reflProperties[$key])) {
$reflProperties[$key]->setValue($object, $value);
$reflProperties[$key]->setValue($object, $this->hydrateValue($key, $value));
}
}
return $object;
Expand Down
41 changes: 41 additions & 0 deletions library/Zend/Stdlib/Hydrator/Strategy/DefaultStrategy.php
@@ -0,0 +1,41 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Stdlib
*/

namespace Zend\Stdlib\Hydrator\Strategy;

/**
* @category Zend
* @package Zend_Stdlib
* @subpackage Hydrator
*/
class DefaultStrategy implements StrategyInterface
{
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value)
{
return $value;
}

/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value)
{
return $value;
}
}
35 changes: 35 additions & 0 deletions library/Zend/Stdlib/Hydrator/Strategy/StrategyInterface.php
@@ -0,0 +1,35 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Stdlib
*/

namespace Zend\Stdlib\Hydrator\Strategy;

/**
* @category Zend
* @package Zend_Stdlib
* @subpackage Hydrator
*/
interface StrategyInterface
{
/**
* Converts the given value so that it can be extracted by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be extracted.
*/
public function extract($value);

/**
* Converts the given value so that it can be hydrated by the hydrator.
*
* @param mixed $value The original value.
* @return mixed Returns the value that should be hydrated.
*/
public function hydrate($value);
}