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

Commit e44cb8e

Browse files
committed
Introduce psr to interop container decorator
Enables plugin managers to accept non-interop psr containers as creation context and transparently wrap as interop for backward compatibility
1 parent 0aea76f commit e44cb8e

File tree

4 files changed

+157
-0
lines changed

4 files changed

+157
-0
lines changed

src/AbstractPluginManager.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Zend\ServiceManager;
99

1010
use Interop\Container\ContainerInterface;
11+
use Psr\Container\ContainerInterface as PsrContainerInterface;
1112
use Zend\ServiceManager\Exception\InvalidServiceException;
1213

1314
/**
@@ -52,6 +53,11 @@ abstract class AbstractPluginManager extends ServiceManager implements PluginMan
5253
*/
5354
public function __construct($configInstanceOrParentLocator = null, array $config = [])
5455
{
56+
if ($configInstanceOrParentLocator instanceof PsrContainerInterface
57+
&& ! $configInstanceOrParentLocator instanceof ContainerInterface
58+
) {
59+
$configInstanceOrParentLocator = new PsrContainerDecorator($configInstanceOrParentLocator);
60+
}
5561
if (null !== $configInstanceOrParentLocator
5662
&& ! $configInstanceOrParentLocator instanceof ConfigInterface
5763
&& ! $configInstanceOrParentLocator instanceof ContainerInterface

src/PsrContainerDecorator.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/**
4+
* @link http://github.com/zendframework/zend-servicemanager for the canonical source repository
5+
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (http://www.zend.com)
6+
* @license http://framework.zend.com/license/new-bsd New BSD License
7+
*/
8+
9+
namespace Zend\ServiceManager;
10+
11+
use Interop\Container\ContainerInterface;
12+
use Psr\Container\ContainerExceptionInterface;
13+
use Psr\Container\ContainerInterface as PsrContainerInterface;
14+
use Psr\Container\NotFoundExceptionInterface;
15+
16+
/**
17+
* @internal for use in abstract plugin manager
18+
*/
19+
final class PsrContainerDecorator implements ContainerInterface
20+
{
21+
/**
22+
* @var PsrContainerInterface
23+
*/
24+
private $container;
25+
26+
public function __construct(PsrContainerInterface $container)
27+
{
28+
$this->container = $container;
29+
}
30+
31+
/**
32+
* Finds an entry of the container by its identifier and returns it.
33+
*
34+
* @param string $id Identifier of the entry to look for.
35+
*
36+
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
37+
* @throws ContainerExceptionInterface Error while retrieving the entry.
38+
*
39+
* @return mixed Entry.
40+
*/
41+
public function get($id)
42+
{
43+
return $this->container->get($id);
44+
}
45+
46+
/**
47+
* Returns true if the container can return an entry for the given identifier.
48+
* Returns false otherwise.
49+
*
50+
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
51+
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
52+
*
53+
* @param string $id Identifier of the entry to look for.
54+
*
55+
* @return bool
56+
*/
57+
public function has($id)
58+
{
59+
return $this->container->has($id);
60+
}
61+
62+
/**
63+
* @return PsrContainerInterface
64+
*/
65+
public function getContainer()
66+
{
67+
return $this->container;
68+
}
69+
}

test/AbstractPluginManagerTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99

1010
use Interop\Container\ContainerInterface;
1111
use PHPUnit\Framework\TestCase;
12+
use Psr\Container\ContainerInterface as PsrContainerInterface;
1213
use stdClass;
14+
use Zend\ServiceManager\AbstractPluginManager;
1315
use Zend\ServiceManager\ConfigInterface;
1416
use Zend\ServiceManager\Exception\InvalidArgumentException;
1517
use Zend\ServiceManager\Exception\InvalidServiceException;
1618
use Zend\ServiceManager\Exception\ServiceNotFoundException;
1719
use Zend\ServiceManager\Factory\AbstractFactoryInterface;
1820
use Zend\ServiceManager\Factory\FactoryInterface;
1921
use Zend\ServiceManager\Factory\InvokableFactory;
22+
use Zend\ServiceManager\PsrContainerDecorator;
2023
use Zend\ServiceManager\ServiceManager;
2124
use ZendTest\ServiceManager\TestAsset\InvokableObject;
2225
use ZendTest\ServiceManager\TestAsset\SimplePluginManager;
@@ -60,6 +63,32 @@ public function testInjectCreationContextInFactories()
6063
$this->assertInstanceOf(InvokableObject::class, $object);
6164
}
6265

66+
public function testTransparentlyDecoratesNonInteropPsrContainerAsInteropContainer()
67+
{
68+
$invokableFactory = $this->getMockBuilder(FactoryInterface::class)
69+
->getMock();
70+
$invokableFactory->method('__invoke')
71+
->will($this->returnArgument(0));
72+
73+
$config = [
74+
'factories' => [
75+
'creation context container' => $invokableFactory,
76+
],
77+
];
78+
79+
$container = $this->getMockBuilder(PsrContainerInterface::class)
80+
->getMock();
81+
$pluginManager = $this->getMockForAbstractClass(
82+
AbstractPluginManager::class,
83+
[$container, $config]
84+
);
85+
86+
$object = $pluginManager->get('creation context container');
87+
88+
$this->assertInstanceOf(PsrContainerDecorator::class, $object);
89+
$this->assertSame($container, $object->getContainer());
90+
}
91+
6392
public function testValidateInstance()
6493
{
6594
$config = [

test/PsrContainerDecoratorTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* @link http://github.com/zendframework/zend-servicemanager for the canonical source repository
4+
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (http://www.zend.com)
5+
* @license http://framework.zend.com/license/new-bsd New BSD License
6+
*/
7+
8+
namespace ZendTest\ServiceManager;
9+
10+
use Psr\Container\ContainerInterface;
11+
use stdClass;
12+
use Zend\ServiceManager\PsrContainerDecorator;
13+
use PHPUnit\Framework\TestCase;
14+
15+
/**
16+
* @covers \Zend\ServiceManager\PsrContainerDecorator
17+
*/
18+
class PsrContainerDecoratorTest extends TestCase
19+
{
20+
public function testProxiesHasToDecoratedContainer()
21+
{
22+
$psrContainer = $this->getMockBuilder(ContainerInterface::class)
23+
->getMock();
24+
$psrContainer->expects($this->exactly(2))
25+
->method('has')
26+
->with('string key')
27+
->willReturnOnConsecutiveCalls(true, false);
28+
$decorator = new PsrContainerDecorator($psrContainer);
29+
$this->assertTrue($decorator->has('string key'));
30+
$this->assertFalse($decorator->has('string key'));
31+
}
32+
33+
public function testProxiesGetToDecoratedContainer()
34+
{
35+
$service = new stdClass();
36+
$psrContainer = $this->getMockBuilder(ContainerInterface::class)
37+
->getMock();
38+
$psrContainer->expects($this->once())
39+
->method('get')
40+
->with('string key')
41+
->willReturn($service);
42+
$decorator = new PsrContainerDecorator($psrContainer);
43+
$this->assertSame($service, $decorator->get('string key'));
44+
}
45+
46+
public function testGetterReturnsDecoratedContainer()
47+
{
48+
$psrContainer = $this->getMockBuilder(ContainerInterface::class)
49+
->getMock();
50+
$decorator = new PsrContainerDecorator($psrContainer);
51+
$this->assertSame($psrContainer, $decorator->getContainer());
52+
}
53+
}

0 commit comments

Comments
 (0)