]> git.andy128k.dev Git - ipf.git/commitdiff
rework error pages
authorAndrey Kutejko <andy128k@gmail.com>
Sat, 16 Mar 2019 14:23:54 +0000 (15:23 +0100)
committerAndrey Kutejko <andy128k@gmail.com>
Sat, 16 Mar 2019 14:26:37 +0000 (15:26 +0100)
17 files changed:
ipf/admin/app.php
ipf/admin/controllers/components.php
ipf/admin/controllers/user.php
ipf/error/404.html
ipf/error/404.php
ipf/error/500.html
ipf/error/500.php
ipf/error/500_debug.php [deleted file]
ipf/error/500_debugPage.php [new file with mode: 0644]
ipf/error/page.php [deleted file]
ipf/error/provider.php [new file with mode: 0644]
ipf/http/response/notfound.php
ipf/http/response/servererror.php [deleted file]
ipf/middleware/dispatch.php
ipf/middleware/error.php
ipf/project.php
ipf/router.php

index 50ac73bedb7b6f737fa837b036a2895eafd77e70..0d08d1f00d141579f9d3e43523fcec26bd12b5e7 100644 (file)
@@ -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);
     }
 }
index 77861737efba94be7bf258a3e927d36aa817154c..b2c4dddf00d8073cdd5b6cc106f41920b2550ddf 100644 (file)
@@ -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");
index 4430c4d23566f96e438f1e452dee9c6c12129a72..70ebf99b933b068842fe159d865ec6942d72a78b 100644 (file)
@@ -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);
         }
 
index c62e3a560aa2fd761f7f1d2734687fa54879b5ba..4c449d1fe9526bba5b63695da5b2aade5dda322f 100644 (file)
@@ -2,5 +2,4 @@
 <h1>Error 404</h1>
 <h2>Page not found</h2>
 <p>Sorry, it appears the page you were looking for does not exist anymore or might have been moved.</p>
-<p>Go to <a href="<?php echo IPF::get('app_base') ?>/">home page</a> or go back to <a href="#" onclick="javascript:history.back();">previous page</a>.</p>
-
+<p>Go to <a href="<?php echo $this->app_base ?>/">home page</a> or go back to <a href="#" onclick="javascript:history.back();">previous page</a>.</p>
index 0f88bcaffcbc0651be705fb41366afab7319aa10..08889ba1275ea3b26ef050e0f384ef63d67d65ee 100644 (file)
@@ -1,10 +1,18 @@
 <?php
 
-class IPF_Not_Found_Error_Page extends IPF_Error_Page
+namespace IPF\Error;
+
+use IPF_Settings;
+use PFF\NativeTemplate;
+
+class NotFoundPage extends NativeTemplate
 {
-    protected function templateFile()
+    public static function renderPage(IPF_Settings $settings, $request)
     {
-        return '404.html';
+        $page = new NativeTemplate(array(dirname(__FILE__)));
+        return $page->render('404.html', array(
+            'request' => $request,
+            'app_base' => $settings->get('app_base'),
+        ));
     }
 }
-
index 509e9ea605a7b6ba2863903733adfbdb41b415b5..bcea3a1e46c45026a3ce62618d01aaf247a75753 100644 (file)
@@ -2,5 +2,4 @@
 <h1>Error 500</h1>
 <h2>Server error</h2>
 <p>Our apologies&hellip;</p>
-<p>Go to <a href="<?php echo IPF::get('app_base') ?>/">home page</a> or go back to <a href="#" onclick="javascript:history.back();">previous page</a>.</p>
-
+<p>Go to <a href="<?php echo $this->app_base ?>/">home page</a> or go back to <a href="#" onclick="javascript:history.back();">previous page</a>.</p>
index c2e3f95ec46e3dc5198d56533841398705c6b932..f13d6b7790c9ed226378aba7785d8bd384de099a 100644 (file)
@@ -1,10 +1,19 @@
 <?php
 
-class IPF_Server_Error_Page extends IPF_Error_Page
+namespace IPF\Error;
+
+use IPF_Settings;
+use PFF\NativeTemplate;
+
+class ServerErrorPage extends NativeTemplate
 {
-    protected function templateFile()
+    public static function renderPage(IPF_Settings $settings, $request, $exception = null)
     {
-        return '500.html';
+        $page = new static(array(dirname(__FILE__)));
+        return $page->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 (file)
index 8a763bf..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-
-class IPF_Server_Error_Page_Debug extends IPF_Error_Page
-{
-    protected function templateFile()
-    {
-        return '500_debug.html';
-    }
-
-    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 => $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) {
-            ?><h3><?php echo $name ?></h3>
-            <table class="values">
-              <?php foreach ($values as $name => $value): ?>
-                <tr>
-                  <th><?php $this->e($name) ?></th>
-                  <td><?php $this->e($this->debug_print_r($value)) ?></td>
-                </tr>
-              <?php endforeach; ?>
-            </table><?php
-        }
-    }
-
-    function frames($exception)
-    {
-        $result = array();
-
-        $file = $exception->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] : "<arg-{$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 = "<ol start={$start} class=source>";
-
-        $rows = explode('<br />', nl2br(highlight_file($file, true)));
-        $rows = array_slice($rows, $start, 20);
-
-        foreach ($rows as $k => $row) {
-            $attrs = ($k + $start === $line) ? ' class=current-line' : '';
-            $ol .= "<li{$attrs}>{$row}</li>";
-        }
-        $ol .= '</ol>';
-        return $ol;
-    }
-}
-
diff --git a/ipf/error/500_debugPage.php b/ipf/error/500_debugPage.php
new file mode 100644 (file)
index 0000000..2b13fde
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+
+namespace IPF\Error;
+
+use Exception;
+use PFF\NativeTemplate;
+use ReflectionException;
+use ReflectionFunction;
+use ReflectionMethod;
+use stdClass;
+
+class ServerErrorDebugPage extends NativeTemplate
+{
+    public static function renderPage($request, $exception)
+    {
+        $page = new static(array(dirname(__FILE__)));
+        return $page->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) {
+            ?><h3><?php echo $name ?></h3>
+            <table class="values">
+            <?php foreach ($values as $name => $value): ?>
+                <tr>
+                    <th><?php $this->e($name) ?></th>
+                    <td><?php $this->e($this->debug_print_r($value)) ?></td>
+                </tr>
+            <?php endforeach; ?>
+            </table><?php
+        }
+    }
+
+    function frames(Exception $exception)
+    {
+        $result = array();
+
+        $file = $exception->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] : "<arg-{$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 = "<ol start={$start} class=source>";
+
+        $rows = explode('<br />', nl2br(highlight_file($file, true)));
+        $rows = array_slice($rows, $start, 20);
+
+        foreach ($rows as $k => $row) {
+            $attrs = ($k + $start === $line) ? ' class=current-line' : '';
+            $ol .= "<li{$attrs}>{$row}</li>";
+        }
+        $ol .= '</ol>';
+        return $ol;
+    }
+}
diff --git a/ipf/error/page.php b/ipf/error/page.php
deleted file mode 100644 (file)
index 3e9f0dd..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-abstract class IPF_Error_Page extends \PFF\NativeTemplate
-{
-    public static function render404($request)
-    {
-        if (IPF::get('render404')) {
-            $func = IPF::get('render404');
-            return IPF::callFunction($func, array($request));
-        } else {
-            return IPF_Not_Found_Error_Page::renderPage($request);
-        }
-    }
-
-    public static function render500($request, $exception)
-    {
-        if (IPF::get('debug')) {
-            return IPF_Server_Error_Page_Debug::renderPage($request, $exception);
-        } elseif (IPF::get('render500')) {
-            $func = IPF::get('render500');
-            return IPF::callFunction($func, array($request, $exception));
-        } else {
-            return IPF_Server_Error_Page::renderPage($request, $exception);
-        }
-    }
-
-    protected static function renderPage($request, $exception=null)
-    {
-        $page = new static(array(dirname(__FILE__)));
-        return $page->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 (file)
index 0000000..959d257
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+namespace IPF\Error;
+
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+class ErrorPageProvider implements ServiceProviderInterface
+{
+    public function register(Container $container)
+    {
+        $container['render404'] = function ($c) {
+            $settings = $c['settings'];
+            return function ($request) use ($settings) {
+                return NotFoundPage::renderPage($settings, $request);
+            };
+        };
+        $container['render500'] = function ($c) {
+            $settings = $c['settings'];
+            return function ($request, $exception) use ($settings) {
+                $isDebug = $settings->get('debug');
+                if ($isDebug) {
+                    return ServerErrorDebugPage::renderPage($request, $exception);
+                } else {
+                    return ServerErrorPage::renderPage($settings, $request, $exception);
+                }
+            };
+        };
+    }
+}
index 2a551aa2a1653aaa4332041826e9ba330966be0b..4dfa43962510e6d558ee00d7a21b11d30f917ab0 100644 (file)
@@ -1,11 +1,15 @@
 <?php
 
+use Pimple\Container;
+
 class IPF_HTTP_Response_NotFound extends IPF_HTTP_Response
 {
-    function __construct($request=null)
+    function __construct(Container $container, IPF_HTTP_Request $request)
     {
-        parent::__construct(IPF_Error_Page::render404($request));
+        $render404 = $container['render404'];
+        $content = call_user_func($render404, $request);
+
+        parent::__construct($content);
         $this->status_code = 404;
     }
 }
-
diff --git a/ipf/http/response/servererror.php b/ipf/http/response/servererror.php
deleted file mode 100644 (file)
index 9b4e86d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-class IPF_HTTP_Response_ServerError extends IPF_HTTP_Response
-{
-    function __construct($request, $exception, $mimetype=null)
-    {
-        parent::__construct(IPF_Error_Page::render500($request, $exception), $mimetype);
-        $this->status_code = 500;
-    }
-}
index 0d8e1ab5af99fe88ade14ea004de1c0a4801ced7..007617bbc491d15b1ab9ea2d6caf9cabe9690ed2 100644 (file)
@@ -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);
         }
     }
 
index 01b3832b3448cb035c04cf79722a82296fa8a80a..7cec3905a24102fcbe05422e0606841b6936447d 100644 (file)
@@ -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;
+    }
+}
index ddad1f67fe408ca40b208d5ced89b1a688774e8e..d4b9b6f1c5bc97f68cf45dd5ca1f3e1f6b50cb0b 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use IPF\CoreServicesProvider;
+use IPF\Error\ErrorPageProvider;
 use IPF\Template\TemplateProvider;
 use Pimple\Container;
 
@@ -38,7 +39,11 @@ final class IPF_Project
         }
         $this->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();
index 0572b6a094602a4046fb845c1a2498cc671cae28..02f13cafa7a0c9f5ee0c48fb3fbf797700ecf653 100644 (file)
@@ -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);
     }
 }
-