3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Mvc\View\Http
;
14 use Zend\EventManager\AbstractListenerAggregate
;
15 use Zend\EventManager\EventManagerInterface
;
16 use Zend\EventManager\ListenerAggregateInterface
;
17 use Zend\Mvc\MvcEvent
;
18 use Zend\Mvc\View\SendResponseListener
;
19 use Zend\ServiceManager\ServiceManager
;
20 use Zend\View\HelperPluginManager
as ViewHelperManager
;
21 use Zend\View\Renderer\PhpRenderer
as ViewPhpRenderer
;
22 use Zend\View\Resolver
as ViewResolver
;
23 use Zend\View\Strategy\PhpRendererStrategy
;
27 * Prepares the view layer
29 * Instantiates and configures all classes related to the view layer, including
30 * the renderer (and its associated resolver(s) and helper manager), the view
31 * object (and its associated rendering strategies), and the various MVC
32 * strategies and listeners.
34 * Defines and manages the following services:
36 * - ViewHelperManager (also aliased to Zend\View\HelperPluginManager)
37 * - ViewTemplateMapResolver (also aliased to Zend\View\Resolver\TemplateMapResolver)
38 * - ViewTemplatePathStack (also aliased to Zend\View\Resolver\TemplatePathStack)
39 * - ViewResolver (also aliased to Zend\View\Resolver\AggregateResolver and ResolverInterface)
40 * - ViewRenderer (also aliased to Zend\View\Renderer\PhpRenderer and RendererInterface)
41 * - ViewPhpRendererStrategy (also aliased to Zend\View\Strategy\PhpRendererStrategy)
42 * - View (also aliased to Zend\View\View)
43 * - DefaultRenderingStrategy (also aliased to Zend\Mvc\View\Http\DefaultRenderingStrategy)
44 * - ExceptionStrategy (also aliased to Zend\Mvc\View\Http\ExceptionStrategy)
45 * - RouteNotFoundStrategy (also aliased to Zend\Mvc\View\Http\RouteNotFoundStrategy and 404Strategy)
48 class ViewManager
extends AbstractListenerAggregate
51 * @var object application configuration service
66 * Various properties representing strategies and objects instantiated and
67 * configured by the view manager
69 protected $exceptionStrategy;
70 protected $helperManager;
71 protected $mvcRenderingStrategy;
73 protected $rendererStrategy;
75 protected $routeNotFoundStrategy;
83 public function attach(EventManagerInterface
$events)
85 $this->listeners
[] = $events->attach(MvcEvent
::EVENT_BOOTSTRAP
, array($this, 'onBootstrap'), 10000);
89 * Detach aggregate listeners from the specified event manager
91 * @param EventManagerInterface $events
94 public function detach(EventManagerInterface
$events)
96 foreach ($this->listeners
as $index => $listener) {
97 if ($events->detach($listener)) {
98 unset($this->listeners
[$index]);
104 * Prepares the view layer
109 public function onBootstrap($event)
111 $application = $event->getApplication();
112 $services = $application->getServiceManager();
113 $config = $services->get('Config');
114 $events = $application->getEventManager();
115 $sharedEvents = $events->getSharedManager();
117 $this->config
= isset($config['view_manager']) && (is_array($config['view_manager']) ||
$config['view_manager'] instanceof ArrayAccess
)
118 ?
$config['view_manager']
120 $this->services
= $services;
121 $this->event
= $event;
123 $routeNotFoundStrategy = $this->getRouteNotFoundStrategy();
124 $exceptionStrategy = $this->getExceptionStrategy();
125 $mvcRenderingStrategy = $this->getMvcRenderingStrategy();
126 $createViewModelListener = new CreateViewModelListener();
127 $injectTemplateListener = new InjectTemplateListener();
128 $injectViewModelListener = new InjectViewModelListener();
130 $this->registerMvcRenderingStrategies($events);
131 $this->registerViewStrategies();
133 $events->attach($routeNotFoundStrategy);
134 $events->attach($exceptionStrategy);
135 $events->attach(MvcEvent
::EVENT_DISPATCH_ERROR
, array($injectViewModelListener, 'injectViewModel'), -100);
136 $events->attach(MvcEvent
::EVENT_RENDER_ERROR
, array($injectViewModelListener, 'injectViewModel'), -100);
137 $events->attach($mvcRenderingStrategy);
139 $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent
::EVENT_DISPATCH
, array($createViewModelListener, 'createViewModelFromArray'), -80);
140 $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent
::EVENT_DISPATCH
, array($routeNotFoundStrategy, 'prepareNotFoundViewModel'), -90);
141 $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent
::EVENT_DISPATCH
, array($createViewModelListener, 'createViewModelFromNull'), -80);
142 $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent
::EVENT_DISPATCH
, array($injectTemplateListener, 'injectTemplate'), -90);
143 $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent
::EVENT_DISPATCH
, array($injectViewModelListener, 'injectViewModel'), -100);
147 * Instantiates and configures the renderer's helper manager
149 * @return \Zend\View\HelperPluginManager
151 public function getHelperManager()
153 if ($this->helperManager
) {
154 return $this->helperManager
;
157 return $this->helperManager
= $this->services
->get('ViewHelperManager');
161 * Instantiates and configures the renderer's resolver
163 * @return ViewResolver\ResolverInterface
165 public function getResolver()
167 if (null === $this->resolver
) {
168 $this->resolver
= $this->services
->get('ViewResolver');
171 return $this->resolver
;
175 * Instantiates and configures the renderer
177 * @return ViewPhpRenderer
179 public function getRenderer()
181 if ($this->renderer
) {
182 return $this->renderer
;
185 $this->renderer
= new ViewPhpRenderer
;
186 $this->renderer
->setHelperPluginManager($this->getHelperManager());
187 $this->renderer
->setResolver($this->getResolver());
189 $model = $this->getViewModel();
190 $modelHelper = $this->renderer
->plugin('view_model');
191 $modelHelper->setRoot($model);
193 $this->services
->setService('ViewRenderer', $this->renderer
);
194 $this->services
->setAlias('Zend\View\Renderer\PhpRenderer', 'ViewRenderer');
195 $this->services
->setAlias('Zend\View\Renderer\RendererInterface', 'ViewRenderer');
197 return $this->renderer
;
201 * Instantiates and configures the renderer strategy for the view
203 * @return PhpRendererStrategy
205 public function getRendererStrategy()
207 if ($this->rendererStrategy
) {
208 return $this->rendererStrategy
;
211 $this->rendererStrategy
= new PhpRendererStrategy(
215 $this->services
->setService('ViewPhpRendererStrategy', $this->rendererStrategy
);
216 $this->services
->setAlias('Zend\View\Strategy\PhpRendererStrategy', 'ViewPhpRendererStrategy');
218 return $this->rendererStrategy
;
222 * Instantiates and configures the view
226 public function getView()
232 $this->view
= new View();
233 $this->view
->setEventManager($this->services
->get('EventManager'));
234 $this->view
->getEventManager()->attach($this->getRendererStrategy());
236 $this->services
->setService('View', $this->view
);
237 $this->services
->setAlias('Zend\View\View', 'View');
243 * Retrieves the layout template name from the configuration
247 public function getLayoutTemplate()
249 $layout = 'layout/layout';
250 if (isset($this->config
['layout'])) {
251 $layout = $this->config
['layout'];
257 * Instantiates and configures the default MVC rendering strategy
259 * @return DefaultRenderingStrategy
261 public function getMvcRenderingStrategy()
263 if ($this->mvcRenderingStrategy
) {
264 return $this->mvcRenderingStrategy
;
267 $this->mvcRenderingStrategy
= new DefaultRenderingStrategy($this->getView());
268 $this->mvcRenderingStrategy
->setLayoutTemplate($this->getLayoutTemplate());
270 $this->services
->setService('DefaultRenderingStrategy', $this->mvcRenderingStrategy
);
271 $this->services
->setAlias('Zend\Mvc\View\DefaultRenderingStrategy', 'DefaultRenderingStrategy');
272 $this->services
->setAlias('Zend\Mvc\View\Http\DefaultRenderingStrategy', 'DefaultRenderingStrategy');
274 return $this->mvcRenderingStrategy
;
278 * Instantiates and configures the exception strategy
280 * @return ExceptionStrategy
282 public function getExceptionStrategy()
284 if ($this->exceptionStrategy
) {
285 return $this->exceptionStrategy
;
288 $this->exceptionStrategy
= new ExceptionStrategy();
290 $displayExceptions = false;
291 $exceptionTemplate = 'error';
293 if (isset($this->config
['display_exceptions'])) {
294 $displayExceptions = $this->config
['display_exceptions'];
296 if (isset($this->config
['exception_template'])) {
297 $exceptionTemplate = $this->config
['exception_template'];
300 $this->exceptionStrategy
->setDisplayExceptions($displayExceptions);
301 $this->exceptionStrategy
->setExceptionTemplate($exceptionTemplate);
303 $this->services
->setService('ExceptionStrategy', $this->exceptionStrategy
);
304 $this->services
->setAlias('Zend\Mvc\View\ExceptionStrategy', 'ExceptionStrategy');
305 $this->services
->setAlias('Zend\Mvc\View\Http\ExceptionStrategy', 'ExceptionStrategy');
307 return $this->exceptionStrategy
;
311 * Instantiates and configures the "route not found", or 404, strategy
313 * @return RouteNotFoundStrategy
315 public function getRouteNotFoundStrategy()
317 if ($this->routeNotFoundStrategy
) {
318 return $this->routeNotFoundStrategy
;
321 $this->routeNotFoundStrategy
= new RouteNotFoundStrategy();
323 $displayExceptions = false;
324 $displayNotFoundReason = false;
325 $notFoundTemplate = '404';
327 if (isset($this->config
['display_exceptions'])) {
328 $displayExceptions = $this->config
['display_exceptions'];
330 if (isset($this->config
['display_not_found_reason'])) {
331 $displayNotFoundReason = $this->config
['display_not_found_reason'];
333 if (isset($this->config
['not_found_template'])) {
334 $notFoundTemplate = $this->config
['not_found_template'];
337 $this->routeNotFoundStrategy
->setDisplayExceptions($displayExceptions);
338 $this->routeNotFoundStrategy
->setDisplayNotFoundReason($displayNotFoundReason);
339 $this->routeNotFoundStrategy
->setNotFoundTemplate($notFoundTemplate);
341 $this->services
->setService('RouteNotFoundStrategy', $this->routeNotFoundStrategy
);
342 $this->services
->setAlias('Zend\Mvc\View\RouteNotFoundStrategy', 'RouteNotFoundStrategy');
343 $this->services
->setAlias('Zend\Mvc\View\Http\RouteNotFoundStrategy', 'RouteNotFoundStrategy');
344 $this->services
->setAlias('404Strategy', 'RouteNotFoundStrategy');
346 return $this->routeNotFoundStrategy
;
350 * Configures the MvcEvent view model to ensure it has the template injected
352 * @return \Zend\View\Model\ModelInterface
354 public function getViewModel()
356 if ($this->viewModel
) {
357 return $this->viewModel
;
360 $this->viewModel
= $model = $this->event
->getViewModel();
361 $model->setTemplate($this->getLayoutTemplate());
363 return $this->viewModel
;
367 * Register additional mvc rendering strategies
369 * If there is a "mvc_strategies" key of the view manager configuration, loop
370 * through it. Pull each as a service from the service manager, and, if it
371 * is a ListenerAggregate, attach it to the view, at priority 100. This
372 * latter allows each to trigger before the default mvc rendering strategy,
373 * and for them to trigger in the order they are registered.
375 protected function registerMvcRenderingStrategies(EventManagerInterface
$events)
377 if (!isset($this->config
['mvc_strategies'])) {
380 $mvcStrategies = $this->config
['mvc_strategies'];
381 if (is_string($mvcStrategies)) {
382 $mvcStrategies = array($mvcStrategies);
384 if (!is_array($mvcStrategies) && !$mvcStrategies instanceof Traversable
) {
388 foreach ($mvcStrategies as $mvcStrategy) {
389 if (!is_string($mvcStrategy)) {
393 $listener = $this->services
->get($mvcStrategy);
394 if ($listener instanceof ListenerAggregateInterface
) {
395 $events->attach($listener, 100);
401 * Register additional view strategies
403 * If there is a "strategies" key of the view manager configuration, loop
404 * through it. Pull each as a service from the service manager, and, if it
405 * is a ListenerAggregate, attach it to the view, at priority 100. This
406 * latter allows each to trigger before the default strategy, and for them
407 * to trigger in the order they are registered.
411 protected function registerViewStrategies()
413 if (!isset($this->config
['strategies'])) {
416 $strategies = $this->config
['strategies'];
417 if (is_string($strategies)) {
418 $strategies = array($strategies);
420 if (!is_array($strategies) && !$strategies instanceof Traversable
) {
424 $view = $this->getView();
426 foreach ($strategies as $strategy) {
427 if (!is_string($strategy)) {
431 $listener = $this->services
->get($strategy);
432 if ($listener instanceof ListenerAggregateInterface
) {
433 $view->getEventManager()->attach($listener, 100);