fix travis build
[GitHub/Stricted/Domain-Control-Panel.git] / vendor / Zend / Mvc / Application.php
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10 namespace Zend\Mvc;
11
12 use Zend\EventManager\EventManagerAwareInterface;
13 use Zend\EventManager\EventManagerInterface;
14 use Zend\ServiceManager\ServiceManager;
15 use Zend\Stdlib\RequestInterface;
16 use Zend\Stdlib\ResponseInterface;
17
18 /**
19 * Main application class for invoking applications
20 *
21 * Expects the user will provide a configured ServiceManager, configured with
22 * the following services:
23 *
24 * - EventManager
25 * - ModuleManager
26 * - Request
27 * - Response
28 * - RouteListener
29 * - Router
30 * - DispatchListener
31 * - MiddlewareListener
32 * - ViewManager
33 *
34 * The most common workflow is:
35 * <code>
36 * $services = new Zend\ServiceManager\ServiceManager($servicesConfig);
37 * $app = new Application($appConfig, $services);
38 * $app->bootstrap();
39 * $response = $app->run();
40 * $response->send();
41 * </code>
42 *
43 * bootstrap() opts in to the default route, dispatch, and view listeners,
44 * sets up the MvcEvent, and triggers the bootstrap event. This can be omitted
45 * if you wish to setup your own listeners and/or workflow; alternately, you
46 * can simply extend the class to override such behavior.
47 */
48 class Application implements
49 ApplicationInterface,
50 EventManagerAwareInterface
51 {
52 const ERROR_CONTROLLER_CANNOT_DISPATCH = 'error-controller-cannot-dispatch';
53 const ERROR_CONTROLLER_NOT_FOUND = 'error-controller-not-found';
54 const ERROR_CONTROLLER_INVALID = 'error-controller-invalid';
55 const ERROR_EXCEPTION = 'error-exception';
56 const ERROR_ROUTER_NO_MATCH = 'error-router-no-match';
57 const ERROR_MIDDLEWARE_CANNOT_DISPATCH = 'error-middleware-cannot-dispatch';
58
59 /**
60 * @var array
61 */
62 protected $configuration = null;
63
64 /**
65 * Default application event listeners
66 *
67 * @var array
68 */
69 protected $defaultListeners = [
70 'RouteListener',
71 'MiddlewareListener',
72 'DispatchListener',
73 'HttpMethodListener',
74 'ViewManager',
75 'SendResponseListener',
76 ];
77
78 /**
79 * MVC event token
80 * @var MvcEvent
81 */
82 protected $event;
83
84 /**
85 * @var EventManagerInterface
86 */
87 protected $events;
88
89 /**
90 * @var \Zend\Stdlib\RequestInterface
91 */
92 protected $request;
93
94 /**
95 * @var ResponseInterface
96 */
97 protected $response;
98
99 /**
100 * @var ServiceManager
101 */
102 protected $serviceManager = null;
103
104 /**
105 * Constructor
106 *
107 * @param mixed $configuration
108 * @param ServiceManager $serviceManager
109 * @param null|EventManagerInterface $events
110 * @param null|RequestInterface $request
111 * @param null|ResponseInterface $response
112 */
113 public function __construct(
114 $configuration,
115 ServiceManager $serviceManager,
116 EventManagerInterface $events = null,
117 RequestInterface $request = null,
118 ResponseInterface $response = null
119 ) {
120 $this->configuration = $configuration;
121 $this->serviceManager = $serviceManager;
122 $this->setEventManager($events ?: $serviceManager->get('EventManager'));
123 $this->request = $request ?: $serviceManager->get('Request');
124 $this->response = $response ?: $serviceManager->get('Response');
125 }
126
127 /**
128 * Retrieve the application configuration
129 *
130 * @return array|object
131 */
132 public function getConfig()
133 {
134 return $this->serviceManager->get('config');
135 }
136
137 /**
138 * Bootstrap the application
139 *
140 * Defines and binds the MvcEvent, and passes it the request, response, and
141 * router. Attaches the ViewManager as a listener. Triggers the bootstrap
142 * event.
143 *
144 * @param array $listeners List of listeners to attach.
145 * @return Application
146 */
147 public function bootstrap(array $listeners = [])
148 {
149 $serviceManager = $this->serviceManager;
150 $events = $this->events;
151
152 // Setup default listeners
153 $listeners = array_unique(array_merge($this->defaultListeners, $listeners));
154
155 foreach ($listeners as $listener) {
156 $serviceManager->get($listener)->attach($events);
157 }
158
159 // Setup MVC Event
160 $this->event = $event = new MvcEvent();
161 $event->setName(MvcEvent::EVENT_BOOTSTRAP);
162 $event->setTarget($this);
163 $event->setApplication($this);
164 $event->setRequest($this->request);
165 $event->setResponse($this->response);
166 $event->setRouter($serviceManager->get('Router'));
167
168 // Trigger bootstrap events
169 $events->triggerEvent($event);
170
171 return $this;
172 }
173
174 /**
175 * Retrieve the service manager
176 *
177 * @return ServiceManager
178 */
179 public function getServiceManager()
180 {
181 return $this->serviceManager;
182 }
183
184 /**
185 * Get the request object
186 *
187 * @return \Zend\Stdlib\RequestInterface
188 */
189 public function getRequest()
190 {
191 return $this->request;
192 }
193
194 /**
195 * Get the response object
196 *
197 * @return ResponseInterface
198 */
199 public function getResponse()
200 {
201 return $this->response;
202 }
203
204 /**
205 * Get the MVC event instance
206 *
207 * @return MvcEvent
208 */
209 public function getMvcEvent()
210 {
211 return $this->event;
212 }
213
214 /**
215 * Set the event manager instance
216 *
217 * @param EventManagerInterface $eventManager
218 * @return Application
219 */
220 public function setEventManager(EventManagerInterface $eventManager)
221 {
222 $eventManager->setIdentifiers([
223 __CLASS__,
224 get_class($this),
225 ]);
226 $this->events = $eventManager;
227 return $this;
228 }
229
230 /**
231 * Retrieve the event manager
232 *
233 * Lazy-loads an EventManager instance if none registered.
234 *
235 * @return EventManagerInterface
236 */
237 public function getEventManager()
238 {
239 return $this->events;
240 }
241
242 /**
243 * Static method for quick and easy initialization of the Application.
244 *
245 * If you use this init() method, you cannot specify a service with the
246 * name of 'ApplicationConfig' in your service manager config. This name is
247 * reserved to hold the array from application.config.php.
248 *
249 * The following services can only be overridden from application.config.php:
250 *
251 * - ModuleManager
252 * - SharedEventManager
253 * - EventManager & Zend\EventManager\EventManagerInterface
254 *
255 * All other services are configured after module loading, thus can be
256 * overridden by modules.
257 *
258 * @param array $configuration
259 * @return Application
260 */
261 public static function init($configuration = [])
262 {
263 // Prepare the service manager
264 $smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : [];
265 $smConfig = new Service\ServiceManagerConfig($smConfig);
266
267 $serviceManager = new ServiceManager();
268 $smConfig->configureServiceManager($serviceManager);
269 $serviceManager->setService('ApplicationConfig', $configuration);
270
271 // Load modules
272 $serviceManager->get('ModuleManager')->loadModules();
273
274 // Prepare list of listeners to bootstrap
275 $listenersFromAppConfig = isset($configuration['listeners']) ? $configuration['listeners'] : [];
276 $config = $serviceManager->get('config');
277 $listenersFromConfigService = isset($config['listeners']) ? $config['listeners'] : [];
278
279 $listeners = array_unique(array_merge($listenersFromConfigService, $listenersFromAppConfig));
280
281 return $serviceManager->get('Application')->bootstrap($listeners);
282 }
283
284 /**
285 * Run the application
286 *
287 * @triggers route(MvcEvent)
288 * Routes the request, and sets the RouteMatch object in the event.
289 * @triggers dispatch(MvcEvent)
290 * Dispatches a request, using the discovered RouteMatch and
291 * provided request.
292 * @triggers dispatch.error(MvcEvent)
293 * On errors (controller not found, action not supported, etc.),
294 * populates the event with information about the error type,
295 * discovered controller, and controller class (if known).
296 * Typically, a handler should return a populated Response object
297 * that can be returned immediately.
298 * @return self
299 */
300 public function run()
301 {
302 $events = $this->events;
303 $event = $this->event;
304
305 // Define callback used to determine whether or not to short-circuit
306 $shortCircuit = function ($r) use ($event) {
307 if ($r instanceof ResponseInterface) {
308 return true;
309 }
310 if ($event->getError()) {
311 return true;
312 }
313 return false;
314 };
315
316 // Trigger route event
317 $event->setName(MvcEvent::EVENT_ROUTE);
318 $event->stopPropagation(false); // Clear before triggering
319 $result = $events->triggerEventUntil($shortCircuit, $event);
320 if ($result->stopped()) {
321 $response = $result->last();
322 if ($response instanceof ResponseInterface) {
323 $event->setName(MvcEvent::EVENT_FINISH);
324 $event->setTarget($this);
325 $event->setResponse($response);
326 $event->stopPropagation(false); // Clear before triggering
327 $events->triggerEvent($event);
328 $this->response = $response;
329 return $this;
330 }
331 }
332
333 if ($event->getError()) {
334 return $this->completeRequest($event);
335 }
336
337 // Trigger dispatch event
338 $event->setName(MvcEvent::EVENT_DISPATCH);
339 $event->stopPropagation(false); // Clear before triggering
340 $result = $events->triggerEventUntil($shortCircuit, $event);
341
342 // Complete response
343 $response = $result->last();
344 if ($response instanceof ResponseInterface) {
345 $event->setName(MvcEvent::EVENT_FINISH);
346 $event->setTarget($this);
347 $event->setResponse($response);
348 $event->stopPropagation(false); // Clear before triggering
349 $events->triggerEvent($event);
350 $this->response = $response;
351 return $this;
352 }
353
354 $response = $this->response;
355 $event->setResponse($response);
356 $this->completeRequest($event);
357
358 return $this;
359 }
360
361 /**
362 * @deprecated
363 */
364 public function send()
365 {
366 }
367
368 /**
369 * Complete the request
370 *
371 * Triggers "render" and "finish" events, and returns response from
372 * event object.
373 *
374 * @param MvcEvent $event
375 * @return Application
376 */
377 protected function completeRequest(MvcEvent $event)
378 {
379 $events = $this->events;
380 $event->setTarget($this);
381
382 $event->setName(MvcEvent::EVENT_RENDER);
383 $event->stopPropagation(false); // Clear before triggering
384 $events->triggerEvent($event);
385
386 $event->setName(MvcEvent::EVENT_FINISH);
387 $event->stopPropagation(false); // Clear before triggering
388 $events->triggerEvent($event);
389
390 return $this;
391 }
392 }