Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

324 lines (291 sloc) 8.952 kb
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Mvc
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Mvc;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\ModuleManager\ModuleManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\RequestInterface;
use Zend\Stdlib\ResponseInterface;
/**
* Main application class for invoking applications
*
* Expects the user will provide a configured ServiceManager, configured with
* the following services:
*
* - EventManager
* - ModuleManager
* - Request
* - Response
* - RouteListener
* - Router
* - DispatchListener
* - ViewManager
*
* The most common workflow is:
* <code>
* $services = new Zend\ServiceManager\ServiceManager($servicesConfig);
* $app = new Application($appConfig, $services);
* $app->bootstrap();
* $response = $app->run();
* $response->send();
* </code>
*
* bootstrap() opts in to the default route, dispatch, and view listeners,
* sets up the MvcEvent, and triggers the bootstrap event. This can be omitted
* if you wish to setup your own listeners and/or workflow; alternately, you
* can simply extend the class to override such behavior.
*
* @category Zend
* @package Zend_Mvc
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Application implements
ApplicationInterface,
EventManagerAwareInterface
{
const ERROR_CONTROLLER_CANNOT_DISPATCH = 'error-controller-cannot-dispatch';
const ERROR_CONTROLLER_NOT_FOUND = 'error-controller-not-found';
const ERROR_CONTROLLER_INVALID = 'error-controller-invalid';
const ERROR_EXCEPTION = 'error-exception';
const ERROR_ROUTER_NO_MATCH = 'error-router-no-match';
/**
* @var array
*/
protected $configuration = null;
/**
* MVC event token
* @var MvcEvent
*/
protected $event;
/**
* @var EventManagerInterface
*/
protected $events;
/**
* @var RequestInterface
*/
protected $request;
/**
* @var ResponseInterface
*/
protected $response;
/**
* @var ServiceManager
*/
protected $serviceManager = null;
/**
* @var ModuleManagerInterface
*/
protected $moduleManager;
/**
* Constructor
*
* @param mixed $configuration
* @param ServiceManager $serviceManager
*/
public function __construct($configuration, ServiceManager $serviceManager)
{
$this->configuration = $configuration;
$this->serviceManager = $serviceManager;
$this->setEventManager($serviceManager->get('EventManager'));
$this->moduleManager = $serviceManager->get('ModuleManager');
$this->request = $serviceManager->get('Request');
$this->response = $serviceManager->get('Response');
}
/**
* Retrieve the application configuration
*
* @return array|object
*/
public function getConfiguration()
{
return $this->serviceManager->get('Configuration');
}
/**
* Bootstrap the application
*
* Defines and binds the MvcEvent, and passes it the request, response, and
* router. Attaches the ViewManager as a listener. Triggers the bootstrap
* event.
*
* @return Application
*/
public function bootstrap()
{
$serviceManager = $this->serviceManager;
$events = $this->events();
$events->attach($serviceManager->get('RouteListener'));
$events->attach($serviceManager->get('DispatchListener'));
$events->attach($serviceManager->get('ViewManager'));
// Setup MVC Event
$this->event = $event = new MvcEvent();
$event->setTarget($this);
$event->setApplication($this)
->setRequest($this->getRequest())
->setResponse($this->getResponse())
->setRouter($serviceManager->get('Router'));
// Trigger bootstrap events
$events->trigger('bootstrap', $event);
return $this;
}
/**
* Retrieve the service manager
*
* @return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
/**
* Get the request object
*
* @return RequestInterface
*/
public function getRequest()
{
return $this->request;
}
/**
* Get the response object
*
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
/**
* Get the MVC event instance
*
* @return MvcEvent
*/
public function getMvcEvent()
{
return $this->event;
}
/**
* Set the event manager instance
*
* @param EventManagerInterface $eventManager
* @return Application
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers(array(
__CLASS__,
get_called_class(),
'application',
));
$this->events = $eventManager;
return $this;
}
/**
* Retrieve the event manager
*
* Lazy-loads an EventManager instance if none registered.
*
* @return EventManagerInterface
*/
public function events()
{
return $this->events;
}
/**
* Run the application
*
* @triggers route(MvcEvent)
* Routes the request, and sets the RouteMatch object in the event.
* @triggers dispatch(MvcEvent)
* Dispatches a request, using the discovered RouteMatch and
* provided request.
* @triggers dispatch.error(MvcEvent)
* On errors (controller not found, action not supported, etc.),
* populates the event with information about the error type,
* discovered controller, and controller class (if known).
* Typically, a handler should return a populated Response object
* that can be returned immediately.
* @return ResponseInterface
*/
public function run()
{
$events = $this->events();
$event = $this->getMvcEvent();
// Define callback used to determine whether or not to short-circuit
$shortCircuit = function ($r) use ($event) {
if ($r instanceof ResponseInterface) {
return true;
}
if ($event->getError()) {
return true;
}
return false;
};
// Trigger route event
$result = $events->trigger('route', $event, $shortCircuit);
if ($result->stopped()) {
$response = $result->last();
if ($response instanceof ResponseInterface) {
$event->setTarget($this);
$events->trigger('finish', $event);
return $response;
}
if ($event->getError()) {
return $this->completeRequest($event);
}
return $event->getResponse();
}
if ($event->getError()) {
return $this->completeRequest($event);
}
// Trigger dispatch event
$result = $events->trigger('dispatch', $event, $shortCircuit);
// Complete response
$response = $result->last();
if ($response instanceof ResponseInterface) {
$event->setTarget($this);
$events->trigger('finish', $event);
return $response;
}
$response = $this->getResponse();
$event->setResponse($response);
return $this->completeRequest($event);
}
/**
* Complete the request
*
* Triggers "render" and "finish" events, and returns response from
* event object.
*
* @param MvcEvent $event
* @return ResponseInterface
*/
protected function completeRequest(MvcEvent $event)
{
$events = $this->events();
$event->setTarget($this);
$events->trigger('render', $event);
$events->trigger('finish', $event);
return $event->getResponse();
}
}
Jump to Line
Something went wrong with that request. Please try again.