fix travis build
[GitHub/Stricted/Domain-Control-Panel.git] / vendor / Zend / Mvc / View / Http / RouteNotFoundStrategy.php
CommitLineData
44d399bc
S
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
10namespace Zend\Mvc\View\Http;
11
12use Zend\EventManager\AbstractListenerAggregate;
13use Zend\EventManager\EventManagerInterface;
14use Zend\Http\Response as HttpResponse;
15use Zend\Mvc\Application;
16use Zend\Mvc\MvcEvent;
17use Zend\Stdlib\ResponseInterface as Response;
18use Zend\View\Model\ViewModel;
19
20class RouteNotFoundStrategy extends AbstractListenerAggregate
21{
22 /**
23 * Whether or not to display exceptions related to the 404 condition
24 *
25 * @var bool
26 */
27 protected $displayExceptions = false;
28
29 /**
30 * Whether or not to display the reason for a 404
31 *
32 * @var bool
33 */
34 protected $displayNotFoundReason = false;
35
36 /**
37 * Template to use to report page not found conditions
38 *
39 * @var string
40 */
41 protected $notFoundTemplate = 'error';
42
43 /**
44 * The reason for a not-found condition
45 *
46 * @var false|string
47 */
48 protected $reason = false;
49
50 /**
51 * {@inheritDoc}
52 */
53 public function attach(EventManagerInterface $events, $priority = 1)
54 {
55 $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'prepareNotFoundViewModel'], -90);
56 $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'detectNotFoundError']);
57 $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'prepareNotFoundViewModel']);
58 }
59
60 /**
61 * Set value indicating whether or not to display exceptions related to a not-found condition
62 *
63 * @param bool $displayExceptions
64 * @return RouteNotFoundStrategy
65 */
66 public function setDisplayExceptions($displayExceptions)
67 {
68 $this->displayExceptions = (bool) $displayExceptions;
69 return $this;
70 }
71
72 /**
73 * Should we display exceptions related to a not-found condition?
74 *
75 * @return bool
76 */
77 public function displayExceptions()
78 {
79 return $this->displayExceptions;
80 }
81
82 /**
83 * Set value indicating whether or not to display the reason for a not-found condition
84 *
85 * @param bool $displayNotFoundReason
86 * @return RouteNotFoundStrategy
87 */
88 public function setDisplayNotFoundReason($displayNotFoundReason)
89 {
90 $this->displayNotFoundReason = (bool) $displayNotFoundReason;
91 return $this;
92 }
93
94 /**
95 * Should we display the reason for a not-found condition?
96 *
97 * @return bool
98 */
99 public function displayNotFoundReason()
100 {
101 return $this->displayNotFoundReason;
102 }
103
104 /**
105 * Get template for not found conditions
106 *
107 * @param string $notFoundTemplate
108 * @return RouteNotFoundStrategy
109 */
110 public function setNotFoundTemplate($notFoundTemplate)
111 {
112 $this->notFoundTemplate = (string) $notFoundTemplate;
113 return $this;
114 }
115
116 /**
117 * Get template for not found conditions
118 *
119 * @return string
120 */
121 public function getNotFoundTemplate()
122 {
123 return $this->notFoundTemplate;
124 }
125
126 /**
127 * Detect if an error is a 404 condition
128 *
129 * If a "controller not found" or "invalid controller" error type is
130 * encountered, sets the response status code to 404.
131 *
132 * @param MvcEvent $e
133 * @return void
134 */
135 public function detectNotFoundError(MvcEvent $e)
136 {
137 $error = $e->getError();
138 if (empty($error)) {
139 return;
140 }
141
142 switch ($error) {
143 case Application::ERROR_CONTROLLER_NOT_FOUND:
144 case Application::ERROR_CONTROLLER_INVALID:
145 case Application::ERROR_ROUTER_NO_MATCH:
146 $this->reason = $error;
147 $response = $e->getResponse();
148 if (!$response) {
149 $response = new HttpResponse();
150 $e->setResponse($response);
151 }
152 $response->setStatusCode(404);
153 break;
154 default:
155 return;
156 }
157 }
158
159 /**
160 * Create and return a 404 view model
161 *
162 * @param MvcEvent $e
163 * @return void
164 */
165 public function prepareNotFoundViewModel(MvcEvent $e)
166 {
167 $vars = $e->getResult();
168 if ($vars instanceof Response) {
169 // Already have a response as the result
170 return;
171 }
172
173 $response = $e->getResponse();
174 if ($response->getStatusCode() != 404) {
175 // Only handle 404 responses
176 return;
177 }
178
179 if (!$vars instanceof ViewModel) {
180 $model = new ViewModel();
181 if (is_string($vars)) {
182 $model->setVariable('message', $vars);
183 } else {
184 $model->setVariable('message', 'Page not found.');
185 }
186 } else {
187 $model = $vars;
188 if ($model->getVariable('message') === null) {
189 $model->setVariable('message', 'Page not found.');
190 }
191 }
192
193 $model->setTemplate($this->getNotFoundTemplate());
194
195 // If displaying reasons, inject the reason
196 $this->injectNotFoundReason($model);
197
198 // If displaying exceptions, inject
199 $this->injectException($model, $e);
200
201 // Inject controller if we're displaying either the reason or the exception
202 $this->injectController($model, $e);
203
204 $e->setResult($model);
205 }
206
207 /**
208 * Inject the not-found reason into the model
209 *
210 * If $displayNotFoundReason is enabled, checks to see if $reason is set,
211 * and, if so, injects it into the model. If not, it injects
212 * Application::ERROR_CONTROLLER_CANNOT_DISPATCH.
213 *
214 * @param ViewModel $model
215 * @return void
216 */
217 protected function injectNotFoundReason(ViewModel $model)
218 {
219 if (!$this->displayNotFoundReason()) {
220 return;
221 }
222
223 // no route match, controller not found, or controller invalid
224 if ($this->reason) {
225 $model->setVariable('reason', $this->reason);
226 return;
227 }
228
229 // otherwise, must be a case of the controller not being able to
230 // dispatch itself.
231 $model->setVariable('reason', Application::ERROR_CONTROLLER_CANNOT_DISPATCH);
232 }
233
234 /**
235 * Inject the exception message into the model
236 *
237 * If $displayExceptions is enabled, and an exception is found in the
238 * event, inject it into the model.
239 *
240 * @param ViewModel $model
241 * @param MvcEvent $e
242 * @return void
243 */
244 protected function injectException($model, $e)
245 {
246 if (!$this->displayExceptions()) {
247 return;
248 }
249
250 $model->setVariable('display_exceptions', true);
251
252 $exception = $e->getParam('exception', false);
253
254 // @TODO clean up once PHP 7 requirement is enforced
255 if (!$exception instanceof \Exception && !$exception instanceof \Throwable) {
256 return;
257 }
258
259 $model->setVariable('exception', $exception);
260 }
261
262 /**
263 * Inject the controller and controller class into the model
264 *
265 * If either $displayExceptions or $displayNotFoundReason are enabled,
266 * injects the controllerClass from the MvcEvent. It checks to see if a
267 * controller is present in the MvcEvent, and, if not, grabs it from
268 * the route match if present; if a controller is found, it injects it into
269 * the model.
270 *
271 * @param ViewModel $model
272 * @param MvcEvent $e
273 * @return void
274 */
275 protected function injectController($model, $e)
276 {
277 if (!$this->displayExceptions() && !$this->displayNotFoundReason()) {
278 return;
279 }
280
281 $controller = $e->getController();
282 if (empty($controller)) {
283 $routeMatch = $e->getRouteMatch();
284 if (empty($routeMatch)) {
285 return;
286 }
287
288 $controller = $routeMatch->getParam('controller', false);
289 if (!$controller) {
290 return;
291 }
292 }
293
294 $controllerClass = $e->getControllerClass();
295 $model->setVariable('controller', $controller);
296 $model->setVariable('controller_class', $controllerClass);
297 }
298}