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
12 use Zend\EventManager\EventManagerAwareInterface
;
13 use Zend\EventManager\EventManagerInterface
;
14 use Zend\ServiceManager\ServiceManager
;
15 use Zend\Stdlib\ResponseInterface
;
18 * Main application class for invoking applications
20 * Expects the user will provide a configured ServiceManager, configured with
21 * the following services:
32 * The most common workflow is:
34 * $services = new Zend\ServiceManager\ServiceManager($servicesConfig);
35 * $app = new Application($appConfig, $services);
37 * $response = $app->run();
41 * bootstrap() opts in to the default route, dispatch, and view listeners,
42 * sets up the MvcEvent, and triggers the bootstrap event. This can be omitted
43 * if you wish to setup your own listeners and/or workflow; alternately, you
44 * can simply extend the class to override such behavior.
46 class Application
implements
48 EventManagerAwareInterface
50 const ERROR_CONTROLLER_CANNOT_DISPATCH
= 'error-controller-cannot-dispatch';
51 const ERROR_CONTROLLER_NOT_FOUND
= 'error-controller-not-found';
52 const ERROR_CONTROLLER_INVALID
= 'error-controller-invalid';
53 const ERROR_EXCEPTION
= 'error-exception';
54 const ERROR_ROUTER_NO_MATCH
= 'error-router-no-match';
59 protected $configuration = null;
62 * Default application event listeners
66 protected $defaultListeners = array(
70 'SendResponseListener',
80 * @var EventManagerInterface
85 * @var \Zend\Stdlib\RequestInterface
90 * @var ResponseInterface
97 protected $serviceManager = null;
102 * @param mixed $configuration
103 * @param ServiceManager $serviceManager
105 public function __construct($configuration, ServiceManager
$serviceManager)
107 $this->configuration
= $configuration;
108 $this->serviceManager
= $serviceManager;
110 $this->setEventManager($serviceManager->get('EventManager'));
112 $this->request
= $serviceManager->get('Request');
113 $this->response
= $serviceManager->get('Response');
117 * Retrieve the application configuration
119 * @return array|object
121 public function getConfig()
123 return $this->serviceManager
->get('Config');
127 * Bootstrap the application
129 * Defines and binds the MvcEvent, and passes it the request, response, and
130 * router. Attaches the ViewManager as a listener. Triggers the bootstrap
133 * @param array $listeners List of listeners to attach.
134 * @return Application
136 public function bootstrap(array $listeners = array())
138 $serviceManager = $this->serviceManager
;
139 $events = $this->events
;
141 $listeners = array_unique(array_merge($this->defaultListeners
, $listeners));
143 foreach ($listeners as $listener) {
144 $events->attach($serviceManager->get($listener));
148 $this->event
= $event = new MvcEvent();
149 $event->setTarget($this);
150 $event->setApplication($this)
151 ->setRequest($this->getRequest())
152 ->setResponse($this->getResponse())
153 ->setRouter($serviceManager->get('Router'));
155 // Trigger bootstrap events
156 $events->trigger(MvcEvent
::EVENT_BOOTSTRAP
, $event);
161 * Retrieve the service manager
163 * @return ServiceManager
165 public function getServiceManager()
167 return $this->serviceManager
;
171 * Get the request object
173 * @return \Zend\Stdlib\RequestInterface
175 public function getRequest()
177 return $this->request
;
181 * Get the response object
183 * @return ResponseInterface
185 public function getResponse()
187 return $this->response
;
191 * Get the MVC event instance
195 public function getMvcEvent()
201 * Set the event manager instance
203 * @param EventManagerInterface $eventManager
204 * @return Application
206 public function setEventManager(EventManagerInterface
$eventManager)
208 $eventManager->setIdentifiers(array(
212 $this->events
= $eventManager;
217 * Retrieve the event manager
219 * Lazy-loads an EventManager instance if none registered.
221 * @return EventManagerInterface
223 public function getEventManager()
225 return $this->events
;
229 * Static method for quick and easy initialization of the Application.
231 * If you use this init() method, you cannot specify a service with the
232 * name of 'ApplicationConfig' in your service manager config. This name is
233 * reserved to hold the array from application.config.php.
235 * The following services can only be overridden from application.config.php:
238 * - SharedEventManager
239 * - EventManager & Zend\EventManager\EventManagerInterface
241 * All other services are configured after module loading, thus can be
242 * overridden by modules.
244 * @param array $configuration
245 * @return Application
247 public static function init($configuration = array())
249 $smConfig = isset($configuration['service_manager']) ?
$configuration['service_manager'] : array();
250 $listeners = isset($configuration['listeners']) ?
$configuration['listeners'] : array();
251 $serviceManager = new ServiceManager(new Service\
ServiceManagerConfig($smConfig));
252 $serviceManager->setService('ApplicationConfig', $configuration);
253 $serviceManager->get('ModuleManager')->loadModules();
254 return $serviceManager->get('Application')->bootstrap($listeners);
258 * Run the application
260 * @triggers route(MvcEvent)
261 * Routes the request, and sets the RouteMatch object in the event.
262 * @triggers dispatch(MvcEvent)
263 * Dispatches a request, using the discovered RouteMatch and
265 * @triggers dispatch.error(MvcEvent)
266 * On errors (controller not found, action not supported, etc.),
267 * populates the event with information about the error type,
268 * discovered controller, and controller class (if known).
269 * Typically, a handler should return a populated Response object
270 * that can be returned immediately.
271 * @return ResponseInterface
273 public function run()
275 $events = $this->getEventManager();
276 $event = $this->getMvcEvent();
278 // Define callback used to determine whether or not to short-circuit
279 $shortCircuit = function ($r) use ($event) {
280 if ($r instanceof ResponseInterface
) {
283 if ($event->getError()) {
289 // Trigger route event
290 $result = $events->trigger(MvcEvent
::EVENT_ROUTE
, $event, $shortCircuit);
291 if ($result->stopped()) {
292 $response = $result->last();
293 if ($response instanceof ResponseInterface
) {
294 $event->setTarget($this);
295 $event->setResponse($response);
296 $events->trigger(MvcEvent
::EVENT_FINISH
, $event);
299 if ($event->getError()) {
300 return $this->completeRequest($event);
302 return $event->getResponse();
304 if ($event->getError()) {
305 return $this->completeRequest($event);
308 // Trigger dispatch event
309 $result = $events->trigger(MvcEvent
::EVENT_DISPATCH
, $event, $shortCircuit);
312 $response = $result->last();
313 if ($response instanceof ResponseInterface
) {
314 $event->setTarget($this);
315 $event->setResponse($response);
316 $events->trigger(MvcEvent
::EVENT_FINISH
, $event);
320 $response = $this->getResponse();
321 $event->setResponse($response);
322 $this->completeRequest($event);
330 public function send()
335 * Complete the request
337 * Triggers "render" and "finish" events, and returns response from
340 * @param MvcEvent $event
341 * @return Application
343 protected function completeRequest(MvcEvent
$event)
345 $events = $this->getEventManager();
346 $event->setTarget($this);
347 $events->trigger(MvcEvent
::EVENT_RENDER
, $event);
348 $events->trigger(MvcEvent
::EVENT_FINISH
, $event);