<?php namespace Laminas\EventManager; use Psr\Container\ContainerInterface; use function is_string; use function method_exists; /** * Lazy listener instance. * * Used to allow lazy creation of listeners via a dependency injection * container. * * Lazy listener definitions have the following members: * * - listener: the service name of the listener to use. * - method: the method name of the listener to invoke for the specified event. * * If desired, you can pass $env at instantiation; this will be passed to the * container's `build()` method, if it has one, when creating the listener * instance. * * Pass instances directly to the event manager's `attach()` method as the * listener argument. */ class LazyListener { /** @var ContainerInterface Container from which to pull listener. */ private $container; /** @var array Variables/options to use during service creation, if any. */ private $env; /** @var callable Marshaled listener callback. */ private $listener; /** @var string Method name to invoke on listener. */ private $method; /** @var string Service name of listener. */ private $service; /** * @param array $definition * @param array $env */ public function __construct(array $definition, ContainerInterface $container, array $env = []) { if ( ! isset($definition['listener']) || ! is_string($definition['listener']) || empty($definition['listener']) ) { throw new Exception\InvalidArgumentException( 'Lazy listener definition is missing a valid "listener" member; cannot create LazyListener' ); } if ( ! isset($definition['method']) || ! is_string($definition['method']) || empty($definition['method']) ) { throw new Exception\InvalidArgumentException( 'Lazy listener definition is missing a valid "method" member; cannot create LazyListener' ); } $this->service = $definition['listener']; $this->method = $definition['method']; $this->container = $container; $this->env = $env; } /** * Use the listener as an invokable, allowing direct attachment to an event manager. * * @return callable */ public function __invoke(EventInterface $event) { $listener = $this->fetchListener(); $method = $this->method; return $listener->{$method}($event); } /** * @return callable */ private function fetchListener() { if ($this->listener) { return $this->listener; } // In the future, typehint against Laminas\ServiceManager\ServiceLocatorInterface, // which defines this message starting in v3. if (method_exists($this->container, 'build') && ! empty($this->env)) { $this->listener = $this->container->build($this->service, $this->env); return $this->listener; } $this->listener = $this->container->get($this->service); return $this->listener; } }