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

Commit

Permalink
created hydrator strategy chain
Browse files Browse the repository at this point in the history
  • Loading branch information
ojhaujjwal committed Jan 4, 2015
1 parent 19b8cba commit 08bd3f8
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Stdlib\Hydrator\Strategy\Exception;

class DomainException extends \DomainException implements ExceptionInterface
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Stdlib\Hydrator\Strategy\Exception;

interface ExceptionInterface
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Stdlib\Hydrator\Strategy\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
127 changes: 127 additions & 0 deletions library/Zend/Stdlib/Hydrator/Strategy/StrategyChain.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Stdlib\Hydrator\Strategy;

use Traversable;
use Zend\Stdlib\PriorityQueue;

class StrategyChain implements StrategyInterface
{
/**
* Default priority at which strategies are added
*/
const DEFAULT_PRIORITY = 1000;

/**
* Strategy chain
*
* @var PriorityQueue
*/
protected $strategies;

/**
* Initialize Strategy chain
*
* @param null|array|Traversable $strategiesOptions
*/
public function __construct($strategiesOptions = null)
{
$this->strategies = new PriorityQueue();

if (null !== $strategiesOptions) {
$this->setStrategies($strategiesOptions);
}
}

/**
* Sets strategies
*
* @param array|Traversable $strategies
* @return void
* @throws Exception\InvalidArgumentException
*/
public function setStrategies($strategies)
{
if (!is_array($strategies) && !$strategies instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'Expected array or Traversable; received "%s"',
(is_object($strategies) ? get_class($strategies) : gettype($strategies))
));
}

foreach ($strategies as $value) {
if (is_array($value)) {
if (!isset($value['name'])) {
throw new Exception\DomainException('No strategy is provided.');
}
$strategy = $value['name'];
$priority = isset($value['priority']) ? $value['priority'] : static::DEFAULT_PRIORITY;
} else {
$strategy = $value;
$priority = static::DEFAULT_PRIORITY;
}

if (!$strategy instanceof StrategyInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Strategy must implement Zend\Stdlib\Hydrator\Strategy\StrategyInterface, "%s provided instead"',
(is_object($strategy) ? get_class($strategy) : gettype($strategy))
));
}

$this->attach($strategy, $priority);
}
}

/**
* Attach a Strategy to the chain
*
* @param StrategyInterface $strategy
* @param int $priority Priority at which to enqueue strategy; defaults to 1000 (higher executes earlier)
* @return void
*/
public function attach(StrategyInterface $strategy, $priority = self::DEFAULT_PRIORITY)
{
$this->strategies->insert($strategy, $priority);
}

/**
* Get all the strategies
*
* @return PriorityQueue
*/
public function getStrategies()
{
return $this->strategies;
}

/**
* {@inheritDoc}
*/
public function hydrate($value)
{
foreach ($this->strategies as $strategy) {
$value = $strategy->hydrate($value);
}

return $value;
}

/**
* {@inheritDoc}
*/
public function extract($value)
{
foreach (array_reverse(iterator_to_array($this->strategies)) as $strategy) {
$value = $strategy->extract($value);
}

return $value;
}
}
142 changes: 142 additions & 0 deletions tests/ZendTest/Stdlib/Hydrator/Strategy/StrategyChainTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Stdlib\Hydrator\Strategy;

use Zend\Stdlib\Hydrator\Strategy\StrategyChain;
use Zend\Stdlib\Hydrator\Strategy\ClosureStrategy;

class StrategyChainTest extends \PHPUnit_Framework_TestCase
{
public function testEmptyStrategyChainReturnsOriginalValue()
{
$chain = new StrategyChain();
$this->assertEquals('something', $chain->hydrate('something'));
$this->assertEquals('something', $chain->extract('something'));
}

public function testStrategiesAreExecutedAccordingToPriority()
{
$chain = new StrategyChain();
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 8;
},
function ($value) {
return $value % 8;
}
),
10
);
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 3;
},
function ($value) {
return $value % 3;
}
),
100
);
$this->assertEquals(1, $chain->extract(20));
$this->assertEquals(2, $chain->hydrate(20));

$chain = new StrategyChain();
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 6;
},
function ($value) {
return $value % 9;
}
),
110
);
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 7;
},
function ($value) {
return $value % 4;
}
),
100
);
$this->assertEquals(2, $chain->extract(30));
$this->assertEquals(3, $chain->hydrate(30));

$chain = new StrategyChain();
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 9;
},
function ($value) {
return $value % 7;
}
)
);
$chain->attach(
new ClosureStrategy(
function ($value) {
return $value % 12;
},
function ($value) {
return $value % 3;
}
)
);
$this->assertEquals(3, $chain->extract(87));
$this->assertEquals(0, $chain->hydrate(87));
}

public function testSetStrategies()
{
$chain = new StrategyChain(array(
array(
'name' => new ClosureStrategy(function ($value) { return $value % 9; }),
'priority' => 4,
),
new ClosureStrategy(function ($value) { return $value % 2; }),
array(
'name' => new ClosureStrategy(function ($value) { return $value % 7; }),
),
));

$this->assertEquals(1, $chain->extract(80));
$this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $chain->getStrategies());
$this->assertCount(3, $chain->getStrategies());
}

public function testGetExceptionWhenStrategyIsNotProvided()
{
$this->setExpectedException('Zend\Stdlib\Hydrator\Strategy\Exception\DomainException');

$chain = new StrategyChain(array(
array(
'priority' => 4,
),
));
}

public function testGetExceptionWithInvalidStrategy()
{
$this->setExpectedException('Zend\Stdlib\Hydrator\Strategy\Exception\InvalidArgumentException');

$chain = new StrategyChain(array(
array(
'name' => 'asdfsadf',
),
));
}
}

0 comments on commit 08bd3f8

Please sign in to comment.