diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 52c5a45b..c6bd9ac5 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -318,8 +318,9 @@ protected function createServiceViaCallback($callable, $cName, $rName) $factory = reset($callable); } + // duck-type MutableCreationOptionsInterface for forward compatibility if (isset($factory) - && ($factory instanceof MutableCreationOptionsInterface) + && method_exists($factory, 'setCreationOptions') && is_array($this->creationOptions) && !empty($this->creationOptions) ) { diff --git a/src/Factory/InvokableFactory.php b/src/Factory/InvokableFactory.php index 4781baab..03c991cd 100644 --- a/src/Factory/InvokableFactory.php +++ b/src/Factory/InvokableFactory.php @@ -46,19 +46,7 @@ public function __construct($creationOptions = null) return; } - if ($creationOptions instanceof Traversable) { - $creationOptions = iterator_to_array($creationOptions); - } - - if (! is_array($creationOptions)) { - throw new InvalidServiceException(sprintf( - '%s cannot use non-array, non-traversable creation options; received %s', - __CLASS__, - (is_object($creationOptions) ? get_class($creationOptions) : gettype($creationOptions)) - )); - } - - $this->creationOptions = $creationOptions; + $this->setCreationOptions($creationOptions); } /** @@ -115,4 +103,24 @@ public function createService(ServiceLocatorInterface $serviceLocator, $canonica __CLASS__ )); } + + /** + * {@inheritdoc} + */ + public function setCreationOptions(array $creationOptions) + { + if ($creationOptions instanceof Traversable) { + $creationOptions = iterator_to_array($creationOptions); + } + + if (! is_array($creationOptions)) { + throw new InvalidServiceException(sprintf( + '%s cannot use non-array, non-traversable creation options; received %s', + __CLASS__, + (is_object($creationOptions) ? get_class($creationOptions) : gettype($creationOptions)) + )); + } + + $this->creationOptions = $creationOptions; + } } diff --git a/test/AbstractPluginManagerTest.php b/test/AbstractPluginManagerTest.php index 90b9676e..c70e3bb5 100644 --- a/test/AbstractPluginManagerTest.php +++ b/test/AbstractPluginManagerTest.php @@ -15,8 +15,10 @@ use Zend\ServiceManager\Config; use Zend\ServiceManager\Exception\InvalidArgumentException; use Zend\ServiceManager\Exception\RuntimeException; +use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceManager; use ZendTest\ServiceManager\TestAsset\FooPluginManager; +use ZendTest\ServiceManager\TestAsset\InvokableObject; use ZendTest\ServiceManager\TestAsset\MockSelfReturningDelegatorFactory; class AbstractPluginManagerTest extends \PHPUnit_Framework_TestCase @@ -333,4 +335,19 @@ public function testPassingArgumentsOtherThanNullConfigOrContainerAsFirstConstru $this->setExpectedException(InvalidArgumentException::class); new FooPluginManager($arg); } + + public function testInvokableFactoryHasMutableOptions() + { + $pluginManager = new FooPluginManager($this->serviceManager); + $pluginManager->setAlias('foo', InvokableObject::class); + $pluginManager->setFactory(InvokableObject::class, InvokableFactory::class); + + $options = ['option' => 'a']; + $object = $pluginManager->get('foo', $options); + $this->assertEquals($options, $object->getOptions()); + + $options = ['option' => 'b']; + $object = $pluginManager->get('foo', $options); + $this->assertEquals($options, $object->getOptions()); + } } diff --git a/test/TestAsset/FooPluginManager.php b/test/TestAsset/FooPluginManager.php index e06edd97..ef9e2864 100644 --- a/test/TestAsset/FooPluginManager.php +++ b/test/TestAsset/FooPluginManager.php @@ -13,6 +13,8 @@ class FooPluginManager extends AbstractPluginManager { + protected $shareByDefault = false; + /** * {@inheritDoc} */