From: Andrey Kutejko Date: Sat, 16 Mar 2019 14:23:54 +0000 (+0100) Subject: rework error pages X-Git-Url: https://git.andy128k.dev/?a=commitdiff_plain;h=9b1ee5cc90e386cae4a71d3c6bbfc73ca8f1d654;p=ipf.git rework error pages --- diff --git a/ipf/admin/app.php b/ipf/admin/app.php index 50ac73b..0d08d1f 100644 --- a/ipf/admin/app.php +++ b/ipf/admin/app.php @@ -150,7 +150,7 @@ class IPF_Admin_App extends IPF_Application class IPF_Admin_LoginRequired extends IPF_Router_Shortcut { - public function response($request) + public function response($container, $request) { return new IPF_HTTP_Response_Redirect(IPF_HTTP_URL::urlForView(array('IPF_Admin_User_Controller', 'login'))); } @@ -158,8 +158,8 @@ class IPF_Admin_LoginRequired extends IPF_Router_Shortcut class IPF_Admin_AccessDenied extends IPF_Router_Shortcut { - public function response($request) + public function response($container, $request) { - return new IPF_HTTP_Response_NotFound($request); + return new IPF_HTTP_Response_NotFound($container, $request); } } diff --git a/ipf/admin/controllers/components.php b/ipf/admin/controllers/components.php index 7786173..b2c4ddd 100644 --- a/ipf/admin/controllers/components.php +++ b/ipf/admin/controllers/components.php @@ -43,7 +43,7 @@ class IPF_Admin_Components_Controller extends IPF_Admin_Base_Controller $this->checkPermissions('view', 'change'); if (!isset($this->request->POST['ids']) || !is_array($this->request->POST['ids'])) - return new IPF_HTTP_Response_NotFound($this->request); + return new IPF_HTTP_Response_NotFound($this->container, $this->request); if ($this->component->reorder($this->request->POST['ids'])) return new IPF_HTTP_Response_Json("Ok"); diff --git a/ipf/admin/controllers/user.php b/ipf/admin/controllers/user.php index 4430c4d..70ebf99 100644 --- a/ipf/admin/controllers/user.php +++ b/ipf/admin/controllers/user.php @@ -57,7 +57,7 @@ class IPF_Admin_User_Controller extends IPF_Admin_Base_Controller if (!$this->request->user->isAnonymous() && $this->request->user->is_superuser) { $user = $this->authApp()->findUser($this->params[1]); if (!$user) - return new IPF_HTTP_Response_NotFound($this->request); + return new IPF_HTTP_Response_NotFound($this->container, $this->request); $this->authApp()->login($this->request, $user); } diff --git a/ipf/error/404.html b/ipf/error/404.html index c62e3a5..4c449d1 100644 --- a/ipf/error/404.html +++ b/ipf/error/404.html @@ -2,5 +2,4 @@

Error 404

Page not found

Sorry, it appears the page you were looking for does not exist anymore or might have been moved.

-

Go to home page or go back to previous page.

- +

Go to home page or go back to previous page.

diff --git a/ipf/error/404.php b/ipf/error/404.php index 0f88bca..08889ba 100644 --- a/ipf/error/404.php +++ b/ipf/error/404.php @@ -1,10 +1,18 @@ render('404.html', array( + 'request' => $request, + 'app_base' => $settings->get('app_base'), + )); } } - diff --git a/ipf/error/500.html b/ipf/error/500.html index 509e9ea..bcea3a1 100644 --- a/ipf/error/500.html +++ b/ipf/error/500.html @@ -2,5 +2,4 @@

Error 500

Server error

Our apologies…

-

Go to home page or go back to previous page.

- +

Go to home page or go back to previous page.

diff --git a/ipf/error/500.php b/ipf/error/500.php index c2e3f95..f13d6b7 100644 --- a/ipf/error/500.php +++ b/ipf/error/500.php @@ -1,10 +1,19 @@ render('500.html', array( + 'request' => $request, + 'exception' => $exception, + 'app_base' => $settings->get('app_base'), + )); } } - diff --git a/ipf/error/500_debug.php b/ipf/error/500_debug.php deleted file mode 100644 index 8a763bf..0000000 --- a/ipf/error/500_debug.php +++ /dev/null @@ -1,152 +0,0 @@ -__debugInfo() : get_object_vars($v); - $result[] = get_class($v) . ' Object'; - $result[] = '{'; - foreach ($props as $key => $val) { - $result[] = ' [' . $key . '] => ' . $this->debug_print_r($val, $indent+2); - } - $result[] = '}'; - } elseif ($v instanceof stdClass) { - $result[] = 'stdClass'; - $result[] = '{'; - foreach ($v as $k => $v) { - $result[] = ' ' . $k . ' => ' . $this->debug_print_r($v, $indent+2); - } - $result[] = '}'; - } elseif (is_array($v)) { - if ($v) { - $result[] = 'Array'; - $result[] = '{'; - foreach ($v as $k => $v) { - $result[] = ' [' . $k . '] => ' . $this->debug_print_r($v, $indent+2); - } - $result[] = '}'; - } else { - $result[] = 'Array()'; - } - } elseif (is_bool($v)) { - return $v ? 'true' : 'false'; - } else { - $result = explode("\n", print_r($v, true)); - } - - $i = str_repeat(' ', $indent); - foreach ($result as &$line) - $line = $i . $line; - return ltrim(implode("\n", $result)); - } - - function parse_headers($list) - { - $result = array(); - foreach ($list as $line) { - list($name, $value) = explode(':', $line, 2); - $result[$name] = $value; - } - return $result; - } - - function values($name, $values) - { - if ($values) { - ?>

- - $value): ?> - - - - - -
e($name) ?>e($this->debug_print_r($value)) ?>
getFile(); - $line = $exception->getLine(); - foreach ($exception->getTrace() as $frame) { - $params = array(); - if (isset($frame["function"])) { - try { - if (isset($frame["class"])) { - $r = new ReflectionMethod($frame["class"]."::".$frame["function"]); - } else { - $r = new ReflectionFunction($frame["function"]); - } - foreach ($r->getParameters() as $p) { - $params[$p->getPosition()] = $p->getName(); - } - } catch (ReflectionException $e) { - } - } - - $args = array(); - if (isset($frame['args'])) { - foreach ($frame['args'] as $index => $arg) { - $name = array_key_exists($index, $params) ? $params[$index] : ""; - $args[$name] = $arg; - } - } - - $result[] = array( - 'file' => $file, - 'line' => $line, - 'class' => @$frame['class'], - 'type' => @$frame['type'], - 'function' => @$frame['function'], - 'func' => @$frame['class'].@$frame['type'].@$frame['function'], - 'args' => $args, - ); - - $file = @$frame['file']; - $line = @$frame['line']; - } - - if ($file) { - $result[] = array( - 'file' => $file, - 'line' => $line, - 'class' => '', - 'type' => '', - 'function' => '', - 'func' => '', - 'args' => array(), - ); - } - - return $result; - } - - function sourceFile($file, $line) - { - $start = max($line - 10, 0); - $ol = "
    "; - - $rows = explode('
    ', nl2br(highlight_file($file, true))); - $rows = array_slice($rows, $start, 20); - - foreach ($rows as $k => $row) { - $attrs = ($k + $start === $line) ? ' class=current-line' : ''; - $ol .= "{$row}"; - } - $ol .= '
'; - return $ol; - } -} - diff --git a/ipf/error/500_debugPage.php b/ipf/error/500_debugPage.php new file mode 100644 index 0000000..2b13fde --- /dev/null +++ b/ipf/error/500_debugPage.php @@ -0,0 +1,164 @@ +render('500_debug.html', array( + 'request' => $request, + 'exception' => $exception, + )); + } + + function debug_print_r($v, $indent = 0) + { + $result = array(); + + if (is_object($v)) { + $props = method_exists($v, '__debugInfo') ? $v->__debugInfo() : get_object_vars($v); + $result[] = get_class($v) . ' Object'; + $result[] = '{'; + foreach ($props as $key => $val) { + $result[] = ' [' . $key . '] => ' . $this->debug_print_r($val, $indent + 2); + } + $result[] = '}'; + } elseif ($v instanceof stdClass) { + $result[] = 'stdClass'; + $result[] = '{'; + foreach ($v as $k => $v1) { + $result[] = ' ' . $k . ' => ' . $this->debug_print_r($v1, $indent + 2); + } + $result[] = '}'; + } elseif (is_array($v)) { + if ($v) { + $result[] = 'Array'; + $result[] = '{'; + foreach ($v as $k => $v1) { + $result[] = ' [' . $k . '] => ' . $this->debug_print_r($v1, $indent + 2); + } + $result[] = '}'; + } else { + $result[] = 'Array()'; + } + } elseif (is_bool($v)) { + return $v ? 'true' : 'false'; + } else { + $result = explode("\n", print_r($v, true)); + } + + $i = str_repeat(' ', $indent); + foreach ($result as &$line) + $line = $i . $line; + return ltrim(implode("\n", $result)); + } + + function parse_headers($list) + { + $result = array(); + foreach ($list as $line) { + list($name, $value) = explode(':', $line, 2); + $result[$name] = $value; + } + return $result; + } + + function values($name, $values) + { + if ($values) { + ?>

+ + $value): ?> + + + + + +
e($name) ?>e($this->debug_print_r($value)) ?>
getFile(); + $line = $exception->getLine(); + foreach ($exception->getTrace() as $frame) { + $params = array(); + if (isset($frame["function"])) { + try { + if (isset($frame["class"])) { + $r = new ReflectionMethod($frame["class"] . "::" . $frame["function"]); + } else { + $r = new ReflectionFunction($frame["function"]); + } + foreach ($r->getParameters() as $p) { + $params[$p->getPosition()] = $p->getName(); + } + } catch (ReflectionException $e) { + } + } + + $args = array(); + if (isset($frame['args'])) { + foreach ($frame['args'] as $index => $arg) { + $name = array_key_exists($index, $params) ? $params[$index] : ""; + $args[$name] = $arg; + } + } + + $result[] = array( + 'file' => $file, + 'line' => $line, + 'class' => @$frame['class'], + 'type' => @$frame['type'], + 'function' => @$frame['function'], + 'func' => @$frame['class'] . @$frame['type'] . @$frame['function'], + 'args' => $args, + ); + + $file = @$frame['file']; + $line = @$frame['line']; + } + + if ($file) { + $result[] = array( + 'file' => $file, + 'line' => $line, + 'class' => '', + 'type' => '', + 'function' => '', + 'func' => '', + 'args' => array(), + ); + } + + return $result; + } + + function sourceFile($file, $line) + { + $start = max($line - 10, 0); + $ol = "
    "; + + $rows = explode('
    ', nl2br(highlight_file($file, true))); + $rows = array_slice($rows, $start, 20); + + foreach ($rows as $k => $row) { + $attrs = ($k + $start === $line) ? ' class=current-line' : ''; + $ol .= "{$row}"; + } + $ol .= '
'; + return $ol; + } +} diff --git a/ipf/error/page.php b/ipf/error/page.php deleted file mode 100644 index 3e9f0dd..0000000 --- a/ipf/error/page.php +++ /dev/null @@ -1,35 +0,0 @@ -render($page->templateFile(), array('request' => $request, 'exception' => $exception)); - } - - abstract protected function templateFile(); -} - diff --git a/ipf/error/provider.php b/ipf/error/provider.php new file mode 100644 index 0000000..959d257 --- /dev/null +++ b/ipf/error/provider.php @@ -0,0 +1,30 @@ +get('debug'); + if ($isDebug) { + return ServerErrorDebugPage::renderPage($request, $exception); + } else { + return ServerErrorPage::renderPage($settings, $request, $exception); + } + }; + }; + } +} diff --git a/ipf/http/response/notfound.php b/ipf/http/response/notfound.php index 2a551aa..4dfa439 100644 --- a/ipf/http/response/notfound.php +++ b/ipf/http/response/notfound.php @@ -1,11 +1,15 @@ status_code = 404; } } - diff --git a/ipf/http/response/servererror.php b/ipf/http/response/servererror.php deleted file mode 100644 index 9b4e86d..0000000 --- a/ipf/http/response/servererror.php +++ /dev/null @@ -1,10 +0,0 @@ -status_code = 500; - } -} diff --git a/ipf/middleware/dispatch.php b/ipf/middleware/dispatch.php index 0d8e1ab..007617b 100644 --- a/ipf/middleware/dispatch.php +++ b/ipf/middleware/dispatch.php @@ -6,7 +6,7 @@ class IPF_Dispatch_Middleware extends IPF_Middleware { $m = $this->getRouter()->match($request); if (!$m) { - return new IPF_HTTP_Response_NotFound($request); + return new IPF_HTTP_Response_NotFound($this->container, $request); } list($route, $match) = $m; @@ -18,7 +18,7 @@ class IPF_Dispatch_Middleware extends IPF_Middleware $controller = new $controllerClass($this->container); return $controller->process($route->action(), $request, $match); } catch (IPF_Router_Shortcut $e) { - return $e->response($request); + return $e->response($this->container, $request); } } diff --git a/ipf/middleware/error.php b/ipf/middleware/error.php index 01b3832..7cec390 100644 --- a/ipf/middleware/error.php +++ b/ipf/middleware/error.php @@ -18,7 +18,7 @@ class IPF_Error_Middleware extends IPF_Middleware throw new \Exception('Response is not a IPF_HTTP_Response'); } catch (\Exception $exception) { error_log($exception); - $response = new IPF_HTTP_Response_ServerError($request, $exception); + $response = $this->getServerErrorResponse($request, $exception); } if ($this->previous_error_handler) set_error_handler($this->previous_error_handler); @@ -41,9 +41,23 @@ class IPF_Error_Middleware extends IPF_Middleware $error = error_get_last(); if ($error) { $exception = new \ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line']); - $response = new IPF_HTTP_Response_ServerError($request, $exception); + $response = $this->getServerErrorResponse($request, $exception); $response->render(); } } -} + /** + * @param IPF_HTTP_Request $request + * @param Exception $exception + * @return IPF_HTTP_Response + */ + private function getServerErrorResponse(IPF_HTTP_Request $request, Exception $exception) + { + $render500 = $this->container['render500']; + $content = call_user_func($render500, $request, $exception); + + $response = new IPF_HTTP_Response($content, null); + $response->status_code = 500; + return $response; + } +} diff --git a/ipf/project.php b/ipf/project.php index ddad1f6..d4b9b6f 100644 --- a/ipf/project.php +++ b/ipf/project.php @@ -1,6 +1,7 @@ container['apps'] = $apps; $this->container['router'] = function ($c) { - return new IPF_Router; + $settings = $c['settings']; + return new IPF_Router( + $settings->get('urls'), + $settings->get('app_base') + ); }; $this->router = $this->container['router']; } @@ -72,6 +77,7 @@ final class IPF_Project { $this->container->register(new CoreServicesProvider()); $this->container->register(new TemplateProvider()); + $this->container->register(new ErrorPageProvider()); $this->container['databaseConnection'] = function ($c) { return IPF_Database::connect(); diff --git a/ipf/router.php b/ipf/router.php index 0572b6a..02f13ca 100644 --- a/ipf/router.php +++ b/ipf/router.php @@ -4,10 +4,13 @@ class IPF_Router { /** @var IPF_Route[] */ private $routes = array(); + /** @var string */ + private $app_base; - public function __construct() + public function __construct(array $urls, $app_base) { - $this->flattenRoutes(IPF::get('urls')); + $this->app_base = $app_base; + $this->flattenRoutes($urls); } private function flattenRoutes($routes, $prefix='', $common=array()) @@ -62,7 +65,7 @@ class IPF_Router { foreach ($this->routes as $route) if ($route->routesTo($view)) - return IPF::get('app_base') . $route->matcher()->reverse($params); + return $this->app_base . $route->matcher()->reverse($params); throw new IPF_Exception('Error, the view: '.print_r($view, true).' has not been found.'); } } @@ -187,14 +190,13 @@ class IPF_Route abstract class IPF_Router_Shortcut extends Exception { - public abstract function response($request); + public abstract function response($container, $request); } class IPF_HTTP_Error404 extends IPF_Router_Shortcut { - public function response($request) + public function response($container, $request) { - return new IPF_HTTP_Response_NotFound($request); + return new IPF_HTTP_Response_NotFound($container, $request); } } -