diff --git a/plugins/example.json b/plugins/example.json index f19280d2..f1f399af 100644 --- a/plugins/example.json +++ b/plugins/example.json @@ -41,8 +41,8 @@ "priority": "130" }, "Redirect Example": { - "pattern": "/redirectExample", - "file": "account/manage" + "redirect_from": "/redirectExample", + "redirect_to": "account/manage" } } } diff --git a/system/functions.php b/system/functions.php index 0449e4b2..7dbf59ee 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1531,6 +1531,12 @@ function camelCaseToUnderscore($input) return ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_'); } +function removeIfFirstSlash(&$text) { + if(strpos($text, '/') === 0) { + $text = str_replace_first('/', '', $text); + } +}; + // validator functions require_once LIBS . 'validator.php'; require_once SYSTEM . 'compat/base.php'; diff --git a/system/libs/plugins.php b/system/libs/plugins.php index 6910a51d..68aa2547 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -76,23 +76,39 @@ class Plugins { if (isset($plugin['routes'])) { foreach ($plugin['routes'] as $_name => $info) { // default method: get - $methods = isset($info['method']) ? explode(',', $info['method']) : ['GET']; - foreach ($methods as $method) { - if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'])) { - self::$warnings[] = $warningPreTitle . 'Unallowed method ' . $method . '... Disabling this route...'; - continue; + $method = $info['method'] ?? ['GET']; + if ($method !== '*') { + $methods = is_string($method) ? explode(',', $info['method']) : $method; + foreach ($methods as $method) { + if (!in_array($method, ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'])) { + self::$warnings[] = $warningPreTitle . 'Not allowed method ' . $method . '... Disabling this route...'; + } } } + else { + $methods = '*'; // all available methods + } if (!isset($info['priority'])) { $info['priority'] = 100; // default priority } - // replace first occurence of / in pattern if found (will be auto-added later) - if(strpos($info['pattern'], '/') === 0) { - $info['pattern'] = str_replace_first('/', '', $info['pattern']); + if (isset($info['redirect_from'])) { + removeIfFirstSlash($info['redirect_from']); + + $info['pattern'] = $info['redirect_from']; + if (!isset($info['redirect_to'])) { + self::$warnings[] = $warningPreTitle . 'redirect set without "redirect_to".'; + } + else { + removeIfFirstSlash($info['redirect_to']); + $info['file'] = '__redirect__/' . $info['redirect_to']; + } } + // replace first occurence of / in pattern if found (will be auto-added later) + removeIfFirstSlash($info['pattern']); + foreach ($routes as $id => &$route) { if($route[1] == $info['pattern']) { if($info['priority'] < $route[3]) { @@ -102,7 +118,6 @@ class Plugins { else { self::$warnings[] = $warningPreTitle . "Duplicated route with lower priority: {$route[1]} ({$route[3]}). Disabling this route..."; unset($routes[$id]); - continue; } } } diff --git a/system/router.php b/system/router.php index 9adee97b..5718f900 100644 --- a/system/router.php +++ b/system/router.php @@ -65,31 +65,37 @@ if($logged && $account_logged && $account_logged->isLoaded()) { $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { $routes = require SYSTEM . 'routes.php'; - $duplicates = []; + $isAlreadyDefined = []; $routesTmp = []; foreach(getDatabasePages() as $page) { - $duplicates[$page] = true; - $routesTmp[] = [['GET', 'POST'], $page, 'database/' . $page, true]; + $isAlreadyDefined[$page] = true; + $routesTmp[] = ['*', $page, '__database__/' . $page, true]; } Plugins::clearWarnings(); foreach (Plugins::getRoutes() as $route) { - if(!isset($duplicates[$route[1]])) { - $duplicates[$route[1]] = true; + if(!isset($isAlreadyDefined[$route[1]])) { + $isAlreadyDefined[$route[1]] = true; $routesTmp[] = [$route[0], $route[1], $route[2]]; } } foreach ($routes as $route) { - if(!isset($duplicates[$route[1]])) { - $routesTmp[] = [$route[0], $route[1], 'system/pages/' . $route[2]]; + if(!isset($isAlreadyDefined[$route[1]])) { + if (strpos($route[2], '__redirect__') === false && strpos($route[2], '__database__') === false) { + $routesTmp[] = [$route[0], $route[1], 'system/pages/' . $route[2]]; + } + else { + $routesTmp[] = [$route[0], $route[1], $route[2]]; + } } } + //var_dump($routesTmp); foreach ($routesTmp as $route) { - if (strpos($route[2], '.php') === false && !isset($route[3])) { - $route[2] = str_replace('system/pages/', '', 'redirect/' . $route[2]); + if ($route[0] === '*') { + $route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; } $r->addRoute($route[0], $route[1], $route[2]); @@ -170,9 +176,8 @@ else { $_REQUEST = array_merge($_REQUEST, $vars); $_GET = array_merge($_GET, $vars); - if (strpos($path, 'database/') !== false) { - //var_dump($path); - $pageName = str_replace('database/', '', $path); + if (strpos($path, '__database__/') !== false) { + $pageName = str_replace('__database__/', '', $path); $success = false; $tmp_content = getCustomPage($pageName, $success); @@ -188,8 +193,8 @@ else { $page = $pageName; $file = false; } - } else if (strpos($path, 'redirect/') !== false) { - $path = str_replace('redirect/', '', $path); + } else if (strpos($path, '__redirect__/') !== false) { + $path = str_replace('__redirect__/', '', $path); header('Location: ' . BASE_URL . $path); exit; } else { diff --git a/system/routes.php b/system/routes.php index 8085b734..3d873d86 100644 --- a/system/routes.php +++ b/system/routes.php @@ -9,10 +9,10 @@ */ return [ - ['GET', '', 'news'], // redirect empty URL to news + ['GET', '', '__redirect__/news'], // redirect empty URL to news ['GET', 'news/archive/{id:[0-9]+}[/]', 'news/archive.php'], - [['GET', 'POST'], 'account/base[/]', '404.php'], // this is to block account/base.php + ['*', 'account/base[/]', '404.php'], // this is to block account/base.php [['GET', 'POST'], 'account/password[/]', 'account/change_password.php'], [['GET', 'POST'], 'account/register/new[/]', 'account/register_new.php'], [['GET', 'POST'], 'account/email[/]', 'account/change_email.php'],