PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/Error/ExceptionRenderer.php

https://bitbucket.org/udeshika/fake_twitter
PHP | 285 lines | 141 code | 19 blank | 125 comment | 23 complexity | 298145edf3979c769f14764619e0c8d6 MD5 | raw file
  1. <?php
  2. /**
  3. * Exception Renderer
  4. *
  5. * Provides Exception rendering features. Which allow exceptions to be rendered
  6. * as HTML pages.
  7. *
  8. * PHP 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  11. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  12. *
  13. * Licensed under The MIT License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17. * @link http://cakephp.org CakePHP(tm) Project
  18. * @package Cake.Error
  19. * @since CakePHP(tm) v 2.0
  20. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  21. */
  22. App::uses('Sanitize', 'Utility');
  23. App::uses('Router', 'Routing');
  24. App::uses('CakeResponse', 'Network');
  25. /**
  26. * Exception Renderer.
  27. *
  28. * Captures and handles all unhandled exceptions. Displays helpful framework errors when debug > 1.
  29. * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
  30. * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error.
  31. *
  32. * ### Implementing application specific exception rendering
  33. *
  34. * You can implement application specific exception handling in one of a few ways:
  35. *
  36. * - Create a AppController::appError();
  37. * - Create a subclass of ExceptionRenderer and configure it to be the `Exception.renderer`
  38. *
  39. * #### Using AppController::appError();
  40. *
  41. * This controller method is called instead of the default exception handling. It receives the
  42. * thrown exception as its only argument. You should implement your error handling in that method.
  43. *
  44. * #### Using a subclass of ExceptionRenderer
  45. *
  46. * Using a subclass of ExceptionRenderer gives you full control over how Exceptions are rendered, you
  47. * can configure your class in your core.php, with `Configure::write('Exception.renderer', 'MyClass');`
  48. * You should place any custom exception renderers in `app/Lib/Error`.
  49. *
  50. * @package Cake.Error
  51. */
  52. class ExceptionRenderer {
  53. /**
  54. * Controller instance.
  55. *
  56. * @var Controller
  57. */
  58. public $controller = null;
  59. /**
  60. * template to render for CakeException
  61. *
  62. * @var string
  63. */
  64. public $template = '';
  65. /**
  66. * The method corresponding to the Exception this object is for.
  67. *
  68. * @var string
  69. */
  70. public $method = '';
  71. /**
  72. * The exception being handled.
  73. *
  74. * @var Exception
  75. */
  76. public $error = null;
  77. /**
  78. * Creates the controller to perform rendering on the error response.
  79. * If the error is a CakeException it will be converted to either a 400 or a 500
  80. * code error depending on the code used to construct the error.
  81. *
  82. * @param Exception $exception Exception
  83. */
  84. public function __construct(Exception $exception) {
  85. $this->controller = $this->_getController($exception);
  86. if (method_exists($this->controller, 'apperror')) {
  87. return $this->controller->appError($exception);
  88. }
  89. $method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
  90. $code = $exception->getCode();
  91. $methodExists = method_exists($this, $method);
  92. if ($exception instanceof CakeException && !$methodExists) {
  93. $method = '_cakeError';
  94. if (empty($template)) {
  95. $template = 'error500';
  96. }
  97. if ($template == 'internalError') {
  98. $template = 'error500';
  99. }
  100. } elseif ($exception instanceof PDOException) {
  101. $method = 'pdoError';
  102. $template = 'pdo_error';
  103. $code = 500;
  104. } elseif (!$methodExists) {
  105. $method = 'error500';
  106. if ($code >= 400 && $code < 500) {
  107. $method = 'error400';
  108. }
  109. }
  110. if (Configure::read('debug') == 0) {
  111. if ($method == '_cakeError') {
  112. $method = 'error400';
  113. }
  114. if ($code == 500) {
  115. $method = 'error500';
  116. }
  117. }
  118. $this->template = $template;
  119. $this->method = $method;
  120. $this->error = $exception;
  121. }
  122. /**
  123. * Get the controller instance to handle the exception.
  124. * Override this method in subclasses to customize the controller used.
  125. * This method returns the built in `CakeErrorController` normally, or if an error is repeated
  126. * a bare controller will be used.
  127. *
  128. * @param Exception $exception The exception to get a controller for.
  129. * @return Controller
  130. */
  131. protected function _getController($exception) {
  132. App::uses('CakeErrorController', 'Controller');
  133. if (!$request = Router::getRequest(false)) {
  134. $request = new CakeRequest();
  135. }
  136. $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
  137. try {
  138. $controller = new CakeErrorController($request, $response);
  139. } catch (Exception $e) {
  140. $controller = new Controller($request, $response);
  141. $controller->viewPath = 'Errors';
  142. }
  143. return $controller;
  144. }
  145. /**
  146. * Renders the response for the exception.
  147. *
  148. * @return void
  149. */
  150. public function render() {
  151. if ($this->method) {
  152. call_user_func_array(array($this, $this->method), array($this->error));
  153. }
  154. }
  155. /**
  156. * Generic handler for the internal framework errors CakePHP can generate.
  157. *
  158. * @param CakeException $error
  159. * @return void
  160. */
  161. protected function _cakeError(CakeException $error) {
  162. $url = $this->controller->request->here();
  163. $code = ($error->getCode() >= 400 && $error->getCode() < 506) ? $error->getCode() : 500;
  164. $this->controller->response->statusCode($code);
  165. $this->controller->set(array(
  166. 'code' => $code,
  167. 'url' => h($url),
  168. 'name' => $error->getMessage(),
  169. 'error' => $error,
  170. ));
  171. try {
  172. $this->controller->set($error->getAttributes());
  173. $this->_outputMessage($this->template);
  174. } catch (MissingViewException $e) {
  175. $this->_outputMessage('error500');
  176. } catch (Exception $e) {
  177. $this->_outputMessageSafe('error500');
  178. }
  179. }
  180. /**
  181. * Convenience method to display a 400 series page.
  182. *
  183. * @param Exception $error
  184. * @return void
  185. */
  186. public function error400($error) {
  187. $message = $error->getMessage();
  188. if (Configure::read('debug') == 0 && $error instanceof CakeException) {
  189. $message = __d('cake', 'Not Found');
  190. }
  191. $url = $this->controller->request->here();
  192. $this->controller->response->statusCode($error->getCode());
  193. $this->controller->set(array(
  194. 'name' => $message,
  195. 'url' => h($url),
  196. 'error' => $error,
  197. ));
  198. $this->_outputMessage('error400');
  199. }
  200. /**
  201. * Convenience method to display a 500 page.
  202. *
  203. * @param Exception $error
  204. * @return void
  205. */
  206. public function error500($error) {
  207. $message = $error->getMessage();
  208. if (Configure::read('debug') == 0) {
  209. $message = __d('cake', 'An Internal Error Has Occurred.');
  210. }
  211. $url = $this->controller->request->here();
  212. $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
  213. $this->controller->response->statusCode($code);
  214. $this->controller->set(array(
  215. 'name' => $message,
  216. 'message' => h($url),
  217. 'error' => $error,
  218. ));
  219. $this->_outputMessage('error500');
  220. }
  221. /**
  222. * Convenience method to display a PDOException.
  223. *
  224. * @param PDOException $error
  225. * @return void
  226. */
  227. public function pdoError(PDOException $error) {
  228. $url = $this->controller->request->here();
  229. $code = 500;
  230. $this->controller->response->statusCode($code);
  231. $this->controller->set(array(
  232. 'code' => $code,
  233. 'url' => h($url),
  234. 'name' => $error->getMessage(),
  235. 'error' => $error,
  236. ));
  237. try {
  238. $this->_outputMessage($this->template);
  239. } catch (Exception $e) {
  240. $this->_outputMessageSafe('error500');
  241. }
  242. }
  243. /**
  244. * Generate the response using the controller object.
  245. *
  246. * @param string $template The template to render.
  247. * @return void
  248. */
  249. protected function _outputMessage($template) {
  250. $this->controller->render($template);
  251. $this->controller->afterFilter();
  252. $this->controller->response->send();
  253. }
  254. /**
  255. * A safer way to render error messages, replaces all helpers, with basics
  256. * and doesn't call component methods.
  257. *
  258. * @param string $template The template to render
  259. * @return void
  260. */
  261. protected function _outputMessageSafe($template) {
  262. $this->controller->helpers = array('Form', 'Html', 'Session');
  263. $this->controller->render($template);
  264. $this->controller->response->send();
  265. }
  266. }