3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Mvc\Service
;
12 use Interop\Container\ContainerInterface
;
14 use Zend\Config\Config
;
15 use Zend\ModuleManager\Listener\ServiceListener
;
16 use Zend\ModuleManager\Listener\ServiceListenerInterface
;
17 use Zend\Mvc\Application
;
19 use Zend\ServiceManager\Exception\ServiceNotCreatedException
;
20 use Zend\ServiceManager\FactoryInterface
;
21 use Zend\ServiceManager\Factory\InvokableFactory
;
22 use Zend\ServiceManager\ServiceLocatorInterface
;
24 class ServiceListenerFactory
implements FactoryInterface
29 const MISSING_KEY_ERROR
= 'Invalid service listener options detected, %s array must contain %s key.';
34 const VALUE_TYPE_ERROR
= 'Invalid service listener options detected, %s must be a string, %s given.';
37 * Default mvc-related service configuration -- can be overridden by modules.
39 * @todo Re-enable form abstract service factory after zend-form updated to servicemanager v3.
42 protected $defaultServiceConfig = [
44 'configuration' => 'config',
45 'Configuration' => 'config',
46 'console' => 'ConsoleAdapter',
47 'Console' => 'ConsoleAdapter',
48 'ConsoleDefaultRenderingStrategy' => View\Console\DefaultRenderingStrategy
::class,
49 'ControllerLoader' => 'ControllerManager',
50 'Di' => 'DependencyInjector',
51 'HttpDefaultRenderingStrategy' => View\Http\DefaultRenderingStrategy
::class,
52 'MiddlewareListener' => 'Zend\Mvc\MiddlewareListener',
53 'RouteListener' => 'Zend\Mvc\RouteListener',
54 'SendResponseListener' => 'Zend\Mvc\SendResponseListener',
55 'View' => 'Zend\View\View',
56 'ViewFeedRenderer' => 'Zend\View\Renderer\FeedRenderer',
57 'ViewJsonRenderer' => 'Zend\View\Renderer\JsonRenderer',
58 'ViewPhpRendererStrategy' => 'Zend\View\Strategy\PhpRendererStrategy',
59 'ViewPhpRenderer' => 'Zend\View\Renderer\PhpRenderer',
60 'ViewRenderer' => 'Zend\View\Renderer\PhpRenderer',
61 'Zend\Di\LocatorInterface' => 'DependencyInjector',
62 'Zend\Form\Annotation\FormAnnotationBuilder' => 'FormAnnotationBuilder',
63 'Zend\Mvc\Controller\PluginManager' => 'ControllerPluginManager',
64 'Zend\Mvc\View\Http\InjectTemplateListener' => 'InjectTemplateListener',
65 'Zend\View\Renderer\RendererInterface' => 'Zend\View\Renderer\PhpRenderer',
66 'Zend\View\Resolver\TemplateMapResolver' => 'ViewTemplateMapResolver',
67 'Zend\View\Resolver\TemplatePathStack' => 'ViewTemplatePathStack',
68 'Zend\View\Resolver\AggregateResolver' => 'ViewResolver',
69 'Zend\View\Resolver\ResolverInterface' => 'ViewResolver',
73 'Application' => ApplicationFactory
::class,
74 'config' => 'Zend\Mvc\Service\ConfigFactory',
75 'ControllerManager' => 'Zend\Mvc\Service\ControllerManagerFactory',
76 'ControllerPluginManager' => 'Zend\Mvc\Service\ControllerPluginManagerFactory',
77 'ConsoleAdapter' => 'Zend\Mvc\Service\ConsoleAdapterFactory',
78 'ConsoleExceptionStrategy' => ConsoleExceptionStrategyFactory
::class,
79 'ConsoleRouter' => ConsoleRouterFactory
::class,
80 'ConsoleRouteNotFoundStrategy' => ConsoleRouteNotFoundStrategyFactory
::class,
81 'ConsoleViewManager' => 'Zend\Mvc\Service\ConsoleViewManagerFactory',
82 'DependencyInjector' => DiFactory
::class,
83 'DiAbstractServiceFactory' => DiAbstractServiceFactoryFactory
::class,
84 'DiServiceInitializer' => DiServiceInitializerFactory
::class,
85 'DiStrictAbstractServiceFactory' => DiStrictAbstractServiceFactoryFactory
::class,
86 'DispatchListener' => 'Zend\Mvc\Service\DispatchListenerFactory',
87 'FilterManager' => 'Zend\Mvc\Service\FilterManagerFactory',
88 'FormAnnotationBuilder' => 'Zend\Mvc\Service\FormAnnotationBuilderFactory',
89 'FormElementManager' => 'Zend\Mvc\Service\FormElementManagerFactory',
90 'HttpExceptionStrategy' => HttpExceptionStrategyFactory
::class,
91 'HttpMethodListener' => 'Zend\Mvc\Service\HttpMethodListenerFactory',
92 'HttpRouteNotFoundStrategy' => HttpRouteNotFoundStrategyFactory
::class,
93 'HttpRouter' => HttpRouterFactory
::class,
94 'HttpViewManager' => 'Zend\Mvc\Service\HttpViewManagerFactory',
95 'HydratorManager' => 'Zend\Mvc\Service\HydratorManagerFactory',
96 'InjectTemplateListener' => 'Zend\Mvc\Service\InjectTemplateListenerFactory',
97 'InputFilterManager' => 'Zend\Mvc\Service\InputFilterManagerFactory',
98 'LogProcessorManager' => 'Zend\Mvc\Service\LogProcessorManagerFactory',
99 'LogWriterManager' => 'Zend\Mvc\Service\LogWriterManagerFactory',
100 'MvcTranslator' => 'Zend\Mvc\Service\TranslatorServiceFactory',
101 'PaginatorPluginManager' => 'Zend\Mvc\Service\PaginatorPluginManagerFactory',
102 'Request' => 'Zend\Mvc\Service\RequestFactory',
103 'Response' => 'Zend\Mvc\Service\ResponseFactory',
104 'Router' => 'Zend\Mvc\Service\RouterFactory',
105 'RoutePluginManager' => 'Zend\Mvc\Service\RoutePluginManagerFactory',
106 'SerializerAdapterManager' => 'Zend\Mvc\Service\SerializerAdapterPluginManagerFactory',
107 'TranslatorPluginManager' => 'Zend\Mvc\Service\TranslatorPluginManagerFactory',
108 'ValidatorManager' => 'Zend\Mvc\Service\ValidatorManagerFactory',
109 View\Console\DefaultRenderingStrategy
::class => InvokableFactory
::class,
110 'ViewHelperManager' => 'Zend\Mvc\Service\ViewHelperManagerFactory',
111 View\Http\DefaultRenderingStrategy
::class => HttpDefaultRenderingStrategyFactory
::class,
112 'ViewFeedStrategy' => 'Zend\Mvc\Service\ViewFeedStrategyFactory',
113 'ViewJsonStrategy' => 'Zend\Mvc\Service\ViewJsonStrategyFactory',
114 'ViewManager' => 'Zend\Mvc\Service\ViewManagerFactory',
115 'ViewResolver' => 'Zend\Mvc\Service\ViewResolverFactory',
116 'ViewTemplateMapResolver' => 'Zend\Mvc\Service\ViewTemplateMapResolverFactory',
117 'ViewTemplatePathStack' => 'Zend\Mvc\Service\ViewTemplatePathStackFactory',
118 'ViewPrefixPathStackResolver' => 'Zend\Mvc\Service\ViewPrefixPathStackResolverFactory',
119 'Zend\Mvc\MiddlewareListener' => InvokableFactory
::class,
120 'Zend\Mvc\RouteListener' => InvokableFactory
::class,
121 'Zend\Mvc\SendResponseListener' => InvokableFactory
::class,
122 'Zend\View\Renderer\FeedRenderer' => InvokableFactory
::class,
123 'Zend\View\Renderer\JsonRenderer' => InvokableFactory
::class,
124 'Zend\View\Renderer\PhpRenderer' => ViewPhpRendererFactory
::class,
125 'Zend\View\Strategy\PhpRendererStrategy' => ViewPhpRendererStrategyFactory
::class,
126 'Zend\View\View' => ViewFactory
::class,
128 'abstract_factories' => [
129 'Zend\Form\FormAbstractServiceFactory',
136 * When executed under zend-servicemanager v3, injects additional aliases
137 * to ensure backwards compatibility.
139 public function __construct()
141 $r = new ReflectionClass(ServiceLocatorInterface
::class);
142 if ($r->hasMethod('build')) {
143 $this->injectV3Aliases();
148 * Create the service listener service
150 * Tries to get a service named ServiceListenerInterface from the service
151 * locator, otherwise creates a ServiceListener instance, passing it the
152 * container instance and the default service configuration, which can be
153 * overridden by modules.
155 * It looks for the 'service_listener_options' key in the application
156 * config and tries to add service/plugin managers as configured. The value
157 * of 'service_listener_options' must be a list (array) which contains the
160 * - service_manager: the name of the service manage to create as string
161 * - config_key: the name of the configuration key to search for as string
162 * - interface: the name of the interface that modules can implement as string
163 * - method: the name of the method that modules have to implement as string
165 * @param ServiceLocatorInterface $serviceLocator
166 * @return ServiceListenerInterface
167 * @throws ServiceNotCreatedException for invalid ServiceListener service
168 * @throws ServiceNotCreatedException For invalid configurations.
170 public function __invoke(ContainerInterface
$container, $requestedName, array $options = null)
172 $configuration = $container->get('ApplicationConfig');
174 $serviceListener = $container->has('ServiceListenerInterface')
175 ?
$container->get('ServiceListenerInterface')
176 : new ServiceListener($container);
178 if (! $serviceListener instanceof ServiceListenerInterface
) {
179 throw new ServiceNotCreatedException(
180 'The service named ServiceListenerInterface must implement '
181 . ServiceListenerInterface
::class
185 $serviceListener->setDefaultServiceConfig($this->defaultServiceConfig
);
187 if (isset($configuration['service_listener_options'])) {
188 $this->injectServiceListenerOptions($configuration['service_listener_options'], $serviceListener);
191 return $serviceListener;
195 * Create and return the ServiceListener (v2)
197 * @param ServiceLocatorInterface $container
198 * @return ServiceListenerInterface
200 public function createService(ServiceLocatorInterface
$container)
202 return $this($container, ServiceListener
::class);
206 * Validate and inject plugin manager options into the service listener.
208 * @param array $options
209 * @param ServiceListenerInterface $serviceListener
210 * @throws ServiceListenerInterface for invalid $options types
212 private function injectServiceListenerOptions($options, ServiceListenerInterface
$serviceListener)
214 if (! is_array($options)) {
215 throw new ServiceNotCreatedException(sprintf(
216 'The value of service_listener_options must be an array, %s given.',
217 (is_object($options) ?
get_class($options) : gettype($options))
221 foreach ($options as $key => $newServiceManager) {
222 $this->validatePluginManagerOptions($newServiceManager, $key);
224 $serviceListener->addServiceManager(
225 $newServiceManager['service_manager'],
226 $newServiceManager['config_key'],
227 $newServiceManager['interface'],
228 $newServiceManager['method']
234 * Validate the structure and types for plugin manager configuration options.
236 * Ensures all required keys are present in the expected types.
238 * @param array $options
239 * @param string $name Plugin manager service name; used for exception messages
240 * @throws ServiceNotCreatedException for any missing configuration options.
241 * @throws ServiceNotCreatedException for configuration options of invalid types.
243 private function validatePluginManagerOptions($options, $name)
245 if (! is_array($options)) {
246 throw new ServiceNotCreatedException(sprintf(
247 'Plugin manager configuration for "%s" is invalid; must be an array, received "%s"',
249 (is_object($options) ?
get_class($options) : gettype($options))
253 if (! isset($options['service_manager'])) {
254 throw new ServiceNotCreatedException(sprintf(self
::MISSING_KEY_ERROR
, $name, 'service_manager'));
257 if (! is_string($options['service_manager'])) {
258 throw new ServiceNotCreatedException(sprintf(
259 self
::VALUE_TYPE_ERROR
,
261 gettype($options['service_manager'])
265 if (! isset($options['config_key'])) {
266 throw new ServiceNotCreatedException(sprintf(self
::MISSING_KEY_ERROR
, $name, 'config_key'));
269 if (! is_string($options['config_key'])) {
270 throw new ServiceNotCreatedException(sprintf(
271 self
::VALUE_TYPE_ERROR
,
273 gettype($options['config_key'])
277 if (! isset($options['interface'])) {
278 throw new ServiceNotCreatedException(sprintf(self
::MISSING_KEY_ERROR
, $name, 'interface'));
281 if (! is_string($options['interface'])) {
282 throw new ServiceNotCreatedException(sprintf(
283 self
::VALUE_TYPE_ERROR
,
285 gettype($options['interface'])
289 if (! isset($options['method'])) {
290 throw new ServiceNotCreatedException(sprintf(self
::MISSING_KEY_ERROR
, $name, 'method'));
293 if (! is_string($options['method'])) {
294 throw new ServiceNotCreatedException(sprintf(
295 self
::VALUE_TYPE_ERROR
,
297 gettype($options['method'])
303 * Inject additional aliases for zend-servicemanager v3 usage
305 * If the constructor detects that we're operating under zend-servicemanager v3,
306 * this method injects additional aliases to ensure that common services
307 * can be retrieved using both Titlecase and lowercase, and will get the
312 private function injectV3Aliases()
314 $this->defaultServiceConfig
['aliases']['application'] = 'Application';
315 $this->defaultServiceConfig
['aliases']['Config'] = 'config';
316 $this->defaultServiceConfig
['aliases']['request'] = 'Request';
317 $this->defaultServiceConfig
['aliases']['response'] = 'Response';
318 $this->defaultServiceConfig
['aliases']['router'] = 'Router';