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

Commit 3c95b8a

Browse files
committed
Backwards compatibility for hydrators
As noted in zendframework/zendframework#7672, on updating to: - zend-stdlib >= 2.7.0 - zend-mvc >= 2.6.0 backwards compatibility is broken with regards to typehints against hydrators. The reason is two-fold: - The `HydratorPluginManager` is simply an extension of the one provided in zend-hydrator, meaning that all plugins returned are under the `Zend\Hydrator` namespace, not the `Zend\Stdlib\Hydrator` namespace. - zend-mvc altered the `HydratorPluginManager` mapping to use the instance from zend-hydrator instead of zend-stdlib. This patch addresses the first point of each. It does the following: - Updates the DelegatingHydratorFactory to return a zend-stdlib instance. - Updates the HydratorPluginManager to override the defaults from zend-hydrator, and have them return zend-stdlib extensions. - Adds a test suite for HydratorPluginManager to verify backwards compatibility. A related commit against the zend-mvc 2.6 series will occur shortly, having it use the zend-stdlib HydratorPluginManager.
1 parent 61502e2 commit 3c95b8a

File tree

4 files changed

+127
-5
lines changed

4 files changed

+127
-5
lines changed

composer.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
}
1414
},
1515
"require": {
16-
"php": ">=5.5",
16+
"php": "^5.5 || ^7.0",
1717
"zendframework/zend-hydrator": "~1.0"
1818
},
1919
"require-dev": {
@@ -37,8 +37,9 @@
3737
"prefer-stable": true,
3838
"extra": {
3939
"branch-alias": {
40-
"dev-master": "2.7-dev",
41-
"dev-develop": "2.8-dev"
40+
"dev-release-2.7": "2.7-dev",
41+
"dev-master": "3.0-dev",
42+
"dev-develop": "3.1-dev"
4243
}
4344
},
4445
"autoload-dev": {

src/Hydrator/DelegatingHydratorFactory.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@
99

1010
namespace Zend\Stdlib\Hydrator;
1111

12-
use Zend\Hydrator\DelegatingHydratorFactory as BaseDelegatingHydratorFactory;
12+
use Zend\ServiceManager\FactoryInterface;
13+
use Zend\ServiceManager\ServiceLocatorInterface;
1314

1415
/**
1516
* @deprecated Use Zend\Hydrator\DelegatingHydratorFactory from zendframework/zend-hydrator instead.
1617
*/
17-
class DelegatingHydratorFactory extends BaseDelegatingHydratorFactory
18+
class DelegatingHydratorFactory implements FactoryInterface
1819
{
20+
public function createService(ServiceLocatorInterface $serviceLocator)
21+
{
22+
// Assume that this factory is registered with the HydratorManager,
23+
// and just pass it directly on.
24+
return new DelegatingHydrator($serviceLocator);
25+
}
1926
}

src/Hydrator/HydratorPluginManager.php

+1
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,6 @@ class HydratorPluginManager extends BaseHydratorPluginManager
4848
*/
4949
protected $factories = [
5050
'Zend\Stdlib\Hydrator\DelegatingHydrator' => 'Zend\Stdlib\Hydrator\DelegatingHydratorFactory',
51+
'zendstdlibhydratordelegatinghydrator' => 'Zend\Stdlib\Hydrator\DelegatingHydratorFactory',
5152
];
5253
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zend-stdlib for the canonical source repository
6+
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace ZendTest\Stdlib\Hydrator;
11+
12+
use PHPUnit_Framework_TestCase as TestCase;
13+
use ReflectionProperty;
14+
use Zend\Hydrator\HydratorPluginManager as BasePluginManager;
15+
use Zend\Stdlib\Hydrator\HydratorInterface;
16+
use Zend\Stdlib\Hydrator\HydratorPluginManager;
17+
18+
class HydratorPluginManagerTest extends TestCase
19+
{
20+
public function setUp()
21+
{
22+
$this->hydrators = new HydratorPluginManager();
23+
}
24+
25+
public function testExtendsZendHydratorPluginManager()
26+
{
27+
$this->assertInstanceOf(BasePluginManager::class, $this->hydrators);
28+
}
29+
30+
public function aliases()
31+
{
32+
$hydrators = new HydratorPluginManager();
33+
$r = new ReflectionProperty($hydrators, 'aliases');
34+
$r->setAccessible(true);
35+
foreach ($r->getValue($hydrators) as $alias => $target) {
36+
yield $alias => [$alias, $target];
37+
}
38+
}
39+
40+
/**
41+
* @dataProvider aliases
42+
*/
43+
public function testAllAliasesReturnStdlibEquivalents($alias, $expected)
44+
{
45+
$this->assertContains('\\Stdlib\\', $expected, 'Alias target is not a Stdlib class?');
46+
47+
$hydrator = $this->hydrators->get($alias);
48+
$this->assertInstanceOf(
49+
$expected,
50+
$hydrator,
51+
sprintf('Alias %s did not retrieve expected %s instance; got %s', $alias, $expected, get_class($hydrator))
52+
);
53+
$this->assertInstanceOf(
54+
HydratorInterface::class,
55+
$hydrator,
56+
sprintf('Alias %s resolved to %s, which is not a HydratorInterface instance', $alias, get_class($hydrator))
57+
);
58+
}
59+
60+
public function invokables()
61+
{
62+
$hydrators = new HydratorPluginManager();
63+
$r = new ReflectionProperty($hydrators, 'invokableClasses');
64+
$r->setAccessible(true);
65+
foreach ($r->getValue($hydrators) as $name => $target) {
66+
yield $name => [$name, $target];
67+
}
68+
}
69+
70+
/**
71+
* @dataProvider invokables
72+
*/
73+
public function testAllInvokablesReturnStdlibInstances($name, $expected)
74+
{
75+
$this->assertContains('\\Stdlib\\', $expected, 'Invokable target is not a Stdlib class?');
76+
77+
$hydrator = $this->hydrators->get($name);
78+
$this->assertInstanceOf($expected, $hydrator, sprintf(
79+
'Invokable %s did not retrieve expected %s instance; got %s',
80+
$name,
81+
$expected,
82+
get_class($hydrator)
83+
));
84+
$this->assertInstanceOf(HydratorInterface::class, $hydrator, sprintf(
85+
'Invokable %s resolved to %s, which is not a HydratorInterface instance',
86+
$name,
87+
get_class($hydrator)
88+
));
89+
}
90+
91+
public function factories()
92+
{
93+
$hydrators = new HydratorPluginManager();
94+
$r = new ReflectionProperty($hydrators, 'factories');
95+
$r->setAccessible(true);
96+
foreach ($r->getValue($hydrators) as $name => $factory) {
97+
yield $name => [$name, $factory];
98+
}
99+
}
100+
101+
/**
102+
* @dataProvider factories
103+
*/
104+
public function testAllFactoriesReturnStdlibInstances($name, $factory)
105+
{
106+
$hydrator = $this->hydrators->get($name);
107+
$this->assertInstanceOf(HydratorInterface::class, $hydrator, sprintf(
108+
'Factory for %s resolved to %s, which is not a HydratorInterface instance',
109+
$name,
110+
get_class($hydrator)
111+
));
112+
}
113+
}

0 commit comments

Comments
 (0)