From a41bd469c62f39cd091a4fa5bde1fabc63732c6a Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 18 Jun 2012 16:21:12 -0500 Subject: [PATCH 01/11] Added ability to pull from peering managers first - Basically, allows overriding of items configured in the SM via a peering manager --- src/ServiceManager.php | 66 ++++++++++++++++++++++++++----------- test/ServiceManagerTest.php | 18 ++++++++++ 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 4a580885..a86d2d67 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -59,6 +59,11 @@ class ServiceManager implements ServiceLocatorInterface */ protected $peeringServiceManagers = array(); + /** + * @var bool + */ + protected $retrieveFromPeeringManagerFirst = false; + /** * @var bool Track whether not ot throw exceptions during create() */ @@ -109,6 +114,17 @@ public function getThrowExceptionInCreate() return $this->throwExceptionInCreate; } + public function setRetrieveFromPeeringManagerFirst($retrieveFromPeeringManagerFirst = true) + { + $this->retrieveFromPeeringManagerFirst = (bool) $retrieveFromPeeringManagerFirst; + return $this; + } + + public function retrieveFromPeeringManagerFirst() + { + return $this->retrieveFromPeeringManagerFirst; + } + /** * @param $name * @param $invokableClass @@ -282,25 +298,20 @@ public function get($name, $usePeeringServiceManagers = true) $selfException = null; if (!$instance && !is_array($instance)) { - try { - $instance = $this->create(array($cName, $rName)); - } catch (\Exception $selfException) { - if (!$selfException instanceof Exception\ServiceNotFoundException && - !$selfException instanceof Exception\ServiceNotCreatedException) { - throw $selfException; - } - if ($usePeeringServiceManagers) { - foreach ($this->peeringServiceManagers as $peeringServiceManager) { - try { - $instance = $peeringServiceManager->get($name); - } catch (Exception\ServiceNotFoundException $e) { - continue; - } catch (Exception\ServiceNotCreatedException $e) { - continue; - } catch (\Exception $e) { - throw $e; - } - break; + $retrieveFromPeeringManagerFirst = $this->retrieveFromPeeringManagerFirst(); + if ($usePeeringServiceManagers && $retrieveFromPeeringManagerFirst) { + $instance = $this->retrieveFromPeeringManager($name); + } + if (!$instance) { + try { + $instance = $this->create(array($cName, $rName)); + } catch (\Exception $selfException) { + if (!$selfException instanceof Exception\ServiceNotFoundException && + !$selfException instanceof Exception\ServiceNotCreatedException) { + throw $selfException; + } + if ($usePeeringServiceManagers && !$retrieveFromPeeringManagerFirst) { + $instance = $this->retrieveFromPeeringManager($name); } } } @@ -604,4 +615,21 @@ public function getRegisteredServices() ); } + protected function retrieveFromPeeringManager($name) + { + $instance = null; + foreach ($this->peeringServiceManagers as $peeringServiceManager) { + try { + $instance = $peeringServiceManager->get($name); + } catch (Exception\ServiceNotFoundException $e) { + continue; + } catch (Exception\ServiceNotCreatedException $e) { + continue; + } catch (\Exception $e) { + throw $e; + } + break; + } + return $instance; + } } diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index d8aad618..1d4ede71 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -217,6 +217,24 @@ public function testCanRetrieveFromChildPeeringManager() $this->assertEquals('bar', $parent->get('foo')); } + /** + * @group fml + */ + public function testAllowsRetrievingFromPeeringContainerFirst() + { + $parent = new ServiceManager(); + $parent->setFactory('foo', function($sm) { + return 'bar'; + }); + $child = new ServiceManager(); + $child->setFactory('foo', function($sm) { + return 'baz'; + }); + $child->addPeeringServiceManager($parent, ServiceManager::SCOPE_PARENT); + $child->setRetrieveFromPeeringManagerFirst(true); + $this->assertEquals('bar', $child->get('foo')); + } + /** * @covers Zend\ServiceManager\ServiceManager::create */ From 5fe7de62359ff47e9e618b85d728f94fc75c2099 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 18 Jun 2012 16:36:04 -0500 Subject: [PATCH 02/11] Move creational code to methods - Will allow overriding later in subclasses --- src/ServiceManager.php | 149 ++++++++++++++++++++++++------------ test/ServiceManagerTest.php | 3 - 2 files changed, 101 insertions(+), 51 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index a86d2d67..415a6c04 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -345,7 +345,7 @@ public function get($name, $usePeeringServiceManagers = true) public function create($name) { $instance = false; - $rName = null; + $rName = null; if (is_array($name)) { list($cName, $rName) = $name; @@ -356,59 +356,15 @@ public function create($name) $cName = $this->canonicalizeName($cName); if (isset($this->invokableClasses[$cName])) { - $invokable = $this->invokableClasses[$cName]; - if (!class_exists($invokable)) { - throw new Exception\ServiceNotCreatedException(sprintf( - '%s: failed retrieving "%s%s" via invokable class "%s"; class does not exist', - __METHOD__, - $cName, - ($rName ? '(alias: ' . $rName . ')' : ''), - $cName - )); - } - $instance = new $invokable; + $instance = $this->createFromInvokable($cName, $rName); } if (!$instance && isset($this->factories[$cName])) { - $factory = $this->factories[$cName]; - if (is_string($factory) && class_exists($factory, true)) { - $factory = new $factory; - $this->factories[$cName] = $factory; - } - if ($factory instanceof FactoryInterface) { - $instance = $this->createServiceViaCallback(array($factory, 'createService'), $cName, $rName); - } elseif (is_callable($factory)) { - $instance = $this->createServiceViaCallback($factory, $cName, $rName); - } else { - throw new Exception\ServiceNotCreatedException(sprintf( - 'While attempting to create %s%s an invalid factory was registered for this instance type.', - $cName, - ($rName ? '(alias: ' . $rName . ')' : '') - )); - } + $instance = $this->createFromFactory($cName, $rName); } if (!$instance && !empty($this->abstractFactories)) { - foreach ($this->abstractFactories as $index => $abstractFactory) { - // support factories as strings - if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { - $this->abstractFactories[$index] = $abstractFactory = new $abstractFactory; - } - if ($abstractFactory instanceof AbstractFactoryInterface) { - $instance = $this->createServiceViaCallback(array($abstractFactory, 'createServiceWithName'), $cName, $rName); - } elseif (is_callable($abstractFactory)) { - $instance = $this->createServiceViaCallback($abstractFactory, $cName, $rName); - } else { - throw new Exception\ServiceNotCreatedException(sprintf( - 'While attempting to create %s%s an abstract factory could not produce a valid instance.', - $cName, - ($rName ? '(alias: ' . $rName . ')' : '') - )); - } - if (is_object($instance)) { - break; - } - } + $instance = $this->createFromAbstractFactory($cName, $rName); } if ($this->throwExceptionInCreate == true && $instance === false) { @@ -615,6 +571,12 @@ public function getRegisteredServices() ); } + /** + * Attempt to retrieve an instance via a peering manager + * + * @param string $name + * @return mixed + */ protected function retrieveFromPeeringManager($name) { $instance = null; @@ -632,4 +594,95 @@ protected function retrieveFromPeeringManager($name) } return $instance; } + + /** + * Attempt to create an instance via an invokable class + * + * @param string $canonicalName + * @param string $requestedName + * @return null|\stdClass + * @throws Exception\ServiceNotCreatedException If resolved class does not exist + */ + protected function createFromInvokable($canonicalName, $requestedName) + { + $invokable = $this->invokableClasses[$canonicalName]; + if (!class_exists($invokable)) { + throw new Exception\ServiceNotCreatedException(sprintf( + '%s: failed retrieving "%s%s" via invokable class "%s"; class does not exist', + __METHOD__, + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : ''), + $canonicalName + )); + } + $instance = new $invokable; + return $instance; + } + + /** + * Attempt to create an instance via a factory + * + * @param string $canonicalName + * @param string $requestedName + * @return mixed + * @throws Exception\ServiceNotCreatedException If factory is not callable + */ + protected function createFromFactory($canonicalName, $requestedName) + { + $factory = $this->factories[$canonicalName]; + if (is_string($factory) && class_exists($factory, true)) { + $factory = new $factory; + $this->factories[$canonicalName] = $factory; + } + if ($factory instanceof FactoryInterface) { + $instance = $this->createServiceViaCallback(array($factory, 'createService'), $canonicalName, $requestedName); + } elseif (is_callable($factory)) { + $instance = $this->createServiceViaCallback($factory, $canonicalName, $requestedName); + } else { + throw new Exception\ServiceNotCreatedException(sprintf( + 'While attempting to create %s%s an invalid factory was registered for this instance type.', + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : '') + )); + } + return $instance; + } + + /** + * Attempt to create an instance via an abstract factory + * + * @param string $canonicalName + * @param string $requestedName + * @return \stdClass|null + * @throws Exception\ServiceNotCreatedException If abstract factory is not callable + */ + protected function createFromAbstractFactory($canonicalName, $requestedName) + { + foreach ($this->abstractFactories as $index => $abstractFactory) { + // support factories as strings + if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { + $this->abstractFactories[$index] = $abstractFactory = new $abstractFactory; + } + if ($abstractFactory instanceof AbstractFactoryInterface) { + $instance = $this->createServiceViaCallback( + array($abstractFactory, 'createServiceWithName'), + $canonicalName, + $requestedName + ); + } elseif (is_callable($abstractFactory)) { + $instance = $this->createServiceViaCallback($abstractFactory, $canonicalName, $requestedName); + } else { + throw new Exception\ServiceNotCreatedException(sprintf( + 'While attempting to create %s%s an abstract factory could not produce a valid instance.', + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : '') + )); + } + if (is_object($instance)) { + break; + } + } + + return $instance; + } } diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 1d4ede71..ca9c3baa 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -217,9 +217,6 @@ public function testCanRetrieveFromChildPeeringManager() $this->assertEquals('bar', $parent->get('foo')); } - /** - * @group fml - */ public function testAllowsRetrievingFromPeeringContainerFirst() { $parent = new ServiceManager(); From ca638eb15798f4484f988428004f9b99976665d3 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 18 Jun 2012 16:51:44 -0500 Subject: [PATCH 03/11] Refactored FilterChain to use ServiceManager - Updates base ServiceManager to allow arbitrary callables as initializers - Created context-specific ServiceManager - Sets up initial list of invokables, aliases, and shared status - Toggles sharing flag in various setters to be off by default - Modifies get() to allow passing options as second argument - Overrides createFromInvokable to pass options to constructor, if present - Adds initializer to ensure we have a valid filter Basically, serves as a POC for a SM-based plugin broker. --- src/ServiceManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 415a6c04..07064cca 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -378,8 +378,10 @@ public function create($name) foreach ($this->initializers as $initializer) { if ($initializer instanceof InitializerInterface) { $initializer->initialize($instance); - } else { + } elseif (is_object($initializer) && is_callable($initializer)) { $initializer($instance); + } else { + call_user_func($initializer, $instance); } } From e3eb4a40f5b00a95c01a3806617e9a66259c6d3a Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 19 Jun 2012 11:54:19 -0500 Subject: [PATCH 04/11] Moved common functionality to AbstractPluginManager - AbstractPluginManager defines: - allowOverride as on by default - validatePlugin() as abstract, and __construct() adds it as an initializer - get/createFromInvokable() allow passing options for requested plugins - Filter\ServiceManager now extends AbstractPluginManager, and only needs to define invokables, aliases, and validatePlugin() --- src/AbstractPluginManager.php | 133 ++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/AbstractPluginManager.php diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php new file mode 100644 index 00000000..76e2c2e4 --- /dev/null +++ b/src/AbstractPluginManager.php @@ -0,0 +1,133 @@ +addInitializer(array($this, 'validatePlugin'), true); + } + + /** + * Validate the plugin + * + * Checks that the filter loaded is either a valid callback or an instance + * of FilterInterface. + * + * @param mixed $plugin + * @return void + * @throws Exception\RuntimeException if invalid + */ + abstract public function validatePlugin($plugin); + + /** + * Retrieve a service from the manager by name + * + * Allows passing an array of options to use when creating the instance. + * createFromInvokable() will use these and pass them to the instance + * constructor if not null and a non-empty array. + * + * @param string $name + * @param array $options + * @param bool $usePeeringServiceManagers + * @return object + */ + public function get($name, $options = array(), $usePeeringServiceManagers = true) + { + $this->creationOptions = $options; + $instance = parent::get($name, $usePeeringServiceManagers); + $this->creationOptions = null; + return $instance; + } + + /** + * Attempt to create an instance via an invokable class + * + * Overrides parent implementation by passing $creationOptions to the + * constructor, if non-null. + * + * @param string $canonicalName + * @param string $requestedName + * @return null|\stdClass + * @throws Exception\ServiceNotCreatedException If resolved class does not exist + */ + protected function createFromInvokable($canonicalName, $requestedName) + { + $invokable = $this->invokableClasses[$canonicalName]; + if (!class_exists($invokable)) { + throw new Exception\ServiceNotCreatedException(sprintf( + '%s: failed retrieving "%s%s" via invokable class "%s"; class does not exist', + __METHOD__, + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : ''), + $canonicalName + )); + } + + if (null === $this->creationOptions + || (is_array($this->creationOptions) && empty($this->creationOptions)) + ) { + $instance = new $invokable(); + } else { + $instance = new $invokable($this->creationOptions); + } + + return $instance; + } +} From 93977487be295ab8e9142bce890fbc5faaf78c23 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 20 Jun 2012 11:08:47 -0500 Subject: [PATCH 05/11] Added way to retrieve by class name - If the plugin service does not exist, and it's a class name, add it as an invokable - Allows us to remove any aliases for class names! --- src/AbstractPluginManager.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 76e2c2e4..d5e7bc97 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -90,6 +90,11 @@ abstract public function validatePlugin($plugin); */ public function get($name, $options = array(), $usePeeringServiceManagers = true) { + // Allow specifying a class name directly; registers as an invokable class + if (!$this->has($name) && class_exists($name)) { + $this->setInvokableClass($name, $name); + } + $this->creationOptions = $options; $instance = parent::get($name, $usePeeringServiceManagers); $this->creationOptions = null; From 74db241fdd719ad666b23c525de29902aa2f4699 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 21 Jun 2012 08:35:38 -0500 Subject: [PATCH 06/11] Refactored Log to use AbstractPluginManager - Removed WriterBroker and WriterLoader - Added WriterPluginManager - Modified Logger to use WriterPluginManager - Overrode setService() in AbstractPluginManager in order to validate the service before registering it. --- src/AbstractPluginManager.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index d5e7bc97..4698ef17 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -101,6 +101,25 @@ public function get($name, $options = array(), $usePeeringServiceManagers = true return $instance; } + /** + * Register a service with the locator. + * + * Validates that the service object via validatePlugin() prior to + * attempting to register it. + * + * @param string $name + * @param mixed $service + * @param bool $shared + * @return AbstractPluginManager + * @throws Exception\InvalidServiceNameException + */ + public function setService($name, $service, $shared = true) + { + $this->validatePlugin($service); + parent::setService($name, $service, $shared); + return $this; + } + /** * Attempt to create an instance via an invokable class * From af157c9ac20e4b0d672f793d7c899b93d308a6bc Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 21 Jun 2012 08:40:03 -0500 Subject: [PATCH 07/11] Only validate a service if not null - in order to allow unsetting a service instance --- src/AbstractPluginManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 4698ef17..d0ea91c8 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -115,7 +115,9 @@ public function get($name, $options = array(), $usePeeringServiceManagers = true */ public function setService($name, $service, $shared = true) { - $this->validatePlugin($service); + if ($service) { + $this->validatePlugin($service); + } parent::setService($name, $service, $shared); return $this; } From 70f7f38ba0b1a16323d896962faeeb1c0b00d66f Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 21 Jun 2012 16:28:22 -0500 Subject: [PATCH 08/11] Refactored View to use AbstractPluginManager - Helper management - Removed HelperLoader and HelperBroker - Created HelperPluginManager - Refactored PhpRenderer to use HelperPluginManager - Helpers - Removed Navigation\HelperLoader, and replaced with Navigatin\PluginManager - Refactored Navigation to use a PluginManager instead of HelperLoader + internal registry - Fixed HeadLink and HeadMeta helpers; don't look for Pluggable interface, but instead duck type on plugin() method - Forms - changed Form HelperLoader to a SM configuration object - duck type on plugin() instead of type check on Pluggable - Refactored Mvc\View\ViewManager to remove references to HelperLoader and rename HelperBroker to HelperManager; kept original alias for ViewHelperBroker for migration. Moved all plugin mapping to helper manager configuration. - Ensured all tests related to views, MVC, and forms pass --- src/ServiceManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 07064cca..67e1f83f 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -329,7 +329,9 @@ public function get($name, $usePeeringServiceManagers = true) ); } - if (isset($this->shared[$cName]) && $this->shared[$cName] === true) { + if (!isset($this->instances[$cName]) + && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) + ) { $this->instances[$cName] = $instance; } From 3266fc06b080aa7aef39adeee4f48b9590dff915 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 21 Jun 2012 23:44:20 -0500 Subject: [PATCH 09/11] Better capabilities surrounding sharing - Added flag "sharedByDefault" to ServiceManager implementation, set to true by default - Disabling the flag disables storing created instances for re-use - Used with a variety of components: Cache, Crypt, Paginator, and the static variants of Filter and Validator - Cannot re-set the flag if allowOverride is false --- src/ServiceManager.php | 50 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 67e1f83f..f4a40b4c 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -59,6 +59,13 @@ class ServiceManager implements ServiceLocatorInterface */ protected $peeringServiceManagers = array(); + /** + * Whether or not to share by default + * + * @var bool + */ + protected $shareByDefault = true; + /** * @var bool */ @@ -96,6 +103,35 @@ public function getAllowOverride() return $this->allowOverride; } + /** + * Set flag indicating whether services are shared by default + * + * @param bool $shareByDefault + * @return ServiceManager + * @throws Exception\RuntimeException if allowOverride is false + */ + public function setShareByDefault($shareByDefault) + { + if ($this->allowOverride === false) { + throw new Exception\RuntimeException(sprintf( + '%s: cannot alter default shared service setting; container is marked immutable (allow_override is false)', + __METHOD__ + )); + } + $this->shareByDefault = (bool) $shareByDefault; + return $this; + } + + /** + * Are services shared by default? + * + * @return bool + */ + public function shareByDefault() + { + return $this->shareByDefault; + } + /** * @param bool $throwExceptionInCreate * @return ServiceManager @@ -114,12 +150,23 @@ public function getThrowExceptionInCreate() return $this->throwExceptionInCreate; } + /** + * Set flag indicating whether to pull from peering manager before attempting creation + * + * @param bool $retrieveFromPeeringManagerFirst + * @return ServiceManager + */ public function setRetrieveFromPeeringManagerFirst($retrieveFromPeeringManagerFirst = true) { $this->retrieveFromPeeringManagerFirst = (bool) $retrieveFromPeeringManagerFirst; return $this; } + /** + * Should we retrieve from the peering manager prior to attempting to create a service? + * + * @return bool + */ public function retrieveFromPeeringManagerFirst() { return $this->retrieveFromPeeringManagerFirst; @@ -329,7 +376,8 @@ public function get($name, $usePeeringServiceManagers = true) ); } - if (!isset($this->instances[$cName]) + if ($this->shareByDefault() + && !isset($this->instances[$cName]) && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) ) { $this->instances[$cName] = $instance; From 6684eb7b572db11057b620c6dff841dcc22ccedb Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 22 Jun 2012 00:20:59 -0500 Subject: [PATCH 10/11] Refactored Mvc\Router to use AbstractPluginManager - Removed RouteBroker - Created RoutePluginManager; does not share by default, and overrides createFromInvokable() to create using route class' factory methods. - Refactored SimpleRouteStack, TreeRouteStack, and Part route to use RoutePluginManager, and to have config key "route_plugins" instead of "route_broker" - Ensured all tests pass --- src/AbstractPluginManager.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index d0ea91c8..a3407916 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -20,6 +20,8 @@ namespace Zend\ServiceManager; +use Zend\Code\Reflection\ClassReflection; + /** * ServiceManager implementation for managing plugins * @@ -156,4 +158,25 @@ protected function createFromInvokable($canonicalName, $requestedName) return $instance; } + + /** + * Determine if a class implements a given interface + * + * For PHP versions >= 5.3.7, uses is_subclass_of; otherwise, uses + * reflection to determine the interfaces implemented. + * + * @param string $class + * @param string $type + * @return bool + */ + protected function isSubclassOf($class, $type) + { + if (version_compare(PHP_VERSION, '5.3.7', 'gte')) { + return is_subclass_of($class, $type); + } + + $r = new ClassReflection($class); + $interfaces = $r->getInterfaceNames(); + return (in_array($type, $interfaces)); + } } From 8c09cfc7816f8fa24e56476b32342facaf71ecc7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 25 Jun 2012 08:26:18 -0500 Subject: [PATCH 11/11] [zen-56][zendframework/zf2#1550] pull from peering managers first - Necessary to allow overriding a plugin; reported by Evan Coury --- src/AbstractPluginManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index a3407916..4367354e 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -51,6 +51,13 @@ abstract class AbstractPluginManager extends ServiceManager */ protected $creationOptions = null; + /** + * Enable this by default to allow overriding the default plugins + * + * @var bool + */ + protected $retrieveFromPeeringManagerFirst = true; + /** * Constructor *