1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
21:
22: App::uses('Sanitize', 'Utility');
23: App::uses('Router', 'Routing');
24: App::uses('CakeResponse', 'Network');
25: App::uses('Controller', 'Controller');
26:
27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
54: class ExceptionRenderer {
55:
56: 57: 58: 59: 60:
61: public $controller = null;
62:
63: 64: 65: 66: 67:
68: public $template = '';
69:
70: 71: 72: 73: 74:
75: public $method = '';
76:
77: 78: 79: 80: 81:
82: public $error = null;
83:
84: 85: 86: 87: 88: 89: 90:
91: public function __construct(Exception $exception) {
92: $this->controller = $this->_getController($exception);
93:
94: if (method_exists($this->controller, 'appError')) {
95: $this->controller->appError($exception);
96: return;
97: }
98: $method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
99: $code = $exception->getCode();
100:
101: $methodExists = method_exists($this, $method);
102:
103: if ($exception instanceof CakeException && !$methodExists) {
104: $method = '_cakeError';
105: if (empty($template) || $template === 'internalError') {
106: $template = 'error500';
107: }
108: } elseif ($exception instanceof PDOException) {
109: $method = 'pdoError';
110: $template = 'pdo_error';
111: $code = 500;
112: } elseif (!$methodExists) {
113: $method = 'error500';
114: if ($code >= 400 && $code < 500) {
115: $method = 'error400';
116: }
117: }
118:
119: $isNotDebug = !Configure::read('debug');
120: if ($isNotDebug && $method === '_cakeError') {
121: $method = 'error400';
122: }
123: if ($isNotDebug && $code == 500) {
124: $method = 'error500';
125: }
126: $this->template = $template;
127: $this->method = $method;
128: $this->error = $exception;
129: }
130:
131: 132: 133: 134: 135: 136: 137: 138: 139:
140: protected function _getController($exception) {
141: App::uses('AppController', 'Controller');
142: App::uses('CakeErrorController', 'Controller');
143: if (!$request = Router::getRequest(true)) {
144: $request = new CakeRequest();
145: }
146: $response = new CakeResponse();
147:
148: if (method_exists($exception, 'responseHeader')) {
149: $response->header($exception->responseHeader());
150: }
151:
152: if (class_exists('AppController')) {
153: try {
154: $controller = new CakeErrorController($request, $response);
155: $controller->startupProcess();
156: $startup = true;
157: } catch (Exception $e) {
158: $startup = false;
159: }
160:
161:
162:
163: if ($startup === false &&
164: !empty($controller) &&
165: $controller->Components->enabled('RequestHandler')
166: ) {
167: try {
168: $controller->RequestHandler->startup($controller);
169: } catch (Exception $e) {
170: }
171: }
172: }
173: if (empty($controller)) {
174: $controller = new Controller($request, $response);
175: $controller->viewPath = 'Errors';
176: }
177: return $controller;
178: }
179:
180: 181: 182: 183: 184:
185: public function render() {
186: if ($this->method) {
187: call_user_func_array(array($this, $this->method), array($this->error));
188: }
189: }
190:
191: 192: 193: 194: 195: 196:
197: protected function _cakeError(CakeException $error) {
198: $url = $this->controller->request->here();
199: $code = ($error->getCode() >= 400 && $error->getCode() < 506) ? $error->getCode() : 500;
200: $this->controller->response->statusCode($code);
201: $this->controller->set(array(
202: 'code' => $code,
203: 'name' => h($error->getMessage()),
204: 'message' => h($error->getMessage()),
205: 'url' => h($url),
206: 'error' => $error,
207: '_serialize' => array('code', 'name', 'message', 'url')
208: ));
209: $this->controller->set($error->getAttributes());
210: $this->_outputMessage($this->template);
211: }
212:
213: 214: 215: 216: 217: 218:
219: public function error400($error) {
220: $message = $error->getMessage();
221: if (!Configure::read('debug') && $error instanceof CakeException) {
222: $message = __d('cake', 'Not Found');
223: }
224: $url = $this->controller->request->here();
225: $this->controller->response->statusCode($error->getCode());
226: $this->controller->set(array(
227: 'name' => h($message),
228: 'message' => h($message),
229: 'url' => h($url),
230: 'error' => $error,
231: '_serialize' => array('name', 'message', 'url')
232: ));
233: $this->_outputMessage('error400');
234: }
235:
236: 237: 238: 239: 240: 241:
242: public function error500($error) {
243: $message = $error->getMessage();
244: if (!Configure::read('debug')) {
245: $message = __d('cake', 'An Internal Error Has Occurred.');
246: }
247: $url = $this->controller->request->here();
248: $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
249: $this->controller->response->statusCode($code);
250: $this->controller->set(array(
251: 'name' => h($message),
252: 'message' => h($message),
253: 'url' => h($url),
254: 'error' => $error,
255: '_serialize' => array('name', 'message', 'url')
256: ));
257: $this->_outputMessage('error500');
258: }
259:
260: 261: 262: 263: 264: 265:
266: public function pdoError(PDOException $error) {
267: $url = $this->controller->request->here();
268: $code = 500;
269: $this->controller->response->statusCode($code);
270: $this->controller->set(array(
271: 'code' => $code,
272: 'name' => h($error->getMessage()),
273: 'message' => h($error->getMessage()),
274: 'url' => h($url),
275: 'error' => $error,
276: '_serialize' => array('code', 'name', 'message', 'url', 'error')
277: ));
278: $this->_outputMessage($this->template);
279: }
280:
281: 282: 283: 284: 285: 286:
287: protected function _outputMessage($template) {
288: try {
289: $this->controller->render($template);
290: $this->controller->afterFilter();
291: $this->controller->response->send();
292: } catch (MissingViewException $e) {
293: $attributes = $e->getAttributes();
294: if (isset($attributes['file']) && strpos($attributes['file'], 'error500') !== false) {
295: $this->_outputMessageSafe('error500');
296: } else {
297: $this->_outputMessage('error500');
298: }
299: } catch (MissingPluginException $e) {
300: $attributes = $e->getAttributes();
301: if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->plugin) {
302: $this->controller->plugin = null;
303: }
304: $this->_outputMessageSafe('error500');
305: } catch (Exception $e) {
306: $this->_outputMessageSafe('error500');
307: }
308: }
309:
310: 311: 312: 313: 314: 315: 316:
317: protected function _outputMessageSafe($template) {
318: $this->controller->layoutPath = null;
319: $this->controller->subDir = null;
320: $this->controller->viewPath = 'Errors';
321: $this->controller->layout = 'error';
322: $this->controller->helpers = array('Form', 'Html', 'Session');
323:
324: $view = new View($this->controller);
325: $this->controller->response->body($view->render($template, 'error'));
326: $this->controller->response->type('html');
327: $this->controller->response->send();
328: }
329:
330: }
331: