1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: App::uses('Sanitize', 'Utility');
24: App::uses('Router', 'Routing');
25: App::uses('CakeResponse', 'Network');
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: return $this->controller->appError($exception);
96: }
97: $method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
98: $code = $exception->getCode();
99:
100: $methodExists = method_exists($this, $method);
101:
102: if ($exception instanceof CakeException && !$methodExists) {
103: $method = '_cakeError';
104: if (empty($template)) {
105: $template = 'error500';
106: }
107: if ($template == 'internalError') {
108: $template = 'error500';
109: }
110: } elseif ($exception instanceof PDOException) {
111: $method = 'pdoError';
112: $template = 'pdo_error';
113: $code = 500;
114: } elseif (!$methodExists) {
115: $method = 'error500';
116: if ($code >= 400 && $code < 500) {
117: $method = 'error400';
118: }
119: }
120:
121: if (Configure::read('debug') == 0) {
122: if ($method == '_cakeError') {
123: $method = 'error400';
124: }
125: if ($code == 500) {
126: $method = 'error500';
127: }
128: }
129: $this->template = $template;
130: $this->method = $method;
131: $this->error = $exception;
132: }
133:
134: 135: 136: 137: 138: 139: 140: 141: 142:
143: protected function _getController($exception) {
144: App::uses('CakeErrorController', 'Controller');
145: if (!$request = Router::getRequest(true)) {
146: $request = new CakeRequest();
147: }
148: $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
149: try {
150: $controller = new CakeErrorController($request, $response);
151: } catch (Exception $e) {
152: $controller = new Controller($request, $response);
153: $controller->viewPath = 'Errors';
154: }
155: return $controller;
156: }
157:
158: 159: 160: 161: 162:
163: public function render() {
164: if ($this->method) {
165: call_user_func_array(array($this, $this->method), array($this->error));
166: }
167: }
168:
169: 170: 171: 172: 173: 174:
175: protected function _cakeError(CakeException $error) {
176: $url = $this->controller->request->here();
177: $code = ($error->getCode() >= 400 && $error->getCode() < 506) ? $error->getCode() : 500;
178: $this->controller->response->statusCode($code);
179: $this->controller->set(array(
180: 'code' => $code,
181: 'url' => h($url),
182: 'name' => $error->getMessage(),
183: 'error' => $error,
184: '_serialize' => array('code', 'url', 'name')
185: ));
186: $this->controller->set($error->getAttributes());
187: $this->_outputMessage($this->template);
188: }
189:
190: 191: 192: 193: 194: 195:
196: public function error400($error) {
197: $message = $error->getMessage();
198: if (Configure::read('debug') == 0 && $error instanceof CakeException) {
199: $message = __d('cake', 'Not Found');
200: }
201: $url = $this->controller->request->here();
202: $this->controller->response->statusCode($error->getCode());
203: $this->controller->set(array(
204: 'name' => $message,
205: 'url' => h($url),
206: 'error' => $error,
207: '_serialize' => array('name', 'url')
208: ));
209: $this->_outputMessage('error400');
210: }
211:
212: 213: 214: 215: 216: 217:
218: public function error500($error) {
219: $message = $error->getMessage();
220: if (Configure::read('debug') == 0) {
221: $message = __d('cake', 'An Internal Error Has Occurred.');
222: }
223: $url = $this->controller->request->here();
224: $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
225: $this->controller->response->statusCode($code);
226: $this->controller->set(array(
227: 'name' => $message,
228: 'message' => h($url),
229: 'error' => $error,
230: '_serialize' => array('name', 'message')
231: ));
232: $this->_outputMessage('error500');
233: }
234:
235: 236: 237: 238: 239: 240:
241: public function pdoError(PDOException $error) {
242: $url = $this->controller->request->here();
243: $code = 500;
244: $this->controller->response->statusCode($code);
245: $this->controller->set(array(
246: 'code' => $code,
247: 'url' => h($url),
248: 'name' => $error->getMessage(),
249: 'error' => $error,
250: '_serialize' => array('code', 'url', 'name', 'error')
251: ));
252: $this->_outputMessage($this->template);
253: }
254:
255: 256: 257: 258: 259: 260:
261: protected function _outputMessage($template) {
262: try {
263: $this->controller->render($template);
264: $this->controller->afterFilter();
265: $this->controller->response->send();
266: } catch (MissingViewException $e) {
267: try {
268: $this->_outputMessage('error500');
269: } catch (Exception $e) {
270: $this->_outputMessageSafe('error500');
271: }
272: } catch (Exception $e) {
273: $this->_outputMessageSafe('error500');
274: }
275: }
276:
277: 278: 279: 280: 281: 282: 283:
284: protected function _outputMessageSafe($template) {
285: $this->controller->layoutPath = '';
286: $this->controller->subDir = '';
287: $this->controller->viewPath = 'Errors/';
288: $this->controller->viewClass = 'View';
289: $this->controller->helpers = array('Form', 'Html', 'Session');
290:
291: $this->controller->render($template);
292: $this->controller->response->type('html');
293: $this->controller->response->send();
294: }
295:
296: }
297: