diff --git a/admin/index.php b/admin/index.php index bfc42cf8..7ef1c31f 100644 --- a/admin/index.php +++ b/admin/index.php @@ -52,9 +52,6 @@ if(!$logged || !admin()) { $page = 'login'; } -// more pages have action, lets define it here -$action = $_REQUEST['action'] ?? ''; - // include our page $file = BASE . 'admin/pages/' . $page . '.php'; if(!@file_exists($file)) { diff --git a/index.php b/index.php index 234e98dc..693d90d7 100644 --- a/index.php +++ b/index.php @@ -28,19 +28,13 @@ require_once 'common.php'; require_once SYSTEM . 'functions.php'; $uri = $_SERVER['REQUEST_URI']; - -$tmp = BASE_DIR; -if(!empty($tmp)) - $uri = str_replace(BASE_DIR . '/', '', $uri); -else - $uri = str_replace_first('/', '', $uri); - -$uri = str_replace_first('index.php', '', $uri); -if(($pos = strpos($uri, '?') === 0) || $pos == 9) { - $uri = str_replace_first('?', '', $uri); +if(false !== strpos($uri, 'index.php')) { + $uri = str_replace_first('/index.php', '', $uri); } -define('URI', $uri); +if(0 === strpos($uri, '/')) { + $uri = str_replace_first('/', '', $uri); +} if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { $tmp = explode('.', $uri); @@ -51,7 +45,7 @@ if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { exit(); } -if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|php|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { +if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|gz|ttf|woff|ico)$/i", $_SERVER['REQUEST_URI'])) { http_response_code(404); exit; } @@ -98,6 +92,8 @@ require_once SYSTEM . 'status.php'; $twig->addGlobal('config', $config); $twig->addGlobal('status', $status); +require_once SYSTEM . 'router.php'; + require SYSTEM . 'migrate.php'; $hooks->trigger(HOOK_STARTUP); @@ -146,35 +142,6 @@ if($config['visitors_counter']) $visitors = new Visitors($config['visitors_counter_ttl']); } -// page content loading -if(!isset($content[0])) - $content = ''; -$load_it = true; - -// check if site has been closed -$site_closed = false; -if(fetchDatabaseConfig('site_closed', $site_closed)) { - $site_closed = ($site_closed == 1); - if($site_closed) { - if(!admin()) - { - $title = getDatabaseConfig('site_closed_title'); - $content .= '
' . getDatabaseConfig('site_closed_message') . '
' . getDatabaseConfig('site_closed_message') . '
Site is under maintenance (closed mode). Only privileged users can see it.
'; $ignore = false; +/** @var boolean $logged */ +/** @var OTS_Account $account_logged */ $logged_access = 1; if($logged && $account_logged && $account_logged->isLoaded()) { $logged_access = $account_logged->getAccess(); } -$success = false; -$tmp_content = getCustomPage($uri, $success); -if($success) { - $content .= $tmp_content; - if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { - $pageInfo = getCustomPageInfo($uri); - $content = $twig->render('admin.pages.links.html.twig', array( - 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') - )) . $content; +/** + * Routes loading + */ +$dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { + $routes = require SYSTEM . 'routes.php'; + + $duplicates = []; + + $routesTmp = []; + foreach(getDatabasePages() as $page) { + $duplicates[$page] = true; + $routesTmp[] = [['GET', 'POST'], $page, 'database/' . $page, true]; } - $page = $uri; -} else { - // old support for pages like /?subtopic=accountmanagement - $page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? ''); - if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { - if(config('backward_support')) { - require SYSTEM . 'compat_pages.php'; + Plugins::clearWarnings(); + foreach (Plugins::getRoutes() as $route) { + if(!isset($duplicates[$route[1]])) { + $duplicates[$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]]; + } + } + + foreach ($routesTmp as $route) { + if (strpos($route[2], '.php') === false && !isset($route[3])) { + $route[2] = str_replace('system/pages/', '', 'redirect/' . $route[2]); } - $file = SYSTEM . 'pages/' . $page . '.php'; - if (!is_file($file)) { - $page = '404'; - $file = SYSTEM . 'pages/404.php'; + $r->addRoute($route[0], $route[1], $route[2]); + } + + if (config('env') === 'dev') { + foreach(Plugins::getWarnings() as $warning) { + log_append('router.log', $warning); } } +}, + [ + 'cacheFile' => CACHE . 'route.cache', + 'cacheDisabled' => config('env') === 'dev', + ] +); + +// Fetch method and URI +$httpMethod = $_SERVER['REQUEST_METHOD']; + +// Strip query string (?foo=bar) and decode URI +/** @var string $uri */ +if (false !== $pos = strpos($uri, '?')) { + if ($pos !== 1) { + $uri = substr($uri, 0, $pos); + } else { - $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { - $routes = require SYSTEM . 'routes.php'; + $uri = str_replace_first('?', '', $uri); + } +} - $duplicates = []; - Plugins::clearWarnings(); - foreach (Plugins::getRoutes() as $route) { - $duplicates[$route[1]] = true; - $r->addRoute($route[0], '/' . $route[1], $route[2]); +$uri = rawurldecode($uri); +define('URI', $uri); + +$found = true; + +// old support for pages like /?subtopic=accountmanagement +$page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? ''); +if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { + if (config('backward_support')) { + require SYSTEM . 'compat/pages.php'; + } + + $file = loadPageFromFileSystem($page, $found); + if(!$found) { + $file = false; + } +} +else { + $routeInfo = $dispatcher->dispatch($httpMethod, $uri); + switch ($routeInfo[0]) { + case FastRoute\Dispatcher::NOT_FOUND: + // ... 404 Not Found + //var_dump('not found'); + /** + * Fallback to load page from templates/ or system/pages/ directory + */ + $page = $uri; + if (preg_match('/^[A-z0-9\/\-]+$/', $page)) { + $file = loadPageFromFileSystem($page, $found); + } else { + $found = false; } - foreach ($routes as $route) { - if(!isset($duplicates[$route[1]])) { - $r->addRoute($route[0], '/' . $route[1], 'system/pages/' . $route[2]); - } - } + break; - if (config('env') === 'dev') { - foreach(Plugins::getWarnings() as $warning) { - log_append('router.log', $warning); - } - } - }, - [ - 'cacheFile' => CACHE . 'route.cache', - 'cacheDisabled' => config('env') === 'dev', - ] - ); + case FastRoute\Dispatcher::METHOD_NOT_ALLOWED: + // ... 405 Method Not Allowed + $page = '405'; + $allowedMethods = $routeInfo[1]; + $file = SYSTEM . 'pages/405.php'; + break; - // Fetch method and URI from somewhere - $httpMethod = $_SERVER['REQUEST_METHOD']; - $uri = $_SERVER['REQUEST_URI']; + case FastRoute\Dispatcher::FOUND: + $path = $routeInfo[1]; + $vars = $routeInfo[2]; - // Strip query string (?foo=bar) and decode URI - if (false !== $pos = strpos($uri, '?')) { - if ($pos !== 1) { - $uri = substr($uri, 0, $pos); - } - else { - $uri = str_replace_first('?', '', $uri); - } - } - $uri = rawurldecode($uri); + $_REQUEST = array_merge($_REQUEST, $vars); + $_GET = array_merge($_GET, $vars); - $routeInfo = $dispatcher->dispatch($httpMethod, $uri); - switch ($routeInfo[0]) { - case FastRoute\Dispatcher::NOT_FOUND: - // ... 404 Not Found - $tmp = URI; - $found = true; + if (strpos($path, 'database/') !== false) { + //var_dump($path); + $pageName = str_replace('database/', '', $path); - $page = $tmp; - if (preg_match('/^[A-z0-9\/\-]+$/', $tmp)) { - global $template_path; - $file = $template_path . '/pages/' . $tmp . '.php'; - if (!is_file($file)) { - $file = SYSTEM . 'pages/' . $tmp . '.php'; - if (!is_file($file)) { - $found = false; - } - } - } - else { - $tmp_ = BASE_DIR; - $uri = $_SERVER['REQUEST_URI']; - if (!empty($tmp)) { - $uri = str_replace(BASE_DIR . '/', '', $uri); + $success = false; + $tmp_content = getCustomPage($pageName, $success); + if ($success) { + $content .= $tmp_content; + if (hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { + $pageInfo = getCustomPageInfo($pageName); + $content = $twig->render('admin.pages.links.html.twig', array( + 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') + )) . $content; } - if (false !== $pos = strpos($uri, '?')) { - $tmp = substr($uri, 0, $pos); - } - - if (empty($tmp)) { - $page = 'news'; - $file = SYSTEM . 'pages/news.php'; - } - else { - $found = false; - } + $page = $pageName; + $file = false; } - - if (!$found) { - $page = '404'; - $file = SYSTEM . 'pages/404.php'; - } - - break; - - case FastRoute\Dispatcher::METHOD_NOT_ALLOWED: - // ... 405 Method Not Allowed - $page = '405'; - $allowedMethods = $routeInfo[1]; - $file = SYSTEM . 'pages/405.php'; - break; - - case FastRoute\Dispatcher::FOUND: - $path = $routeInfo[1]; - $vars = $routeInfo[2]; - - $_REQUEST = array_merge($_REQUEST, $vars); - $_GET = array_merge($_GET, $vars); - + } else if (strpos($path, 'redirect/') !== false) { + $path = str_replace('redirect/', '', $path); + header('Location: ' . BASE_URL . $path); + exit; + } else { // parse for define PAGE $tmp = BASE_DIR; $uri = $_SERVER['REQUEST_URI']; @@ -172,24 +209,23 @@ if($success) { $page = $uri; $file = BASE . $path; + } - unset($tmp, $uri); - break; - } + unset($tmp, $uri); + break; } } -define('PAGE', $page); -if(config('backward_support')) { - $subtopic = $page; +if (!$found) { + $page = '404'; + $file = SYSTEM . 'pages/404.php'; } -$action = isset($_REQUEST['action']) ? strtolower($_REQUEST['action']) : ''; -define('ACTION', $action); +define('PAGE', $page); ob_start(); if($hooks->trigger(HOOK_BEFORE_PAGE)) { - if(!$ignore) + if(!$ignore && $file !== false) require $file; } @@ -202,13 +238,49 @@ $content .= ob_get_contents(); ob_end_clean(); $hooks->trigger(HOOK_AFTER_PAGE); +if(!isset($title)) { + $title = ucfirst($page); +} + if(config('backward_support')) { $main_content = $content; - if(!isset($title)) { - $title = ucfirst($page); - } - $topic = $title; } unset($page); + +function getDatabasePages() { + global $db; + $pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages'); + $ret = []; + + if ($pages->rowCount() < 1) { + return $ret; + } + + foreach($pages->fetchAll() as $page) { + $ret [] = $page['name']; + } + + return $ret; +} + +function loadPageFromFileSystem($page, &$found) { + $file = SYSTEM . 'pages/' . $page . '.php'; + if (!is_file($file)) { + // feature: convert camelCase to snake_case + // so instead of forum/move_thread + // we can write: forum/moveThread + $file = SYSTEM . 'pages/' . camelCaseToUnderscore($page) . '.php'; + if (!is_file($file)) { + // feature: load pages from templates/ dir + global $template_path; + $file = $template_path . '/pages/' . $page . '.php'; + if (!is_file($file)) { + $found = false; + } + } + } + + return $file; +} diff --git a/system/routes.php b/system/routes.php index aa42dbf0..8085b734 100644 --- a/system/routes.php +++ b/system/routes.php @@ -9,9 +9,11 @@ */ return [ + ['GET', '', '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 [['GET', 'POST'], 'account/password[/]', 'account/change_password.php'], - [['GET', 'POST'], 'account/register[/]', 'account/register.php'], [['GET', 'POST'], 'account/register/new[/]', 'account/register_new.php'], [['GET', 'POST'], 'account/email[/]', 'account/change_email.php'], [['GET', 'POST'], 'account/info[/]', 'account/change_info.php'], @@ -22,7 +24,7 @@ return [ [['GET', 'POST'], 'account/character/comment[/{name:[A-Za-z0-9-_%+\']+}]', 'account/change_comment.php'], ['GET', 'account/confirm_email/{hash:[A-Za-z0-9-_]+}[/]', 'account/confirm_email.php'], - ['GET', 'bans[/{page:\d+}]', 'bans.php'], + ['GET', 'bans/{page:\d+}[/]', 'bans.php'], [['GET', 'POST'], 'characters[/{name:[A-Za-z0-9-_%+\']+}]', 'characters.php'], ['GET', 'changelog[/{page:\d+}]', 'changelog.php'], ['GET', 'creatures[/{name:[A-Za-z0-9-_%+\']+}]', 'creatures.php'], @@ -45,9 +47,7 @@ return [ ['GET', 'highscores/{list:[A-Za-z0-9-_]+}/{vocation:[A-Za-z0-9-_]+}[/]', 'highscores.php'], ['GET', 'highscores/{list:[A-Za-z0-9-_]+}[/]', 'highscores.php'], - ['GET', '', 'news.php'], - [['GET', 'POST'], 'news/archive[/]', 'newsarchive.php'], - ['GET', 'news/archive/{id:[0-9]+}[/]', 'newsarchive.php'], + ['GET', 'online/{order:[A-Za-z0-9-_]+}[/]', 'online.php'], /* '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), '/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), diff --git a/system/templates/online.html.twig b/system/templates/online.html.twig index 04e0b651..b7c9d916 100644 --- a/system/templates/online.html.twig +++ b/system/templates/online.html.twig @@ -85,14 +85,14 @@# | +# | {% endif %} {% if config.online_outfit %}Outfit | {% endif %} -Name | -Level | -Vocation | +Name | +Level | +Vocation |