Source of file DispatchListener.php
Size: 8,136 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Mvc/DispatchListener.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Mvc; use ArrayObject; use Zend\EventManager\EventManagerInterface; use Zend\EventManager\ListenerAggregateInterface; use Zend\Mvc\Exception\InvalidControllerException; use Zend\Stdlib\ArrayUtils; /** * Default dispatch listener * * Pulls controllers from the service manager's "ControllerManager" service. * * If the controller cannot be found a "404" result is set up. Otherwise it * will continue to try to load the controller. * * If the controller is not dispatchable it sets up a "404" result. In case * of any other exceptions it trigger the "dispatch.error" event in an attempt * to return a 500 status. * * If the controller subscribes to InjectApplicationEventInterface, it injects * the current MvcEvent into the controller. * * It then calls the controller's "dispatch" method, passing it the request and * response. If an exception occurs, it triggers the "dispatch.error" event, * in an attempt to return a 500 status. * * The return value of dispatching the controller is placed into the result * property of the MvcEvent, and returned. */ class DispatchListener implements ListenerAggregateInterface { /** * @var \Zend\Stdlib\CallbackHandler[] */ protected $listeners = array(); /** * Attach listeners to an event manager * * @param EventManagerInterface $events * @return void */ public function attach(EventManagerInterface $events) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch')); if (function_exists('zend_monitor_custom_event_ex')) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'reportMonitorEvent')); } } /** * Detach listeners from an event manager * * @param EventManagerInterface $events * @return void */ public function detach(EventManagerInterface $events) { foreach ($this->listeners as $index => $listener) { if ($events->detach($listener)) { unset($this->listeners[$index]); } } } /** * Listen to the "dispatch" event * * @param MvcEvent $e * @return mixed */ public function onDispatch(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); $controllerName = $routeMatch->getParam('controller', 'not-found'); $application = $e->getApplication(); $events = $application->getEventManager(); $controllerLoader = $application->getServiceManager()->get('ControllerManager'); if (!$controllerLoader->has($controllerName)) { $return = $this->marshalControllerNotFoundEvent($application::ERROR_CONTROLLER_NOT_FOUND, $controllerName, $e, $application); return $this->complete($return, $e); } try { $controller = $controllerLoader->get($controllerName); } catch (InvalidControllerException $exception) { $return = $this->marshalControllerNotFoundEvent($application::ERROR_CONTROLLER_INVALID, $controllerName, $e, $application, $exception); return $this->complete($return, $e); } catch (\Exception $exception) { $return = $this->marshalBadControllerEvent($controllerName, $e, $application, $exception); return $this->complete($return, $e); } $request = $e->getRequest(); $response = $application->getResponse(); if ($controller instanceof InjectApplicationEventInterface) { $controller->setEvent($e); } try { $return = $controller->dispatch($request, $response); } catch (\Exception $ex) { $e->setError($application::ERROR_EXCEPTION) ->setController($controllerName) ->setControllerClass(get_class($controller)) ->setParam('exception', $ex); $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e); $return = $results->last(); if (! $return) { $return = $e->getResult(); } } return $this->complete($return, $e); } /** * @param MvcEvent $e */ public function reportMonitorEvent(MvcEvent $e) { $error = $e->getError(); $exception = $e->getParam('exception'); if ($exception instanceof \Exception) { zend_monitor_custom_event_ex($error, $exception->getMessage(), 'Zend Framework Exception', array('code' => $exception->getCode(), 'trace' => $exception->getTraceAsString())); } } /** * Complete the dispatch * * @param mixed $return * @param MvcEvent $event * @return mixed */ protected function complete($return, MvcEvent $event) { if (!is_object($return)) { if (ArrayUtils::hasStringKeys($return)) { $return = new ArrayObject($return, ArrayObject::ARRAY_AS_PROPS); } } $event->setResult($return); return $return; } /** * Marshal a controller not found exception event * * @param string $type * @param string $controllerName * @param MvcEvent $event * @param Application $application * @param \Exception $exception * @return mixed */ protected function marshalControllerNotFoundEvent( $type, $controllerName, MvcEvent $event, Application $application, \Exception $exception = null ) { $event->setError($type) ->setController($controllerName) ->setControllerClass('invalid controller class or alias: ' . $controllerName); if ($exception !== null) { $event->setParam('exception', $exception); } $events = $application->getEventManager(); $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event); $return = $results->last(); if (! $return) { $return = $event->getResult(); } return $return; } /** * Marshal a controller not found exception event * * @deprecated Use marshalControllerNotFoundEvent() instead * @param string $type * @param string $controllerName * @param MvcEvent $event * @param Application $application * @param \Exception $exception * @return mixed */ protected function marshallControllerNotFoundEvent( $type, $controllerName, MvcEvent $event, Application $application, \Exception $exception = null ) { trigger_error(sprintf( '%s is deprecated; please use %s::marshalControllerNotFoundEvent instead', __METHOD__, __CLASS__ ), E_USER_DEPRECATED); return $this->marshalControllerNotFoundEvent($type, $controllerName, $event, $application, $exception); } /** * Marshal a bad controller exception event * * @param string $controllerName * @param MvcEvent $event * @param Application $application * @param \Exception $exception * @return mixed */ protected function marshalBadControllerEvent( $controllerName, MvcEvent $event, Application $application, \Exception $exception ) { $event->setError($application::ERROR_EXCEPTION) ->setController($controllerName) ->setParam('exception', $exception); $events = $application->getEventManager(); $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event); $return = $results->last(); if (! $return) { $return = $event->getResult(); } return $return; } } |