Another approach to fix duplicates - priorities

Priority description: (lower number - higher priority)
1-99 Highest priority - overrides everything, even pages from database, use with caption
100 - default for pages in database
101-999 - recommended range for plugins
1000 - default value for plugins if no other specified
1001 - 9999 - no usage currently
10000 - default myaac routes
This commit is contained in:
slawkens 2024-06-13 21:35:47 +02:00
parent c1d4b4f80c
commit c7a6a539a9
4 changed files with 68 additions and 46 deletions

View File

@ -40,6 +40,8 @@
"redirect_to": "account/manage" "redirect_to": "account/manage"
} }
}, },
"routes-default-priority": 1000,
"pages-default-priority": 1000,
"settings": "plugins/your-plugin-folder/settings.php", "settings": "plugins/your-plugin-folder/settings.php",
"autoload": { "autoload": {
"pages": true, "pages": true,

View File

@ -91,34 +91,66 @@ if($logged && $account_logged && $account_logged->isLoaded()) {
$dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) {
$routes = require SYSTEM . 'routes.php'; $routes = require SYSTEM . 'routes.php';
$isAlreadyDefined = [];
$routesFinal = []; $routesFinal = [];
foreach(getDatabasePages() as $page) { foreach(getDatabasePages() as $page) {
$isAlreadyDefined[$page] = true; $routesFinal[] = ['*', $page, '__database__/' . $page, 100];
$routesFinal[] = ['*', $page, '__database__/' . $page, true];
} }
Plugins::clearWarnings(); Plugins::clearWarnings();
foreach (Plugins::getRoutes() as $route) { foreach (Plugins::getRoutes() as $route) {
if(!isset($isAlreadyDefined[$route[1]])) { $routesFinal[] = [$route[0], $route[1], $route[2], $route[3] ?? 1000];
$isAlreadyDefined[$route[1]] = true; /*
$routesFinal[] = [$route[0], $route[1], $route[2]]; echo '<pre>';
} var_dump($route[1], $route[3], $route[2]);
echo '/<pre>';
*/
} }
foreach ($routes as $route) { foreach ($routes as $route) {
if(!isset($isAlreadyDefined[$route[1]])) { if (!str_contains($route[2], '__redirect__') && !str_contains($route[2], '__database__')) {
if (strpos($route[2], '__redirect__') === false && strpos($route[2], '__database__') === false) { $routesFinal[] = [$route[0], $route[1], 'system/pages/' . $route[2], $route[3] ?? 10000];
$routesFinal[] = [$route[0], $route[1], 'system/pages/' . $route[2]]; }
} else {
else { $routesFinal[] = [$route[0], $route[1], $route[2], $route[3] ?? 10000];
$routesFinal[] = [$route[0], $route[1], $route[2]];
}
$isAlreadyDefined[$route[1]] = true;
} }
} }
// sort required for the next step (filter)
usort($routesFinal, function ($a, $b)
{
// key 3 is priority
if ($a[3] == $b[3]) {
return 0;
}
return ($a[3] < $b[3]) ? -1 : 1;
});
// remove duplicates
// if same route pattern, but different priority
$routesFinal = array_filter($routesFinal, function ($a) {
$aliases = [
[':int', ':string', ':alphanum'],
[':\d+', ':[A-Za-z0-9-_%+\' ]+', ':[A-Za-z0-9]+'],
];
// apply aliases
$a[1] = str_replace($aliases[0], $aliases[1], $a[1]);
static $duplicates = [];
if (isset($duplicates[$a[1]])) {
return false;
}
$duplicates[$a[1]] = true;
return true;
});
/*
echo '<pre>';
var_dump($routesFinal);
echo '</pre>';
die;
*/
foreach ($routesFinal as $route) { foreach ($routesFinal as $route) {
if ($route[0] === '*') { if ($route[0] === '*') {
$route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; $route[0] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];

View File

@ -15,9 +15,9 @@ return [
['GET', 'news/{id:int}', 'news/archive.php'], ['GET', 'news/{id:int}', 'news/archive.php'],
// block access to some files // block access to some files
['*', 'account/base', '404.php'], // this is to block account/base.php ['*', 'account/base', '404.php', 10], // this is to block account/base.php
['*', 'forum/base', '404.php'], ['*', 'forum/base', '404.php', 10],
['*', 'guilds/base', '404.php'], ['*', 'guilds/base', '404.php', 10],
[['GET', 'POST'], 'account/password', 'account/change_password.php'], [['GET', 'POST'], 'account/password', 'account/change_password.php'],
[['GET', 'POST'], 'account/register/new', 'account/register_new.php'], [['GET', 'POST'], 'account/register/new', 'account/register_new.php'],

View File

@ -24,9 +24,9 @@ class Plugins {
$duplicates = []; $duplicates = [];
$routes = []; $routes = [];
foreach(self::getAllPluginsJson() as $plugin) { foreach(self::getAllPluginsJson() as $plugin) {
$priority = 100; $routesDefaultPriority = 1000;
if (isset($plugin['priority'])) { if (isset($plugin['routes-default-priority'])) {
$priority = $plugin['priority']; $routesDefaultPriority = $plugin['routes-default-priority'];
} }
$warningPreTitle = 'Plugin: ' . $plugin['name'] . ' - '; $warningPreTitle = 'Plugin: ' . $plugin['name'] . ' - ';
@ -49,7 +49,7 @@ class Plugins {
} }
if (!isset($info['priority'])) { if (!isset($info['priority'])) {
$info['priority'] = 100; // default priority $info['priority'] = $routesDefaultPriority; // default priority taken from plugin.json
} }
if (isset($info['redirect_from'])) { if (isset($info['redirect_from'])) {
@ -68,27 +68,15 @@ class Plugins {
// replace first occurrence of / in pattern if found (will be auto-added later) // replace first occurrence of / in pattern if found (will be auto-added later)
removeIfFirstSlash($info['pattern']); removeIfFirstSlash($info['pattern']);
foreach ($routes as $id => &$route) { $routes[] = [$methods, $info['pattern'], $info['file'], $info['priority']];
if($route[1] == $info['pattern']) {
if($info['priority'] < $route[3]) {
self::$warnings[] = $warningPreTitle . "Duplicated route with lower priority: {$info['pattern']}. Disabling this route...";
continue 2;
}
else {
self::$warnings[] = $warningPreTitle . "Duplicated route with lower priority: {$route[1]} ({$route[3]}). Disabling this route...";
unset($routes[$id]);
}
}
}
$tmp = preg_replace("/\[[^)]+\]/",'', $info['pattern']);
if (!isset($duplicates[$tmp])) {
$routes[] = [$methods, $info['pattern'], $info['file'], $info['priority']];
$duplicates[$tmp] = true;
}
} }
} }
$pagesDefaultPriority = 1000;
if (isset($plugin['pages-default-priority'])) {
$pagesDefaultPriority = $plugin['pages-default-priority'];
}
if (self::getAutoLoadOption($plugin, 'pages', true)) { if (self::getAutoLoadOption($plugin, 'pages', true)) {
// //
// Get all plugins/*/pages/*.php pages // Get all plugins/*/pages/*.php pages
@ -99,7 +87,7 @@ class Plugins {
$name = pathinfo($file, PATHINFO_FILENAME); $name = pathinfo($file, PATHINFO_FILENAME);
if (!isset($duplicates[$name])) { if (!isset($duplicates[$name])) {
$routes[] = [['get', 'post'], $name, $file, $priority]; $routes[] = [['get', 'post'], $name, $file, $pagesDefaultPriority];
$duplicates[$name] = true; $duplicates[$name] = true;
} }
} }
@ -119,7 +107,7 @@ class Plugins {
$name = $folderName . '/' . pathinfo($file, PATHINFO_FILENAME); $name = $folderName . '/' . pathinfo($file, PATHINFO_FILENAME);
if (!isset($duplicates[$name])) { if (!isset($duplicates[$name])) {
$routes[] = [['get', 'post'], $name, $file, $priority]; $routes[] = [['get', 'post'], $name, $file, $pagesDefaultPriority];
$duplicates[$name] = true; $duplicates[$name] = true;
} }
} }
@ -139,9 +127,9 @@ class Plugins {
// cleanup before passing back // cleanup before passing back
// priority is not needed anymore // priority is not needed anymore
foreach ($routes as &$route) { //foreach ($routes as &$route) {
unset($route[3]); // unset($route[3]);
} //}
if ($cache->enabled()) { if ($cache->enabled()) {
$cache->set('plugins_routes', serialize($routes), 600); $cache->set('plugins_routes', serialize($routes), 600);