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

Commit

Permalink
Merge branch 'hotfix/4496'
Browse files Browse the repository at this point in the history
  • Loading branch information
weierophinney committed May 24, 2013
196 parents 5e73b09 + a0d0796 + c382628 + ee15e76 + 5f29760 + 714d1a8 + 84b0297 + cbc5f03 + 76361f8 + e7209df + 87630e0 + df43daf + f7d6cbb + 7e2b798 + 3ed1ead + 87505b6 + c229265 + eb61c8f + efcb00e + 0a0842f + b6d0c88 + 7edee62 + 60ea64c + a08bcca + b40ec3e + 63172ed + 448f428 + 92a516a + 5ecbc99 + a2df21b + 4de87f2 + 7c259ec + a22bdcb + 084ad9f + 9414e5a + 489be93 + cb39e7e + 54a28dc + c9c769e + dda791d + 70d382a + 8bbad0e + 9321185 + 7ab35a6 + b93694e + 3ea7087 + 0fe3d3a + bd5e189 + d1cba17 + 8d75392 + 3fb5b55 + 6cb0ccb + 30aa565 + 8409977 + 8074ba0 + 8f92486 + 94860d1 + 05d33c4 + 425826b + f0e91f0 + e31468f + 7d2af87 + 2e4dc80 + 19d128f + 1b9e4b2 + 1c46483 + fdda3f2 + 595fcd1 + 213395c + 8e514a8 + 2f30186 + bb4ed65 + 132d5b6 + 030ff33 + f2f20f3 + a50e133 + 4c554ee + dbfb1b8 + ccab83f + 00b350f + 78945d0 + f0e5f4b + ceb7d8c + 9e124d1 + 3de5912 + b6a974a + 10a6438 + cb6c1e7 + 18afd6c + 3baf1bd + c800904 + f52dcb8 + 126ccb2 + e7d6206 + e2d24ab + ec1abfc + 290ea90 + 9f4ca1b + edaa760 + c4c0c95 + d21f055 + 5b18029 + e6b97af + 010fb36 + 64c7b8d + 636523e + 4cc2cd6 + e34098a + 16367cd + 943c77f + 8226e5b + 0b47726 + 3cd8a03 + cc4782c + 9c653a6 + 656dbe5 + 9bce1ba + 7dc18ca + 861130d + 2d2ffbd + 4f413a5 + 2e1067a + 1d082e4 + e8aeb79 + b562091 + ff2fdc3 + 4aa72c0 + 1bb67ac + cd015c8 + 5e89910 + 0c21258 + dd54faf + 57f9063 + b88ce2e + af68643 + 06cd3b4 + 2c71b71 + ee02c35 + 9456314 + 5a77a7b + e98a077 + 738f2e6 + cb1e63c + 736df07 + d0a0154 + 990523c + 78687de + a5b6e79 + 6e9dfe9 + e201a1c + d9b45ef + 76222ad + 16d67da + 1ab2258 + b81d711 + ed2e9bc + 61efe82 + f353ea5 + 1f02519 + 58c1fe8 + ed502d9 + 2defba6 + 4885013 + 06a8384 + 17d9eed + 3b21b5d + c62101c + 909ef34 + 13d376a + 8a75367 + 98a3cf5 + 270f2c4 + 3038cfa + 1112202 + c8fb359 + 8d37cd0 + 4d868a7 + 555cb91 + 7ac5858 + 8103f1f + 9fe9c96 + a3ecac6 + 10e77c1 + e0d3e13 + 19ad608 + e0d665c + 1a5b402 + 56ae12a + 9073fc1 + 2d5b32f + a8e6198 + 83e8f34 + 30eb247 + 6204c2f + c3855a9 + cf0246f commit fdeb27b
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/Hydrator/ClassMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Zend\Stdlib\Hydrator\Filter\HasFilter;
use Zend\Stdlib\Hydrator\Filter\IsFilter;
use Zend\Stdlib\Hydrator\Filter\MethodMatchFilter;
use Zend\Stdlib\Hydrator\Filter\NumberOfParameterFilter;
use Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter;

class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
{
Expand All @@ -29,6 +29,11 @@ class ClassMethods extends AbstractHydrator implements HydratorOptionsInterface
*/
protected $underscoreSeparatedKeys = true;

/**
* @var \Zend\Stdlib\Hydrator\Filter\FilterInterface
*/
private $callableMethodFilter;

/**
* Define if extract values will use camel case or name with underscore
* @param bool|array $underscoreSeparatedKeys
Expand All @@ -38,10 +43,12 @@ public function __construct($underscoreSeparatedKeys = true)
parent::__construct();
$this->setUnderscoreSeparatedKeys($underscoreSeparatedKeys);

$this->callableMethodFilter = new OptionalParametersFilter();

$this->filterComposite->addFilter("is", new IsFilter());
$this->filterComposite->addFilter("has", new HasFilter());
$this->filterComposite->addFilter("get", new GetFilter());
$this->filterComposite->addFilter("parameter", new NumberOfParameterFilter(), FilterComposite::CONDITION_AND);
$this->filterComposite->addFilter("parameter", new OptionalParametersFilter(), FilterComposite::CONDITION_AND);
}

/**
Expand Down Expand Up @@ -128,8 +135,7 @@ public function extract($object)
continue;
}

$reflectionMethod = new ReflectionMethod(get_class($object) . '::' . $method);
if ($reflectionMethod->getNumberOfParameters() > 0) {
if (!$this->callableMethodFilter->filter(get_class($object) . '::' . $method)) {
continue;
}

Expand Down
54 changes: 54 additions & 0 deletions src/Hydrator/Filter/OptionalParametersFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Stdlib\Hydrator\Filter;

use InvalidArgumentException;
use ReflectionException;
use ReflectionMethod;
use ReflectionParameter;

/**
* Filter that includes methods which have no parameters or only optional parameters
*/
class OptionalParametersFilter implements FilterInterface
{
/**
* Map of methods already analyzed
* by {@see \Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter::filter()},
* cached for performance reasons
*
* @var bool[]
*/
private static $propertiesCache = array();

/**
* {@inheritDoc}
*/
public function filter($property)
{
if (isset(self::$propertiesCache[$property])) {
return self::$propertiesCache[$property];
}

try {
$reflectionMethod = new ReflectionMethod($property);
} catch (ReflectionException $exception) {
throw new InvalidArgumentException(sprintf('Method %s doesn\'t exist', $property));
}

$mandatoryParameters = array_filter(
$reflectionMethod->getParameters(),
function (ReflectionParameter $parameter) {
return ! $parameter->isOptional();
}
);

return self::$propertiesCache[$property] = empty($mandatoryParameters);
}
}
43 changes: 43 additions & 0 deletions test/Hydrator/ClassMethodsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Stdlib\Hydrator;

use Zend\Stdlib\Hydrator\ClassMethods;
use ZendTest\Stdlib\TestAsset\ClassMethodsOptionalParameters;

/**
* Unit tests for {@see \Zend\Stdlib\Hydrator\ClassMethods}
*
* @covers \Zend\Stdlib\Hydrator\ClassMethods
* @group Zend_Stdlib
*/
class ClassMethodsTest extends \PHPUnit_Framework_TestCase
{
/**
* @var ClassMethods
*/
protected $hydrator;

/**
* {@inheritDoc}
*/
public function setUp()
{
$this->hydrator = new ClassMethods();
}

/**
* Verifies that extraction can happen even when a getter has parameters if those are all optional
*/
public function testCanExtractFromMethodsWithOptionalParameters()
{
$this->assertSame(array('foo' => 'bar'), $this->hydrator->extract(new ClassMethodsOptionalParameters()));
}
}
120 changes: 120 additions & 0 deletions test/Hydrator/Filter/OptionalParametersFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Stdlib\Hydrator\Filter;

use Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter;

/**
* Unit tests for {@see \Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter}
*
* @covers \Zend\Stdlib\Hydrator\Filter\OptionalParametersFilter
* @group Zend_Stdlib
*/
class OptionalParametersFilterTest extends \PHPUnit_Framework_TestCase
{
/**
* @var OptionalParametersFilter
*/
protected $filter;

/**
* {@inheritDoc}
*/
public function setUp()
{
$this->filter = new OptionalParametersFilter();
}

/**
* Verifies a list of methods against expected results
*
* @param string $method
* @param bool $expectedResult
*
* @dataProvider methodProvider
*/
public function testMethods($method, $expectedResult)
{
$this->assertSame($expectedResult, $this->filter->filter($method));
}

/**
* Verifies a list of methods against expected results over subsequent calls, checking
* that the filter behaves consistently regardless of cache optimizations
*
* @param string $method
* @param bool $expectedResult
*
* @dataProvider methodProvider
*/
public function testMethodsOnSubsequentCalls($method, $expectedResult)
{
for ($i = 0; $i < 5; $i += 1) {
$this->assertSame($expectedResult, $this->filter->filter($method));
}
}

public function testTriggersExceptionOnUnknownMethod()
{
$this->setExpectedException('InvalidArgumentException');
$this->filter->filter(__CLASS__ . '::' . 'nonExistingMethod');
}

/**
* Provides a list of methods to be checked against the filter
*
* @return array
*/
public function methodProvider()
{
return array(
array(__CLASS__ . '::' . 'methodWithoutParameters', true),
array(__CLASS__ . '::' . 'methodWithSingleMandatoryParameter', false),
array(__CLASS__ . '::' . 'methodWithSingleOptionalParameter', true),
array(__CLASS__ . '::' . 'methodWithMultipleMandatoryParameters', false),
array(__CLASS__ . '::' . 'methodWithMultipleOptionalParameters', true),
);
}

/**
* Test asset method
*/
public function methodWithoutParameters()
{
}

/**
* Test asset method
*/
public function methodWithSingleMandatoryParameter($parameter)
{
}

/**
* Test asset method
*/
public function methodWithSingleOptionalParameter($parameter = null)
{
}

/**
* Test asset method
*/
public function methodWithMultipleMandatoryParameters($parameter, $otherParameter)
{
}

/**
* Test asset method
*/
public function methodWithMultipleOptionalParameters($parameter = null, $otherParameter = null)
{
}
}
41 changes: 41 additions & 0 deletions test/TestAsset/ClassMethodsOptionalParameters.php
Original file line number Diff line number Diff line change
@@ -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-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Stdlib
*/

namespace ZendTest\Stdlib\TestAsset;

/**
* Test asset to check how optional parameters of are treated methods
*/
class ClassMethodsOptionalParameters
{
/**
* @var string
*/
public $foo = 'bar';

/**
* @param mixed $optional
*
* @return string
*/
public function getFoo($optional = null)
{
return $this->foo;
}

/**
* @param string $foo
* @param mixed $optional
*/
public function setFoo($foo, $optional = null)
{
$this->foo = (string) $foo;
}
}

0 comments on commit fdeb27b

Please sign in to comment.