From e52a301d9eb17928220c19f0e4017861a27e0572 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 8 Jun 2021 19:17:38 +0200 Subject: [PATCH] [WIP] nikic/fast-route implementation I will describe it more in Pull Request --- composer.json | 3 +- index.php | 169 +------------ plugins/example.json | 16 +- system/compat_pages.php | 13 +- system/functions.php | 9 + system/hooks.php | 2 + system/libs/plugins.php | 98 +++++++- system/login.php | 204 +++++++--------- system/pages/405.php | 16 ++ system/pages/account/base.php | 29 +++ system/pages/account/change_comment.php | 9 +- system/pages/account/change_email.php | 9 +- system/pages/account/change_info.php | 12 +- system/pages/account/change_name.php | 9 +- system/pages/account/change_password.php | 9 +- system/pages/account/change_sex.php | 9 +- system/pages/account/confirm_email.php | 2 +- .../{createaccount.php => account/create.php} | 0 system/pages/account/create_character.php | 7 + system/pages/account/delete_character.php | 7 + system/pages/account/logout.php | 37 +++ .../{lostaccount.php => account/lost.php} | 0 system/pages/account/manage.php | 97 ++++++++ .../{account.php => account/redirect.php} | 13 +- system/pages/account/register.php | 9 +- system/pages/account/register_new.php | 9 +- system/pages/accountmanagement.php | 151 ------------ system/pages/forum.php | 223 ++++-------------- system/pages/forum/admin.php | 95 ++++++++ system/pages/forum/base.php | 51 ++++ system/pages/forum/edit_post.php | 4 +- system/pages/forum/move_thread.php | 4 +- system/pages/forum/new_post.php | 15 +- system/pages/forum/new_thread.php | 4 +- system/pages/forum/remove_post.php | 4 +- system/pages/forum/show_board.php | 2 + system/pages/forum/show_thread.php | 2 + system/pages/guilds.php | 9 +- system/pages/guilds/accept_invite.php | 4 +- system/pages/guilds/add_rank.php | 4 +- system/pages/guilds/base.php | 17 ++ system/pages/guilds/change_description.php | 2 + system/pages/guilds/change_logo.php | 4 +- system/pages/guilds/change_motd.php | 4 +- system/pages/guilds/change_nick.php | 2 + system/pages/guilds/change_rank.php | 2 + system/pages/guilds/cleanup_guilds.php | 4 +- system/pages/guilds/cleanup_players.php | 4 +- system/pages/guilds/create.php | 4 +- system/pages/guilds/delete_by_admin.php | 4 +- system/pages/guilds/delete_guild.php | 4 +- system/pages/guilds/delete_invite.php | 4 +- system/pages/guilds/delete_rank.php | 2 + system/pages/guilds/invite.php | 4 +- system/pages/guilds/kick_player.php | 4 +- .../guilds/{leave_guild.php => leave.php} | 2 + .../guilds/{list_of_guilds.php => list.php} | 2 + system/pages/guilds/manager.php | 4 +- system/pages/guilds/pass_leadership.php | 4 +- system/pages/guilds/save_ranks.php | 2 + system/pages/guilds/show.php | 5 +- system/pages/highscores.php | 16 +- system/router.php | 214 +++++++++++++++++ system/routes.php | 56 +++++ system/templates/account.login.html.twig | 4 +- 65 files changed, 1075 insertions(+), 668 deletions(-) create mode 100644 system/pages/405.php create mode 100644 system/pages/account/base.php rename system/pages/{createaccount.php => account/create.php} (100%) create mode 100644 system/pages/account/logout.php rename system/pages/{lostaccount.php => account/lost.php} (100%) create mode 100644 system/pages/account/manage.php rename system/pages/{account.php => account/redirect.php} (50%) delete mode 100644 system/pages/accountmanagement.php create mode 100644 system/pages/forum/admin.php create mode 100644 system/pages/forum/base.php create mode 100644 system/pages/guilds/base.php rename system/pages/guilds/{leave_guild.php => leave.php} (98%) rename system/pages/guilds/{list_of_guilds.php => list.php} (97%) create mode 100644 system/router.php create mode 100644 system/routes.php diff --git a/composer.json b/composer.json index f5c67e7d..0c6a17f1 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "phpmailer/phpmailer": "^6.1", "composer/semver": "^3.2", "twig/twig": "~1.42.5", - "erusev/parsedown": "^1.7" + "erusev/parsedown": "^1.7", + "nikic/fast-route": "^1.3" } } diff --git a/index.php b/index.php index 1c47f2e8..eb03ad9d 100644 --- a/index.php +++ b/index.php @@ -35,7 +35,11 @@ if(!empty($tmp)) else $uri = str_replace_first('/', '', $uri); -$uri = str_replace(array('index.php/', '?'), '', $uri); +$uri = str_replace_first('index.php', '', $uri); +if(($pos = strpos($uri, '?') === 0) || $pos == 9) { + $uri = str_replace_first('?', '', $uri); +} + define('URI', $uri); if(preg_match("/^[A-Za-z0-9-_%'+]+\.png$/i", $uri)) { @@ -74,106 +78,6 @@ if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . throw new RuntimeException('Setup detected that install/ directory exists. Please visit this url to start MyAAC Installation.
Delete install/ directory if you already installed MyAAC.
Remember to REFRESH this page when you\'re done!'); } -$found = false; -if(empty($uri) || isset($_REQUEST['template'])) { - $_REQUEST['p'] = 'news'; - $found = true; -} -else { - $tmp = strtolower($uri); - if(!preg_match('/[^A-z0-9_\-]/', $uri) && file_exists(SYSTEM . 'pages/' . $tmp . '.php')) { - $_REQUEST['p'] = $uri; - $found = true; - } - else { - $rules = array( - '/^account\/manage\/?$/' => array('subtopic' => 'accountmanagement'), - '/^account\/create\/?$/' => array('subtopic' => 'createaccount'), - '/^account\/lost\/?$/' => array('subtopic' => 'lostaccount'), - '/^account\/logout\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'logout'), - '/^account\/password\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_password'), - '/^account\/register\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register'), - '/^account\/register\/new\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'register_new'), - '/^account\/email\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_email'), - '/^account\/info\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_info'), - '/^account\/character\/create\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'create_character'), - '/^account\/character\/name\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_name'), - '/^account\/character\/sex\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_sex'), - '/^account\/character\/delete\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'delete_character'), - '/^account\/character\/comment\/[A-Za-z0-9-_%+\']+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment', 'name' => '$3'), - '/^account\/character\/comment\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'change_comment'), - '/^account\/confirm_email\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'accountmanagement', 'action' => 'confirm_email', 'v' => '$2'), - '/^bans\/[0-9]+\/?$/' => array('subtopic' => 'bans', 'page' => '$1'), - '/^characters\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'characters', 'name' => '$1'), - '/^changelog\/[0-9]+\/?$/' => array('subtopic' => 'changelog', 'page' => '$1'), - '/^commands\/add\/?$/' => array('subtopic' => 'commands', 'action' => 'add'), - '/^commands\/edit\/?$/' => array('subtopic' => 'commands', 'action' => 'edit'), - '/^creatures\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'creatures', 'creature' => '$1'), - '/^faq\/add\/?$/' => array('subtopic' => 'faq', 'action' => 'add'), - '/^faq\/edit\/?$/' => array('subtopic' => 'faq', 'action' => 'edit'), - '/^forum\/add_board\/?$/' => array('subtopic' => 'forum', 'action' => 'add_board'),# - '/^forum\/edit_board\/?$/' => array('subtopic' => 'forum', 'action' => 'edit_board'), - '/^forum\/board\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2'), - '/^forum\/board\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_board', 'id' => '$2', 'page' => '$3'), - '/^forum\/thread\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2'), - '/^forum\/thread\/[0-9]+\/[0-9]+\/?$/' => array('subtopic' => 'forum', 'action' => 'show_thread', 'id' => '$2', 'page' => '$3'), - '/^gallery\/add\/?$/' => array('subtopic' => 'gallery', 'action' => 'add'), - '/^gallery\/edit\/?$/' => array('subtopic' => 'gallery', 'action' => 'edit'), - '/^gallery\/[0-9]+\/?$/' => array('subtopic' => 'gallery', 'image' => '$1'), - '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), - '/^guilds\/[A-Za-z0-9-_%+\']+$/' => array('subtopic' => 'guilds', 'action' => 'show', 'guild' => '$1'), - '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2', 'page' => '$3'), - '/^highscores\/[A-Za-z0-9-_]+\/[0-9]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'page' => '$2'), - '/^highscores\/[A-Za-z0-9-_]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1', 'vocation' => '$2'), - '/^highscores\/[A-Za-z0-9-_\']+\/?$/' => array('subtopic' => 'highscores', 'list' => '$1'), - '/^news\/add\/?$/' => array('subtopic' => 'news', 'action' => 'add'), - '/^news\/edit\/?$/' => array('subtopic' => 'news', 'action' => 'edit'), - '/^news\/archive\/?$/' => array('subtopic' => 'newsarchive'), - '/^news\/archive\/[0-9]+\/?$/' => array('subtopic' => 'newsarchive', 'id' => '$2'), - '/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), - '/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), - '/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view') - ); - - foreach($rules as $rule => $redirect) { - if (preg_match($rule, $uri)) { - $tmp = explode('/', $uri); - /* @var $redirect array */ - foreach($redirect as $key => $value) { - - if(strpos($value, '$') !== false) { - $value = str_replace('$' . $value[1], $tmp[$value[1]], $value); - } - - $_REQUEST[$key] = $value; - $_GET[$key] = $value; - } - - $found = true; - break; - } - } - } -} - -// define page visited, so it can be used within events system -$page = isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : (isset($_REQUEST['p']) ? $_REQUEST['p'] : ''); -if(empty($page) || !preg_match('/^[A-z0-9\_\-]+$/', $page)) { - $tmp = URI; - if(!empty($tmp)) { - $page = $tmp; - } - else { - if(!$found) - $page = '404'; - else - $page = 'news'; - } -} - -$page = strtolower($page); -define('PAGE', $page); - $template_place_holders = array(); require_once SYSTEM . 'init.php'; @@ -262,7 +166,7 @@ if(fetchDatabaseConfig('site_closed', $site_closed)) { if(!$logged) { ob_start(); - require SYSTEM . 'pages/accountmanagement.php'; + require SYSTEM . 'pages/account/manage.php'; $content .= ob_get_contents(); ob_end_clean(); $load_it = false; @@ -279,7 +183,6 @@ if($config['backward_support']) { $layout_name = $template_path; $news_content = ''; $tickers_content = ''; - $subtopic = PAGE; $main_content = ''; $config['access_admin_panel'] = 2; @@ -309,65 +212,7 @@ if($config['backward_support']) { $config['status']['serverStatus_' . $key] = $value; } -if($load_it) -{ - if(SITE_CLOSED && admin()) - $content .= '

Site is under maintenance (closed mode). Only privileged users can see it.

'; - - if($config['backward_support']) - require SYSTEM . 'compat_pages.php'; - - $ignore = false; - - $logged_access = 1; - if($logged && $account_logged && $account_logged->isLoaded()) { - $logged_access = $account_logged->getAccess(); - } - - $success = false; - $tmp_content = getCustomPage($page, $success); - if($success) { - $content .= $tmp_content; - if(hasFlag(FLAG_CONTENT_PAGES) || superAdmin()) { - $pageInfo = getCustomPageInfo($page); - $content = $twig->render('admin.pages.links.html.twig', array( - 'page' => array('id' => $pageInfo !== null ? $pageInfo['id'] : 0, 'hidden' => $pageInfo !== null ? $pageInfo['hidden'] : '0') - )) . $content; - } - } else { - $file = $template_path . '/pages/' . $page . '.php'; - if(!@file_exists($file)) - { - $file = SYSTEM . 'pages/' . $page . '.php'; - if(!@file_exists($file)) - { - $page = '404'; - $file = SYSTEM . 'pages/404.php'; - } - } - } - - ob_start(); - if($hooks->trigger(HOOK_BEFORE_PAGE)) { - if(!$ignore) - require $file; - } - - if($config['backward_support'] && isset($main_content[0])) - $content .= $main_content; - - $content .= ob_get_contents(); - ob_end_clean(); - $hooks->trigger(HOOK_AFTER_PAGE); -} - -if($config['backward_support']) { - $main_content = $content; - if(!isset($title)) - $title = ucfirst($page); - - $topic = $title; -} +require SYSTEM . 'router.php'; $title_full = (isset($title) ? $title . ' - ' : '') . $config['lua']['serverName']; require $template_path . '/' . $template_index; diff --git a/plugins/example.json b/plugins/example.json index b3cf2633..63b27e1b 100644 --- a/plugins/example.json +++ b/plugins/example.json @@ -32,5 +32,19 @@ "type": "BEFORE_PAGE", "file": "plugins/example/before.php" } - } + }, + "routes": { + "First Route": { + "pattern": "/YourAwesomePage", + "file": "plugins/your-plugin/your-awesome-page.php", + "method": "GET", + "priority": "130" + }, + "Second Route": { + "pattern": "/YourSecondRoute", + "file": "plugins/your-plugin/your-awesome-page-two.php", + "method": "GET,POST", + "priority": "120" + } + } } diff --git a/system/compat_pages.php b/system/compat_pages.php index 1830ecd5..9c174945 100644 --- a/system/compat_pages.php +++ b/system/compat_pages.php @@ -10,6 +10,18 @@ defined('MYAAC') or die('Direct access not allowed!'); switch($page) { + case 'createaccount': + $page = 'account/create'; + break; + + case 'accountmanagement': + $page = 'account/manage'; + break; + + case 'lostaccount': + $page = 'account/lost'; + break; + case 'whoisonline': $page = 'online'; break; @@ -37,4 +49,3 @@ switch($page) default: break; } -?> diff --git a/system/functions.php b/system/functions.php index fee72b27..b973b43e 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1142,6 +1142,12 @@ function clearCache() global $template_name; if ($cache->fetch('template_ini' . $template_name, $tmp)) $cache->delete('template_ini' . $template_name); + + if ($cache->fetch('plugins_hooks', $tmp)) + $cache->delete('plugins_hooks'); + + if ($cache->fetch('plugins_routes', $tmp)) + $cache->delete('plugins_routes'); } deleteDirectory(CACHE . 'signatures', ['index.html'], true); @@ -1149,6 +1155,9 @@ function clearCache() deleteDirectory(CACHE . 'plugins', ['index.html'], true); deleteDirectory(CACHE, ['signatures', 'twig', 'plugins', 'index.html'], true); + // routes cache + unlink(CACHE . 'route.cache'); + return true; } diff --git a/system/hooks.php b/system/hooks.php index 089af581..4f979836 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -120,5 +120,7 @@ class Hooks foreach(Plugins::getHooks() as $hook) { $this->register($hook['name'], $hook['type'], $hook['file']); } + + Plugins::clearWarnings(); } } diff --git a/system/libs/plugins.php b/system/libs/plugins.php index 57507aae..6910a51d 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -45,12 +45,102 @@ class Plugins { private static $error = null; private static $plugin_json = array(); + public static function getRoutes() + { + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $tmp = ''; + if ($cache->fetch('plugins_routes', $tmp)) { + return unserialize($tmp); + } + } + + $routes = []; + foreach(get_plugins() as $filename) { + $string = file_get_contents(PLUGINS . $filename . '.json'); + $string = self::removeComments($string); + $plugin = json_decode($string, true); + self::$plugin_json = $plugin; + if ($plugin == null) { + self::$warnings[] = 'Cannot load ' . $filename . '.json. File might be not a valid json code.'; + continue; + } + + if(isset($plugin['enabled']) && !getBoolean($plugin['enabled'])) { + self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.'; + continue; + } + + $warningPreTitle = 'Plugin: ' . $filename . ' - '; + + 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; + } + } + + 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']); + } + + foreach ($routes as $id => &$route) { + 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]); + continue; + } + } + } + + $routes[] = [$methods, $info['pattern'], $info['file'], $info['priority']]; + } + } + } +/* + usort($routes, function ($a, $b) + { + // key 3 is priority + if ($a[3] == $b[3]) { + return 0; + } + + return ($a[3] > $b[3]) ? -1 : 1; + }); +*/ + // cleanup before passing back + // priority is not needed anymore + foreach ($routes as &$route) { + unset($route[3]); + } + + if ($cache->enabled()) { + $cache->set('plugins_routes', serialize($routes), 600); + } + + return $routes; + } + public static function getHooks() { $cache = Cache::getInstance(); if ($cache->enabled()) { $tmp = ''; - if ($cache->fetch('hooks', $tmp)) { + if ($cache->fetch('plugins_hooks', $tmp)) { return unserialize($tmp); } } @@ -84,7 +174,7 @@ class Plugins { } if ($cache->enabled()) { - $cache->set('hooks', serialize($hooks), 600); + $cache->set('plugins_hooks', serialize($hooks), 600); } return $hooks; @@ -378,6 +468,10 @@ class Plugins { return self::$warnings; } + public static function clearWarnings() { + self::$warnings = []; + } + public static function getError() { return self::$error; } diff --git a/system/login.php b/system/login.php index 330efd13..73221bf3 100644 --- a/system/login.php +++ b/system/login.php @@ -11,11 +11,6 @@ defined('MYAAC') or die('Direct access not allowed!'); $logged = false; $logged_flags = 0; -$action = isset($_REQUEST['action']) ? strtolower($_REQUEST['action']) : ''; -if(!defined('ACTION')) { - define('ACTION', $action); -} - // stay-logged with sessions $current_session = getSession('account'); if($current_session !== false) @@ -33,135 +28,114 @@ if($current_session !== false) } } -if(ACTION === 'logout' && !isset($_REQUEST['account_login'])) { - if(isset($account_logged) && $account_logged->isLoaded()) { - if($hooks->trigger(HOOK_LOGOUT, array('account' => $account_logged, 'password' => getSession('password')))) { - unsetSession('account'); - unsetSession('password'); - unsetSession('remember_me'); - - $logged = false; - unset($account_logged); - - if(isset($_REQUEST['redirect'])) - { - header('Location: ' . urldecode($_REQUEST['redirect'])); - exit; - } - } - } -} -else +// new login with data from form +if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) { - // new login with data from form - if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) + $login_account = $_POST['account_login']; + $login_password = $_POST['password_login']; + $remember_me = isset($_POST['remember_me']); + if(!empty($login_account) && !empty($login_password)) { - $login_account = $_POST['account_login']; - $login_password = $_POST['password_login']; - $remember_me = isset($_POST['remember_me']); - if(!empty($login_account) && !empty($login_password)) + if($cache->enabled()) { + $tmp = ''; + if($cache->fetch('failed_logins', $tmp)) + { + $tmp = unserialize($tmp); + $to_remove = array(); + foreach($tmp as $ip => $t) + { + if(time() - $t['last'] >= 5 * 60) + $to_remove[] = $ip; + } + + foreach($to_remove as $ip) + unset($tmp[$ip]); + } + else + $tmp = array(); + + $ip = $_SERVER['REMOTE_ADDR']; + $t = isset($tmp[$ip]) ? $tmp[$ip] : NULL; + } + + $account_logged = new OTS_Account(); + if(USE_ACCOUNT_NAME) + $account_logged->find($login_account); + else + $account_logged->load($login_account, true); + + $config_salt_enabled = $db->hasColumn('accounts', 'salt'); + if($account_logged->isLoaded() && encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword() + && (!isset($t) || $t['attempts'] < 5) + ) + { + setSession('account', $account_logged->getId()); + setSession('password', encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password)); + if($remember_me) { + setSession('remember_me', true); + } + + $logged = true; + $logged_flags = $account_logged->getWebFlags(); + + if(isset($_POST['admin']) && !admin()) { + $errors[] = 'This account has no admin privileges.'; + unsetSession('account'); + unsetSession('password'); + unsetSession('remember_me'); + $logged = false; + } + else { + $account_logged->setCustomField('web_lastlogin', time()); + } + + $hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); + } + else + { + $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); + + // temporary solution for blocking failed login attempts if($cache->enabled()) { - $tmp = ''; - if($cache->fetch('failed_logins', $tmp)) + if(isset($t)) { - $tmp = unserialize($tmp); - $to_remove = array(); - foreach($tmp as $ip => $t) - { - if(time() - $t['last'] >= 5 * 60) - $to_remove[] = $ip; - } + $t['attempts']++; + $t['last'] = time(); - foreach($to_remove as $ip) - unset($tmp[$ip]); + if($t['attempts'] >= 5) + $errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.'; + else + $errors[] = 'Account name or password is not correct.'; } else - $tmp = array(); - - $ip = $_SERVER['REMOTE_ADDR']; - $t = isset($tmp[$ip]) ? $tmp[$ip] : NULL; - } - - $account_logged = new OTS_Account(); - if(USE_ACCOUNT_NAME) - $account_logged->find($login_account); - else - $account_logged->load($login_account, true); - - $config_salt_enabled = $db->hasColumn('accounts', 'salt'); - if($account_logged->isLoaded() && encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword() - && (!isset($t) || $t['attempts'] < 5) - ) - { - setSession('account', $account_logged->getId()); - setSession('password', encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $login_password)); - if($remember_me) { - setSession('remember_me', true); - } - - $logged = true; - $logged_flags = $account_logged->getWebFlags(); - - if(isset($_POST['admin']) && !admin()) { - $errors[] = 'This account has no admin privileges.'; - unsetSession('account'); - unsetSession('password'); - unsetSession('remember_me'); - $logged = false; - } - else { - $account_logged->setCustomField('web_lastlogin', time()); - } - - $hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me)); - } - else - { - $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); - - // temporary solution for blocking failed login attempts - if($cache->enabled()) { - if(isset($t)) - { - $t['attempts']++; - $t['last'] = time(); - - if($t['attempts'] >= 5) - $errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.'; - else - $errors[] = 'Account name or password is not correct.'; - } - else - { - $t = array('attempts' => 1, 'last' => time()); - $errors[] = 'Account name or password is not correct.'; - } - - $tmp[$ip] = $t; - $cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour - } - else { + $t = array('attempts' => 1, 'last' => time()); $errors[] = 'Account name or password is not correct.'; } + + $tmp[$ip] = $t; + $cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour + } + else { + $errors[] = 'Account name or password is not correct.'; } } - else { - $errors[] = 'Please enter your account ' . (USE_ACCOUNT_NAME ? 'name' : 'number') . ' and password.'; - - $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); - } } + else { + $errors[] = 'Please enter your account ' . (USE_ACCOUNT_NAME ? 'name' : 'number') . ' and password.'; - if($logged) { - $logged_flags = $account_logged->getWebFlags(); - $twig->addGlobal('logged', true); - $twig->addGlobal('account_logged', $account_logged); + $hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me)); } } +if($logged) { + $logged_flags = $account_logged->getWebFlags(); + $twig->addGlobal('logged', true); + $twig->addGlobal('account_logged', $account_logged); +} + setSession('last_visit', time()); if(defined('PAGE')) { setSession('last_page', PAGE); diff --git a/system/pages/405.php b/system/pages/405.php new file mode 100644 index 00000000..3d585f59 --- /dev/null +++ b/system/pages/405.php @@ -0,0 +1,16 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = '405 Method Not Allowed'; + +header('HTTP/1.0 405 Method Not Allowed'); +?> +

Method not allowed

+

The requested method: for URL was not found on this server.

diff --git a/system/pages/account/base.php b/system/pages/account/base.php new file mode 100644 index 00000000..dc6cebb9 --- /dev/null +++ b/system/pages/account/base.php @@ -0,0 +1,29 @@ + + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +if(!$logged) +{ + if(!empty($errors)) + $twig->display('error_box.html.twig', array('errors' => $errors)); + + $twig->display('account.login.html.twig', array( + 'redirect' => isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : null, + 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', + 'error' => isset($errors[0]) ? $errors[0] : null + )); + + return; +} +else { + $show_form = true; + $config_salt_enabled = $db->hasColumn('accounts', 'salt'); +} diff --git a/system/pages/account/change_comment.php b/system/pages/account/change_comment.php index 43cfd0ca..0f0bc2f1 100644 --- a/system/pages/account/change_comment.php +++ b/system/pages/account/change_comment.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Comment'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_name = isset($_REQUEST['name']) ? stripslashes(urldecode($_REQUEST['name'])) : null; $new_comment = isset($_POST['comment']) ? htmlspecialchars(stripslashes(substr($_POST['comment'],0,2000))) : NULL; $new_hideacc = isset($_POST['accountvisible']) ? (int)$_POST['accountvisible'] : NULL; @@ -56,4 +63,4 @@ if($show_form) { )); } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 0bd668a5..750d8378 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change E-Mail'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $email_new_time = $account_logged->getCustomField("email_new_time"); if($email_new_time > 10) { @@ -159,4 +166,4 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) { 'custom_buttons' => $custom_buttons )); } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_info.php b/system/pages/account/change_info.php index df2a52f6..e3a8174a 100644 --- a/system/pages/account/change_info.php +++ b/system/pages/account/change_info.php @@ -10,6 +10,16 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Info'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +if($config['account_country']) + require SYSTEM . 'countries.conf.php'; + $show_form = true; $new_rlname = isset($_POST['info_rlname']) ? htmlspecialchars(stripslashes($_POST['info_rlname'])) : NULL; $new_location = isset($_POST['info_location']) ? htmlspecialchars(stripslashes($_POST['info_location'])) : NULL; @@ -59,4 +69,4 @@ if($show_form) { 'account_country' => isset($account_country) ? $account_country : '' )); } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index 6771760b..009c39f8 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Name'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : NULL; $name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : NULL; if((!$config['account_change_character_name'])) @@ -83,4 +90,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_password.php b/system/pages/account/change_password.php index bd63c46d..d4ec8647 100644 --- a/system/pages/account/change_password.php +++ b/system/pages/account/change_password.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Password'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $new_password = isset($_POST['newpassword']) ? $_POST['newpassword'] : NULL; $new_password2 = isset($_POST['newpassword2']) ? $_POST['newpassword2'] : NULL; $old_password = isset($_POST['oldpassword']) ? $_POST['oldpassword'] : NULL; @@ -82,4 +89,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index f3eb8299..c67ac608 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Change Sex'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $sex_changed = false; $player_id = isset($_POST['player_id']) ? (int)$_POST['player_id'] : NULL; $new_sex = isset($_POST['new_sex']) ? (int)$_POST['new_sex'] : NULL; @@ -85,4 +92,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/account/confirm_email.php b/system/pages/account/confirm_email.php index 078ba324..9d8712c2 100644 --- a/system/pages/account/confirm_email.php +++ b/system/pages/account/confirm_email.php @@ -11,7 +11,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Confirm Email'; -$hash = isset($_GET['v']) ? $_GET['v'] : ''; +$hash = isset($_GET['hash']) ? $_GET['hash'] : ''; if(empty($hash)) { warning('Please enter email hash code.
If you copied the link, please try again with full link.'); return; diff --git a/system/pages/createaccount.php b/system/pages/account/create.php similarity index 100% rename from system/pages/createaccount.php rename to system/pages/account/create.php diff --git a/system/pages/account/create_character.php b/system/pages/account/create_character.php index 7c148966..3216a71a 100644 --- a/system/pages/account/create_character.php +++ b/system/pages/account/create_character.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Create Character'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $character_name = isset($_POST['name']) ? stripslashes($_POST['name']) : null; $character_sex = isset($_POST['sex']) ? (int)$_POST['sex'] : null; $character_vocation = isset($_POST['vocation']) ? (int)$_POST['vocation'] : null; diff --git a/system/pages/account/delete_character.php b/system/pages/account/delete_character.php index 2c2bb341..818344d8 100644 --- a/system/pages/account/delete_character.php +++ b/system/pages/account/delete_character.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Delete Character'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $player_name = isset($_POST['delete_name']) ? stripslashes($_POST['delete_name']) : null; $password_verify = isset($_POST['delete_password']) ? $_POST['delete_password'] : null; $password_verify = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $password_verify); diff --git a/system/pages/account/logout.php b/system/pages/account/logout.php new file mode 100644 index 00000000..c13f5da7 --- /dev/null +++ b/system/pages/account/logout.php @@ -0,0 +1,37 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$title = 'Logout'; + +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +if(isset($account_logged) && $account_logged->isLoaded()) { + if($hooks->trigger(HOOK_LOGOUT, array('account' => $account_logged, 'password' => getSession('password')))) { + unsetSession('account'); + unsetSession('password'); + unsetSession('remember_me'); + + $logged = false; + unset($account_logged); + + if(isset($_REQUEST['redirect'])) + { + header('Location: ' . urldecode($_REQUEST['redirect'])); + exit; + } + } +} + +$twig->display('account.logout.html.twig'); diff --git a/system/pages/lostaccount.php b/system/pages/account/lost.php similarity index 100% rename from system/pages/lostaccount.php rename to system/pages/account/lost.php diff --git a/system/pages/account/manage.php b/system/pages/account/manage.php new file mode 100644 index 00000000..10aea0ce --- /dev/null +++ b/system/pages/account/manage.php @@ -0,0 +1,97 @@ + + * @author Slawkens + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +$title = 'Account Management'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + +$groups = new OTS_Groups_List(); + +$freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS; +$dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days'; +/** + * @var OTS_Account $account_logged + */ +if(!$account_logged->isPremium()) + $account_status = 'Free Account'; +else + $account_status = '' . ($freePremium ? 'Gratis Premium Account' : 'Premium Account, ' . $account_logged->getPremDays() . ' '.$dayOrDays.' left') . ''; + +$recovery_key = $account_logged->getCustomField('key'); +if(empty($recovery_key)) + $account_registered = 'No'; +else +{ + if($config['generate_new_reckey'] && $config['mail_enabled']) + $account_registered = 'Yes ( Buy new Recovery Key )'; + else + $account_registered = 'Yes'; +} + +$account_created = $account_logged->getCreated(); +$account_email = $account_logged->getEMail(); +$email_new_time = $account_logged->getCustomField("email_new_time"); +if($email_new_time > 1) + $email_new = $account_logged->getCustomField("email_new"); +$account_rlname = $account_logged->getRLName(); +$account_location = $account_logged->getLocation(); +if($account_logged->isBanned()) + if($account_logged->getBanTime() > 0) + $welcome_message = 'Your account is banished until '.date("j F Y, G:i:s", $account_logged->getBanTime()).'!'; + else + $welcome_message = 'Your account is banished FOREVER!'; +else + $welcome_message = 'Welcome to your account!'; + +$email_change = ''; +$email_request = false; +if($email_new_time > 1) +{ + if($email_new_time < time()) + $email_change = '
(You can accept '.$email_new.' as a new email.)'; + else + { + $email_change = '
You can accept new e-mail after '.date("j F Y", $email_new_time)."."; + $email_request = true; + } +} + +$actions = array(); +foreach($account_logged->getActionsLog(0, 1000) as $action) { + $actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6'])); +} + +$players = array(); +/** @var OTS_Players_List $account_players */ +$account_players = $account_logged->getPlayersList(); +$account_players->orderBy('id'); + +$twig->display('account.management.html.twig', array( + 'welcome_message' => $welcome_message, + 'recovery_key' => $recovery_key, + 'email_change' => $email_change, + 'email_request' => $email_request, + 'email_new_time' => $email_new_time, + 'email_new' => isset($email_new) ? $email_new : '', + 'account' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId(), + 'account_email' => $account_email, + 'account_created' => $account_created, + 'account_status' => $account_status, + 'account_registered' => $account_registered, + 'account_rlname' => $account_rlname, + 'account_location' => $account_location, + 'actions' => $actions, + 'players' => $account_players +)); diff --git a/system/pages/account.php b/system/pages/account/redirect.php similarity index 50% rename from system/pages/account.php rename to system/pages/account/redirect.php index 31366187..8abff630 100644 --- a/system/pages/account.php +++ b/system/pages/account/redirect.php @@ -1,16 +1,17 @@ * @author Slawkens * @copyright 2019 MyAAC * @link https://my-aac.org */ defined('MYAAC') or die('Direct access not allowed!'); -if($action == 'confirm_email') { - require_once PAGES . 'account/confirm_email.php'; -} -?> +$redirect = urldecode($_REQUEST['redirect']); + +$twig->display('account.redirect.html.twig', array( + 'redirect' => $redirect +)); diff --git a/system/pages/account/register.php b/system/pages/account/register.php index bfb69ee1..feb808a4 100644 --- a/system/pages/account/register.php +++ b/system/pages/account/register.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Register Account'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + $_POST['reg_password'] = isset($_POST['reg_password']) ? $_POST['reg_password'] : ''; $reg_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); $old_key = $account_logged->getCustomField("key"); @@ -55,4 +62,4 @@ if($show_form) { $twig->display('account.generate_recovery_key.html.twig'); } -?> \ No newline at end of file +?> diff --git a/system/pages/account/register_new.php b/system/pages/account/register_new.php index dfe9749f..f647ffbf 100644 --- a/system/pages/account/register_new.php +++ b/system/pages/account/register_new.php @@ -10,6 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Register Account'; +require __DIR__ . '/base.php'; + +if(!$logged) { + return; +} + if(isset($_POST['reg_password'])) $reg_password = encrypt(($config_salt_enabled ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); @@ -68,4 +75,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/accountmanagement.php b/system/pages/accountmanagement.php deleted file mode 100644 index e3444a73..00000000 --- a/system/pages/accountmanagement.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @author Slawkens - * @copyright 2019 MyAAC - * @link https://my-aac.org - */ -defined('MYAAC') or die('Direct access not allowed!'); -$title = 'Account Management'; - -if($config['account_country']) - require SYSTEM . 'countries.conf.php'; - -$groups = new OTS_Groups_List(); - -$show_form = true; -$config_salt_enabled = $db->hasColumn('accounts', 'salt'); - -if(ACTION == "logout" && !isset($_REQUEST['account_login'])) { - if(!defined('HOOK_LOGOUT_DISPLAY') || HOOK_LOGOUT_DISPLAY) { // plugin will take care of this message - $twig->display('account.logout.html.twig'); - } - - return; -} - -if(!$logged) -{ - if(ACTION == 'confirm_email') { - require PAGES . 'account/' . ACTION . '.php'; - return; - } - - if(!empty($errors)) - $twig->display('error_box.html.twig', array('errors' => $errors)); - - $twig->display('account.login.html.twig', array( - 'redirect' => isset($_REQUEST['redirect']) ? $_REQUEST['redirect'] : null, - 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', - 'error' => isset($errors[0]) ? $errors[0] : null - )); - - return; -} - -$errors = array(); - - if(isset($_REQUEST['redirect'])) - { - $redirect = urldecode($_REQUEST['redirect']); - - $twig->display('account.redirect.html.twig', array( - 'redirect' => $redirect - )); - return; - } - - if($action == '') - { - $freePremium = isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium']) || $account_logged->getPremDays() == OTS_Account::GRATIS_PREMIUM_DAYS; - $dayOrDays = $account_logged->getPremDays() == 1 ? 'day' : 'days'; - /** - * @var OTS_Account $account_logged - */ - if(!$account_logged->isPremium()) - $account_status = 'Free Account'; - else - $account_status = '' . ($freePremium ? 'Gratis Premium Account' : 'Premium Account, ' . $account_logged->getPremDays() . ' '.$dayOrDays.' left') . ''; - - $recovery_key = $account_logged->getCustomField('key'); - if(empty($recovery_key)) - $account_registered = 'No'; - else - { - if($config['generate_new_reckey'] && $config['mail_enabled']) - $account_registered = 'Yes ( Buy new Recovery Key )'; - else - $account_registered = 'Yes'; - } - - $account_created = $account_logged->getCreated(); - $account_email = $account_logged->getEMail(); - $email_new_time = $account_logged->getCustomField("email_new_time"); - if($email_new_time > 1) - $email_new = $account_logged->getCustomField("email_new"); - $account_rlname = $account_logged->getRLName(); - $account_location = $account_logged->getLocation(); - if($account_logged->isBanned()) - if($account_logged->getBanTime() > 0) - $welcome_message = 'Your account is banished until '.date("j F Y, G:i:s", $account_logged->getBanTime()).'!'; - else - $welcome_message = 'Your account is banished FOREVER!'; - else - $welcome_message = 'Welcome to your account!'; - - $email_change = ''; - $email_request = false; - if($email_new_time > 1) - { - if($email_new_time < time()) - $email_change = '
(You can accept '.$email_new.' as a new email.)'; - else - { - $email_change = '
You can accept new e-mail after '.date("j F Y", $email_new_time)."."; - $email_request = true; - } - } - - $actions = array(); - foreach($account_logged->getActionsLog(0, 1000) as $action) { - $actions[] = array('action' => $action['action'], 'date' => $action['date'], 'ip' => $action['ip'] != 0 ? long2ip($action['ip']) : inet_ntop($action['ipv6'])); - } - - $players = array(); - /** @var OTS_Players_List $account_players */ - $account_players = $account_logged->getPlayersList(); - $account_players->orderBy('id'); - - $twig->display('account.management.html.twig', array( - 'welcome_message' => $welcome_message, - 'recovery_key' => $recovery_key, - 'email_change' => $email_change, - 'email_request' => $email_request, - 'email_new_time' => $email_new_time, - 'email_new' => isset($email_new) ? $email_new : '', - 'account' => USE_ACCOUNT_NAME ? $account_logged->getName() : $account_logged->getId(), - 'account_email' => $account_email, - 'account_created' => $account_created, - 'account_status' => $account_status, - 'account_registered' => $account_registered, - 'account_rlname' => $account_rlname, - 'account_location' => $account_location, - 'actions' => $actions, - 'players' => $account_players - )); - } - else { - if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { - error('Error: Action contains illegal characters.'); - } - else if(file_exists(PAGES . 'account/' . $action . '.php')) { - require PAGES . 'account/' . $action . '.php'; - } - else { - error('This page does not exists.'); - } - } -?> diff --git a/system/pages/forum.php b/system/pages/forum.php index 12ec64e0..85456f2e 100644 --- a/system/pages/forum.php +++ b/system/pages/forum.php @@ -5,198 +5,59 @@ * @package MyAAC * @author Gesior * @author Slawkens - * @copyright 2019 MyAAC + * @copyright 2021 MyAAC * @link https://my-aac.org */ -defined('MYAAC') or die('Direct access not allowed!'); -$title = 'Forum'; +defined('MYAAC') or exit; -if(strtolower($config['forum']) != 'site') +require __DIR__ . '/forum/base.php'; +require __DIR__ . '/forum/admin.php'; + +$errors = []; +if(!empty($action)) { - if($config['forum'] != '') - { - header('Location: ' . $config['forum']); - exit; + if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { + error('Error: Action contains illegal characters.'); } - - echo 'Forum is disabled on this site.'; - return; -} - -if(!$logged) - echo 'You are not logged in. Log in to post on the forum.

'; - -require_once LIBS . 'forum.php'; - -$canEdit = Forum::isModerator(); -if($canEdit) -{ - $groups = new OTS_Groups_List(); - - if(!empty($action)) - { - if($action == 'delete_board' || $action == 'edit_board' || $action == 'hide_board' || $action == 'moveup_board' || $action == 'movedown_board') - $id = $_REQUEST['id']; - - if(isset($_REQUEST['access'])) - $access = $_REQUEST['access']; - - if(isset($_REQUEST['guild'])) - $guild = $_REQUEST['guild']; - - if(isset($_REQUEST['name'])) - $name = $_REQUEST['name']; - - if(isset($_REQUEST['description'])) - $description = stripslashes($_REQUEST['description']); - - $errors = array(); - - if($action == 'add_board') { - if(Forum::add_board($name, $description, $access, $guild, $errors)) - $action = $name = $description = ''; - } - else if($action == 'delete_board') { - Forum::delete_board($id, $errors); - $action = ''; - } - else if($action == 'edit_board') - { - if(isset($id) && !isset($name)) { - $board = Forum::get_board($id); - $name = $board['name']; - $access = $board['access']; - $guild = $board['guild']; - $description = $board['description']; - } - else { - Forum::update_board($id, $name, $access, $guild, $description); - $action = $name = $description = ''; - $access = $guild = 0; - } - } - else if($action == 'hide_board') { - Forum::toggleHidden_board($id, $errors); - $action = ''; - } - else if($action == 'moveup_board') { - Forum::move_board($id, -1, $errors); - $action = ''; - } - else if($action == 'movedown_board') { - Forum::move_board($id, 1, $errors); - $action = ''; - } - - if(!empty($errors)) { - $twig->display('error_box.html.twig', array('errors' => $errors)); - $action = ''; - } - } - - if(empty($action) || $action == 'edit_board') { - $guilds = $db->query('SELECT `id`, `name` FROM `guilds`')->fetchAll(); - $twig->display('forum.add_board.html.twig', array( - 'link' => getLink('forum', ($action == 'edit_board' ? 'edit_board' : 'add_board')), - 'action' => $action, - 'id' => isset($id) ? $id : null, - 'name' => isset($name) ? $name : null, - 'description' => isset($description) ? $description : null, - 'access' => isset($access) ? $access : 0, - 'guild' => isset($guild) ? $guild : null, - 'groups' => $groups, - 'guilds' => $guilds - )); - - if($action == 'edit_board') - $action = ''; - } -} - -$sections = array(); -foreach(getForumBoards() as $section) -{ - $sections[$section['id']] = array( - 'id' => $section['id'], - 'name' => $section['name'], - 'description' => $section['description'], - 'closed' => $section['closed'] == '1', - 'guild' => $section['guild'], - 'access' => $section['access'] - ); - - if($canEdit) { - $sections[$section['id']]['hidden'] = $section['hidden']; + else if(file_exists(PAGES . 'forum/' . $action . '.php')) { + require PAGES . 'forum/' . $action . '.php'; + return; } else { - $sections[$section['id']]['hidden'] = 0; + error('This page does not exists.'); } } -$number_of_rows = 0; -if(empty($action)) -{ - $info = $db->query("SELECT `section`, COUNT(`id`) AS 'threads', SUM(`replies`) AS 'replies' FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = `id` GROUP BY `section`")->fetchAll(); +$info = $db->query("SELECT `section`, COUNT(`id`) AS 'threads', SUM(`replies`) AS 'replies' FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = `id` GROUP BY `section`")->fetchAll(); - $boards = array(); - foreach($info as $data) - $counters[$data['section']] = array('threads' => $data['threads'], 'posts' => $data['replies'] + $data['threads']); - foreach($sections as $id => $section) - { - $show = true; - if(Forum::hasAccess($id)) { - $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $id." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); - $boards[] = array( - 'id' => $id, - 'link' => getForumBoardLink($id), - 'name' => $section['name'], - 'description' => $section['description'], - 'hidden' => $section['hidden'], - 'posts' => isset($counters[$id]['posts']) ? $counters[$id]['posts'] : 0, - 'threads' => isset($counters[$id]['threads']) ? $counters[$id]['threads'] : 0, - 'last_post' => array( - 'name' => isset($last_post['name']) ? $last_post['name'] : null, - 'date' => isset($last_post['post_date']) ? $last_post['post_date'] : null, - 'player_link' => isset($last_post['name']) ? getPlayerLink($last_post['name']) : null, - ) - ); - } +$boards = array(); +foreach($info as $data) + $counters[$data['section']] = array('threads' => $data['threads'], 'posts' => $data['replies'] + $data['threads']); + +foreach($sections as $id => $section) +{ + $show = true; + if(Forum::hasAccess($id)) { + $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $id." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); + $boards[] = array( + 'id' => $id, + 'link' => getForumBoardLink($id), + 'name' => $section['name'], + 'description' => $section['description'], + 'hidden' => $section['hidden'], + 'posts' => isset($counters[$id]['posts']) ? $counters[$id]['posts'] : 0, + 'threads' => isset($counters[$id]['threads']) ? $counters[$id]['threads'] : 0, + 'last_post' => array( + 'name' => isset($last_post['name']) ? $last_post['name'] : null, + 'date' => isset($last_post['post_date']) ? $last_post['post_date'] : null, + 'player_link' => isset($last_post['name']) ? getPlayerLink($last_post['name']) : null, + ) + ); } - - $twig->display('forum.boards.html.twig', array( - 'boards' => $boards, - 'canEdit' => $canEdit, - 'last' => count($sections) - )); - - return; } -$errors = array(); -if($action == 'show_board' || $action == 'show_thread') -{ - require PAGES . 'forum/' . $action . '.php'; - return; -} - -if(!$logged) -{ - $extra_url = ''; - if($action == 'new_post' && isset($_GET['thread_id'])) { - $extra_url = '&action=new_post&thread_id=' . $_GET['thread_id']; - } - - header('Location: ' . BASE_URL . '?subtopic=accountmanagement&redirect=' . BASE_URL . urlencode('?subtopic=forum' . $extra_url)); - return; -} - -if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { - error('Error: Action contains illegal characters.'); -} -else if(file_exists(PAGES . 'forum/' . $action . '.php')) { - require PAGES . 'forum/' . $action . '.php'; -} -else { - error('This page does not exists.'); -} -?> +$twig->display('forum.boards.html.twig', array( + 'boards' => $boards, + 'canEdit' => $canEdit, + 'last' => count($sections) +)); diff --git a/system/pages/forum/admin.php b/system/pages/forum/admin.php new file mode 100644 index 00000000..136c627a --- /dev/null +++ b/system/pages/forum/admin.php @@ -0,0 +1,95 @@ + + * @author Slawkens + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or exit('Direct access not allowed!'); + +$canEdit = Forum::isModerator(); +if($canEdit) { + $groups = new OTS_Groups_List(); + + if(!empty($action)) + { + if($action == 'delete_board' || $action == 'edit_board' || $action == 'hide_board' || $action == 'moveup_board' || $action == 'movedown_board') + $id = $_REQUEST['id']; + + if(isset($_REQUEST['access'])) + $access = $_REQUEST['access']; + + if(isset($_REQUEST['guild'])) + $guild = $_REQUEST['guild']; + + if(isset($_REQUEST['name'])) + $name = $_REQUEST['name']; + + if(isset($_REQUEST['description'])) + $description = stripslashes($_REQUEST['description']); + + $errors = array(); + + if($action == 'add_board') { + if(Forum::add_board($name, $description, $access, $guild, $errors)) + $action = $name = $description = ''; + } + else if($action == 'delete_board') { + Forum::delete_board($id, $errors); + $action = ''; + } + else if($action == 'edit_board') + { + if(isset($id) && !isset($name)) { + $board = Forum::get_board($id); + $name = $board['name']; + $access = $board['access']; + $guild = $board['guild']; + $description = $board['description']; + } + else { + Forum::update_board($id, $name, $access, $guild, $description); + $action = $name = $description = ''; + $access = $guild = 0; + } + } + else if($action == 'hide_board') { + Forum::toggleHidden_board($id, $errors); + $action = ''; + } + else if($action == 'moveup_board') { + Forum::move_board($id, -1, $errors); + $action = ''; + } + else if($action == 'movedown_board') { + Forum::move_board($id, 1, $errors); + $action = ''; + } + + if(!empty($errors)) { + $twig->display('error_box.html.twig', array('errors' => $errors)); + $action = ''; + } + } + + if(empty($action) || $action == 'edit_board') { + $guilds = $db->query('SELECT `id`, `name` FROM `guilds`')->fetchAll(); + $twig->display('forum.add_board.html.twig', array( + 'link' => getLink('forum', ($action == 'edit_board' ? 'edit_board' : 'add_board')), + 'action' => $action, + 'id' => isset($id) ? $id : null, + 'name' => isset($name) ? $name : null, + 'description' => isset($description) ? $description : null, + 'access' => isset($access) ? $access : 0, + 'guild' => isset($guild) ? $guild : null, + 'groups' => $groups, + 'guilds' => $guilds + )); + + if($action == 'edit_board') + $action = ''; + } +} diff --git a/system/pages/forum/base.php b/system/pages/forum/base.php new file mode 100644 index 00000000..fa207ca0 --- /dev/null +++ b/system/pages/forum/base.php @@ -0,0 +1,51 @@ + + * @author Slawkens + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Forum'; + +if(strtolower($config['forum']) != 'site') +{ + if($config['forum'] != '') + { + header('Location: ' . $config['forum']); + exit; + } + + echo 'Forum is disabled on this site.'; + return; +} + +if(!$logged) + echo 'You are not logged in. Log in to post on the forum.

'; + +require_once LIBS . 'forum.php'; + +$sections = array(); +foreach(getForumBoards() as $section) +{ + $sections[$section['id']] = array( + 'id' => $section['id'], + 'name' => $section['name'], + 'description' => $section['description'], + 'closed' => $section['closed'] == '1', + 'guild' => $section['guild'], + 'access' => $section['access'] + ); + + if($canEdit) { + $sections[$section['id']]['hidden'] = $section['hidden']; + } + else { + $sections[$section['id']]['hidden'] = 0; + } +} + +$number_of_rows = 0; diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index f522c5e6..45fd675b 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::canPost($account_logged)) { $post_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : false; @@ -113,4 +115,4 @@ if(Forum::canPost($account_logged)) else echo "
Your account is banned, deleted or you don't have any player with level " . $config['forum_level_required'] . " on your account. You can't post."; -?> \ No newline at end of file +?> diff --git a/system/pages/forum/move_thread.php b/system/pages/forum/move_thread.php index 48fb08f0..8fcb98fb 100644 --- a/system/pages/forum/move_thread.php +++ b/system/pages/forum/move_thread.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!Forum::isModerator()) { echo 'You are not logged in or you are not moderator.'; } @@ -61,4 +63,4 @@ else { else echo 'Post with ID ' . $post_id . ' does not exist.'; } -?> \ No newline at end of file +?> diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index 436e162d..a3e68dff 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -10,6 +10,19 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + +if(!$logged) +{ + $extra_url = ''; + if(isset($_GET['thread_id'])) { + $extra_url = '&action=new_post&thread_id=' . $_GET['thread_id']; + } + + header('Location: ' . BASE_URL . '?subtopic=accountmanagement&redirect=' . BASE_URL . urlencode('?subtopic=forum' . $extra_url)); + return; +} + if(Forum::canPost($account_logged)) { $players_from_account = $db->query("SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = ".(int) $account_logged->getId())->fetchAll(); @@ -116,4 +129,4 @@ if(Forum::canPost($account_logged)) else echo "Your account is banned, deleted or you don't have any player with level " . $config['forum_level_required'] . " on your account. You can't post."; -$twig->display('forum.fullscreen.html.twig'); \ No newline at end of file +$twig->display('forum.fullscreen.html.twig'); diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 489ea2d3..4db06c63 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::canPost($account_logged)) { $players_from_account = $db->query('SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = '.(int) $account_logged->getId())->fetchAll(); @@ -102,4 +104,4 @@ if(Forum::canPost($account_logged)) else echo 'Your account is banned, deleted or you don\'t have any player with level '.$config['forum_level_required'].' on your account. You can\'t post.'; -?> \ No newline at end of file +?> diff --git a/system/pages/forum/remove_post.php b/system/pages/forum/remove_post.php index caef6a03..bd1e75a4 100644 --- a/system/pages/forum/remove_post.php +++ b/system/pages/forum/remove_post.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(Forum::isModerator()) { $id = (int) $_REQUEST['id']; @@ -33,4 +35,4 @@ if(Forum::isModerator()) echo 'Post with ID ' . $id . ' does not exist.'; } else - echo 'You are not logged in or you are not moderator.'; \ No newline at end of file + echo 'You are not logged in or you are not moderator.'; diff --git a/system/pages/forum/show_board.php b/system/pages/forum/show_board.php index 2828f8f0..bf55ce52 100644 --- a/system/pages/forum/show_board.php +++ b/system/pages/forum/show_board.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $links_to_pages = ''; $section_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null; diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index bf6cda75..c6f8a1af 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $links_to_pages = ''; $thread_id = (int) $_REQUEST['id']; $_page = (int) (isset($_REQUEST['page']) ? $_REQUEST['page'] : 0); diff --git a/system/pages/guilds.php b/system/pages/guilds.php index 0688a4c7..cf834210 100644 --- a/system/pages/guilds.php +++ b/system/pages/guilds.php @@ -11,16 +11,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Guilds'; -if($db->hasTable('guild_members')) - define('GUILD_MEMBERS_TABLE', 'guild_members'); -else - define('GUILD_MEMBERS_TABLE', 'guild_membership'); - -define('MOTD_EXISTS', $db->hasColumn('guilds', 'motd')); - //show list of guilds if(empty($action)) { - require PAGES . 'guilds/list_of_guilds.php'; + require PAGES . 'guilds/list.php'; } else { if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { diff --git a/system/pages/guilds/accept_invite.php b/system/pages/guilds/accept_invite.php index d33d5256..7ead9b81 100644 --- a/system/pages/guilds/accept_invite.php +++ b/system/pages/guilds/accept_invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : null; @@ -124,4 +126,4 @@ else { } } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/add_rank.php b/system/pages/guilds/add_rank.php index 56b20949..acb65aea 100644 --- a/system/pages/guilds/add_rank.php +++ b/system/pages/guilds/add_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $rank_name = isset($_REQUEST['rank_name']) ? $_REQUEST['rank_name'] : null; if(!Validator::guildName($guild_name)) { @@ -74,4 +76,4 @@ else } } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/base.php b/system/pages/guilds/base.php new file mode 100644 index 00000000..07fc432d --- /dev/null +++ b/system/pages/guilds/base.php @@ -0,0 +1,17 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); + +if($db->hasTable('guild_members')) + define('GUILD_MEMBERS_TABLE', 'guild_members'); +else + define('GUILD_MEMBERS_TABLE', 'guild_membership'); + +define('MOTD_EXISTS', $db->hasColumn('guilds', 'motd')); diff --git a/system/pages/guilds/change_description.php b/system/pages/guilds/change_description.php index 8d803af5..b4e787ee 100644 --- a/system/pages/guilds/change_description.php +++ b/system/pages/guilds/change_description.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); diff --git a/system/pages/guilds/change_logo.php b/system/pages/guilds/change_logo.php index 2430360d..7e68de23 100644 --- a/system/pages/guilds/change_logo.php +++ b/system/pages/guilds/change_logo.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -122,4 +124,4 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/change_motd.php b/system/pages/guilds/change_motd.php index 490fea5f..c777548d 100644 --- a/system/pages/guilds/change_motd.php +++ b/system/pages/guilds/change_motd.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!MOTD_EXISTS) return; @@ -74,4 +76,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/change_nick.php b/system/pages/guilds/change_nick.php index 5e900a33..bf773124 100644 --- a/system/pages/guilds/change_nick.php +++ b/system/pages/guilds/change_nick.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { $errors[] = "You are not logged in. You can't change nick."; $twig->display('error_box.html.twig', array('errors' => $errors)); diff --git a/system/pages/guilds/change_rank.php b/system/pages/guilds/change_rank.php index 7e4fe92c..cec52e65 100644 --- a/system/pages/guilds/change_rank.php +++ b/system/pages/guilds/change_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { $errors[] = "You are not logged in. You can't change rank."; } diff --git a/system/pages/guilds/cleanup_guilds.php b/system/pages/guilds/cleanup_guilds.php index e5e3804e..ebc41ee3 100644 --- a/system/pages/guilds/cleanup_guilds.php +++ b/system/pages/guilds/cleanup_guilds.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { echo "You are not logged in."; @@ -64,4 +66,4 @@ else echo "0 guilds found."; $twig->display('guilds.back_button.html.twig'); -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/cleanup_players.php b/system/pages/guilds/cleanup_players.php index b22746b1..30b1e8af 100644 --- a/system/pages/guilds/cleanup_players.php +++ b/system/pages/guilds/cleanup_players.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + if(!$logged) { echo "You are not logged in."; @@ -66,4 +68,4 @@ else echo "0 players found."; $twig->display('guilds.back_button.html.twig'); -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/create.php b/system/pages/guilds/create.php index 12a75d0b..9814ade0 100644 --- a/system/pages/guilds/create.php +++ b/system/pages/guilds/create.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; $todo = isset($_REQUEST['todo']) ? $_REQUEST['todo'] : NULL; @@ -131,4 +133,4 @@ else { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_by_admin.php b/system/pages/guilds/delete_by_admin.php index fd9beafb..3e083c8a 100644 --- a/system/pages/guilds/delete_by_admin.php +++ b/system/pages/guilds/delete_by_admin.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -65,4 +67,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_guild.php b/system/pages/guilds/delete_guild.php index cfc87c65..978ac513 100644 --- a/system/pages/guilds/delete_guild.php +++ b/system/pages/guilds/delete_guild.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -77,4 +79,4 @@ if(!empty($errors)) { )); } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/delete_invite.php b/system/pages/guilds/delete_invite.php index 8a58f323..1bf5f730 100644 --- a/system/pages/guilds/delete_invite.php +++ b/system/pages/guilds/delete_invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = stripslashes($_REQUEST['name']); @@ -113,4 +115,4 @@ else 'guild_name' => $guild->getName() )); } -} \ No newline at end of file +} diff --git a/system/pages/guilds/delete_rank.php b/system/pages/guilds/delete_rank.php index 4e52d60e..6a8f642c 100644 --- a/system/pages/guilds/delete_rank.php +++ b/system/pages/guilds/delete_rank.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $rank_to_delete = isset($_REQUEST['rankid']) ? (int) $_REQUEST['rankid'] : null; diff --git a/system/pages/guilds/invite.php b/system/pages/guilds/invite.php index 57eda6cf..09957d2d 100644 --- a/system/pages/guilds/invite.php +++ b/system/pages/guilds/invite.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; @@ -122,4 +124,4 @@ if($show) { $twig->display('guilds.back_button.html.twig', array( 'action' => getLink('guilds') . '/' . $guild_name -)); \ No newline at end of file +)); diff --git a/system/pages/guilds/kick_player.php b/system/pages/guilds/kick_player.php index f121ecfc..5ce79187 100644 --- a/system/pages/guilds/kick_player.php +++ b/system/pages/guilds/kick_player.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : null; @@ -118,4 +120,4 @@ else )); } } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/leave_guild.php b/system/pages/guilds/leave.php similarity index 98% rename from system/pages/guilds/leave_guild.php rename to system/pages/guilds/leave.php index 2ce49c8a..892deb89 100644 --- a/system/pages/guilds/leave_guild.php +++ b/system/pages/guilds/leave.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + //set rights in guild $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $name = isset($_REQUEST['name']) ? stripslashes($_REQUEST['name']) : NULL; diff --git a/system/pages/guilds/list_of_guilds.php b/system/pages/guilds/list.php similarity index 97% rename from system/pages/guilds/list_of_guilds.php rename to system/pages/guilds/list.php index 1d827c7f..a233fa9b 100644 --- a/system/pages/guilds/list_of_guilds.php +++ b/system/pages/guilds/list.php @@ -11,6 +11,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guilds_list = new OTS_Guilds_List(); $guilds_list->orderBy("name"); diff --git a/system/pages/guilds/manager.php b/system/pages/guilds/manager.php index c3cabdc8..4d59c22e 100644 --- a/system/pages/guilds/manager.php +++ b/system/pages/guilds/manager.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); @@ -56,5 +58,3 @@ if(empty($errors)) { if(!empty($errors)) { $twig->display('error_box.html.twig', array('errors' => $errors)); } - -?> \ No newline at end of file diff --git a/system/pages/guilds/pass_leadership.php b/system/pages/guilds/pass_leadership.php index ddb3b4a3..462ac9ec 100644 --- a/system/pages/guilds/pass_leadership.php +++ b/system/pages/guilds/pass_leadership.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : NULL; $pass_to = isset($_REQUEST['player']) ? stripslashes($_REQUEST['player']) : NULL; if(!Validator::guildName($guild_name)) { @@ -116,4 +118,4 @@ if(!empty($guild_errors)) { echo '
' . $twig->render('buttons.back.html.twig') . '
'; } -?> \ No newline at end of file +?> diff --git a/system/pages/guilds/save_ranks.php b/system/pages/guilds/save_ranks.php index fc1ed87a..65e047bb 100644 --- a/system/pages/guilds/save_ranks.php +++ b/system/pages/guilds/save_ranks.php @@ -10,6 +10,8 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) { $errors[] = Validator::getLastError(); diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index ebd04ce6..e74a8201 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -12,6 +12,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Guilds'; + +require __DIR__ . '/base.php'; + $guild_name = isset($_REQUEST['guild']) ? urldecode($_REQUEST['guild']) : null; if(!Validator::guildName($guild_name)) $errors[] = Validator::getLastError(); @@ -159,4 +162,4 @@ $twig->display('guilds.view.html.twig', array( 'invited_list' => $invited_list, 'show_accept_invite' => $show_accept_invite, 'useGuildNick' => $useGuildNick -)); \ No newline at end of file +)); diff --git a/system/pages/highscores.php b/system/pages/highscores.php index 4988443b..107f008b 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -16,11 +16,11 @@ if(config('account_country') && $configHighscoresCountryBox) require SYSTEM . 'countries.conf.php'; $list = isset($_GET['list']) ? $_GET['list'] : 'experience'; -$_page = isset($_GET['page']) ? $_GET['page'] : 1; +$page = isset($_GET['page']) ? $_GET['page'] : 1; $vocation = isset($_GET['vocation']) ? $_GET['vocation'] : 'all'; -if(!is_numeric($_page) || $_page < 1 || $_page > PHP_INT_MAX) { - $_page = 1; +if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) { + $page = 1; } $add_sql = ''; @@ -139,7 +139,7 @@ $configHighscoresPerPage = config('highscores_per_page'); $limit = $configHighscoresPerPage + 1; $needReCache = true; -$cacheKey = 'highscores_' . $skill . '_' . $vocation . '_' . $_page . '_' . $configHighscoresPerPage; +$cacheKey = 'highscores_' . $skill . '_' . $vocation . '_' . $page . '_' . $configHighscoresPerPage; $cache = Cache::getInstance(); if ($cache->enabled()) { @@ -150,7 +150,7 @@ if ($cache->enabled()) { } } -$offset = ($_page - 1) * $configHighscoresPerPage; +$offset = ($page - 1) * $configHighscoresPerPage; if (!isset($highscores) || empty($highscores)) { if ($skill >= POT::SKILL_FIRST && $skill <= POT::SKILL_LAST) { // skills if ($db->hasColumn('players', 'skill_fist')) {// tfs 1.0 @@ -280,14 +280,14 @@ foreach($highscores as $id => &$player) //link to previous page if actual page is not first $linkPreviousPage = ''; -if($_page > 1) { - $linkPreviousPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($_page - 1); +if($page > 1) { + $linkPreviousPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page - 1); } //link to next page if any result will be on next page $linkNextPage = ''; if($show_link_to_next_page) { - $linkNextPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($_page + 1); + $linkNextPage = getLink('highscores') . '/' . $list . ($vocation !== 'all' ? '/' . $vocation : '') . '/' . ($page + 1); } $types = array( diff --git a/system/router.php b/system/router.php new file mode 100644 index 00000000..8117cdaf --- /dev/null +++ b/system/router.php @@ -0,0 +1,214 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ + +if(!$load_it) { + // ignore warnings in some functions/plugins + // page is not loaded anyways + define('ACTION', ''); + define('PAGE', ''); + + return; +} + +if(SITE_CLOSED && admin()) + $content .= '

Site is under maintenance (closed mode). Only privileged users can see it.

'; + +$ignore = false; + +$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; + } + + $page = $uri; +} else { + // old support for pages like /?subtopic=accountmanagement + $page = isset($_REQUEST['p']) ? $_REQUEST['p'] : (isset($_REQUEST['subtopic']) ? $_REQUEST['subtopic'] : ''); + if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { + if(config('backward_support')) { + require SYSTEM . 'compat_pages.php'; + } + + $file = SYSTEM . 'pages/' . $page . '.php'; + if (!is_file($file)) { + $page = '404'; + $file = SYSTEM . 'pages/404.php'; + } + } + else { + $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) { + $routes = require SYSTEM . 'routes.php'; + + $duplicates = []; + Plugins::clearWarnings(); + foreach (Plugins::getRoutes() as $route) { + $duplicates[$route[1]] = true; + $r->addRoute($route[0], '/' . $route[1], $route[2]); + } + + foreach ($routes as $route) { + if(!isset($duplicates[$route[1]])) { + $r->addRoute($route[0], '/' . $route[1], 'system/pages/' . $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 from somewhere + $httpMethod = $_SERVER['REQUEST_METHOD']; + $uri = $_SERVER['REQUEST_URI']; + + // 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); + + $routeInfo = $dispatcher->dispatch($httpMethod, $uri); + switch ($routeInfo[0]) { + case FastRoute\Dispatcher::NOT_FOUND: + // ... 404 Not Found + $tmp = URI; + $found = true; + + $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); + } + + if (false !== $pos = strpos($uri, '?')) { + $tmp = substr($uri, 0, $pos); + } + + if (empty($tmp)) { + $page = 'news'; + $file = SYSTEM . 'pages/news.php'; + } + else { + $found = 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); + + // parse for define PAGE + $tmp = BASE_DIR; + $uri = $_SERVER['REQUEST_URI']; + if (!empty($tmp)) { + $uri = str_replace(BASE_DIR . '/', '', $uri); + } + + if (false !== $pos = strpos($uri, '?')) { + $uri = substr($uri, 0, $pos); + } + if (0 === strpos($uri, '/')) { + $uri = str_replace_first('/', '', $uri); + } + + $page = $uri; + $file = BASE . $path; + + unset($tmp, $uri); + break; + } + } +} + +define('PAGE', $page); +if(config('backward_support')) { + $subtopic = $page; +} + +$action = isset($_REQUEST['action']) ? strtolower($_REQUEST['action']) : ''; +define('ACTION', $action); + +ob_start(); +if($hooks->trigger(HOOK_BEFORE_PAGE)) { + if(!$ignore) + require $file; +} + +unset($file); + +if(config('backward_support') && isset($main_content[0])) + $content .= $main_content; + +$content .= ob_get_contents(); +ob_end_clean(); +$hooks->trigger(HOOK_AFTER_PAGE); + +if(config('backward_support')) { + $main_content = $content; + if(!isset($title)) { + $title = ucfirst($page); + } + + $topic = $title; +} + +unset($page); diff --git a/system/routes.php b/system/routes.php new file mode 100644 index 00000000..aa42dbf0 --- /dev/null +++ b/system/routes.php @@ -0,0 +1,56 @@ + + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ + +return [ + [['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'], + [['GET', 'POST'], 'account/character/create[/]', 'account/create_character.php'], + [['GET', 'POST'], 'account/character/name[/]', 'account/change_name.php'], + [['GET', 'POST'], 'account/character/sex[/]', 'account/change_sex.php'], + [['GET', 'POST'], 'account/character/delete[/]', 'account/delete_character.php'], + [['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', 'POST'], 'characters[/{name:[A-Za-z0-9-_%+\']+}]', 'characters.php'], + ['GET', 'changelog[/{page:\d+}]', 'changelog.php'], + ['GET', 'creatures[/{name:[A-Za-z0-9-_%+\']+}]', 'creatures.php'], + + ['GET', 'faq[/{action:[A-Za-z0-9-_%+\']+}]', 'faq.php'], + + [['GET', 'POST'], 'forum/{action:[A-Za-z0-9-_]+}[/]', 'forum.php'], + ['GET', 'forum/board/{id:[0-9]+}[/]', 'forum/show_board.php'], + ['GET', 'forum/board/{id:[0-9]+}/{page:[0-9]+}[/]', 'forum/show_board.php'], + ['GET', 'forum/thread/{id:[0-9]+}[/]', 'forum/show_thread.php'], + //['GET', 'forum/thread/{id:[0-9]+}/{page:[0-9]+}[/]', 'forum/show_thread.php'], + + ['GET', 'gallery/{image:[0-9]+}[/]', 'gallery.php'], + [['GET', 'POST'], 'gallery/{action:[A-Za-z0-9-_]+}[/]', 'gallery.php'], + + [['GET', 'POST'], 'guilds/{guild:[A-Za-z0-9-_%+\']+}[/]', 'guilds/show.php'], + + ['GET', 'highscores/{list:[A-Za-z0-9-_]+}/{vocation:[A-Za-z0-9-_]+}/{page:[0-9]+}[/]', 'highscores.php'], + ['GET', 'highscores/{list:[A-Za-z0-9-_]+}/{page:[0-9]+}[/]', 'highscores.php'], + ['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'], +/* + '/^gifts\/history\/?$/' => array('subtopic' => 'gifts', 'action' => 'show_history'), + '/^polls\/[0-9]+\/?$/' => array('subtopic' => 'polls', 'id' => '$1'), + '/^spells\/[A-Za-z0-9-_%]+\/[A-Za-z0-9-_]+\/?$/' => array('subtopic' => 'spells', 'vocation' => '$1', 'order' => '$2'), + '/^houses\/view\/?$/' => array('subtopic' => 'houses', 'page' => 'view')*/ +]; diff --git a/system/templates/account.login.html.twig b/system/templates/account.login.html.twig index 2ac4f3f6..5c040f7f 100644 --- a/system/templates/account.login.html.twig +++ b/system/templates/account.login.html.twig @@ -1,4 +1,4 @@ -Please enter your account {{ account|lower }} and your password.
Create an account if you do not have one yet.

+Please enter your account {{ account|lower }} and your password.
Create an account if you do not have one yet.

{% if redirect is not null %} @@ -73,4 +73,4 @@ Please enter your account {{ account|lower }} and your password.