Permalink
Browse files

Moved view events into separate object

- Moved view events into a separate object implementing
  HandlerAggregate, and attached that to the application event instance
  - Instead of attaching to the controller events statically, simply
    using priority in the application event manager
- Fixed issues in MvcEvent and Application discovered by trying 404
  pages
  • Loading branch information...
1 parent 1282cdd commit 7cba6d079e0e08419f2a4aff17c74b70fd377b96 @weierophinney committed Sep 23, 2011
View
@@ -121,6 +121,7 @@ quickstart=/home/matthew/git/zf-quickstart CD=. filter="*.php *.phtml *.ini *.sq
IndexController.php
}
View=View {
+ Listener.php
Helper=Helper {
Url.php
}
@@ -273,7 +273,7 @@ public function dispatch(MvcEvent $e)
try {
$controller = $locator->get($controllerName);
- } catch (ClassNotFoundException $e) {
+ } catch (ClassNotFoundException $exception) {
$error = clone $e;
$error->setError(static::ERROR_CONTROLLER_NOT_FOUND)
->setController($controllerName)
@@ -74,6 +74,11 @@ public function setError($message)
return $this;
}
+ public function getError()
+ {
+ return $this->getParam('error', '');
+ }
+
public function getController()
{
return $this->getParam('controller');
@@ -75,105 +75,7 @@ protected function setupEvents(Application $app)
$url = $view->plugin('url');
$url->setRouter($app->getRouter());
- $layoutHandler = function($content, $response) use ($view) {
- // Layout
- $vars = new ViewVariables(array('content' => $content));
- $layout = $view->render('layouts/layout.phtml', $vars);
-
- $response->setContent($layout);
- };
-
- $events = StaticEventManager::getInstance();
-
- // View Rendering
- $events->attach('Zend\Mvc\Controller\ActionController', 'dispatch', function($e) use ($view, $layoutHandler) {
- $vars = $e->getResult();
- if ($vars instanceof Response) {
- return;
- }
-
- $response = $e->getResponse();
- if ($response->getStatusCode() == 404) {
- // Render 404 responses differently
- return;
- }
-
- $request = $e->getRequest();
- $routeMatch = $e->getRouteMatch();
- $controller = $routeMatch->getParam('controller', 'error');
- $action = $routeMatch->getParam('action', 'index');
- $script = $controller . '/' . $action . '.phtml';
-
- if (is_object($vars)) {
- if ($vars instanceof Traversable) {
- $viewVars = new ViewVariables(array());
- $iterator = ($vars instanceof \IteratorAggregate) ? $vars->getIterator() : $vars;
- $vars = iterator_apply($vars, function($it) use ($viewVars) {
- $viewVars[$it->key()] = $it->current();
- }, array($iterator));
- $vars = $viewVars;
- } else {
- $vars = new ViewVariables((array) $vars);
- }
- } else {
- $vars = new ViewVariables($vars);
- }
-
- // Action content
- $content = $view->render($script, $vars);
-
- // Layout
- $layoutHandler($content, $response);
- return $response;
- }, -10); // post filter
-
- // Render 404 pages
- $events->attach('Zend\Mvc\Controller\ActionController', 'dispatch', function($e) use ($view, $layoutHandler) {
- $vars = $e->getResult();
- if ($vars instanceof Response) {
- return;
- }
-
- $response = $e->getResponse();
- if ($response->getStatusCode() != 404) {
- // Only handle 404's
- return;
- }
-
- $vars = array('message' => 'Page not found.');
-
- $content = $view->render('error/index.phtml', $vars);
-
- // Layout
- $layoutHandler($content, $response);
- return $response;
- }, 10); // post filter
-
- // Error handling
- $app->events()->attach('dispatch.error', function($e) use ($view, $layoutHandler) {
- $error = $e->getError();
- $app = $e->getTarget();
-
- switch ($error) {
- case Application::ERROR_CONTROLLER_NOT_FOUND:
- $vars = array(
- 'message' => 'Page not found.',
- );
- break;
- case Application::ERROR_CONTROLLER_INVALID:
- default:
- $vars = array(
- 'message' => 'Unable to serve page; invalid controller.',
- );
- break;
- }
-
- $content = $view->render('error/index.phtml', $vars);
-
- // Layout
- $response = $app->getResponse();
- $layoutHandler($content, $response);
- return $response;
- });
+ $listener = new View\Listener($view, 'layouts/layout.phtml');
+ $app->events()->attachAggregate($listener);
}
}
@@ -0,0 +1,122 @@
+<?php
+
+namespace site\View;
+
+use ArrayAccess,
+ Zend\EventManager\EventCollection,
+ Zend\EventManager\ListenerAggregate,
+ Zend\Http\Response,
+ Zend\Mvc\Application,
+ Zend\Mvc\MvcEvent,
+ Zend\View\Renderer;
+
+class Listener implements ListenerAggregate
+{
+ protected $layout;
+ protected $listeners = array();
+ protected $view;
+
+ public function __construct(Renderer $renderer, $layout = 'layout.phtml')
+ {
+ $this->view = $renderer;
+ $this->layout = $layout;
+ }
+
+ public function attach(EventCollection $events)
+ {
+ $this->listeners[] = $events->attach('dispatch.error', array($this, 'renderError'));
+ $this->listeners[] = $events->attach('dispatch', array($this, 'render404'), -80);
+ $this->listeners[] = $events->attach('dispatch', array($this, 'renderView'), -100);
+ $this->listeners[] = $events->attach('dispatch', array($this, 'renderLayout'), -1000);
+ }
+
+ public function detach(EventCollection $events)
+ {
+ foreach ($this->listeners as $key => $listener) {
+ $events->detach($listener);
+ unset($this->listeners[$key]);
+ unset($listener);
+ }
+ }
+
+ public function renderView(MvcEvent $e)
+ {
+ $routeMatch = $e->getRouteMatch();
+ $controller = $routeMatch->getParam('controller', 'index');
+ $action = $routeMatch->getParam('action', 'index');
+ $script = $controller . '/' . $action . '.phtml';
+
+ $vars = $e->getResult();
+ if (is_scalar($vars)) {
+ $vars = array('content' => $vars);
+ } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
+ $vars = (array) $vars;
+ }
+
+ $content = $this->view->render($script, $vars);
+
+ $e->setResult($content);
+ return $content;
+ }
+
+ public function renderLayout(MvcEvent $e)
+ {
+ $content = $e->getResult();
+ $layout = $this->view->render($this->layout, array('content' => $content));
+ $response = $e->getResponse();
+ if (!$response) {
+ $response = new Response();
+ $e->setResponse($response);
+ }
+ $response->setContent($layout);
+ return $response;
+ }
+
+ public function render404(MvcEvent $e)
+ {
+ $vars = $e->getResult();
+ if ($vars instanceof Response) {
+ return;
+ }
+
+ $response = $e->getResponse();
+ if ($response->getStatusCode() != 404) {
+ // Only handle 404's
+ return;
+ }
+
+ $vars = array('message' => 'Page not found.');
+
+ $content = $this->view->render('error/index.phtml', $vars);
+
+ $e->setResult($content);
+
+ return $this->renderLayout($e);
+ }
+
+ public function renderError(MvcEvent $e)
+ {
+ $error = $e->getError();
+ $app = $e->getTarget();
+
+ switch ($error) {
+ case Application::ERROR_CONTROLLER_NOT_FOUND:
+ $vars = array(
+ 'message' => 'Page not found.',
+ );
+ break;
+ case Application::ERROR_CONTROLLER_INVALID:
+ default:
+ $vars = array(
+ 'message' => 'Unable to serve page; invalid controller.',
+ );
+ break;
+ }
+
+ $content = $this->view->render('error/index.phtml', $vars);
+
+ $e->setResult($content);
+
+ return $this->renderLayout($e);
+ }
+}
@@ -1,5 +1,6 @@
<?php
return array (
+ 'site\\View\\Listener' => __DIR__ . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . 'Listener.php',
'site\\View\\Helper\\Url' => __DIR__ . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . 'Helper' . DIRECTORY_SEPARATOR . 'Url.php',
'site\\Controller\\ErrorController' => __DIR__ . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR . 'Controller' . DIRECTORY_SEPARATOR . 'ErrorController.php',
'site\\Controller\\IndexController' => __DIR__ . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR . 'Controller' . DIRECTORY_SEPARATOR . 'IndexController.php',

0 comments on commit 7cba6d0

Please sign in to comment.