Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

223 lines (202 sloc) 7.114 kb
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_ServiceManager
*/
namespace Zend\ServiceManager;
/**
* ServiceManager implementation for managing plugins
*
* Automatically registers an initializer which should be used to verify that
* a plugin instance is of a valid type. Additionally, allows plugins to accept
* an array of options for the constructor, which can be used to configure
* the plugin when retrieved. Finally, enables the allowOverride property by
* default to allow registering factories, aliases, and invokables to take
* the place of those provided by the implementing class.
*
* @category Zend
* @package Zend_ServiceManager
*/
abstract class AbstractPluginManager extends ServiceManager implements ServiceLocatorAwareInterface
{
/**
* Allow overriding by default
*
* @var bool
*/
protected $allowOverride = true;
/**
* Whether or not to auto-add a class as an invokable class if it exists
*
* @var bool
*/
protected $autoAddInvokableClass = true;
/**
* Options to use when creating an instance
*
* @var mixed
*/
protected $creationOptions = null;
/**
* The main service locator
*
* @var ServiceLocatorInterface
*/
protected $serviceLocator;
/**
* Constructor
*
* Add a default initializer to ensure the plugin is valid after instance
* creation.
*
* @param null|ConfigInterface $configuration
*/
public function __construct(ConfigInterface $configuration = null)
{
parent::__construct($configuration);
$self = $this;
$this->addInitializer(function ($instance) use ($self) {
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($self);
}
if ($instance instanceof ServiceManagerAwareInterface) {
$instance->setServiceManager($self);
}
});
}
/**
* 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)
{
// Allow specifying a class name directly; registers as an invokable class
if (!$this->has($name) && $this->autoAddInvokableClass && class_exists($name)) {
$this->setInvokableClass($name, $name);
}
$this->creationOptions = $options;
$instance = parent::get($name, $usePeeringServiceManagers);
$this->creationOptions = null;
$this->validatePlugin($instance);
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)
{
if ($service) {
$this->validatePlugin($service);
}
parent::setService($name, $service, $shared);
return $this;
}
/**
* Set the main service locator so factories can have access to it to pull deps
*
* @param ServiceLocatorInterface $serviceLocator
* @return AbstractPluginManager
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
/**
* Get the main plugin manager. Useful for fetching dependencies from within factories.
*
* @return mixed
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
/**
* 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 (null === $this->creationOptions
|| (is_array($this->creationOptions) && empty($this->creationOptions))
) {
$instance = new $invokable();
} else {
$instance = new $invokable($this->creationOptions);
}
return $instance;
}
/**
* Attempt to create an instance via a factory class
*
* Overrides parent implementation by passing $creationOptions to the
* constructor, if non-null.
*
* @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)) {
if (null === $this->creationOptions || (is_array($this->creationOptions) && empty($this->creationOptions))) {
$factory = new $factory();
} else {
$factory = new $factory($this->creationOptions);
}
$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;
}
}
Jump to Line
Something went wrong with that request. Please try again.