Modified vendor/ZendFramework to track weierophinney/feature/view-layer
[zf2.biz/application_blanche.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   = 'Zend\Mvc\Controller\ActionController';
59         $handler = $events->attach($ident, 'dispatch', array($this, 'renderView'), -50);
60         $this->staticListeners[] = array($ident, $handler);
61     }
62
63     public function detachStaticListeners(StaticEventCollection $events)
64     {
65         foreach ($this->staticListeners as $i => $info) {
66             list($id, $handler) = $info;
67             $events->detach($id, $handler);
68             unset($this->staticListeners[$i]);
69         }
70     }
71
72     public function renderView(MvcEvent $e)
73     {
74         $response = $e->getResponse();
75         if (!$response->isSuccess()) {
76             return;
77         }
78
79         $routeMatch = $e->getRouteMatch();
80         $controller = $routeMatch->getParam('controller', 'index');
81         $action     = $routeMatch->getParam('action', 'index');
82         $script     = $controller . '/' . $action . '.phtml';
83
84         $vars       = $e->getResult();
85         if (is_scalar($vars)) {
86             $vars = array('content' => $vars);
87         } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
88             $vars = (array) $vars;
89         }
90
91         $content    = $this->view->render($script, $vars);
92
93         $e->setParam('content', $content);
94         return $content;
95     }
96
97     public function renderLayout(MvcEvent $e)
98     {
99         $response = $e->getResponse();
100         if (!$response) {
101             $response = new Response();
102             $e->setResponse($response);
103         }
104         if ($response->isRedirect()) {
105             return $response;
106         }
107
108         $vars = $e->getResult();
109         if (is_scalar($vars)) {
110             $vars = array('content' => $vars);
111         } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
112             $vars = (array) $vars;
113         }
114
115         if (false !== ($contentParam = $e->getParam('content', false))) {
116             $vars['content'] = $contentParam;
117         }
118
119         $layout   = $this->view->render($this->layout, $vars);
120         $response->setContent($layout);
121         return $response;
122     }
123
124     public function render404(MvcEvent $e)
125     {
126         $vars = $e->getResult();
127         if ($vars instanceof Response) {
128             return;
129         }
130
131         $response = $e->getResponse();
132         if ($response->getStatusCode() != 404) {
133             // Only handle 404's
134             return;
135         }
136
137         $vars = array(
138             'message'            => 'Page not found.',
139             'exception'          => $e->getParam('exception'),
140             'display_exceptions' => $this->displayExceptions(),
141         );
142
143         $content = $this->view->render('error/404.phtml', $vars);
144
145         $e->setResult($content);
146
147         return $this->renderLayout($e);
148     }
149
150     public function renderError(MvcEvent $e)
151     {
152         $error    = $e->getError();
153         $response = $e->getResponse();
154         if (!$response) {
155             $response = new Response();
156             $e->setResponse($response);
157         }
158
159         switch ($error) {
160             case Application::ERROR_CONTROLLER_NOT_FOUND:
161             case Application::ERROR_CONTROLLER_INVALID:
162                 $vars = array(
163                     'message'            => 'Page not found.',
164                     'exception'          => $e->getParam('exception'),
165                     'display_exceptions' => $this->displayExceptions(),
166                 );
167                 $response->setStatusCode(404);
168                 break;
169
170             case Application::ERROR_EXCEPTION:
171             default:
172                 $vars = array(
173                     'message'            => 'An error occurred during execution; please try again later.',
174                     'exception'          => $e->getParam('exception'),
175                     'display_exceptions' => $this->displayExceptions(),
176                 );
177                 $response->setStatusCode(500);
178                 break;
179         }
180
181         $content = $this->view->render('error/index.phtml', $vars);
182
183         $e->setResult($content);
184
185         return $this->renderLayout($e);
186     }
187 }