Update view listener to pass vars to layout
[zf2.biz/galerie.git] / module / Application / src / Application / View / Listener.php
1 <?php
2
3 namespace Application\View;
4
5 use ArrayAccess,
6     Zend\Di\Locator,
7     Zend\EventManager\EventCollection,
8     Zend\EventManager\ListenerAggregate,
9     Zend\EventManager\StaticEventCollection,
10     Zend\Http\PhpEnvironment\Response,
11     Zend\Mvc\Application,
12     Zend\Mvc\MvcEvent,
13     Zend\View\Renderer;
14
15 class Listener implements ListenerAggregate
16 {
17     protected $layout;
18     protected $listeners = array();
19     protected $staticListeners = array();
20     protected $view;
21     protected $displayExceptions = false;
22
23     public function __construct(Renderer $renderer, $layout = 'layout.phtml')
24     {
25         $this->view   = $renderer;
26         $this->layout = $layout;
27     }
28
29     public function setDisplayExceptionsFlag($flag)
30     {
31         $this->displayExceptions = (bool) $flag;
32         return $this;
33     }
34
35     public function displayExceptions()
36     {
37         return $this->displayExceptions;
38     }
39
40     public function attach(EventCollection $events)
41     {
42         $this->listeners[] = $events->attach('dispatch.error', array($this, 'renderError'));
43         $this->listeners[] = $events->attach('dispatch', array($this, 'render404'), -1000);
44         $this->listeners[] = $events->attach('dispatch', array($this, 'renderLayout'), -80);
45     }
46
47     public function detach(EventCollection $events)
48     {
49         foreach ($this->listeners as $key => $listener) {
50             $events->detach($listener);
51             unset($this->listeners[$key]);
52             unset($listener);
53         }
54     }
55
56     public function registerStaticListeners(StaticEventCollection $events, $locator)
57     {
58         $ident   = 'Application\Controller\PageController';
59         $handler = $events->attach($ident, 'dispatch', array($this, 'renderPageController'), -50);
60         $this->staticListeners[] = array($ident, $handler);
61
62         $ident   = 'Zend\Mvc\Controller\ActionController';
63         $handler = $events->attach($ident, 'dispatch', array($this, 'renderView'), -50);
64         $this->staticListeners[] = array($ident, $handler);
65     }
66
67     public function detachStaticListeners(StaticEventCollection $events)
68     {
69         foreach ($this->staticListeners as $i => $info) {
70             list($id, $handler) = $info;
71             $events->detach($id, $handler);
72             unset($this->staticListeners[$i]);
73         }
74     }
75
76     public function renderPageController(MvcEvent $e)
77     {
78         $page = $e->getResult();
79         if ($page instanceof Response) {
80             return;
81         }
82
83         $response = $e->getResponse();
84         if ($response->isNotFound()) {
85             return;
86         } 
87
88         $routeMatch = $e->getRouteMatch();
89
90         if (!$routeMatch) {
91             $page = '404';
92         } else {
93             $page = $routeMatch->getParam('action', '404');
94         }
95
96         if ($page == '404') {
97             $response->setStatusCode(404);
98         }
99
100         $script     = 'error/' . $page . '.phtml';
101
102         // Action content
103         $content    = $this->view->render($script);
104         $e->setResult($content);
105
106         return $this->renderLayout($e);
107     }
108
109     public function renderView(MvcEvent $e)
110     {
111         $response = $e->getResponse();
112         if (!$response->isSuccess()) {
113             return;
114         }
115
116         $routeMatch = $e->getRouteMatch();
117         $controller = $routeMatch->getParam('controller', 'index');
118         $action     = $routeMatch->getParam('action', 'index');
119         $script     = $controller . '/' . $action . '.phtml';
120
121         $vars       = $e->getResult();
122         if (is_scalar($vars)) {
123             $vars = array('content' => $vars);
124         } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
125             $vars = (array) $vars;
126         }
127
128         $content    = $this->view->render($script, $vars);
129
130         $e->setParam('content', $content);
131         return $content;
132     }
133
134     public function renderLayout(MvcEvent $e)
135     {
136         $response = $e->getResponse();
137         if (!$response) {
138             $response = new Response();
139             $e->setResponse($response);
140         }
141         if ($response->isRedirect()) {
142             return $response;
143         }
144
145         $vars = $e->getResult();
146         if (is_scalar($vars)) {
147             $vars = array('content' => $vars);
148         } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
149             $vars = (array) $vars;
150         }
151
152         if (false !== ($contentParam = $e->getParam('content', false))) {
153             $vars['content'] = $contentParam;
154         }
155
156         $layout   = $this->view->render($this->layout, $vars);
157         $response->setContent($layout);
158         return $response;
159     }
160
161     public function render404(MvcEvent $e)
162     {
163         $vars = $e->getResult();
164         if ($vars instanceof Response) {
165             return;
166         }
167
168         $response = $e->getResponse();
169         if ($response->getStatusCode() != 404) {
170             // Only handle 404's
171             return;
172         }
173
174         $vars = array(
175             'message'            => 'Page not found.',
176             'exception'          => $e->getParam('exception'),
177             'display_exceptions' => $this->displayExceptions(),
178         );
179
180         $content = $this->view->render('error/404.phtml', $vars);
181
182         $e->setResult($content);
183
184         return $this->renderLayout($e);
185     }
186
187     public function renderError(MvcEvent $e)
188     {
189         $error    = $e->getError();
190         $app      = $e->getTarget();
191         $response = $e->getResponse();
192         if (!$response) {
193             $response = new Response();
194             $e->setResponse($response);
195         }
196
197         switch ($error) {
198             case Application::ERROR_CONTROLLER_NOT_FOUND:
199             case Application::ERROR_CONTROLLER_INVALID:
200                 $vars = array(
201                     'message'            => 'Page not found.',
202                     'exception'          => $e->getParam('exception'),
203                     'display_exceptions' => $this->displayExceptions(),
204                 );
205                 $response->setStatusCode(404);
206                 break;
207
208             case Application::ERROR_EXCEPTION:
209             default:
210                 $exception = $e->getParam('exception');
211                 $vars = array(
212                     'message'            => 'An error occurred during execution; please try again later.',
213                     'exception'          => $e->getParam('exception'),
214                     'display_exceptions' => $this->displayExceptions(),
215                 );
216                 $response->setStatusCode(500);
217                 break;
218         }
219
220         $content = $this->view->render('error/index.phtml', $vars);
221
222         $e->setResult($content);
223
224         return $this->renderLayout($e);
225     }
226 }