From 8985917a96e4a3a5f285eb68224e0c2a470796dd Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 18:28:31 +0100 Subject: [PATCH 001/232] Fixes to account number --- admin/pages/accounts.php | 18 ++++++++++++++---- install/steps/7-finish.php | 2 +- system/libs/pot/OTS_Account.php | 23 ++++++++++++----------- system/libs/pot/OTS_Player.php | 2 +- system/login.php | 2 +- system/pages/account/login.php | 2 +- tools/validate.php | 7 ++++--- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index e481c782..554ed60c 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -16,6 +16,11 @@ $use_datatable = true; if ($config['account_country']) require SYSTEM . 'countries.conf.php'; +$nameOrNumberColumn = 'name'; +if (USE_ACCOUNT_NUMBER) { + $nameOrNumberColumn = 'number'; +} + $hasSecretColumn = $db->hasColumn('accounts', 'secret'); $hasCoinsColumn = $db->hasColumn('accounts', 'coins'); $hasPointsColumn = $db->hasColumn('accounts', 'premium_points'); @@ -48,7 +53,7 @@ else if (isset($_REQUEST['search'])) { if (strlen($search_account) < 3 && !Validator::number($search_account)) { echo_error('Player name is too short.'); } else { - $query = $db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $db->quote($search_account)); + $query = $db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $db->quote($search_account)); if ($query->rowCount() == 1) { $query = $query->fetch(); $id = (int)$query['id']; @@ -203,7 +208,7 @@ else if (isset($_REQUEST['search'])) { } } } else if ($id == 0) { - $accounts_db = $db->query('SELECT `id`, `name`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC'); + $accounts_db = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '`' . ($hasTypeColumn ? ',type' : ($hasGroupColumn ? ',group_id' : '')) . ' FROM `accounts` ORDER BY `id` ASC'); ?>
@@ -215,7 +220,7 @@ else if (isset($_REQUEST['search'])) { ID - Name + Position @@ -226,7 +231,7 @@ else if (isset($_REQUEST['search'])) { - + Account Name:
+ +
+ + +
diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index 81ace38f..75a76f70 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -8,7 +8,7 @@ if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['save else { require SYSTEM . 'init.php'; if(!$error) { - if(USE_ACCOUNT_NAME) + if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) $account = isset($_SESSION['var_account']) ? $_SESSION['var_account'] : null; else $account_id = isset($_SESSION['var_account_id']) ? $_SESSION['var_account_id'] : null; diff --git a/system/libs/pot/OTS_Account.php b/system/libs/pot/OTS_Account.php index 89db0d16..b511ff29 100644 --- a/system/libs/pot/OTS_Account.php +++ b/system/libs/pot/OTS_Account.php @@ -231,26 +231,22 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable * @param int $id Account number. * @throws PDOException On PDO operation error. */ - public function load($id, $fresh = false, $searchOnlyById = false) + public function load($id, $fresh = false) { if(!$fresh && isset(self::$cache[$id])) { $this->data = self::$cache[$id]; return; } - $numberColumn = 'id'; $nameOrNumber = ''; - if (!$searchOnlyById) { - if (USE_ACCOUNT_NAME) { - $nameOrNumber = '`name`,'; - } else if (USE_ACCOUNT_NUMBER) { - $nameOrNumber = '`number`,'; - $numberColumn = 'number'; - } + if (USE_ACCOUNT_NAME) { + $nameOrNumber = '`name`,'; + } else if (USE_ACCOUNT_NUMBER) { + $nameOrNumber = '`number`,'; } // SELECT query on database - $this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `blocked`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `' . $numberColumn . '` = ' . (int) $id)->fetch(); + $this->data = $this->db->query('SELECT `id`, ' . $nameOrNumber . '`password`, `email`, `blocked`, `rlname`, `location`, `country`, `web_flags`, ' . ($this->db->hasColumn('accounts', 'premdays') ? '`premdays`, ' : '') . ($this->db->hasColumn('accounts', 'lastday') ? '`lastday`, ' : ($this->db->hasColumn('accounts', 'premend') ? '`premend`,' : ($this->db->hasColumn('accounts', 'premium_ends_at') ? '`premium_ends_at`,' : ''))) . '`created` FROM `accounts` WHERE `id` = ' . (int) $id)->fetch(); self::$cache[$id] = $this->data; } @@ -268,8 +264,13 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable */ public function find($name) { + $nameOrNumberColumn = 'name'; + if (USE_ACCOUNT_NUMBER) { + $nameOrNumberColumn = 'number'; + } + // finds player's ID - $id = $this->db->query('SELECT `id` FROM `accounts` WHERE `name` = ' . $this->db->quote($name) )->fetch(); + $id = $this->db->query('SELECT `id` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` = ' . $this->db->quote($name) )->fetch(); // if anything was found if( isset($id['id']) ) diff --git a/system/libs/pot/OTS_Player.php b/system/libs/pot/OTS_Player.php index b5f48dc6..b111a150 100644 --- a/system/libs/pot/OTS_Player.php +++ b/system/libs/pot/OTS_Player.php @@ -602,7 +602,7 @@ class OTS_Player extends OTS_Row_DAO } $account = new OTS_Account(); - $account->load($this->data['account_id'], false, true); + $account->load($this->data['account_id']); return $account; } diff --git a/system/login.php b/system/login.php index 5d55cd18..e002b0b2 100644 --- a/system/login.php +++ b/system/login.php @@ -16,7 +16,7 @@ $current_session = getSession('account'); if($current_session !== false) { $account_logged = new OTS_Account(); - $account_logged->load($current_session); + $account_logged->find($current_session); if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password') //&& (!isset($_SESSION['admin']) || admin()) && (getSession('remember_me') !== false || getSession('last_visit') > time() - 15 * 60)) { // login for 15 minutes if "remember me" is not used diff --git a/system/pages/account/login.php b/system/pages/account/login.php index 9cc31503..99c812b7 100644 --- a/system/pages/account/login.php +++ b/system/pages/account/login.php @@ -37,7 +37,7 @@ if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) } if (!config('account_login_by_email') || config('account_login_by_email_fallback')) { - if(USE_ACCOUNT_NAME) { + if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) { $account_logged->find($login_account); } else { $account_logged->load($login_account, true); diff --git a/tools/validate.php b/tools/validate.php index b0718062..6e80a6e6 100644 --- a/tools/validate.php +++ b/tools/validate.php @@ -27,15 +27,16 @@ if(isset($_GET['account'])) error_(Validator::getLastError()); $_account = new OTS_Account(); - if(USE_ACCOUNT_NAME) + if(USE_ACCOUNT_NAME || USE_ACCOUNT_NUMBER) $_account->find($account); else $_account->load($account); + $accountNameOrNumber = (USE_ACCOUNT_NAME ? ' name' : 'number'); if($_account->isLoaded()) - error_('Account with this name already exist.'); + error_("Account with this $accountNameOrNumber already exist."); - success_('Good account' . (USE_ACCOUNT_NAME ? ' name' : '') . ' ( ' . $account . ' ).'); + success_("Good account $accountNameOrNumber ($account)."); } else if(isset($_GET['email'])) { From ed7e9e1eae9ba22d916d29ea410a19570c87a61b Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 18:40:31 +0100 Subject: [PATCH 002/232] fixes to account number part 2 --- system/login.php | 2 +- system/pages/account/login.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/login.php b/system/login.php index e002b0b2..5d55cd18 100644 --- a/system/login.php +++ b/system/login.php @@ -16,7 +16,7 @@ $current_session = getSession('account'); if($current_session !== false) { $account_logged = new OTS_Account(); - $account_logged->find($current_session); + $account_logged->load($current_session); if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password') //&& (!isset($_SESSION['admin']) || admin()) && (getSession('remember_me') !== false || getSession('last_visit') > time() - 15 * 60)) { // login for 15 minutes if "remember me" is not used diff --git a/system/pages/account/login.php b/system/pages/account/login.php index 99c812b7..a62aa827 100644 --- a/system/pages/account/login.php +++ b/system/pages/account/login.php @@ -48,7 +48,7 @@ if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) && (!isset($t) || $t['attempts'] < 5) ) { - setSession('account', $account_logged->getNumber()); + setSession('account', $account_logged->getId()); setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password)); if($remember_me) { setSession('remember_me', true); From fc0eb0e793fe4769c36875fae54ff151cfe99bdd Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 8 Feb 2023 15:22:14 +0100 Subject: [PATCH 003/232] add missing hook --- system/hooks.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/hooks.php b/system/hooks.php index 3201880d..448d40c0 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -51,6 +51,7 @@ define('HOOK_ACCOUNT_CREATE_POST', ++$i); define('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE', ++$i); define('HOOK_ACCOUNT_LOGIN_BEFORE_ACCOUNT', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT', ++$i); +define('HOOK_ACCOUNT_LOGIN_BEFORE_PASSWORD', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i); define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i); From 66ec66b29131cf6b287041197e6ab2a0455ff057 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 18:47:56 +0100 Subject: [PATCH 004/232] Allow TinyMCE to resize horizontally and vertically --- system/templates/tinymce.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/system/templates/tinymce.html.twig b/system/templates/tinymce.html.twig index b0817800..880de4f0 100644 --- a/system/templates/tinymce.html.twig +++ b/system/templates/tinymce.html.twig @@ -9,6 +9,7 @@ theme: "silver", plugins: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help code emoticons', toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code', + resize: 'both', image_advtab: true, images_upload_url: '{{ constant('BASE_URL') }}admin/tools/upload_image.php', images_upload_credentials: true, From 7d8dbcbde7497ac04b831cdd495743d812c9c197 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 19:40:55 +0100 Subject: [PATCH 005/232] fixes to account number part 3 --- admin/pages/accounts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 554ed60c..8c648578 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -58,7 +58,7 @@ else if (isset($_REQUEST['search'])) { $query = $query->fetch(); $id = (int)$query['id']; } else { - $query = $db->query('SELECT `id`, `name` FROM `accounts` WHERE `name` LIKE ' . $db->quote('%' . $search_account . '%')); + $query = $db->query('SELECT `id`, `' . $nameOrNumberColumn . '` FROM `accounts` WHERE `' . $nameOrNumberColumn . '` LIKE ' . $db->quote('%' . $search_account . '%')); if ($query->rowCount() > 0 && $query->rowCount() <= 10) { $str_construct = 'Do you mean?
    '; foreach ($query as $row) From c88156802a56596a1e6ac3b0eb912a64bcc45fa1 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 21:51:46 +0100 Subject: [PATCH 006/232] fix pages not found --- system/pages/{experiencestages.php => experience_stages.php} | 0 system/pages/{experiencetable.php => experience_table.php} | 0 system/pages/{serverinfo.php => server_info.php} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename system/pages/{experiencestages.php => experience_stages.php} (100%) rename system/pages/{experiencetable.php => experience_table.php} (100%) rename system/pages/{serverinfo.php => server_info.php} (100%) diff --git a/system/pages/experiencestages.php b/system/pages/experience_stages.php similarity index 100% rename from system/pages/experiencestages.php rename to system/pages/experience_stages.php diff --git a/system/pages/experiencetable.php b/system/pages/experience_table.php similarity index 100% rename from system/pages/experiencetable.php rename to system/pages/experience_table.php diff --git a/system/pages/serverinfo.php b/system/pages/server_info.php similarity index 100% rename from system/pages/serverinfo.php rename to system/pages/server_info.php From d565b90736fe0a6139ddd7c17867666ae640b42f Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 21:51:54 +0100 Subject: [PATCH 007/232] Update accounts.php --- admin/pages/accounts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 8c648578..f96d0ec2 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -62,7 +62,7 @@ else if (isset($_REQUEST['search'])) { if ($query->rowCount() > 0 && $query->rowCount() <= 10) { $str_construct = 'Do you mean?'; echo_error($str_construct); } else if ($query->rowCount() > 10) From 590fe0762d33411bb4c2ee81c87567294bb5082d Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 14 Feb 2023 22:03:22 +0100 Subject: [PATCH 008/232] small fixes --- system/router.php | 11 +++++++---- templates/tibiacom/index.php | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/system/router.php b/system/router.php index ff8c7d3d..596121f5 100644 --- a/system/router.php +++ b/system/router.php @@ -55,10 +55,9 @@ if (BASE_DIR !== '') { define('URI', $uri); -/** @var boolean $load_it */ if(!$load_it) { // ignore warnings in some functions/plugins - // page is not loaded anyways + // page is not loaded anyway define('PAGE', ''); return; @@ -147,6 +146,10 @@ $found = true; // old support for pages like /?subtopic=accountmanagement $page = $_REQUEST['p'] ?? ($_REQUEST['subtopic'] ?? ''); if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { + if (isset($_REQUEST['p'])) { // some plugins may require this + $_REQUEST['subtopic'] = $_REQUEST['p']; + } + if (config('backward_support')) { require SYSTEM . 'compat/pages.php'; } @@ -161,7 +164,6 @@ else { 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 */ @@ -282,7 +284,8 @@ function getDatabasePages() { return $ret; } -function loadPageFromFileSystem($page, &$found) { +function loadPageFromFileSystem($page, &$found): string +{ $file = SYSTEM . 'pages/' . $page . '.php'; if (!is_file($file)) { // feature: convert camelCase to snake_case diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 8ebbd5b6..989a05ca 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -27,7 +27,7 @@ if(isset($config['boxes'])) var loginStatus=""; Date: Tue, 14 Feb 2023 23:22:17 +0100 Subject: [PATCH 009/232] add some notice --- nginx-sample.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/nginx-sample.conf b/nginx-sample.conf index 5a2deab7..8db44d54 100644 --- a/nginx-sample.conf +++ b/nginx-sample.conf @@ -22,6 +22,7 @@ server { deny all; } + # this is very important, be sure its in your nginx conf - it prevents access to logs etc. location /system { deny all; return 404; From 6ae1bf58147eee6427b6612afa60864c5315f3b3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 15 Feb 2023 08:06:08 +0100 Subject: [PATCH 010/232] Add missing header to some files --- system/exception.php | 9 ++++++++- system/functions.php | 3 +-- system/logout.php | 9 +++++++++ system/migrate.php | 11 ++++++++++- system/pages/account/login.php | 11 +++++++++++ system/router.php | 3 ++- system/routes.php | 1 + system/twig.php | 9 +++++++++ 8 files changed, 51 insertions(+), 5 deletions(-) diff --git a/system/exception.php b/system/exception.php index 3ad1fefe..e46f0d54 100644 --- a/system/exception.php +++ b/system/exception.php @@ -1,5 +1,12 @@ + * @copyright 2023 MyAAC + * @link https://my-aac.org + */ require LIBS . 'SensitiveException.php'; /** diff --git a/system/functions.php b/system/functions.php index db3bfd8f..a2c7d202 100644 --- a/system/functions.php +++ b/system/functions.php @@ -7,12 +7,11 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ +defined('MYAAC') or die('Direct access not allowed!'); use PHPMailer\PHPMailer\PHPMailer; use Twig\Loader\ArrayLoader as Twig_ArrayLoader; -defined('MYAAC') or die('Direct access not allowed!'); - function message($message, $type, $return) { if(IS_CLI) { diff --git a/system/logout.php b/system/logout.php index a7f5d8fd..af443aa3 100644 --- a/system/logout.php +++ b/system/logout.php @@ -1,4 +1,13 @@ + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); if(isset($account_logged) && $account_logged->isLoaded()) { if($hooks->trigger(HOOK_LOGOUT, ['account_id' => $account_logged->getId()])) { diff --git a/system/migrate.php b/system/migrate.php index 46daeef6..4eb7bf7a 100644 --- a/system/migrate.php +++ b/system/migrate.php @@ -1,4 +1,13 @@ + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); // database migrations $tmp = ''; @@ -19,4 +28,4 @@ else { // register first version require SYSTEM . 'migrations/' . $i . '.php'; updateDatabaseConfig('database_version', $i); } -} \ No newline at end of file +} diff --git a/system/pages/account/login.php b/system/pages/account/login.php index a62aa827..557aeb86 100644 --- a/system/pages/account/login.php +++ b/system/pages/account/login.php @@ -1,4 +1,15 @@ + * @author Slawkens + * @copyright 2023 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Login'; // new login with data from form if(!$logged && isset($_POST['account_login'], $_POST['password_login'])) diff --git a/system/router.php b/system/router.php index 596121f5..4f3b6321 100644 --- a/system/router.php +++ b/system/router.php @@ -4,9 +4,10 @@ * * @package MyAAC * @author Slawkens - * @copyright 2021 MyAAC + * @copyright 2023 MyAAC * @link https://my-aac.org */ +defined('MYAAC') or die('Direct access not allowed!'); if(!isset($content[0])) $content = ''; diff --git a/system/routes.php b/system/routes.php index a7ddd295..c6dfa780 100644 --- a/system/routes.php +++ b/system/routes.php @@ -7,6 +7,7 @@ * @copyright 2021 MyAAC * @link https://my-aac.org */ +defined('MYAAC') or die('Direct access not allowed!'); return [ ['GET', '', '__redirect__/news'], // redirect empty URL to news diff --git a/system/twig.php b/system/twig.php index 5b912875..87d2ad6f 100644 --- a/system/twig.php +++ b/system/twig.php @@ -1,4 +1,13 @@ + * @copyright 2021 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); use Twig\Environment as Twig_Environment; use Twig\Extension\DebugExtension as Twig_DebugExtension; From 6c4b3dea9683e1022a341e23946f819942500e4a Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 15 Feb 2023 08:06:57 +0100 Subject: [PATCH 011/232] Delete autoload.php --- system/autoload.php | 206 -------------------------------------------- 1 file changed, 206 deletions(-) delete mode 100644 system/autoload.php diff --git a/system/autoload.php b/system/autoload.php deleted file mode 100644 index a13db1db..00000000 --- a/system/autoload.php +++ /dev/null @@ -1,206 +0,0 @@ -register(); - -// register the base directories for the namespace prefix -$loader->addNamespace('Composer\Semver', LIBS . 'semver'); -$loader->addNamespace('Twig', LIBS . 'Twig'); -/** - * An example of a general-purpose implementation that includes the optional - * functionality of allowing multiple base directories for a single namespace - * prefix. - * - * Given a foo-bar package of classes in the file system at the following - * paths ... - * - * /path/to/packages/foo-bar/ - * src/ - * Baz.php # Foo\Bar\Baz - * Qux/ - * Quux.php # Foo\Bar\Qux\Quux - * tests/ - * BazTest.php # Foo\Bar\BazTest - * Qux/ - * QuuxTest.php # Foo\Bar\Qux\QuuxTest - * - * ... add the path to the class files for the \Foo\Bar\ namespace prefix - * as follows: - * - * register(); - * - * // register the base directories for the namespace prefix - * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src'); - * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests'); - * - * The following line would cause the autoloader to attempt to load the - * \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php: - * - * prefixes[$prefix]) === false) { - $this->prefixes[$prefix] = array(); - } - - // retain the base directory for the namespace prefix - if ($prepend) { - array_unshift($this->prefixes[$prefix], $base_dir); - } else { - array_push($this->prefixes[$prefix], $base_dir); - } - } - - /** - * Loads the class file for a given class name. - * - * @param string $class The fully-qualified class name. - * @return mixed The mapped file name on success, or boolean false on - * failure. - */ - public function loadClass($class) - { - if (0 === strpos($class, 'Twig_')) { - $file = LIBS . 'Twig/' . str_replace(array('_', "\0"), array('/', ''), $class).'.php'; - - if((config('env') === 'dev') && !is_file($file)) { - return false; - } - - require $file; - return false; - } - - // the current namespace prefix - $prefix = $class; - - // work backwards through the namespace names of the fully-qualified - // class name to find a mapped file name - while (false !== $pos = strrpos($prefix, '\\')) { - - // retain the trailing namespace separator in the prefix - $prefix = substr($class, 0, $pos + 1); - - // the rest is the relative class name - $relative_class = substr($class, $pos + 1); - - // try to load a mapped file for the prefix and relative class - $mapped_file = $this->loadMappedFile($prefix, $relative_class); - if ($mapped_file) { - return $mapped_file; - } - - // remove the trailing namespace separator for the next iteration - // of strrpos() - $prefix = rtrim($prefix, '\\'); - } - - // never found a mapped file - return false; - } - - /** - * Load the mapped file for a namespace prefix and relative class. - * - * @param string $prefix The namespace prefix. - * @param string $relative_class The relative class name. - * @return mixed Boolean false if no mapped file can be loaded, or the - * name of the mapped file that was loaded. - */ - protected function loadMappedFile($prefix, $relative_class) - { - // are there any base directories for this namespace prefix? - if (isset($this->prefixes[$prefix]) === false) { - return false; - } - - // look through base directories for this namespace prefix - foreach ($this->prefixes[$prefix] as $base_dir) { - - // replace the namespace prefix with the base directory, - // replace namespace separators with directory separators - // in the relative class name, append with .php - $file = $base_dir - . str_replace('\\', '/', $relative_class) - . '.php'; - - // if the mapped file exists, require it - if ($this->requireFile($file)) { - // yes, we're done - return $file; - } - } - - // never found it - return false; - } - - /** - * If a file exists, require it from the file system. - * - * @param string $file The file to require. - * @return bool True if the file exists, false if not. - */ - protected function requireFile($file) - { - if (config('env') !== 'dev' || file_exists($file)) { - require $file; - return true; - } - return false; - } -} \ No newline at end of file From 7bc20b0993c76e460f799761a6fb27918e324ee7 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 15 Feb 2023 17:12:30 +0100 Subject: [PATCH 012/232] change spaces to tabs --- system/pages/guilds/list.php | 28 +- system/pages/guilds/show.php | 158 +++--- system/templates/guilds.list.html.twig | 290 +++++------ system/templates/guilds.view.html.twig | 636 ++++++++++++------------- 4 files changed, 556 insertions(+), 556 deletions(-) diff --git a/system/pages/guilds/list.php b/system/pages/guilds/list.php index 6296db72..2b65e15d 100644 --- a/system/pages/guilds/list.php +++ b/system/pages/guilds/list.php @@ -19,23 +19,23 @@ $guilds_list->orderBy("name"); $guilds = array(); if(count($guilds_list) > 0) { - foreach ($guilds_list as $guild) { - $guild_logo = $guild->getCustomField('logo_name'); - if (empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo)) - $guild_logo = "default.gif"; + foreach ($guilds_list as $guild) { + $guild_logo = $guild->getCustomField('logo_name'); + if (empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo)) + $guild_logo = "default.gif"; - $description = $guild->getCustomField('description'); - $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
    ', $description, $count); - if ($count < $config['guild_description_lines_limit']) - $description = wordwrap(nl2br($description), 60, "
    ", true); + $description = $guild->getCustomField('description'); + $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
    ', $description, $count); + if ($count < $config['guild_description_lines_limit']) + $description = wordwrap(nl2br($description), 60, "
    ", true); - $guildName = $guild->getName(); - $guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description); - } + $guildName = $guild->getName(); + $guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description); + } }; $twig->display('guilds.list.html.twig', array( - 'guilds' => $guilds, - 'logged' => isset($logged) ? $logged : false, - 'isAdmin' => admin(), + 'guilds' => $guilds, + 'logged' => isset($logged) ? $logged : false, + 'isAdmin' => admin(), )); diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index dc10480c..f4b4f15c 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -49,78 +49,78 @@ $players_from_account_in_guild = array(); $players_from_account_ids = array(); if($logged) { - $account_players = $account_logged->getPlayers(); - foreach($account_players as $player) - { - $players_from_account_ids[] = $player->getId(); - $player_rank = $player->getRank(); - if($player_rank->isLoaded()) - { - foreach($rank_list as $rank_in_guild) - { - if($guild_owner->isLoaded() && $rank_in_guild->isLoaded() && $player_rank->isLoaded() && - $rank_in_guild->getId() == $player_rank->getId()) - { - $players_from_account_in_guild[] = $player->getName(); - if($guild_owner->getId() == $player->getId()) - { - $guild_vice = true; - $guild_leader = true; - } - else if($player_rank->getLevel() > 1) - { - $guild_vice = true; - $level_in_guild = $player_rank->getLevel(); - } - } - } - } - } + $account_players = $account_logged->getPlayers(); + foreach($account_players as $player) + { + $players_from_account_ids[] = $player->getId(); + $player_rank = $player->getRank(); + if($player_rank->isLoaded()) + { + foreach($rank_list as $rank_in_guild) + { + if($guild_owner->isLoaded() && $rank_in_guild->isLoaded() && $player_rank->isLoaded() && + $rank_in_guild->getId() == $player_rank->getId()) + { + $players_from_account_in_guild[] = $player->getName(); + if($guild_owner->getId() == $player->getId()) + { + $guild_vice = true; + $guild_leader = true; + } + else if($player_rank->getLevel() > 1) + { + $guild_vice = true; + $level_in_guild = $player_rank->getLevel(); + } + } + } + } + } } //show guild page $guild_logo = $guild->getCustomField('logo_name'); if(empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo)) - $guild_logo = "default.gif"; + $guild_logo = "default.gif"; $description = $guild->getCustomField('description'); $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
    ', $description, $count); if($count < $config['guild_description_lines_limit']) - $description = wordwrap(nl2br($description), 60, "
    ", true); + $description = wordwrap(nl2br($description), 60, "
    ", true); //$description = $description_with_lines; $guild_owner = $guild->getOwner(); if($guild_owner->isLoaded()) - $guild_owner_name = $guild_owner->getName(); + $guild_owner_name = $guild_owner->getName(); $guild_members = array(); foreach($rank_list as $rank) { - if($db->hasTable(GUILD_MEMBERS_TABLE)) - $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` ORDER BY `name`;'); - else if($db->hasColumn('players', 'rank_id')) - $players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `deleted` = 0;'); + if($db->hasTable(GUILD_MEMBERS_TABLE)) + $players_with_rank = $db->query('SELECT `players`.`id` as `id`, `' . GUILD_MEMBERS_TABLE . '`.`rank_id` as `rank_id` FROM `players`, `' . GUILD_MEMBERS_TABLE . '` WHERE `' . GUILD_MEMBERS_TABLE . '`.`rank_id` = ' . $rank->getId() . ' AND `players`.`id` = `' . GUILD_MEMBERS_TABLE . '`.`player_id` ORDER BY `name`;'); + else if($db->hasColumn('players', 'rank_id')) + $players_with_rank = $db->query('SELECT `id`, `rank_id` FROM `players` WHERE `rank_id` = ' . $rank->getId() . ' AND `deleted` = 0;'); - $players_with_rank_number = $players_with_rank->rowCount(); - if($players_with_rank_number > 0) - { - $members = array(); - foreach($players_with_rank as $result) - { - $player = new OTS_Player(); - $player->load($result['id']); - if(!$player->isLoaded()) - continue; + $players_with_rank_number = $players_with_rank->rowCount(); + if($players_with_rank_number > 0) + { + $members = array(); + foreach($players_with_rank as $result) + { + $player = new OTS_Player(); + $player->load($result['id']); + if(!$player->isLoaded()) + continue; - $members[] = $player; - } + $members[] = $player; + } - $guild_members[] = array( - 'rank_name' => $rank->getName(), - 'rank_level' => $rank->getLevel(), - 'members' => $members - ); - } + $guild_members[] = array( + 'rank_name' => $rank->getName(), + 'rank_level' => $rank->getLevel(), + 'members' => $members + ); + } } include(SYSTEM . 'libs/pot/InvitesDriver.php'); @@ -129,37 +129,37 @@ $invited_list = $guild->listInvites(); $show_accept_invite = 0; if($logged && count($invited_list) > 0) { - foreach($invited_list as $invited_player) - { - if(count($account_players) > 0) - { - foreach($account_players as $player_from_acc) - { - if($player_from_acc->isLoaded() && $invited_player->isLoaded() && $player_from_acc->getName() == $invited_player->getName()) - $show_accept_invite++; - } - } - } + foreach($invited_list as $invited_player) + { + if(count($account_players) > 0) + { + foreach($account_players as $player_from_acc) + { + if($player_from_acc->isLoaded() && $invited_player->isLoaded() && $player_from_acc->getName() == $invited_player->getName()) + $show_accept_invite++; + } + } + } } $useGuildNick = false; if($db->hasColumn('players', 'guildnick')) - $useGuildNick = true; + $useGuildNick = true; $twig->display('guilds.view.html.twig', array( - 'logo' => $guild_logo, - 'guild_name' => $guild_name, - 'description' => $description, - 'guild_owner' => $guild_owner->isLoaded() ? $guild_owner : null, - 'guild_creation_date' => $guild->getCreationData(), - 'guild_members' => $guild_members, - 'players_from_account_ids' => $players_from_account_ids, - 'players_from_account_in_guild' => $players_from_account_in_guild, - 'level_in_guild' => $level_in_guild, - 'isLeader' => $guild_leader, - 'isVice' => $guild_vice, - 'logged' => $logged, - 'invited_list' => $invited_list, - 'show_accept_invite' => $show_accept_invite, - 'useGuildNick' => $useGuildNick + 'logo' => $guild_logo, + 'guild_name' => $guild_name, + 'description' => $description, + 'guild_owner' => $guild_owner->isLoaded() ? $guild_owner : null, + 'guild_creation_date' => $guild->getCreationData(), + 'guild_members' => $guild_members, + 'players_from_account_ids' => $players_from_account_ids, + 'players_from_account_in_guild' => $players_from_account_in_guild, + 'level_in_guild' => $level_in_guild, + 'isLeader' => $guild_leader, + 'isVice' => $guild_vice, + 'logged' => $logged, + 'invited_list' => $invited_list, + 'show_accept_invite' => $show_accept_invite, + 'useGuildNick' => $useGuildNick )); diff --git a/system/templates/guilds.list.html.twig b/system/templates/guilds.list.html.twig index f1c03404..da5016b0 100644 --- a/system/templates/guilds.list.html.twig +++ b/system/templates/guilds.list.html.twig @@ -1,162 +1,162 @@
    -
    -
    - - - - -
    Active Guilds on {{ config.lua.serverName }}
    - - - - -
    -
    +
    +
    + + + + +
    Active Guilds on {{ config.lua.serverName }}
    + + + + +
    +
    - - - - + + +
    -
    - - - - + {% endif %} + + {% endif %} + +
    -
    -
    -
    -
    -
    - - - {% if guilds|length > 0 %} - - - - - +
    LogoDescription 
    + + + - - -
    +
    + + + + - - -
    +
    +
    +
    +
    +
    + + + {% if guilds|length > 0 %} + + + + + - {% set i = 0 %} - {% for guild in guilds %} - {% set i = i + 1 %} - - + {% set i = 0 %} + {% for guild in guilds %} + {% set i = i + 1 %} + + - + {% if guild.description is not empty %} +
    + {{ guild.description }} + {% endif %} + - - - {% endfor %} - {% else %} - - + + + {% endfor %} + {% else %} + + - {% if logged %} - - {% endif %} - - {% endif %} - -
    LogoDescription 
    - -
    + + - - {{ guild.name }}{% if isAdmin %} - Delete this guild (for ADMIN only!){% endif %} - + + + {{ guild.name }}{% if isAdmin %} - Delete this guild (for ADMIN only!){% endif %} + - {% if guild.description is not empty %} -
    - {{ guild.description }} - {% endif %} -
    - - - - - - -
    -
    - {{ include('buttons.view.html.twig') }} -
    -
    -
    - Create Guild -
    - Actually there is no guild on server.{% if logged %} Create first! Press button "Create Guild"{% endif %} -
    + + + + + + +
    +
    + {{ include('buttons.view.html.twig') }} +
    +
    +
    + Create Guild +
    + Actually there is no guild on server.{% if logged %} Create first! Press button "Create Guild"{% endif %} +
    - - - - {% set button_name = 'Found Guild' %} - {% set button_image = '_sbutton_foundguild' %} - {% include('buttons.base.html.twig') %} - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    + {% if logged %} +
    + + + + {% set button_name = 'Found Guild' %} + {% set button_image = '_sbutton_foundguild' %} + {% include('buttons.base.html.twig') %} + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + +

- - - + + + - + {% if logged %} +
+ If you have any problem with guilds try: +
+ Cleanup players - can't join guild/be invited? Can't create guild? Try cleanup players. +
+ Cleanup guilds - made guild, you are a leader, but you are not on players list? Cleanup guilds! + {% endif %} + - - - + + +
- -
+ + - - - {% if logged %} - No guild found that suits your needs? - - {% set button_name = 'Found Guild' %} - {% set button_image = '_sbutton_foundguild' %} - {% include('buttons.base.html.twig') %} - - {% else %} - Before you can create a guild you must login. -
- - {% include('buttons.login.html.twig') %} - - {% endif %} - -
+
+ + + {% if logged %} + No guild found that suits your needs? + + {% set button_name = 'Found Guild' %} + {% set button_image = '_sbutton_foundguild' %} + {% include('buttons.base.html.twig') %} + + {% else %} + Before you can create a guild you must login. +
+ + {% include('buttons.login.html.twig') %} + + {% endif %} + +
- {% if logged %} -
- If you have any problem with guilds try: -
- Cleanup players - can't join guild/be invited? Can't create guild? Try cleanup players. -
- Cleanup guilds - made guild, you are a leader, but you are not on players list? Cleanup guilds! - {% endif %} -
- -
+ +
diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 52d5e8b5..36efbc3d 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -1,347 +1,347 @@
-
-
- - - - +
+
+
- -
+ + + - + - - - -
+ +

{{ guild_name }}

{{ guild_name }}

- -
-
+ + + + + + +
- - - - + + +
-
-
-
-
- - - - -
Guild Information
- - - - -
-
-
+ + + + + + +
+
+
+
+
+ + + + +
Guild Information
+ + + + +
+
+
- - - - + + +
-
- - - - - - -
-
- {% if descriptions is not empty %} - {{ description }} -
-
- {% endif %} + + + + - - -
+
+ + + + - - -
+
+ {% if descriptions is not empty %} + {{ description }} +
+
+ {% endif %} - {% if guild_owner is not empty %} - {% set guildOwnerName = guild_owner.getName() %} + {% if guild_owner is not empty %} + {% set guildOwnerName = guild_owner.getName() %} - {{ guildOwnerName }} is guild leader of {{ guild_name }}. -
- {% endif %} + {{ guildOwnerName }} is guild leader of {{ guild_name }}. +
+ {% endif %} - The guild was founded on {{ config.lua.serverName }} on {{ guild_creation_date|date("j F Y") }}. - {% if isLeader %} - - Manage Guild - - {% endif %} -
-
-
-
-
-
+ The guild was founded on {{ config.lua.serverName }} on {{ guild_creation_date|date("j F Y") }}. + {% if isLeader %} + + Manage Guild + + {% endif %} +
+
+
+
+
+
-
-
-
-
-
- - - - -
Guild Members
- - - - -
-
-
+
+
+
+
+
+ + + + +
Guild Members
+ + + + +
+
+
- - - - + + +
-
- - - - + + + {% endfor %} + +
-
-
- - - - - - - - - +
RankName{% if useGuildNick %} and Title{% endif %}VocationLevelStatus
+ + + - - -
+
+ + + + - - -
+
+
+ + + + + + + + + - {% set showedRank, i = false, 0 %} - {% for rank in guild_members if rank.members|length > 0 %} - {% set rankStyle, i = getStyle(i), i + 1 %} + {% set showedRank, i = false, 0 %} + {% for rank in guild_members if rank.members|length > 0 %} + {% set rankStyle, i = getStyle(i), i + 1 %} - {% for player in rank.members %} - - + {% for player in rank.members %} + + - + {% if level_in_guild > rank.rank_level or isLeader %} + {% if guildOwnerName != playerName %} + + {KICK} + + {% endif %} + {% endif %} + {% else %} + {% if showGuildNick %} ({{ guildNickRaw }}){% endif %} + {% endif %} + + - - - - - {% endfor %} + + + + + {% endfor %} - {% set showedRank = false %} - {% else %} - - - - {% endfor %} - -
RankName{% if useGuildNick %} and Title{% endif %}VocationLevelStatus
- {% if not showedRank %}{{ rank.rank_name }}{% endif %} - {% set showedRank = true %} -
+ {% if not showedRank %}{{ rank.rank_name }}{% endif %} + {% set showedRank = true %} + - {% set playerName = player.getName() %} -
- {{ getPlayerLink(playerName, true)|raw }} +
+ {% set playerName = player.getName() %} + + {{ getPlayerLink(playerName, true)|raw }} - {% set showGuildNick = false %} - {% if player.getGuildNick() is not empty %} - {% set showGuildNick = true %} - {% set guildNickRaw = player.getGuildNick()|raw %} - {% endif %} + {% set showGuildNick = false %} + {% if player.getGuildNick() is not empty %} + {% set showGuildNick = true %} + {% set guildNickRaw = player.getGuildNick()|raw %} + {% endif %} - {% if logged %} - {% if player.getId() in players_from_account_ids %} - () - {% else %} - {% if showGuildNick %} ({{ guildNickRaw }}){% endif %} - {% endif %} + {% if logged %} + {% if player.getId() in players_from_account_ids %} + () + {% else %} + {% if showGuildNick %} ({{ guildNickRaw }}){% endif %} + {% endif %} - {% if level_in_guild > rank.rank_level or isLeader %} - {% if guildOwnerName != playerName %} - - {KICK} - - {% endif %} - {% endif %} - {% else %} - {% if showGuildNick %} ({{ guildNickRaw }}){% endif %} - {% endif %} - - {{ player.getVocationName() }}{{ player.getLevel() }} - Online{% else %} red;">Offline{% endif %} -
{{ player.getVocationName() }}{{ player.getLevel() }} + Online{% else %} red;">Offline{% endif %} +
No guild members found.
-
-
-
-
-
-
-
+ {% set showedRank = false %} + {% else %} +
No guild members found.
+
+ +
+
+ + + + +
+
-
-
-
- - - - -
Invited Characters
- - - - -
-
+
+
+
+ + + + +
Invited Characters
+ + + + +
+
- - - - + + +
-
- - - - + + {% endif %} + {% else %} + + + + {% endfor %} + +
-
- - - - - +
Name
+ + + - - -
+
+ + + + - - -
+
+ + + + + - {% set i = 0 %} - {% for invited_player in invited_list if invited_list|length > 0 %} - {% if invited_player.isLoaded() %} - - {% set i = i + 1 %} + {% set i = 0 %} + {% for invited_player in invited_list if invited_list|length > 0 %} + {% if invited_player.isLoaded() %} + + {% set i = i + 1 %} - - - {% endif %} - {% else %} - - - - {% endfor %} - -
Name
- {{ getPlayerLink(invited_player.getName(), true)|raw }} + + {{ getPlayerLink(invited_player.getName(), true)|raw }} - {% if isVice %} - - {% endif %} -
- No invited characters found. -
-
-
-
-
-
-
+ {% if isVice %} + + {% endif %} +
+ No invited characters found. +
+
+
+
+ + + + +
+
-
- - - - + + +
-
- - - - + + + +
-
- - - - {% if not logged %} - - - - {% else %} - {% if show_accept_invite > 0 %} - - - - {% endif %} +
+
- {{ include('buttons.login.html.twig') }} -
- -
+ + + - - -
+
+ + + + - - -
+
+ + + + {% if not logged %} + + + + {% else %} + {% if show_accept_invite > 0 %} + + + + {% endif %} - {% if isVice %} - - - + {% if isVice %} + + + - - - - {% endif %} + + + + {% endif %} - {% if players_from_account_in_guild|length > 0 %} - - - - {% endif %} - {% endif %} + {% if players_from_account_in_guild|length > 0 %} + + + + {% endif %} + {% endif %} - - - - - -
+ {{ include('buttons.login.html.twig') }} +
+ +
- {% set button_name = 'Invite Character' %} - {% set button_image = '_sbutton_invitecharacter' %} - {% include('buttons.base.html.twig') %} -
+ {% set button_name = 'Invite Character' %} + {% set button_image = '_sbutton_invitecharacter' %} + {% include('buttons.base.html.twig') %} +
- {% set button_name = 'Edit Ranks' %} - {% set button_image = '_sbutton_editranks' %} - {% include('buttons.base.html.twig') %} -
+ {% set button_name = 'Edit Ranks' %} + {% set button_image = '_sbutton_editranks' %} + {% include('buttons.base.html.twig') %} +
- {% set button_name = 'Leave Guild' %} - {% set button_image = '_sbutton_leaveguild' %} - {% include('buttons.base.html.twig') %} -
+ {% set button_name = 'Leave Guild' %} + {% set button_image = '_sbutton_leaveguild' %} + {% include('buttons.base.html.twig') %} +
- {{ include('buttons.back.html.twig') }} -
-
-
-
-
-
- - +
+
+ {{ include('buttons.back.html.twig') }} +
+
+
+
+ + + + +
+
+
From d17c547bcaf32c85308d162828c4f45d0bc13775 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 15 Feb 2023 17:12:56 +0100 Subject: [PATCH 013/232] add $params as optional parameter to hook twig function --- system/twig.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/twig.php b/system/twig.php index 87d2ad6f..4f3639d8 100644 --- a/system/twig.php +++ b/system/twig.php @@ -90,14 +90,14 @@ $function = new TwigFunction('truncate', function ($s, $n) { }); $twig->addFunction($function); -$function = new TwigFunction('hook', function ($hook) { +$function = new TwigFunction('hook', function ($hook, array $params = []) { global $hooks; if(is_string($hook)) { $hook = constant($hook); } - $hooks->trigger($hook); + $hooks->trigger($hook, $params); }); $twig->addFunction($function); From 61285b6b8c5a2aae8a1748d32171edc76e9fb78d Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 15 Feb 2023 17:32:48 +0100 Subject: [PATCH 014/232] small fix to routes with string --- system/router.php | 2 +- system/routes.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/router.php b/system/router.php index 4f3b6321..60d5268a 100644 --- a/system/router.php +++ b/system/router.php @@ -118,7 +118,7 @@ $dispatcher = FastRoute\cachedDispatcher(function (FastRoute\RouteCollector $r) $aliases = [ [':int', ':string', ':alphanum'], - [':\d+', ':[A-Za-z0-9-_%+\']+}', ':[A-Za-z0-9]+'], + [':\d+', ':[A-Za-z0-9-_%+\']+', ':[A-Za-z0-9]+'], ]; // apply aliases diff --git a/system/routes.php b/system/routes.php index c6dfa780..28d03168 100644 --- a/system/routes.php +++ b/system/routes.php @@ -30,7 +30,7 @@ return [ ['GET', 'account/confirm_email/{hash:[A-Za-z0-9-_]+}[/]', 'account/confirm_email.php'], ['GET', 'bans/{page:\d+}[/]', 'bans.php'], - [['GET', 'POST'], 'characters[/{name:string]', 'characters.php'], + [['GET', 'POST'], 'characters[/{name:string}]', 'characters.php'], ['GET', 'changelog[/{page:int}]', 'changelog.php'], ['GET', 'creatures[/{name:string}]', 'creatures.php'], From 3ed9a5d3d8981d861f03edf9a8790237c4bc8434 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 05:16:22 +0100 Subject: [PATCH 015/232] add hook: HOOK_GUILDS_AFTER_INVITED_CHARACTERS, for guild wars --- system/hooks.php | 4 +++- system/pages/guilds/show.php | 1 + system/templates/guilds.view.html.twig | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/system/hooks.php b/system/hooks.php index 448d40c0..3c4629d9 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -66,8 +66,10 @@ define('HOOK_ADMIN_LOGIN_AFTER_ACCOUNT', ++$i); define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i); define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i); define('HOOK_EMAIL_CONFIRMED', ++$i); +define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i); + const HOOK_FIRST = HOOK_STARTUP; -const HOOK_LAST = HOOK_EMAIL_CONFIRMED; +define('HOOK_LAST', $i); require_once LIBS . 'plugins.php'; class Hook diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index f4b4f15c..34420e23 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -148,6 +148,7 @@ if($db->hasColumn('players', 'guildnick')) $twig->display('guilds.view.html.twig', array( 'logo' => $guild_logo, + 'guild_id' => $guild->getId(), 'guild_name' => $guild_name, 'description' => $description, 'guild_owner' => $guild_owner->isLoaded() ? $guild_owner : null, diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 36efbc3d..a6d7c60e 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -265,6 +265,8 @@

+ {{ hook(constant('HOOK_GUILDS_AFTER_INVITED_CHARACTERS'), { 'guild_id': guild_id }) }} +
From c7ec1f44e9281db3a725f7da783b3dd2c7dece6e Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 06:57:46 +0100 Subject: [PATCH 016/232] Option to enable/disable plugin by renaming file + cleanup new function: getAllPluginsJson removeComments removed - json doesnt allow for comments anyway --- admin/pages/plugins.php | 48 ++++++--- system/functions.php | 13 ++- system/libs/plugins.php | 127 +++++++++++++---------- system/templates/admin.plugins.html.twig | 17 ++- 4 files changed, 129 insertions(+), 76 deletions(-) diff --git a/admin/pages/plugins.php b/admin/pages/plugins.php index 65132118..6072455b 100644 --- a/admin/pages/plugins.php +++ b/admin/pages/plugins.php @@ -23,13 +23,29 @@ if (isset($_REQUEST['uninstall'])) { } else { error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); } -} else if (isset($_FILES["plugin"]["name"])) { - $file = $_FILES["plugin"]; - $filename = $file["name"]; - $tmp_name = $file["tmp_name"]; - $type = $file["type"]; +} +else if (isset($_REQUEST['enable'])) { + $enable = $_REQUEST['enable']; + if (Plugins::enable($enable)) { + success('Successfully enabled plugin ' . $enable); + } else { + error('Error while enabling plugin ' . $enable . ': ' . Plugins::getError()); + } +} +else if (isset($_REQUEST['disable'])) { + $disable = $_REQUEST['disable']; + if (Plugins::disable($disable)) { + success('Successfully disabled plugin ' . $disable); + } else { + error('Error while disabling plugin ' . $disable . ': ' . Plugins::getError()); + } +} else if (isset($_FILES['plugin']['name'])) { + $file = $_FILES['plugin']; + $filename = $file['name']; + $tmp_name = $file['tmp_name']; + $type = $file['type']; - $name = explode(".", $filename); + $name = explode('.', $filename); $accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', 'application/octet-stream', 'application/zip-compressed'); if (isset($file['error'])) { @@ -90,21 +106,23 @@ if (isset($_REQUEST['uninstall'])) { } $plugins = array(); -foreach (get_plugins() as $plugin) { +foreach (get_plugins(true) as $plugin) { $string = file_get_contents(BASE . 'plugins/' . $plugin . '.json'); - $string = Plugins::removeComments($string); $plugin_info = json_decode($string, true); - if ($plugin_info == false) { + if (!$plugin_info) { warning('Cannot load plugin info ' . $plugin . '.json'); } else { + $disabled = (strpos($plugin, 'disabled.') !== false); + $pluginOriginal = ($disabled ? str_replace('disabled.', '', $plugin) : $plugin); $plugins[] = array( - 'name' => isset($plugin_info['name']) ? $plugin_info['name'] : '', - 'description' => isset($plugin_info['description']) ? $plugin_info['description'] : '', - 'version' => isset($plugin_info['version']) ? $plugin_info['version'] : '', - 'author' => isset($plugin_info['author']) ? $plugin_info['author'] : '', - 'contact' => isset($plugin_info['contact']) ? $plugin_info['contact'] : '', - 'file' => $plugin, + 'name' => $plugin_info['name'] ?? '', + 'description' => $plugin_info['description'] ?? '', + 'version' => $plugin_info['version'] ?? '', + 'author' => $plugin_info['author'] ?? '', + 'contact' => $plugin_info['contact'] ?? '', + 'file' => $pluginOriginal, + 'enabled' => !$disabled, 'uninstall' => isset($plugin_info['uninstall']) ); } diff --git a/system/functions.php b/system/functions.php index a2c7d202..d1184272 100644 --- a/system/functions.php +++ b/system/functions.php @@ -791,16 +791,21 @@ function get_templates() * Generates list of installed plugins * @return array $plugins */ -function get_plugins() +function get_plugins($disabled = false): array { - $ret = array(); + $ret = []; $path = PLUGINS; - foreach(scandir($path, 0) as $file) { + foreach(scandir($path, SCANDIR_SORT_DESCENDING) as $file) { $file_ext = pathinfo($file, PATHINFO_EXTENSION); $file_name = pathinfo($file, PATHINFO_FILENAME); - if ($file === '.' || $file === '..' || $file === 'disabled' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file)) + if ($file === '.' || $file === '..' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file)) { continue; + } + + if (!$disabled && strpos($file, 'disabled.') !== false) { + continue; + } $ret[] = str_replace('.json', '', $file_name); } diff --git a/system/libs/plugins.php b/system/libs/plugins.php index 3d9792b9..420c1cdd 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -10,7 +10,7 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) { +function is_sub_dir($path = NULL, $parent_folder = BASE) { //Get directory path minus last folder $dir = dirname($path); @@ -41,9 +41,9 @@ function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) { use Composer\Semver\Semver; class Plugins { - private static $warnings = array(); + private static $warnings = []; private static $error = null; - private static $plugin_json = array(); + private static $plugin_json = []; public static function getRoutes() { @@ -56,22 +56,8 @@ class Plugins { } $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 . ' - '; + foreach(self::getAllPluginsJson() as $plugin) { + $warningPreTitle = 'Plugin: ' . $plugin['name'] . ' - '; if (isset($plugin['routes'])) { foreach ($plugin['routes'] as $_name => $info) { @@ -161,28 +147,14 @@ class Plugins { } $hooks = []; - 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; - } - + foreach(self::getAllPluginsJson() as $plugin) { if (isset($plugin['hooks'])) { foreach ($plugin['hooks'] as $_name => $info) { if (defined('HOOK_'. $info['type'])) { $hook = constant('HOOK_'. $info['type']); $hooks[] = ['name' => $_name, 'type' => $hook, 'file' => $info['file']]; } else { - self::$warnings[] = 'Plugin: ' . $filename . '. Unknown event type: ' . $info['type']; + self::$warnings[] = 'Plugin: ' . $plugin['name'] . '. Unknown event type: ' . $info['type']; } } } @@ -195,6 +167,41 @@ class Plugins { return $hooks; } + public static function getAllPluginsJson($disabled = false) + { + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $tmp = ''; + if ($cache->fetch('plugins', $tmp)) { + return unserialize($tmp); + } + } + + $plugins = []; + foreach (get_plugins($disabled) as $filename) { + $string = file_get_contents(PLUGINS . $filename . '.json'); + $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; + } + + $plugins[] = $plugin; + } + + if ($cache->enabled()) { + $cache->set('plugins', serialize($plugins), 600); + } + + return $plugins; + } + public static function install($file) { global $db; @@ -235,7 +242,6 @@ class Plugins { } $string = file_get_contents($file_name); - $string = self::removeComments($string); $plugin_json = json_decode($string, true); self::$plugin_json = $plugin_json; if ($plugin_json == null) { @@ -435,7 +441,35 @@ class Plugins { return false; } - public static function uninstall($plugin_name) + public static function enable($pluginFileName): bool + { + return self::enableDisable($pluginFileName, true); + } + + public static function disable($pluginFileName): bool + { + return self::enableDisable($pluginFileName, false); + } + + private static function enableDisable($pluginFileName, $enable): bool + { + $filenameJson = $pluginFileName . '.json'; + $fileExist = is_file(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson); + if (!$fileExist) { + self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. File does not exist.'; + return false; + } + + $result = rename(PLUGINS . ($enable ? 'disabled.' : '') . $filenameJson, PLUGINS . ($enable ? '' : 'disabled.') . $filenameJson); + if (!$result) { + self::$error = 'Cannot ' . ($enable ? 'enable' : 'disable') . ' plugin: ' . $pluginFileName . '. Permission problem.'; + return false; + } + + return true; + } + + public static function uninstall($plugin_name): bool { $filename = BASE . 'plugins/' . $plugin_name . '.json'; if(!file_exists($filename)) { @@ -443,9 +477,8 @@ class Plugins { return false; } $string = file_get_contents($filename); - $string = self::removeComments($string); $plugin_info = json_decode($string, true); - if($plugin_info == false) { + if(!$plugin_info) { self::$error = 'Cannot load plugin info ' . $plugin_name . '.json'; return false; } @@ -527,22 +560,6 @@ class Plugins { return self::$plugin_json; } - public static function removeComments($string) { - $string = preg_replace('!/\*.*?\*/!s', '', $string); - $string = preg_replace('/\n\s*\n/', "\n", $string); - // Removes multi-line comments and does not create - // a blank line, also treats white spaces/tabs - $string = preg_replace('!^[ \t]*/\*.*?\*/[ \t]*[\r\n]!s', '', $string); - - // Removes single line '//' comments, treats blank characters - $string = preg_replace('![ \t]*//.*[ \t]*[\r\n]!', '', $string); - - // Strip blank lines - $string = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $string); - - return $string; - } - /** * Install menus * Helper function for plugins diff --git a/system/templates/admin.plugins.html.twig b/system/templates/admin.plugins.html.twig index 07d2c044..bffb82f3 100644 --- a/system/templates/admin.plugins.html.twig +++ b/system/templates/admin.plugins.html.twig @@ -6,6 +6,7 @@
+ @@ -16,6 +17,17 @@ {% for plugin in plugins %} + @@ -29,7 +41,8 @@ - {% endif %} + {% endif %} + {% endfor %} @@ -39,6 +52,6 @@ From d04e44f52f2583bed91cb85e86282ced1d7c8283 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 07:21:38 +0100 Subject: [PATCH 017/232] add info which plugin is going to be uninstalled --- system/functions.php | 2 +- system/templates/admin.plugins.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/functions.php b/system/functions.php index d1184272..e489ffb9 100644 --- a/system/functions.php +++ b/system/functions.php @@ -796,7 +796,7 @@ function get_plugins($disabled = false): array $ret = []; $path = PLUGINS; - foreach(scandir($path, SCANDIR_SORT_DESCENDING) as $file) { + foreach(scandir($path, SCANDIR_SORT_ASCENDING) as $file) { $file_ext = pathinfo($file, PATHINFO_EXTENSION); $file_name = pathinfo($file, PATHINFO_FILENAME); if ($file === '.' || $file === '..' || $file === 'example.json' || $file_ext !== 'json' || is_dir($path . $file)) { diff --git a/system/templates/admin.plugins.html.twig b/system/templates/admin.plugins.html.twig index bffb82f3..d6ffe7b2 100644 --- a/system/templates/admin.plugins.html.twig +++ b/system/templates/admin.plugins.html.twig @@ -38,7 +38,7 @@ + + + +
Enabled Name Version Author
+ {% if plugin.enabled %} + + Enabled + + {% else %} + + Disabled + + {% endif %} + {{ plugin.name }}
{{ plugin.description|raw }}
{{ plugin.file }}.json {% if plugin.uninstall %} - + {% endif %} From 58598742e88f21ab8d30007e7bde16143fcf509d Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 08:43:21 +0100 Subject: [PATCH 018/232] change spaces to tabs --- system/pages/houses.php | 264 +++++++++++----------- system/templates/houses.html.twig | 298 ++++++++++++------------- system/templates/houses.view.html.twig | 90 ++++---- 3 files changed, 326 insertions(+), 326 deletions(-) diff --git a/system/pages/houses.php b/system/pages/houses.php index db1a6992..de4bc943 100644 --- a/system/pages/houses.php +++ b/system/pages/houses.php @@ -14,17 +14,17 @@ $title = 'Houses'; $errors = array(); if(!$db->hasColumn('houses', 'name')) { - $errors[] = 'Houses list is not available on this server.'; + $errors[] = 'Houses list is not available on this server.'; - $twig->display('houses.html.twig', array( - 'errors' => $errors - )); + $twig->display('houses.html.twig', array( + 'errors' => $errors + )); return; } $rentType = trim(strtolower($config['lua']['houseRentPeriod'])); if($rentType != 'yearly' && $rentType != 'monthly' && $rentType != 'weekly' && $rentType != 'daily') - $rentType = 'never'; + $rentType = 'never'; $state = ''; $order = ''; @@ -32,116 +32,116 @@ $type = ''; if(isset($_GET['page']) && $_GET['page'] == 'view' && isset($_REQUEST['house'])) { - $beds = array("", "one", "two", "three", "fourth", "fifth"); - $houseName = $_REQUEST['house']; - $houseId = (Validator::number($_REQUEST['house']) ? $_REQUEST['house'] : -1); - $selectHouse = $db->query('SELECT * FROM ' . $db->tableName('houses') . ' WHERE ' . $db->fieldName('name') . ' LIKE ' . $db->quote($houseName) . ' OR `id` = ' . $db->quote($houseId)); + $beds = array("", "one", "two", "three", "fourth", "fifth"); + $houseName = $_REQUEST['house']; + $houseId = (Validator::number($_REQUEST['house']) ? $_REQUEST['house'] : -1); + $selectHouse = $db->query('SELECT * FROM ' . $db->tableName('houses') . ' WHERE ' . $db->fieldName('name') . ' LIKE ' . $db->quote($houseName) . ' OR `id` = ' . $db->quote($houseId)); - $house = array(); - if($selectHouse->rowCount() > 0) - { - $house = $selectHouse->fetch(); - $houseId = $house['id']; + $house = array(); + if($selectHouse->rowCount() > 0) + { + $house = $selectHouse->fetch(); + $houseId = $house['id']; - $title = $house['name'] . ' - ' . $title; + $title = $house['name'] . ' - ' . $title; - $imgPath = 'images/houses/' . $houseId . '.gif'; - if(!file_exists($imgPath)) { - $imgPath = 'images/houses/default.jpg'; - } + $imgPath = 'images/houses/' . $houseId . '.gif'; + if(!file_exists($imgPath)) { + $imgPath = 'images/houses/default.jpg'; + } - $bedsMessage = null; - $houseBeds = $house['beds']; - if($houseBeds > 0) - $bedsMessage = 'House have ' . (isset($beds[$houseBeds]) ? $beds[$houseBeds] : $houseBeds) . ' bed' . ($houseBeds > 1 ? 's' : ''); - else - $bedsMessage = 'This house dont have any beds'; + $bedsMessage = null; + $houseBeds = $house['beds']; + if($houseBeds > 0) + $bedsMessage = 'House have ' . (isset($beds[$houseBeds]) ? $beds[$houseBeds] : $houseBeds) . ' bed' . ($houseBeds > 1 ? 's' : ''); + else + $bedsMessage = 'This house dont have any beds'; - $houseOwner = $house['owner']; - if($houseOwner > 0) - { - $guild = NULL; - $owner = null; - if(isset($house['guild']) && $house['guild'] == 1) - { - $guild = new OTS_Guild(); - $guild->load($houseOwner); - $owner = getGuildLink($guild->getName()); - } - else - $owner = getCreatureName($houseOwner); + $houseOwner = $house['owner']; + if($houseOwner > 0) + { + $guild = NULL; + $owner = null; + if(isset($house['guild']) && $house['guild'] == 1) + { + $guild = new OTS_Guild(); + $guild->load($houseOwner); + $owner = getGuildLink($guild->getName()); + } + else + $owner = getCreatureName($houseOwner); - if($rentType != 'never' && $house['paid'] > 0) - { - $who = ''; - if($guild) - $who = $guild->getName(); - else - { - $player = new OTS_Player(); - $player->load($houseOwner); - if($player->isLoaded()) - { - $sexs = array('She', 'He'); - $who = $sexs[$player->getSex()]; - } - } - $owner .= ' ' . $who . ' has paid the rent until ' . date("M d Y, H:i:s", $house['paid']) . ' CEST.'; - } - } - } - else - $errors[] = 'House with name ' . $houseName . ' does not exists.'; + if($rentType != 'never' && $house['paid'] > 0) + { + $who = ''; + if($guild) + $who = $guild->getName(); + else + { + $player = new OTS_Player(); + $player->load($houseOwner); + if($player->isLoaded()) + { + $sexs = array('She', 'He'); + $who = $sexs[$player->getSex()]; + } + } + $owner .= ' ' . $who . ' has paid the rent until ' . date("M d Y, H:i:s", $house['paid']) . ' CEST.'; + } + } + } + else + $errors[] = 'House with name ' . $houseName . ' does not exists.'; - $twig->display('houses.view.html.twig', array( - 'errors' => $errors, - 'imgPath' => isset($imgPath) ? $imgPath : null, - 'houseName' => isset($house['name']) ? $house['name'] : null, - 'bedsMessage' => isset($bedsMessage) ? $bedsMessage : null, - 'houseSize' => isset($house['size']) ? $house['size'] : null, - 'houseRent' => isset($house['rent']) ? $house['rent'] : null, - 'owner' => isset($owner) ? $owner : null, - 'rentType' => isset($rentType) ? $rentType : null - )); + $twig->display('houses.view.html.twig', array( + 'errors' => $errors, + 'imgPath' => isset($imgPath) ? $imgPath : null, + 'houseName' => isset($house['name']) ? $house['name'] : null, + 'bedsMessage' => isset($bedsMessage) ? $bedsMessage : null, + 'houseSize' => isset($house['size']) ? $house['size'] : null, + 'houseRent' => isset($house['rent']) ? $house['rent'] : null, + 'owner' => isset($owner) ? $owner : null, + 'rentType' => isset($rentType) ? $rentType : null + )); - if (count($errors) > 0) { - return; - } + if (count($errors) > 0) { + return; + } } $cleanOldHouse = null; if(isset($config['lua']['houseCleanOld'])) { - $cleanOldHouse = (int)(eval('return ' . $config['lua']['houseCleanOld'] . ';') / (24 * 60 * 60)); + $cleanOldHouse = (int)(eval('return ' . $config['lua']['houseCleanOld'] . ';') / (24 * 60 * 60)); } $housesSearch = false; if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) && (isset($_POST['type']) || !$db->hasColumn('houses', 'guild'))) { - $townName = $config['towns'][$_POST['town']]; - $order = $_POST['order']; - $orderby = '`name`'; - if(!empty($order)) - { - if($order == 'size') - $orderby = '`size`'; - else if($order == 'rent') - $orderby = '`rent`'; - } + $townName = $config['towns'][$_POST['town']]; + $order = $_POST['order']; + $orderby = '`name`'; + if(!empty($order)) + { + if($order == 'size') + $orderby = '`size`'; + else if($order == 'rent') + $orderby = '`rent`'; + } - $town = 'town'; - if($db->hasColumn('houses', 'town_id')) - $town = 'town_id'; - else if($db->hasColumn('houses', 'townid')) - $town = 'townid'; + $town = 'town'; + if($db->hasColumn('houses', 'town_id')) + $town = 'town_id'; + else if($db->hasColumn('houses', 'townid')) + $town = 'townid'; - $whereby = '`' . $town . '` = ' .(int)$_POST['town']; - $state = $_POST['state']; - if(!empty($state)) - $whereby .= ' AND `owner` ' . ($state == 'free' ? '' : '!'). '= 0'; + $whereby = '`' . $town . '` = ' .(int)$_POST['town']; + $state = $_POST['state']; + if(!empty($state)) + $whereby .= ' AND `owner` ' . ($state == 'free' ? '' : '!'). '= 0'; - $type = isset($_POST['type']) ? $_POST['type'] : NULL; - if($type == 'guildhalls' && !$db->hasColumn('houses', 'guild')) - $type = 'all'; + $type = isset($_POST['type']) ? $_POST['type'] : NULL; + if($type == 'guildhalls' && !$db->hasColumn('houses', 'guild')) + $type = 'all'; if (!empty($type) && $type != 'all') { @@ -158,49 +158,49 @@ if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) && } } - $houses_info = $db->query('SELECT * FROM `houses` WHERE ' . $whereby. ' ORDER BY ' . $orderby); + $houses_info = $db->query('SELECT * FROM `houses` WHERE ' . $whereby. ' ORDER BY ' . $orderby); - $players_info = $db->query("SELECT `houses`.`id` AS `houseid` , `players`.`name` AS `ownername` FROM `houses` , `players` , `accounts` WHERE `players`.`id` = `houses`.`owner` AND `accounts`.`id` = `players`.`account_id`"); - $players = array(); - foreach($players_info->fetchAll() as $player) - $players[$player['houseid']] = array('name' => $player['ownername']); + $players_info = $db->query("SELECT `houses`.`id` AS `houseid` , `players`.`name` AS `ownername` FROM `houses` , `players` , `accounts` WHERE `players`.`id` = `houses`.`owner` AND `accounts`.`id` = `players`.`account_id`"); + $players = array(); + foreach($players_info->fetchAll() as $player) + $players[$player['houseid']] = array('name' => $player['ownername']); - $houses = array(); - foreach($houses_info->fetchAll() as $house) - { - $owner = isset($players[$house['id']]) ? $players[$house['id']] : array(); + $houses = array(); + foreach($houses_info->fetchAll() as $house) + { + $owner = isset($players[$house['id']]) ? $players[$house['id']] : array(); - $houseRent = null; - if($db->hasColumn('houses', 'guild') && $house['guild'] == 1 && $house['owner'] != 0) - { - $guild = new OTS_Guild(); - $guild->load($house['owner']); - $houseRent = 'Rented by ' . getGuildLink($guild->getName()); - } - else - { - if(!empty($owner['name'])) - $houseRent = 'Rented by ' . getPlayerLink($owner['name']); - else - $houseRent = 'Free'; - } + $houseRent = null; + if($db->hasColumn('houses', 'guild') && $house['guild'] == 1 && $house['owner'] != 0) + { + $guild = new OTS_Guild(); + $guild->load($house['owner']); + $houseRent = 'Rented by ' . getGuildLink($guild->getName()); + } + else + { + if(!empty($owner['name'])) + $houseRent = 'Rented by ' . getPlayerLink($owner['name']); + else + $houseRent = 'Free'; + } - $houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => $house['size'], 'rent' => $house['rent'], 'rentedBy' => $houseRent); - } + $houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => $house['size'], 'rent' => $house['rent'], 'rentedBy' => $houseRent); + } - $housesSearch = true; + $housesSearch = true; } $guild = $db->hasColumn('houses', 'guild') ? ' or guildhall' : ''; $twig->display('houses.html.twig', array( - 'state' => $state, - 'order' => $order, - 'type' => $type, - 'houseType' => $type == 'guildhalls' ? 'Guildhalls' : 'Houses and Flats', - 'townName' => isset($townName) ? $townName : null, - 'townId' => isset($_POST['town']) ? $_POST['town'] : null, - 'guild' => $guild, - 'cleanOldHouse' => isset($cleanOld) ? $cleanOld : null, - 'housesSearch' => $housesSearch, - 'houses' => isset($houses) ? $houses : null -)); \ No newline at end of file + 'state' => $state, + 'order' => $order, + 'type' => $type, + 'houseType' => $type == 'guildhalls' ? 'Guildhalls' : 'Houses and Flats', + 'townName' => isset($townName) ? $townName : null, + 'townId' => isset($_POST['town']) ? $_POST['town'] : null, + 'guild' => $guild, + 'cleanOldHouse' => isset($cleanOld) ? $cleanOld : null, + 'housesSearch' => $housesSearch, + 'houses' => isset($houses) ? $houses : null +)); diff --git a/system/templates/houses.html.twig b/system/templates/houses.html.twig index 4e75942c..20e8926d 100644 --- a/system/templates/houses.html.twig +++ b/system/templates/houses.html.twig @@ -1,171 +1,171 @@
- {% if errors is not empty %} - {% for error in errors %} -

{{ error }}

- {% endfor %} - {% else %} - -
-
- - - - -
House Search
- - - - -
-
+ {% if errors is not empty %} + {% for error in errors %} +

{{ error }}

+ {% endfor %} + {% else %} +
+
+
+ + + + +
House Search
+ + + + +
+
- - + + + {% endfor %} + {% endif %} + +
-
- Here you can see the list of all available houses, flats{{ guildString }}. - Click on any view button to get more information about a house or adjust - the search criteria and start a new search. -

- {% if cleanOldHouse is not empty or rentType != 'never' %} - Every morning during global server save there is automatic house cleaning. Server delete house owners who have not logged in last {{ cleanOldHouse }} days{% if rentType != 'never' %} or have not paid {{ rentType }} house rent. Remember to leave money for a rent in {% if config.lua.bankSystem is not empty %}your house bank or {% else %}depo in same city where you have house!{% endif %}{% else %}.{% endif %} -

- {% endif %} +
+
+ Here you can see the list of all available houses, flats{{ guildString }}. + Click on any view button to get more information about a house or adjust + the search criteria and start a new search. +

+ {% if cleanOldHouse is not empty or rentType != 'never' %} + Every morning during global server save there is automatic house cleaning. Server delete house owners who have not logged in last {{ cleanOldHouse }} days{% if rentType != 'never' %} or have not paid {{ rentType }} house rent. Remember to leave money for a rent in {% if config.lua.bankSystem is not empty %}your house bank or {% else %}depo in same city where you have house!{% endif %}{% else %}.{% endif %} +

+ {% endif %} - {% if houses is not empty or housesSearch %} - - - - - + {% if houses is not empty or housesSearch %} +
Available {{ houseType }}{% if townName is not empty %} in {{ townName }}{% endif %} on {{ config.lua.serverName }}
+ + + + - - {% if houses is not empty %} - - - + + {% if houses is not empty %} + + + - - - {% elseif housesSearch %} - - {% endif %} - + + + {% elseif housesSearch %} + + {% endif %} + - {% if houses is not empty %} - {% set i = 0 %} - {% for house in houses %} - {% set i = i + 1 %} - - + {% if houses is not empty %} + {% set i = 0 %} + {% for house in houses %} + {% set i = i + 1 %} + + - + - + - + - - - {% endfor %} - {% endif %} - -
Available {{ houseType }}{% if townName is not empty %} in {{ townName }}{% endif %} on {{ config.lua.serverName }}
NameSizeRent
NameSizeRentStatus No {{ houseType }} with specified criterias.
Status No {{ houseType }} with specified criterias.
- {{ house.name }} -
+ {{ house.name }} + - {{ house.size }} - + {{ house.size }} + - {{ house.rent }} golds - + {{ house.rent }} golds + - {{ house.rentedBy|raw }} - + {{ house.rentedBy|raw }} + -
- - {{ include('buttons.view.html.twig') }} -
-
-
- {% endif %} +
+
+ + {{ include('buttons.view.html.twig') }} +
+
+
+ {% endif %} -
- - - - - + +
House Search
+ + + + - - - - - + + + + + - - + + + +
+ {% endfor %} + - + +
+ - - + +
+ + - - - - -
House Search
TownStatusOrder
TownStatusOrder
- {% set checked = false %} - {% for id, name in config.towns if id > 0 %} - {% if ((townId is empty and name is not empty) or id == townId) and not checked %} - {% set variable = "checked" %} - {% set checked = true %} - {% else %} - {% set variable = "" %} - {% endif %} +
+ {% set checked = false %} + {% for id, name in config.towns if id > 0 %} + {% if ((townId is empty and name is not empty) or id == townId) and not checked %} + {% set variable = "checked" %} + {% set checked = true %} + {% else %} + {% set variable = "" %} + {% endif %} - - -
- {% endfor %} -
- -
+
+ +
- -
+ +
- -
-
- -
+
+ +
- -
+ +
- -
-
- -
- -
- -
-
-
+
+ +
+ +
+ +
+
+
- - - - - - -
- {{ include('buttons.submit.html.twig') }} -
- -
- - - - {% endif %} - \ No newline at end of file + + + + + + +
+ {{ include('buttons.submit.html.twig') }} +
+ + + + + + {% endif %} + diff --git a/system/templates/houses.view.html.twig b/system/templates/houses.view.html.twig index 31fc5c23..64baad76 100644 --- a/system/templates/houses.view.html.twig +++ b/system/templates/houses.view.html.twig @@ -1,51 +1,51 @@
- {% if errors is not empty %} - {% for error in errors %} -

{{ error }}

- {% endfor %} - {% else %} - -
-
- - - - -
{{ houseName }}
- - - - -
-
+ {% if errors is not empty %} + {% for error in errors %} +

{{ error }}

+ {% endfor %} + {% else %} +
+
+
+ + + + +
{{ houseName }}
+ + + + +
+
- - + +
-
- - - - + - -
- {{ bedsMessage }} and has a size of {{ houseSize }} square meters. +
+
+ + + + - -
+ {{ bedsMessage }} and has a size of {{ houseSize }} square meters. - {% if rentType != 'never' %} - The {{ rentType }} is {{ houseRent }} gold and will be debited to the bank account on {{ config.lua.serverName }}. - {% endif %} -
+ {% if rentType != 'never' %} + The {{ rentType }} is {{ houseRent }} gold and will be debited to the bank account on {{ config.lua.serverName }}. + {% endif %} +
- {% if owner is not empty %} - The house has been rented by {{ owner|raw }}. - {% else %} - No one has bought this house yet. - {% endif %} -
-
-
- {% endif %} + {% if owner is not empty %} + The house has been rented by {{ owner|raw }}. + {% else %} + No one has bought this house yet. + {% endif %} +
+
+ + + + {% endif %} -

\ No newline at end of file +

From 9a475f2c574192918e7b3f10ccb43db64daa0486 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 08:44:17 +0100 Subject: [PATCH 019/232] fix for othire where size is saved in houses.tiles --- system/pages/houses.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/pages/houses.php b/system/pages/houses.php index de4bc943..f548d23b 100644 --- a/system/pages/houses.php +++ b/system/pages/houses.php @@ -165,6 +165,8 @@ if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) && foreach($players_info->fetchAll() as $player) $players[$player['houseid']] = array('name' => $player['ownername']); + $hasTilesColumn = $db->hasColumn('houses', 'tiles'); + $houses = array(); foreach($houses_info->fetchAll() as $house) { @@ -185,7 +187,7 @@ if(isset($_POST['town']) && isset($_POST['state']) && isset($_POST['order']) && $houseRent = 'Free'; } - $houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => $house['size'], 'rent' => $house['rent'], 'rentedBy' => $houseRent); + $houses[] = array('owner' => $owner, 'name' => $house['name'], 'size' => ($hasTilesColumn ? $house['tiles'] : $house['size']), 'rent' => $house['rent'], 'rentedBy' => $houseRent); } $housesSearch = true; From 3a2870a6bb589da890c8d440a45b22a0c22246c3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 16 Feb 2023 10:06:08 +0100 Subject: [PATCH 020/232] 760 is correct permission --- README.md | 2 +- install/includes/twig_error.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6fabc570..8edd3cbc 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Official website: https://my-aac.org chmod 660 images/guilds chmod 660 images/houses chmod 660 images/gallery - chmod -R 770 system/cache + chmod -R 760 system/cache Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser. diff --git a/install/includes/twig_error.html b/install/includes/twig_error.html index 40daedec..aea25001 100644 --- a/install/includes/twig_error.html +++ b/install/includes/twig_error.html @@ -1,4 +1,4 @@ -We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):

chown -R www-data.www-data /var/www/*
chmod -R 660 system/cache +We have detected that you don't have access to write to the system/cache directory. Under linux you can fix it by using this two command, where first one should be enough (for apache):

chown -R www-data.www-data /var/www/*
chmod -R 760 system/cache ").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t(" ",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter; -this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.spinner",{version:"1.12.1",defaultElement:"",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("
").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("
").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("
").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("
").attr("role","tooltip"),s=t("
").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip}); \ No newline at end of file +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(V){"use strict";V.ui=V.ui||{};V.ui.version="1.13.2";var n,i=0,a=Array.prototype.hasOwnProperty,r=Array.prototype.slice;V.cleanData=(n=V.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=V._data(i,"events"))&&e.remove&&V(i).triggerHandler("remove");n(t)}),V.widget=function(t,i,e){var s,n,o,a={},r=t.split(".")[0],l=r+"-"+(t=t.split(".")[1]);return e||(e=i,i=V.Widget),Array.isArray(e)&&(e=V.extend.apply(null,[{}].concat(e))),V.expr.pseudos[l.toLowerCase()]=function(t){return!!V.data(t,l)},V[r]=V[r]||{},s=V[r][t],n=V[r][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},V.extend(n,s,{version:e.version,_proto:V.extend({},e),_childConstructors:[]}),(o=new i).options=V.widget.extend({},o.options),V.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}a[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=V.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},a,{constructor:n,namespace:r,widgetName:t,widgetFullName:l}),s?(V.each(s._childConstructors,function(t,e){var i=e.prototype;V.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),V.widget.bridge(t,n),n},V.widget.extend=function(t){for(var e,i,s=r.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=V(e||this.defaultElement||this)[0],this.element=V(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=V(),this.hoverable=V(),this.focusable=V(),this.classesElementLookup={},e!==this&&(V.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=V(e.style?e.ownerDocument:e.document||e),this.window=V(this.document[0].defaultView||this.document[0].parentWindow)),this.options=V.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:V.noop,_create:V.noop,_init:V.noop,destroy:function(){var i=this;this._destroy(),V.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:V.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return V.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=V.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return V("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(k(s),k(n))?o.important="horizontal":o.important="vertical",u.using.call(this,t,o)}),a.offset(V.extend(h,{using:t}))})},V.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,a=s-o,r=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0")[0],w=d.each;function P(t){return null==t?t+"":"object"==typeof t?p[e.call(t)]||"object":typeof t}function M(t,e,i){var s=v[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:Math.min(s.max,Math.max(0,t)))}function S(s){var n=m(),o=n._rgba=[];return s=s.toLowerCase(),w(g,function(t,e){var i=e.re.exec(s),i=i&&e.parse(i),e=e.space||"rgba";if(i)return i=n[e](i),n[_[e].cache]=i[_[e].cache],o=n._rgba=i._rgba,!1}),o.length?("0,0,0,0"===o.join()&&d.extend(o,B.transparent),n):B[s]}function H(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}y.style.cssText="background-color:rgba(1,1,1,.5)",b.rgba=-1o.mod/2?s+=o.mod:s-n>o.mod/2&&(s-=o.mod)),l[i]=M((n-s)*a+s,e)))}),this[e](l)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=m(t)._rgba;return m(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null!=t?t:2
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return i.wrap(t),i[0]!==n&&!V.contains(i[0],n)||V(n).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(V.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),V.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!V.contains(t[0],e)||V(e).trigger("focus")),t}}),V.extend(V.effects,{version:"1.13.2",define:function(t,e,i){return i||(i=e,e="effect"),V.effects.effect[t]=i,V.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,e="vertical"!==i?(e||100)/100:1;return{height:t.height()*e,width:t.width()*s,outerHeight:t.outerHeight()*e,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(j+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=j+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){V.effects.restoreStyle(t),V.effects.removePlaceholder(t)},setTransition:function(s,t,n,o){return o=o||{},V.each(t,function(t,e){var i=s.cssUnit(e);0
");l.appendTo("body").addClass(t.className).css({top:s.top-a,left:s.left-r,height:i.innerHeight(),width:i.innerWidth(),position:n?"fixed":"absolute"}).animate(o,t.duration,t.easing,function(){l.remove(),"function"==typeof e&&e()})}}),V.fx.step.clip=function(t){t.clipInit||(t.start=V(t.elem).cssClip(),"string"==typeof t.end&&(t.end=G(t.end,t.elem)),t.clipInit=!0),V(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},Y={},V.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){Y[t]=function(t){return Math.pow(t,e+2)}}),V.extend(Y,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),V.each(Y,function(t,e){V.easing["easeIn"+t]=e,V.easing["easeOut"+t]=function(t){return 1-e(1-t)},V.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});y=V.effects,V.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=V(this),n=t.direction||"up",o=s.cssClip(),a={clip:V.extend({},o)},r=V.effects.createPlaceholder(s);a.clip[i[n][0]]=a.clip[i[n][1]],"show"===t.mode&&(s.cssClip(a.clip),r&&r.css(V.effects.clipToBox(a)),a.clip=o),r&&r.animate(V.effects.clipToBox(a),t.duration,t.easing),s.animate(a,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("bounce",function(t,e){var i,s,n=V(this),o=t.mode,a="hide"===o,r="show"===o,l=t.direction||"up",h=t.distance,c=t.times||5,o=2*c+(r||a?1:0),u=t.duration/o,d=t.easing,p="up"===l||"down"===l?"top":"left",f="up"===l||"left"===l,g=0,t=n.queue().length;for(V.effects.createPlaceholder(n),l=n.css(p),h=h||n["top"==p?"outerHeight":"outerWidth"]()/3,r&&((s={opacity:1})[p]=l,n.css("opacity",0).css(p,f?2*-h:2*h).animate(s,u,d)),a&&(h/=Math.pow(2,c-1)),(s={})[p]=l;g
").css({position:"absolute",visibility:"visible",left:-s*p,top:-i*f}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:p,height:f,left:n+(u?a*p:0),top:o+(u?r*f:0),opacity:u?0:1}).animate({left:n+(u?0:a*p),top:o+(u?0:r*f),opacity:u?1:0},t.duration||500,t.easing,m)}),V.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;V(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("fold","hide",function(e,t){var i=V(this),s=e.mode,n="show"===s,o="hide"===s,a=e.size||15,r=/([0-9]+)%/.exec(a),l=!!e.horizFirst?["right","bottom"]:["bottom","right"],h=e.duration/2,c=V.effects.createPlaceholder(i),u=i.cssClip(),d={clip:V.extend({},u)},p={clip:V.extend({},u)},f=[u[l[0]],u[l[1]]],s=i.queue().length;r&&(a=parseInt(r[1],10)/100*f[o?0:1]),d.clip[l[0]]=a,p.clip[l[0]]=a,p.clip[l[1]]=0,n&&(i.cssClip(p.clip),c&&c.css(V.effects.clipToBox(p)),p.clip=u),i.queue(function(t){c&&c.animate(V.effects.clipToBox(d),h,e.easing).animate(V.effects.clipToBox(p),h,e.easing),t()}).animate(d,h,e.easing).animate(p,h,e.easing).queue(t),V.effects.unshift(i,s,4)}),V.effects.define("highlight","show",function(t,e){var i=V(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),V.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("size",function(s,e){var n,i=V(this),t=["fontSize"],o=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],a=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],r=s.mode,l="effect"!==r,h=s.scale||"both",c=s.origin||["middle","center"],u=i.css("position"),d=i.position(),p=V.effects.scaledDimensions(i),f=s.from||p,g=s.to||V.effects.scaledDimensions(i,0);V.effects.createPlaceholder(i),"show"===r&&(r=f,f=g,g=r),n={from:{y:f.height/p.height,x:f.width/p.width},to:{y:g.height/p.height,x:g.width/p.width}},"box"!==h&&"both"!==h||(n.from.y!==n.to.y&&(f=V.effects.setTransition(i,o,n.from.y,f),g=V.effects.setTransition(i,o,n.to.y,g)),n.from.x!==n.to.x&&(f=V.effects.setTransition(i,a,n.from.x,f),g=V.effects.setTransition(i,a,n.to.x,g))),"content"!==h&&"both"!==h||n.from.y!==n.to.y&&(f=V.effects.setTransition(i,t,n.from.y,f),g=V.effects.setTransition(i,t,n.to.y,g)),c&&(c=V.effects.getBaseline(c,p),f.top=(p.outerHeight-f.outerHeight)*c.y+d.top,f.left=(p.outerWidth-f.outerWidth)*c.x+d.left,g.top=(p.outerHeight-g.outerHeight)*c.y+d.top,g.left=(p.outerWidth-g.outerWidth)*c.x+d.left),delete f.outerHeight,delete f.outerWidth,i.css(f),"content"!==h&&"both"!==h||(o=o.concat(["marginTop","marginBottom"]).concat(t),a=a.concat(["marginLeft","marginRight"]),i.find("*[width]").each(function(){var t=V(this),e=V.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},e={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=V.effects.setTransition(t,o,n.from.y,i),e=V.effects.setTransition(t,o,n.to.y,e)),n.from.x!==n.to.x&&(i=V.effects.setTransition(t,a,n.from.x,i),e=V.effects.setTransition(t,a,n.to.x,e)),l&&V.effects.saveStyle(t),t.css(i),t.animate(e,s.duration,s.easing,function(){l&&V.effects.restoreStyle(t)})})),i.animate(g,{queue:!1,duration:s.duration,easing:s.easing,complete:function(){var t=i.offset();0===g.opacity&&i.css("opacity",f.opacity),l||(i.css("position","static"===u?"relative":u).offset(t),V.effects.saveStyle(i)),e()}})}),V.effects.define("scale",function(t,e){var i=V(this),s=t.mode,s=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),s=V.extend(!0,{from:V.effects.scaledDimensions(i),to:V.effects.scaledDimensions(i,s,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(s.from.opacity=1,s.to.opacity=0),V.effects.effect.size.call(this,s,e)}),V.effects.define("puff","hide",function(t,e){t=V.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});V.effects.effect.scale.call(this,t,e)}),V.effects.define("pulsate","show",function(t,e){var i=V(this),s=t.mode,n="show"===s,o=2*(t.times||5)+(n||"hide"===s?1:0),a=t.duration/o,r=0,l=1,s=i.queue().length;for(!n&&i.is(":visible")||(i.css("opacity",0).show(),r=1);l li > :first-child").add(t.find("> :not(li)").even())},heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=V(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||!1!==t.active&&null!=t.active||(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():V()}},_createIcons:function(){var t,e=this.options.icons;e&&(t=V(""),this._addClass(t,"ui-accordion-header-icon","ui-icon "+e.header),t.prependTo(this.headers),t=this.active.children(".ui-accordion-header-icon"),this._removeClass(t,e.header)._addClass(t,null,e.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){"active"!==t?("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons())):this._activate(e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var e=V.ui.keyCode,i=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case e.RIGHT:case e.DOWN:n=this.headers[(s+1)%i];break;case e.LEFT:case e.UP:n=this.headers[(s-1+i)%i];break;case e.SPACE:case e.ENTER:this._eventHandler(t);break;case e.HOME:n=this.headers[0];break;case e.END:n=this.headers[i-1]}n&&(V(t.target).attr("tabIndex",-1),V(n).attr("tabIndex",0),V(n).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===V.ui.keyCode.UP&&t.ctrlKey&&V(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),!1===t.active&&!0===t.collapsible||!this.headers.length?(t.active=!1,this.active=V()):!1===t.active?this._activate(0):this.active.length&&!V.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=V()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;"function"==typeof this.options.header?this.headers=this.options.header(this.element):this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var i,t=this.options,e=t.heightStyle,s=this.element.parent();this.active=this._findActive(t.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=V(this),e=t.uniqueId().attr("id"),i=t.next(),s=i.uniqueId().attr("id");t.attr("aria-controls",s),i.attr("aria-labelledby",e)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(t.event),"fill"===e?(i=s.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=V(this).outerHeight(!0)}),this.headers.next().each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.headers.next().each(function(){var t=V(this).is(":visible");t||V(this).show(),i=Math.max(i,V(this).css("height","").height()),t||V(this).hide()}).height(i))},_activate:function(t){t=this._findActive(t)[0];t!==this.active[0]&&(t=t||this.active[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):V()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():s.next(),r=i.next(),a={oldHeader:i,oldPanel:r,newHeader:o?V():s,newPanel:a};t.preventDefault(),n&&!e.collapsible||!1===this._trigger("beforeActivate",t,a)||(e.active=!o&&this.headers.index(s),this.active=n?V():s,this._toggle(a),this._removeClass(i,"ui-accordion-header-active","ui-state-active"),e.icons&&(i=i.children(".ui-accordion-header-icon"),this._removeClass(i,null,e.icons.activeHeader)._addClass(i,null,e.icons.header)),n||(this._removeClass(s,"ui-accordion-header-collapsed")._addClass(s,"ui-accordion-header-active","ui-state-active"),e.icons&&(n=s.children(".ui-accordion-header-icon"),this._removeClass(n,null,e.icons.header)._addClass(n,null,e.icons.activeHeader)),this._addClass(s.next(),"ui-accordion-content-active")))},_toggle:function(t){var e=t.newPanel,i=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=e,this.prevHide=i,this.options.animate?this._animate(e,i,t):(i.hide(),e.show(),this._toggleComplete(t)),i.attr({"aria-hidden":"true"}),i.prev().attr({"aria-selected":"false","aria-expanded":"false"}),e.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):e.length&&this.headers.filter(function(){return 0===parseInt(V(this).attr("tabIndex"),10)}).attr("tabIndex",-1),e.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,i,e){var s,n,o,a=this,r=0,l=t.css("box-sizing"),h=t.length&&(!i.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=V(t.target),i=V(V.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){V.contains(this.element[0],V.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=V(t.target).closest(".ui-menu-item"),i=V(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=V(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case V.ui.keyCode.PAGE_UP:this.previousPage(t);break;case V.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case V.ui.keyCode.HOME:this._move("first","first",t);break;case V.ui.keyCode.END:this._move("last","last",t);break;case V.ui.keyCode.UP:this.previous(t);break;case V.ui.keyCode.DOWN:this.next(t);break;case V.ui.keyCode.LEFT:this.collapse(t);break;case V.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case V.ui.keyCode.ENTER:case V.ui.keyCode.SPACE:this._activate(t);break;case V.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=V(this),e=t.prev(),i=V("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=V(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!V.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(V.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(V.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=V("
    ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){V(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(V("
    ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==V.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=V("
    ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||V.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?V(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(V.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=V.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(V("
    ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),V.extend(V.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(V.ui.autocomplete.escapeRegex(e),"i");return V.grep(t,function(t){return i.test(t.label||t.value||t)})}}),V.widget("ui.autocomplete",V.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});V.ui.autocomplete;var tt=/ui-corner-([a-z]){2,6}/g;V.widget("ui.controlgroup",{version:"1.13.2",defaultElement:"
    ",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var o=this,a=[];V.each(this.options.items,function(s,t){var e,n={};if(t)return"controlgroupLabel"===s?((e=o.element.find(t)).each(function(){var t=V(this);t.children(".ui-controlgroup-label-contents").length||t.contents().wrapAll("")}),o._addClass(e,null,"ui-widget ui-widget-content ui-state-default"),void(a=a.concat(e.get()))):void(V.fn[s]&&(n=o["_"+s+"Options"]?o["_"+s+"Options"]("middle"):{classes:{}},o.element.find(t).each(function(){var t=V(this),e=t[s]("instance"),i=V.widget.extend({},n);"button"===s&&t.parent(".ui-spinner").length||((e=e||t[s]()[s]("instance"))&&(i.classes=o._resolveClassesValues(i.classes,e)),t[s](i),i=t[s]("widget"),V.data(i[0],"ui-controlgroup-data",e||t[s]("instance")),a.push(i[0]))})))}),this.childWidgets=V(V.uniqueSort(a)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var t=V(this).data("ui-controlgroup-data");t&&t[e]&&t[e]()})},_updateCornerClass:function(t,e){e=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,"ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"),this._addClass(t,null,e)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){t=this._buildSimpleOptions(t,"ui-spinner");return t.classes["ui-spinner-up"]="",t.classes["ui-spinner-down"]="",t},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e&&"auto",classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(i,s){var n={};return V.each(i,function(t){var e=s.options.classes[t]||"",e=String.prototype.trim.call(e.replace(tt,""));n[t]=(e+" "+i[t]).replace(/\s+/g," ")}),n},_setOption:function(t,e){"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"!==t?this.refresh():this._callChildMethod(e?"disable":"enable")},refresh:function(){var n,o=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),n=this.childWidgets,(n=this.options.onlyVisible?n.filter(":visible"):n).length&&(V.each(["first","last"],function(t,e){var i,s=n[e]().data("ui-controlgroup-data");s&&o["_"+s.widgetName+"Options"]?((i=o["_"+s.widgetName+"Options"](1===n.length?"only":e)).classes=o._resolveClassesValues(i.classes,s),s.element[s.widgetName](i)):o._updateCornerClass(n[e](),e)}),this._callChildMethod("refresh"))}});V.widget("ui.checkboxradio",[V.ui.formResetMixin,{version:"1.13.2",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var t,e=this._super()||{};return this._readType(),t=this.element.labels(),this.label=V(t[t.length-1]),this.label.length||V.error("No label found for checkboxradio widget"),this.originalLabel="",(t=this.label.contents().not(this.element[0])).length&&(this.originalLabel+=t.clone().wrapAll("
    ").parent().html()),this.originalLabel&&(e.label=this.originalLabel),null!=(t=this.element[0].disabled)&&(e.disabled=t),e},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var t=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===t&&/radio|checkbox/.test(this.type)||V.error("Can't create checkboxradio on element.nodeName="+t+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var t=this.element[0].name,e="input[name='"+V.escapeSelector(t)+"']";return t?(this.form.length?V(this.form[0].elements).filter(e):V(e).filter(function(){return 0===V(this)._form().length})).not(this.element):V([])},_toggleClasses:function(){var t=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",t)._toggleClass(this.icon,null,"ui-icon-blank",!t),"radio"===this.type&&this._getRadioGroup().each(function(){var t=V(this).checkboxradio("instance");t&&t._removeClass(t.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){if("label"!==t||e){if(this._super(t,e),"disabled"===t)return this._toggleClass(this.label,null,"ui-state-disabled",e),void(this.element[0].disabled=e);this.refresh()}},_updateIcon:function(t){var e="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=V(""),this.iconSpace=V(" "),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(e+=t?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,t?"ui-icon-blank":"ui-icon-check")):e+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",e),t||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),(t=this.iconSpace?t.not(this.iconSpace[0]):t).remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]);var et;V.ui.checkboxradio;V.widget("ui.button",{version:"1.13.2",defaultElement:"
    "+(0
    ":""):"")}f+=_}return f+=F,t._keyEvent=!1,f},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var l,h,c,u,d,p,f=this._get(t,"changeMonth"),g=this._get(t,"changeYear"),m=this._get(t,"showMonthAfterYear"),_=this._get(t,"selectMonthLabel"),v=this._get(t,"selectYearLabel"),b="
    ",y="";if(o||!f)y+=""+a[e]+"";else{for(l=s&&s.getFullYear()===i,h=n&&n.getFullYear()===i,y+=""}if(m||(b+=y+(!o&&f&&g?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!g)b+=""+i+"";else{for(a=this._get(t,"yearRange").split(":"),u=(new Date).getFullYear(),d=(_=function(t){t=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?u+parseInt(t,10):parseInt(t,10);return isNaN(t)?u:t})(a[0]),p=Math.max(d,_(a[1]||"")),d=s?Math.max(d,s.getFullYear()):d,p=n?Math.min(p,n.getFullYear()):p,t.yearshtml+="",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),m&&(b+=(!o&&f&&g?"":" ")+y),b+="
    "},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),e=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),e=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,e)));t.selectedDay=e.getDate(),t.drawMonth=t.selectedMonth=e.getMonth(),t.drawYear=t.selectedYear=e.getFullYear(),"M"!==i&&"Y"!==i||this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),t=this._getMinMaxDate(t,"max"),e=i&&e=i.getTime())&&(!s||e.getTime()<=s.getTime())&&(!n||e.getFullYear()>=n)&&(!o||e.getFullYear()<=o)},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return{shortYearCutoff:e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);e=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),e,this._getFormatConfig(t))}}),V.fn.datepicker=function(t){if(!this.length)return this;V.datepicker.initialized||(V(document).on("mousedown",V.datepicker._checkExternalClick),V.datepicker.initialized=!0),0===V("#"+V.datepicker._mainDivId).length&&V("body").append(V.datepicker.dpDiv);var e=Array.prototype.slice.call(arguments,1);return"string"==typeof t&&("isDisabled"===t||"getDate"===t||"widget"===t)||"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this[0]].concat(e)):this.each(function(){"string"==typeof t?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this].concat(e)):V.datepicker._attachDatepicker(this,t)})},V.datepicker=new st,V.datepicker.initialized=!1,V.datepicker.uuid=(new Date).getTime(),V.datepicker.version="1.13.2";V.datepicker,V.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var rt=!1;V(document).on("mouseup",function(){rt=!1});V.widget("ui.mouse",{version:"1.13.2",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(t){if(!0===V.data(t.target,e.widgetName+".preventClickEvent"))return V.removeData(t.target,e.widgetName+".preventClickEvent"),t.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!rt){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var e=this,i=1===t.which,s=!("string"!=typeof this.options.cancel||!t.target.nodeName)&&V(t.target).closest(this.options.cancel).length;return i&&!s&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(t),!this._mouseStarted)?(t.preventDefault(),!0):(!0===V.data(t.target,this.widgetName+".preventClickEvent")&&V.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return e._mouseMove(t)},this._mouseUpDelegate=function(t){return e._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),rt=!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(V.ui.ie&&(!document.documentMode||document.documentMode<9)&&!t.button)return this._mouseUp(t);if(!t.which)if(t.originalEvent.altKey||t.originalEvent.ctrlKey||t.originalEvent.metaKey||t.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,t),this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&V.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,rt=!1,t.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),V.ui.plugin={add:function(t,e,i){var s,n=V.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var e=V.ui.safeActiveElement(this.document[0]);V(t.target).closest(e).length||V.ui.safeBlur(e)},_mouseStart:function(t){var e=this.options;return this.helper=this._createHelper(t),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),V.ui.ddmanager&&(V.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0i[2]&&(o=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(a=i[3]+this.offset.click.top)),s.grid&&(t=s.grid[1]?this.originalPageY+Math.round((a-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,a=!i||t-this.offset.click.top>=i[1]||t-this.offset.click.top>i[3]?t:t-this.offset.click.top>=i[1]?t-s.grid[1]:t+s.grid[1],t=s.grid[0]?this.originalPageX+Math.round((o-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,o=!i||t-this.offset.click.left>=i[0]||t-this.offset.click.left>i[2]?t:t-this.offset.click.left>=i[0]?t-s.grid[0]:t+s.grid[0]),"y"===s.axis&&(o=this.originalPageX),"x"===s.axis&&(a=this.originalPageY)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:n?0:this.offset.scroll.top),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:n?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,e,i){return i=i||this._uiHash(),V.ui.plugin.call(this,t,[e,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),V.Widget.prototype._trigger.call(this,t,e,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),V.ui.plugin.add("draggable","connectToSortable",{start:function(e,t,i){var s=V.extend({},t,{item:i.element});i.sortables=[],V(i.options.connectToSortable).each(function(){var t=V(this).sortable("instance");t&&!t.options.disabled&&(i.sortables.push(t),t.refreshPositions(),t._trigger("activate",e,s))})},stop:function(e,t,i){var s=V.extend({},t,{item:i.element});i.cancelHelperRemoval=!1,V.each(i.sortables,function(){var t=this;t.isOver?(t.isOver=0,i.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,s))})},drag:function(i,s,n){V.each(n.sortables,function(){var t=!1,e=this;e.positionAbs=n.positionAbs,e.helperProportions=n.helperProportions,e.offset.click=n.offset.click,e._intersectsWith(e.containerCache)&&(t=!0,V.each(n.sortables,function(){return this.positionAbs=n.positionAbs,this.helperProportions=n.helperProportions,this.offset.click=n.offset.click,t=this!==e&&this._intersectsWith(this.containerCache)&&V.contains(e.element[0],this.element[0])?!1:t})),t?(e.isOver||(e.isOver=1,n._parent=s.helper.parent(),e.currentItem=s.helper.appendTo(e.element).data("ui-sortable-item",!0),e.options._helper=e.options.helper,e.options.helper=function(){return s.helper[0]},i.target=e.currentItem[0],e._mouseCapture(i,!0),e._mouseStart(i,!0,!0),e.offset.click.top=n.offset.click.top,e.offset.click.left=n.offset.click.left,e.offset.parent.left-=n.offset.parent.left-e.offset.parent.left,e.offset.parent.top-=n.offset.parent.top-e.offset.parent.top,n._trigger("toSortable",i),n.dropped=e.element,V.each(n.sortables,function(){this.refreshPositions()}),n.currentItem=n.element,e.fromOutside=n),e.currentItem&&(e._mouseDrag(i),s.position=e.position)):e.isOver&&(e.isOver=0,e.cancelHelperRemoval=!0,e.options._revert=e.options.revert,e.options.revert=!1,e._trigger("out",i,e._uiHash(e)),e._mouseStop(i,!0),e.options.revert=e.options._revert,e.options.helper=e.options._helper,e.placeholder&&e.placeholder.remove(),s.helper.appendTo(n._parent),n._refreshOffsets(i),s.position=n._generatePosition(i,!0),n._trigger("fromSortable",i),n.dropped=!1,V.each(n.sortables,function(){this.refreshPositions()}))})}}),V.ui.plugin.add("draggable","cursor",{start:function(t,e,i){var s=V("body"),i=i.options;s.css("cursor")&&(i._cursor=s.css("cursor")),s.css("cursor",i.cursor)},stop:function(t,e,i){i=i.options;i._cursor&&V("body").css("cursor",i._cursor)}}),V.ui.plugin.add("draggable","opacity",{start:function(t,e,i){e=V(e.helper),i=i.options;e.css("opacity")&&(i._opacity=e.css("opacity")),e.css("opacity",i.opacity)},stop:function(t,e,i){i=i.options;i._opacity&&V(e.helper).css("opacity",i._opacity)}}),V.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,e,i){var s=i.options,n=!1,o=i.scrollParentNotHidden[0],a=i.document[0];o!==a&&"HTML"!==o.tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+o.offsetHeight-t.pageY
    ").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&V(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){V(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,a=this;if(this.handles=o.handles||(V(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=V(),this._addedHandles=V(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=V(this.handles[e]),this._on(this.handles[e],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=V(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=V(this.handles[e])[0])!==t.target&&!V.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=V(s.containment).scrollLeft()||0,i+=V(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=V(".ui-resizable-"+this.axis).css("cursor"),V("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),V.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(V.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),V("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,l=this.originalPosition.top+this.originalSize.height,h=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&h&&(t.left=r-e.minWidth),s&&h&&(t.left=r-e.maxWidth),a&&i&&(t.top=l-e.minHeight),n&&i&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e
    ").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){V.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),V.ui.plugin.add("resizable","animate",{stop:function(e){var i=V(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,a=n?0:i.sizeDiff.width,n={width:i.size.width-a,height:i.size.height-o},a=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(V.extend(n,o&&a?{top:o,left:a}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&V(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),V.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=V(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,a=o instanceof V?o.get(0):/parent/.test(o)?e.parent().get(0):o;a&&(n.containerElement=V(a),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:V(document),left:0,top:0,width:V(document).width(),height:V(document).height()||document.body.parentNode.scrollHeight}):(i=V(a),s=[],V(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(a,"left")?a.scrollWidth:o,e=n._hasScroll(a)?a.scrollHeight:e,n.parentData={element:a,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=V(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,a={top:0,left:0},r=e.containerElement,t=!0;r[0]!==document&&/static/.test(r.css("position"))&&(a=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-a.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-a.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-a.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=V(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=V(t.helper),a=o.offset(),r=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o})}}),V.ui.plugin.add("resizable","alsoResize",{start:function(){var t=V(this).resizable("instance").options;V(t.alsoResize).each(function(){var t=V(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=V(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,a={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};V(s.alsoResize).each(function(){var t=V(this),s=V(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];V.each(e,function(t,e){var i=(s[e]||0)+(a[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){V(this).removeData("ui-resizable-alsoresize")}}),V.ui.plugin.add("resizable","ghost",{start:function(){var t=V(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==V.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=V(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=V(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),V.ui.plugin.add("resizable","grid",{resize:function(){var t,e=V(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,l=r[0]||1,h=r[1]||1,c=Math.round((s.width-n.width)/l)*l,u=Math.round((s.height-n.height)/h)*h,d=n.width+c,p=n.height+u,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=l),s&&(p+=h),f&&(d-=l),g&&(p-=h),/^(se|s|e)$/.test(a)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.top=o.top-u):/^(sw)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.left=o.left-c):((p-h<=0||d-l<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",s+1),i=!0),i&&!e&&this._trigger("focus",t),i},open:function(){var t=this;this._isOpen?this._moveToTop()&&this._focusTabbable():(this._isOpen=!0,this.opener=V(V.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"))},_focusTabbable:function(){var t=this._focusedElement;(t=!(t=!(t=!(t=!(t=t||this.element.find("[autofocus]")).length?this.element.find(":tabbable"):t).length?this.uiDialogButtonPane.find(":tabbable"):t).length?this.uiDialogTitlebarClose.filter(":tabbable"):t).length?this.uiDialog:t).eq(0).trigger("focus")},_restoreTabbableFocus:function(){var t=V.ui.safeActiveElement(this.document[0]);this.uiDialog[0]===t||V.contains(this.uiDialog[0],t)||this._focusTabbable()},_keepFocus:function(t){t.preventDefault(),this._restoreTabbableFocus(),this._delay(this._restoreTabbableFocus)},_createWrapper:function(){this.uiDialog=V("
    ").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===V.ui.keyCode.ESCAPE)return t.preventDefault(),void this.close(t);var e,i,s;t.keyCode!==V.ui.keyCode.TAB||t.isDefaultPrevented()||(e=this.uiDialog.find(":tabbable"),i=e.first(),s=e.last(),t.target!==s[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==i[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){s.trigger("focus")}),t.preventDefault()):(this._delay(function(){i.trigger("focus")}),t.preventDefault()))},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=V("
    "),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(t){V(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=V("").button({label:V("").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),t=V("").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(t,"ui-dialog-title"),this._title(t),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=V("
    "),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=V("
    ").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var s=this,t=this.options.buttons;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),V.isEmptyObject(t)||Array.isArray(t)&&!t.length?this._removeClass(this.uiDialog,"ui-dialog-buttons"):(V.each(t,function(t,e){var i;e=V.extend({type:"button"},e="function"==typeof e?{click:e,text:t}:e),i=e.click,t={icon:e.icon,iconPosition:e.iconPosition,showLabel:e.showLabel,icons:e.icons,text:e.text},delete e.click,delete e.icon,delete e.iconPosition,delete e.showLabel,delete e.icons,"boolean"==typeof e.text&&delete e.text,V("",e).button(t).appendTo(s.uiButtonSet).on("click",function(){i.apply(s.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog))},_makeDraggable:function(){var n=this,o=this.options;function a(t){return{position:t.position,offset:t.offset}}this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(t,e){n._addClass(V(this),"ui-dialog-dragging"),n._blockFrames(),n._trigger("dragStart",t,a(e))},drag:function(t,e){n._trigger("drag",t,a(e))},stop:function(t,e){var i=e.offset.left-n.document.scrollLeft(),s=e.offset.top-n.document.scrollTop();o.position={my:"left top",at:"left"+(0<=i?"+":"")+i+" top"+(0<=s?"+":"")+s,of:n.window},n._removeClass(V(this),"ui-dialog-dragging"),n._unblockFrames(),n._trigger("dragStop",t,a(e))}})},_makeResizable:function(){var n=this,o=this.options,t=o.resizable,e=this.uiDialog.css("position"),t="string"==typeof t?t:"n,e,s,w,se,sw,ne,nw";function a(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:o.maxWidth,maxHeight:o.maxHeight,minWidth:o.minWidth,minHeight:this._minHeight(),handles:t,start:function(t,e){n._addClass(V(this),"ui-dialog-resizing"),n._blockFrames(),n._trigger("resizeStart",t,a(e))},resize:function(t,e){n._trigger("resize",t,a(e))},stop:function(t,e){var i=n.uiDialog.offset(),s=i.left-n.document.scrollLeft(),i=i.top-n.document.scrollTop();o.height=n.uiDialog.height(),o.width=n.uiDialog.width(),o.position={my:"left top",at:"left"+(0<=s?"+":"")+s+" top"+(0<=i?"+":"")+i,of:n.window},n._removeClass(V(this),"ui-dialog-resizing"),n._unblockFrames(),n._trigger("resizeStop",t,a(e))}}).css("position",e)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=V(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),e=V.inArray(this,t);-1!==e&&t.splice(e,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||this.document.data("ui-dialog-instances",t=[]),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};V.each(t,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(t,e){var i,s=this.uiDialog;"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:V("").text(""+this.options.closeText).html()}),"draggable"===t&&((i=s.is(":data(ui-draggable)"))&&!e&&s.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&((i=s.is(":data(ui-resizable)"))&&!e&&s.resizable("destroy"),i&&"string"==typeof e&&s.resizable("option","handles",e),i||!1===e||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=V(this);return V("
    ").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return!!V(t.target).closest(".ui-dialog").length||!!V(t.target).closest(".ui-datepicker").length},_createOverlay:function(){var i,s;this.options.modal&&(i=V.fn.jquery.substring(0,4),s=!0,this._delay(function(){s=!1}),this.document.data("ui-dialog-overlays")||this.document.on("focusin.ui-dialog",function(t){var e;s||((e=this._trackingInstances()[0])._allowInteraction(t)||(t.preventDefault(),e._focusTabbable(),"3.4."!==i&&"3.5."!==i||e._delay(e._restoreTabbableFocus)))}.bind(this)),this.overlay=V("
    ").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1))},_destroyOverlay:function(){var t;this.options.modal&&this.overlay&&((t=this.document.data("ui-dialog-overlays")-1)?this.document.data("ui-dialog-overlays",t):(this.document.off("focusin.ui-dialog"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null)}}),!1!==V.uiBackCompat&&V.widget("ui.dialog",V.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}});V.ui.dialog;function lt(t,e,i){return e<=t&&t").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){if(void 0===t)return this.options.value;this.options.value=this._constrainedValue(t),this._refreshValue()},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=!1===t,"number"!=typeof t&&(t=0),!this.indeterminate&&Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,e=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).width(e.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,t===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=V("
    ").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),V.widget("ui.selectable",V.ui.mouse,{version:"1.13.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var i=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){i.elementPos=V(i.element[0]).offset(),i.selectees=V(i.options.filter,i.element[0]),i._addClass(i.selectees,"ui-selectee"),i.selectees.each(function(){var t=V(this),e=t.offset(),e={left:e.left-i.elementPos.left,top:e.top-i.elementPos.top};V.data(this,"selectable-item",{element:this,$element:t,left:e.left,top:e.top,right:e.left+t.outerWidth(),bottom:e.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=V("
    "),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(i){var s=this,t=this.options;this.opos=[i.pageX,i.pageY],this.elementPos=V(this.element[0]).offset(),this.options.disabled||(this.selectees=V(t.filter,this.element[0]),this._trigger("start",i),V(t.appendTo).append(this.helper),this.helper.css({left:i.pageX,top:i.pageY,width:0,height:0}),t.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var t=V.data(this,"selectable-item");t.startselected=!0,i.metaKey||i.ctrlKey||(s._removeClass(t.$element,"ui-selected"),t.selected=!1,s._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,s._trigger("unselecting",i,{unselecting:t.element}))}),V(i.target).parents().addBack().each(function(){var t,e=V.data(this,"selectable-item");if(e)return t=!i.metaKey&&!i.ctrlKey||!e.$element.hasClass("ui-selected"),s._removeClass(e.$element,t?"ui-unselecting":"ui-selected")._addClass(e.$element,t?"ui-selecting":"ui-unselecting"),e.unselecting=!t,e.selecting=t,(e.selected=t)?s._trigger("selecting",i,{selecting:e.element}):s._trigger("unselecting",i,{unselecting:e.element}),!1}))},_mouseDrag:function(s){if(this.dragged=!0,!this.options.disabled){var t,n=this,o=this.options,a=this.opos[0],r=this.opos[1],l=s.pageX,h=s.pageY;return ll||i.righth||i.bottoma&&i.rightr&&i.bottom",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var t=this.element.uniqueId().attr("id");this.ids={element:t,button:t+"-button",menu:t+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=V()},_drawButton:function(){var t,e=this,i=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.trigger("focus"),t.preventDefault()}}),this.element.hide(),this.button=V("",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),t=V("").appendTo(this.button),this._addClass(t,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(i).appendTo(this.button),!1!==this.options.width&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){e._rendered||e._refreshMenu()})},_drawMenu:function(){var i=this;this.menu=V("
      ",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=V("
      ").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,e){t.preventDefault(),i._setSelection(),i._select(e.item.data("ui-selectmenu-item"),t)},focus:function(t,e){e=e.item.data("ui-selectmenu-item");null!=i.focusIndex&&e.index!==i.focusIndex&&(i._trigger("focus",t,{item:e}),i.isOpen||i._select(e,t)),i.focusIndex=e.index,i.button.attr("aria-activedescendant",i.menuItems.eq(e.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t=this.element.find("option");this.menu.empty(),this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,t.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(V.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(t){var e=V("");return this._setText(e,t.label),this._addClass(e,"ui-selectmenu-text"),e},_renderMenu:function(s,t){var n=this,o="";V.each(t,function(t,e){var i;e.optgroup!==o&&(i=V("
    • ",{text:e.optgroup}),n._addClass(i,"ui-selectmenu-optgroup","ui-menu-divider"+(e.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),i.appendTo(s),o=e.optgroup),n._renderItemData(s,e)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(t,e){var i=V("
    • "),s=V("
      ",{title:e.element.attr("title")});return e.disabled&&this._addClass(i,null,"ui-state-disabled"),this._setText(s,e.label),i.append(s).appendTo(t)},_setText:function(t,e){e?t.text(e):t.html(" ")},_move:function(t,e){var i,s=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),s+=":not(.ui-state-disabled)"),(s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](s).eq(-1):i[t+"All"](s).eq(0)).length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?((t=window.getSelection()).removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.trigger("focus"))},_documentClick:{mousedown:function(t){this.isOpen&&(V(t.target).closest(".ui-selectmenu-menu, #"+V.escapeSelector(this.ids.button)).length||this.close(t))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection()).rangeCount&&(this.range=t.getRangeAt(0)):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(t){var e=!0;switch(t.keyCode){case V.ui.keyCode.TAB:case V.ui.keyCode.ESCAPE:this.close(t),e=!1;break;case V.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case V.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case V.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case V.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case V.ui.keyCode.LEFT:this._move("prev",t);break;case V.ui.keyCode.RIGHT:this._move("next",t);break;case V.ui.keyCode.HOME:case V.ui.keyCode.PAGE_UP:this._move("first",t);break;case V.ui.keyCode.END:case V.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),e=!1}e&&t.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){t=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(t,e){var i;"icons"===t&&(i=this.button.find("span.ui-icon"),this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)),this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?V(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;!1!==t?(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t)):this.button.css("width","")},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(t){var i=this,s=[];t.each(function(t,e){e.hidden||s.push(i._parseOption(V(e),t))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),V.widget("ui.slider",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,e=this.options,i=this.element.find(".ui-slider-handle"),s=[],n=e.values&&e.values.length||1;for(i.length>n&&(i.slice(n).remove(),i=i.slice(0,n)),t=i.length;t");this.handles=i.add(V(s.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(t){V(this).data("ui-slider-handle-index",t).attr("tabIndex",0)})},_createRange:function(){var t=this.options;t.range?(!0===t.range&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:Array.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=V("
      ").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),"min"!==t.range&&"max"!==t.range||this._addClass(this.range,"ui-slider-range-"+t.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(t){var i,s,n,o,e,a,r=this,l=this.options;return!l.disabled&&(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),a={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(a),s=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var e=Math.abs(i-r.values(t));(e=this._valueMax())return this._valueMax();var e=0=e&&(t+=0this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return t=null!==this.options.min?Math.max(t,this._precisionOf(this.options.min)):t},_precisionOf:function(t){var e=t.toString(),t=e.indexOf(".");return-1===t?0:e.length-t-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,t,s,n,o=this.options.range,a=this.options,r=this,l=!this._animateOff&&a.animate,h={};this._hasMultipleValues()?this.handles.each(function(t){i=(r.values(t)-r._valueMin())/(r._valueMax()-r._valueMin())*100,h["horizontal"===r.orientation?"left":"bottom"]=i+"%",V(this).stop(1,1)[l?"animate":"css"](h,a.animate),!0===r.options.range&&("horizontal"===r.orientation?(0===t&&r.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},a.animate),1===t&&r.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:a.animate})):(0===t&&r.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},a.animate),1===t&&r.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:a.animate}))),e=i}):(t=this.value(),s=this._valueMin(),n=this._valueMax(),i=n!==s?(t-s)/(n-s)*100:0,h["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](h,a.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},a.animate),"max"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},a.animate),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},a.animate),"max"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},a.animate))},_handleEvents:{keydown:function(t){var e,i,s,n=V(t.target).data("ui-slider-handle-index");switch(t.keyCode){case V.ui.keyCode.HOME:case V.ui.keyCode.END:case V.ui.keyCode.PAGE_UP:case V.ui.keyCode.PAGE_DOWN:case V.ui.keyCode.UP:case V.ui.keyCode.RIGHT:case V.ui.keyCode.DOWN:case V.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(V(t.target),null,"ui-state-active"),!1===this._start(t,n)))return}switch(s=this.options.step,e=i=this._hasMultipleValues()?this.values(n):this.value(),t.keyCode){case V.ui.keyCode.HOME:i=this._valueMin();break;case V.ui.keyCode.END:i=this._valueMax();break;case V.ui.keyCode.PAGE_UP:i=this._trimAlignValue(e+(this._valueMax()-this._valueMin())/this.numPages);break;case V.ui.keyCode.PAGE_DOWN:i=this._trimAlignValue(e-(this._valueMax()-this._valueMin())/this.numPages);break;case V.ui.keyCode.UP:case V.ui.keyCode.RIGHT:if(e===this._valueMax())return;i=this._trimAlignValue(e+s);break;case V.ui.keyCode.DOWN:case V.ui.keyCode.LEFT:if(e===this._valueMin())return;i=this._trimAlignValue(e-s)}this._slide(t,n,i)},keyup:function(t){var e=V(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,e),this._change(t,e),this._removeClass(V(t.target),null,"ui-state-active"))}}}),V.widget("ui.sortable",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t*{ cursor: "+o.cursor+" !important; }").appendTo(n)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return V.ui.ddmanager&&(V.ui.ddmanager.current=this),V.ui.ddmanager&&!o.dropBehaviour&&V.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this.helper.parent().is(this.appendTo)||(this.helper.detach().appendTo(this.appendTo),this.offset.parent=this._getParentOffset()),this.position=this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,this.lastPositionAbs=this.positionAbs=this._convertPositionTo("absolute"),this._mouseDrag(t),!0},_scroll:function(t){var e=this.options,i=!1;return this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageYt[this.floating?"width":"height"]?h&&c:o",i.document[0]);return i._addClass(t,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(t,"ui-sortable-helper"),"tbody"===n?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),V("",i.document[0]).appendTo(t)):"tr"===n?i._createTrPlaceholder(i.currentItem,t):"img"===n&&t.attr("src",i.currentItem.attr("src")),s||t.css("visibility","hidden"),t},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()&&(!o.forcePlaceholderSize||"tbody"!==n&&"tr"!==n)||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=V(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){V(" ",i.document[0]).attr("colspan",V(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,n,o,a,r,l,h,c=null,u=null,d=this.containers.length-1;0<=d;d--)V.contains(this.currentItem[0],this.containers[d].element[0])||(this._intersectsWith(this.containers[d].containerCache)?c&&V.contains(this.containers[d].element[0],c.element[0])||(c=this.containers[d],u=d):this.containers[d].containerCache.over&&(this.containers[d]._trigger("out",t,this._uiHash(this)),this.containers[d].containerCache.over=0));if(c)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(i=1e4,s=null,n=(l=c.floating||this._isFloating(this.currentItem))?"left":"top",o=l?"width":"height",h=l?"pageX":"pageY",e=this.items.length-1;0<=e;e--)V.contains(this.containers[u].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(a=this.items[e].item.offset()[n],r=!1,t[h]-a>this.items[e][o]/2&&(r=!0),Math.abs(t[h]-a)this.containment[2]&&(i=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(s=this.containment[3]+this.offset.click.top)),e.grid&&(t=this.originalPageY+Math.round((s-this.originalPageY)/e.grid[1])*e.grid[1],s=!this.containment||t-this.offset.click.top>=this.containment[1]&&t-this.offset.click.top<=this.containment[3]?t:t-this.offset.click.top>=this.containment[1]?t-e.grid[1]:t+e.grid[1],t=this.originalPageX+Math.round((i-this.originalPageX)/e.grid[0])*e.grid[0],i=!this.containment||t-this.offset.click.left>=this.containment[0]&&t-this.offset.click.left<=this.containment[2]?t:t-this.offset.click.left>=this.containment[0]?t-e.grid[0]:t+e.grid[0])),{top:s-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop()),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function n(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(n("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(n("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var s=this._super(),n=this.element;return V.each(["min","max","step"],function(t,e){var i=n.attr(e);null!=i&&i.length&&(s[e]=i)}),s},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){this.cancelBlur?delete this.cancelBlur:(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t))},mousewheel:function(t,e){var i=V.ui.safeActiveElement(this.document[0]);if(this.element[0]===i&&e){if(!this.spinning&&!this._start(t))return!1;this._spin((0").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&0e.max?e.max:null!==e.min&&t"},_buttonHtml:function(){return""}});var ct;V.ui.spinner;V.widget("ui.tabs",{version:"1.13.2",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:(ct=/#.*$/,function(t){var e=t.href.replace(ct,""),i=location.href.replace(ct,"");try{e=decodeURIComponent(e)}catch(t){}try{i=decodeURIComponent(i)}catch(t){}return 1?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,e=this.tablist.children(":has(a[href])");t.disabled=V.map(e.filter(".ui-state-disabled"),function(t){return e.index(t)}),this._processTabs(),!1!==t.active&&this.anchors.length?this.active.length&&!V.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=V()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=V()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var l=this,t=this.tabs,e=this.anchors,i=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(t){V(this).is(".ui-state-disabled")&&t.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){V(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return V("a",this)[0]}).attr({tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=V(),this.anchors.each(function(t,e){var i,s,n,o=V(e).uniqueId().attr("id"),a=V(e).closest("li"),r=a.attr("aria-controls");l._isLocal(e)?(n=(i=e.hash).substring(1),s=l.element.find(l._sanitizeSelector(i))):(n=a.attr("aria-controls")||V({}).uniqueId()[0].id,(s=l.element.find(i="#"+n)).length||(s=l._createPanel(n)).insertAfter(l.panels[t-1]||l.tablist),s.attr("aria-live","polite")),s.length&&(l.panels=l.panels.add(s)),r&&a.data("ui-tabs-aria-controls",r),a.attr({"aria-controls":n,"aria-labelledby":o}),s.attr("aria-labelledby",o)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),t&&(this._off(t.not(this.tabs)),this._off(e.not(this.anchors)),this._off(i.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(t){return V("
      ").attr("id",t).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(t){var e,i;for(Array.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1),i=0;e=this.tabs[i];i++)e=V(e),!0===t||-1!==V.inArray(i,t)?(e.attr("aria-disabled","true"),this._addClass(e,null,"ui-state-disabled")):(e.removeAttr("aria-disabled"),this._removeClass(e,null,"ui-state-disabled"));this.options.disabled=t,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!0===t)},_setupEvents:function(t){var i={};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,e=this.element.parent();"fill"===t?(i=e.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=V(this).outerHeight(!0)}),this.panels.each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,V(this).height("").height())}).height(i))},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget).closest("li"),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():this._getPanelForTab(s),r=i.length?this._getPanelForTab(i):V(),i={oldTab:i,oldPanel:r,newTab:o?V():s,newPanel:a};t.preventDefault(),s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||n&&!e.collapsible||!1===this._trigger("beforeActivate",t,i)||(e.active=!o&&this.tabs.index(s),this.active=n?V():s,this.xhr&&this.xhr.abort(),r.length||a.length||V.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,i))},_toggle:function(t,e){var i=this,s=e.newPanel,n=e.oldPanel;function o(){i.running=!1,i._trigger("activate",t,e)}function a(){i._addClass(e.newTab.closest("li"),"ui-tabs-active","ui-state-active"),s.length&&i.options.show?i._show(s,i.options.show,o):(s.show(),o())}this.running=!0,n.length&&this.options.hide?this._hide(n,this.options.hide,function(){i._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),a()}):(this._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n.hide(),a()),n.attr("aria-hidden","true"),e.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),s.length&&n.length?e.oldTab.attr("tabIndex",-1):s.length&&this.tabs.filter(function(){return 0===V(this).attr("tabIndex")}).attr("tabIndex",-1),s.attr("aria-hidden","false"),e.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var t=this._findActive(t);t[0]!==this.active[0]&&(t=(t=!t.length?this.active:t).find(".ui-tabs-anchor")[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return!1===t?V():this.tabs.eq(t)},_getIndex:function(t){return t="string"==typeof t?this.anchors.index(this.anchors.filter("[href$='"+V.escapeSelector(t)+"']")):t},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){V.data(this,"ui-tabs-destroy")?V(this).remove():V(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var t=V(this),e=t.data("ui-tabs-aria-controls");e?t.attr("aria-controls",e).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var t=this.options.disabled;!1!==t&&(t=void 0!==i&&(i=this._getIndex(i),Array.isArray(t)?V.map(t,function(t){return t!==i?t:null}):V.map(this.tabs,function(t,e){return e!==i?e:null})),this._setOptionDisabled(t))},disable:function(t){var e=this.options.disabled;if(!0!==e){if(void 0===t)e=!0;else{if(t=this._getIndex(t),-1!==V.inArray(t,e))return;e=Array.isArray(e)?V.merge([t],e).sort():[t]}this._setOptionDisabled(e)}},load:function(t,s){t=this._getIndex(t);function n(t,e){"abort"===e&&o.panels.stop(!1,!0),o._removeClass(i,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===o.xhr&&delete o.xhr}var o=this,i=this.tabs.eq(t),t=i.find(".ui-tabs-anchor"),a=this._getPanelForTab(i),r={tab:i,panel:a};this._isLocal(t[0])||(this.xhr=V.ajax(this._ajaxSettings(t,s,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(i,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,i){setTimeout(function(){a.html(t),o._trigger("load",s,r),n(i,e)},1)}).fail(function(t,e){setTimeout(function(){n(t,e)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href").replace(/#.*$/,""),beforeSend:function(t,e){return n._trigger("beforeLoad",i,V.extend({jqXHR:t,ajaxSettings:e},s))}}},_getPanelForTab:function(t){t=V(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+t))}}),!1!==V.uiBackCompat&&V.widget("ui.tabs",V.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}});V.ui.tabs;V.widget("ui.tooltip",{version:"1.13.2",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var t=V(this).attr("title");return V("").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(t,e){var i=(t.attr("aria-describedby")||"").split(/\s+/);i.push(e),t.data("ui-tooltip-id",e).attr("aria-describedby",String.prototype.trim.call(i.join(" ")))},_removeDescribedBy:function(t){var e=t.data("ui-tooltip-id"),i=(t.attr("aria-describedby")||"").split(/\s+/),e=V.inArray(e,i);-1!==e&&i.splice(e,1),t.removeData("ui-tooltip-id"),(i=String.prototype.trim.call(i.join(" ")))?t.attr("aria-describedby",i):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=V("
      ").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=V([])},_setOption:function(t,e){var i=this;this._super(t,e),"content"===t&&V.each(this.tooltips,function(t,e){i._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur");i.target=i.currentTarget=e.element[0],s.close(i,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var t=V(this);if(t.is("[title]"))return t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")}))},_enable:function(){this.disabledTitles.each(function(){var t=V(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))}),this.disabledTitles=V([])},open:function(t){var i=this,e=V(t?t.target:this.element).closest(this.options.items);e.length&&!e.data("ui-tooltip-id")&&(e.attr("title")&&e.data("ui-tooltip-title",e.attr("title")),e.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&e.parents().each(function(){var t,e=V(this);e.data("ui-tooltip-open")&&((t=V.Event("blur")).target=t.currentTarget=this,i.close(t,!0)),e.attr("title")&&(e.uniqueId(),i.parents[this.id]={element:this,title:e.attr("title")},e.attr("title",""))}),this._registerCloseHandlers(t,e),this._updateContent(e,t))},_updateContent:function(e,i){var t=this.options.content,s=this,n=i?i.type:null;if("string"==typeof t||t.nodeType||t.jquery)return this._open(i,e,t);(t=t.call(e[0],function(t){s._delay(function(){e.data("ui-tooltip-open")&&(i&&(i.type=n),this._open(i,e,t))})}))&&this._open(i,e,t)},_open:function(t,e,i){var s,n,o,a=V.extend({},this.options.position);function r(t){a.of=t,n.is(":hidden")||n.position(a)}i&&((s=this._find(e))?s.tooltip.find(".ui-tooltip-content").html(i):(e.is("[title]")&&(t&&"mouseover"===t.type?e.attr("title",""):e.removeAttr("title")),s=this._tooltip(e),n=s.tooltip,this._addDescribedBy(e,n.attr("id")),n.find(".ui-tooltip-content").html(i),this.liveRegion.children().hide(),(i=V("
      ").html(n.find(".ui-tooltip-content").html())).removeAttr("name").find("[name]").removeAttr("name"),i.removeAttr("id").find("[id]").removeAttr("id"),i.appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:r}),r(t)):n.position(V.extend({of:e},this.options.position)),n.hide(),this._show(n,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(o=this.delayedShow=setInterval(function(){n.is(":visible")&&(r(a.of),clearInterval(o))},13)),this._trigger("open",t,{tooltip:n})))},_registerCloseHandlers:function(t,e){var i={keyup:function(t){t.keyCode===V.ui.keyCode.ESCAPE&&((t=V.Event(t)).currentTarget=e[0],this.close(t,!0))}};e[0]!==this.element[0]&&(i.remove=function(){var t=this._find(e);t&&this._removeTooltip(t.tooltip)}),t&&"mouseover"!==t.type||(i.mouseleave="close"),t&&"focusin"!==t.type||(i.focusout="close"),this._on(!0,e,i)},close:function(t){var e,i=this,s=V(t?t.currentTarget:this.element),n=this._find(s);n?(e=n.tooltip,n.closing||(clearInterval(this.delayedShow),s.data("ui-tooltip-title")&&!s.attr("title")&&s.attr("title",s.data("ui-tooltip-title")),this._removeDescribedBy(s),n.hiding=!0,e.stop(!0),this._hide(e,this.options.hide,function(){i._removeTooltip(V(this))}),s.removeData("ui-tooltip-open"),this._off(s,"mouseleave focusout keyup"),s[0]!==this.element[0]&&this._off(s,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&V.each(this.parents,function(t,e){V(e.element).attr("title",e.title),delete i.parents[t]}),n.closing=!0,this._trigger("close",t,{tooltip:e}),n.hiding||(n.closing=!1))):s.removeData("ui-tooltip-open")},_tooltip:function(t){var e=V("
      ").attr("role","tooltip"),i=V("
      ").appendTo(e),s=e.uniqueId().attr("id");return this._addClass(i,"ui-tooltip-content"),this._addClass(e,"ui-tooltip","ui-widget ui-widget-content"),e.appendTo(this._appendTo(t)),this.tooltips[s]={element:t,tooltip:e}},_find:function(t){t=t.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(t){clearInterval(this.delayedShow),t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){t=t.closest(".ui-front, dialog");return t=!t.length?this.document[0].body:t},_destroy:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur"),e=e.element;i.target=i.currentTarget=e[0],s.close(i,!0),V("#"+t).remove(),e.data("ui-tooltip-title")&&(e.attr("title")||e.attr("title",e.data("ui-tooltip-title")),e.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),!1!==V.uiBackCompat&&V.widget("ui.tooltip",V.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}});V.ui.tooltip}); \ No newline at end of file diff --git a/tools/js/jquery.min.js b/tools/js/jquery.min.js index a1c07fd8..0de648ed 100644 --- a/tools/js/jquery.min.js +++ b/tools/js/jquery.min.js @@ -1,2 +1,2 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.cssHas=ce(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),d.cssHas||y.push(":has"),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType&&e.documentElement||e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 Date: Sat, 13 May 2023 11:34:51 +0200 Subject: [PATCH 069/232] Empty URL = show news --- index.php | 2 +- system/routes.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index e15abb21..5f27f925 100644 --- a/index.php +++ b/index.php @@ -29,7 +29,7 @@ require_once SYSTEM . 'functions.php'; $uri = $_SERVER['REQUEST_URI']; if(false !== strpos($uri, 'index.php')) { - $uri = str_replace_first('/index.php', '', $uri); + $uri = str_replace_first('index.php', '', $uri); } if(0 === strpos($uri, '/')) { diff --git a/system/routes.php b/system/routes.php index d0f5f64d..5d93bd1b 100644 --- a/system/routes.php +++ b/system/routes.php @@ -10,7 +10,7 @@ defined('MYAAC') or die('Direct access not allowed!'); return [ - ['GET', '', '__redirect__/' . (config('friendly_urls') ? '' : 'index.php/') . 'news'], // redirect empty URL to news + ['GET', '', 'news.php'], // empty URL = show news ['GET', 'news/archive/{id:int}[/]', 'news/archive.php'], // block access to some files From da4e18cb695d075af0c442009d00ac52c72ef963 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 13 May 2023 12:49:17 +0200 Subject: [PATCH 070/232] Fixes to routing --- index.php | 2 +- system/router.php | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 5f27f925..e15abb21 100644 --- a/index.php +++ b/index.php @@ -29,7 +29,7 @@ require_once SYSTEM . 'functions.php'; $uri = $_SERVER['REQUEST_URI']; if(false !== strpos($uri, 'index.php')) { - $uri = str_replace_first('index.php', '', $uri); + $uri = str_replace_first('/index.php', '', $uri); } if(0 === strpos($uri, '/')) { diff --git a/system/router.php b/system/router.php index 115eb913..879ad727 100644 --- a/system/router.php +++ b/system/router.php @@ -51,7 +51,11 @@ if (false !== $pos = strpos($uri, '?')) { $uri = rawurldecode($uri); if (BASE_DIR !== '') { $tmp = str_replace_first('/', '', BASE_DIR); - $uri = str_replace_first($tmp . '/', '', $uri); + $uri = str_replace_first($tmp, '', $uri); +} + +if(0 === strpos($uri, '/')) { + $uri = str_replace_first('/', '', $uri); } define('URI', $uri); From bf137189c5f9337d354893d0709a79c7522cc13a Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 15 May 2023 00:22:51 +0200 Subject: [PATCH 071/232] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21f6405c..37dc4488 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Minimum PHP version for this release is 7.2.5. * editable changelogs * revised Accounts & Players editors * option to add/modify menus with plugins + * option to enable/disable plugins * better, updated TinyMCE editor (v6.x) * with option to upload images * list of open source libraries used in project From 946d24690cd1306707a827105e532b3e66b6d736 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 25 May 2023 09:30:44 +0200 Subject: [PATCH 072/232] Update common.php --- common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.php b/common.php index 54b79bbf..fff55002 100644 --- a/common.php +++ b/common.php @@ -24,7 +24,7 @@ * @link https://my-aac.org */ if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); -// test github actions + const MYAAC = true; const MYAAC_VERSION = '0.9.0-dev'; const DATABASE_VERSION = 35; From 8c524171fb297e9f7994b4a5f4d4ab92e1959589 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 25 May 2023 09:31:29 +0200 Subject: [PATCH 073/232] Add cypress.env.json to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 1302f62a..803d6349 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ vendor # npm node_modules +# cypress +cypress.env.json + # created by release.sh releases tmp From de710dff9400c5b0100ea99358fbaec04d7da931 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 25 May 2023 11:39:02 +0200 Subject: [PATCH 074/232] Add cypress/e2e/2-advanced-examples to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 803d6349..5206d08b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules # cypress cypress.env.json +cypress/e2e/2-advanced-examples # created by release.sh releases From 61c26613772c4215722f58ac67e915e3ccbf40a0 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 25 May 2023 11:39:45 +0200 Subject: [PATCH 075/232] Fix warning when no header language set --- system/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/functions.php b/system/functions.php index 0fcc6aa4..97779601 100644 --- a/system/functions.php +++ b/system/functions.php @@ -754,10 +754,10 @@ function get_browser_languages() { $ret = array(); - $acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE']; - if(!isset($acceptLang[0])) + if(empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) return $ret; + $acceptLang = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $languages = strtolower($acceptLang); // $languages = 'pl,en-us;q=0.7,en;q=0.3 '; // need to remove spaces from strings to avoid error From 0d0e5812dd483bebfbeb1dc3878dcdecde8d4c60 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 08:36:20 +0200 Subject: [PATCH 076/232] Change step to $_REQUEST --- install/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/index.php b/install/index.php index 1c008c38..021bd184 100644 --- a/install/index.php +++ b/install/index.php @@ -26,13 +26,13 @@ $twig = new Twig_Environment($twig_loader, array( )); // load installation status -$step = isset($_POST['step']) ? $_POST['step'] : 'welcome'; +$step = $_REQUEST['step'] ?? 'welcome'; $install_status = array(); if(file_exists(CACHE . 'install.txt')) { $install_status = unserialize(file_get_contents(CACHE . 'install.txt')); - if(!isset($_POST['step'])) { + if(!isset($_REQUEST['step'])) { $step = isset($install_status['step']) ? $install_status['step'] : ''; } } From 269ae323e050224c0395bd46cd693ce7c201326d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 08:49:04 +0200 Subject: [PATCH 077/232] Add Cypress tests: install + create account --- cypress.config.js | 9 + cypress/e2e/1-install.cy.js | 87 ++ cypress/e2e/2-create-account.cy.js | 33 + cypress/fixtures/example.json | 5 + cypress/support/commands.js | 25 + cypress/support/e2e.js | 20 + package-lock.json | 1927 ++++++++++++++++++++++++++++ package.json | 5 + 8 files changed, 2111 insertions(+) create mode 100644 cypress.config.js create mode 100644 cypress/e2e/1-install.cy.js create mode 100644 cypress/e2e/2-create-account.cy.js create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/e2e.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 00000000..97f47c41 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,9 @@ +const { defineConfig } = require("cypress"); + +module.exports = defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, +}); diff --git a/cypress/e2e/1-install.cy.js b/cypress/e2e/1-install.cy.js new file mode 100644 index 00000000..dffe065a --- /dev/null +++ b/cypress/e2e/1-install.cy.js @@ -0,0 +1,87 @@ +describe('Install MyAAC', () => { + beforeEach(() => { + // Cypress starts out with a blank slate for each test + // so we must tell it to visit our website with the `cy.visit()` command. + // Since we want to visit the same URL at the start of all our tests, + // we include it in our beforeEach function so that it runs before each test + cy.visit(Cypress.env('URL')) + }) + + it('Go through installer', () => { + cy.visit(Cypress.env('URL') + '/install/?step=welcome') + cy.wait(1000) + + cy.screenshot('install-welcome') + + // step 1 - Welcome + cy.get('select[name="lang"]').select('en') + + //cy.get('input[type=button]').contains('Next »').click() + + cy.get('form').submit() + + // step 2 - License + // just skip + cy.contains('GNU/GPL License'); + cy.get('form').submit() + + // step 3 - Requirements + cy.contains('Requirements check'); + + cy.get('#step').then(elem => { + elem.val('config'); + }); + + cy.get('form').submit() + + // step 4 - Configuration + cy.contains('Basic configuration'); + + cy.get('#vars_server_path').click().clear().type(Cypress.env('SERVER_PATH')) + cy.get('#vars_mail_admin').click().clear().type('noone@example.net') + + cy.get('[type="checkbox"]').uncheck() // usage statistics uncheck + + cy.wait(1000) + + cy.get('form').submit() + + // check if there is any error + + + // step 5 - Import Schema + cy.contains('Import MySQL schema'); + + // AAC is not installed yet, this message should not come + cy.contains('Seems AAC is already installed. Skipping importing MySQL schema..').should('not.exist') + + cy.contains('[class="alert alert-success"]', 'Local configuration has been saved into file: config.local.php').should('be.visible') + + cy.get('form').submit() + + // step 6 - Admin Account + cy.get('#vars_email').click().clear().type('admin@my-aac.org') + cy.get('#vars_account').click().clear().type('admin') + cy.get('#vars_password').click().clear().type('test1234') + cy.get('#vars_password_confirm').click().clear().type('test1234') + cy.get('#vars_player_name').click().clear().type('Admin') + + cy.get('form').submit() + + cy.wait(1000); + cy.get('.class', { timeout: 12_000 }).should('be.visible') + + cy.screenshot('install-finish') + }) + + it('Take Screenshot of the Home Page', () => { + cy.wait(1000) + cy.screenshot('home') + }) + + it('Take Screenshot of Create Account page', () => { + cy.visit(Cypress.env('URL') + '/index.php/account/create') + cy.wait(1000) + cy.screenshot('create-account-page') + }) +}) diff --git a/cypress/e2e/2-create-account.cy.js b/cypress/e2e/2-create-account.cy.js new file mode 100644 index 00000000..11d87409 --- /dev/null +++ b/cypress/e2e/2-create-account.cy.js @@ -0,0 +1,33 @@ +describe('Create Account Page', () => { + beforeEach(() => { + // Cypress starts out with a blank slate for each test + // so we must tell it to visit our website with the `cy.visit()` command. + // Since we want to visit the same URL at the start of all our tests, + // we include it in our beforeEach function so that it runs before each test + cy.visit(Cypress.env('URL') + '/index.php/account/create') + }) + + it('Create Test Account', () => { + cy.screenshot('create-account-page') + + cy.get('#account_input').type('admin') + cy.get('#email').type('admin@example.com') + + cy.get('#password').type('test1234') + cy.get('#password2').type('test1234') + + cy.get('#character_name').type('Slaw') + + cy.get('#sex1').check() + cy.get('#vocation1').check() + cy.get('#accept_rules').check() + + cy.get('#createaccount').submit() + + // no errors please + cy.contains('The Following Errors Have Occurred:').should('not.exist') + + // ss of post page + cy.screenshot('create-account-page-post') + }) +}) diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 00000000..02e42543 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 00000000..66ea16ef --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) \ No newline at end of file diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js new file mode 100644 index 00000000..0e7290a1 --- /dev/null +++ b/cypress/support/e2e.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..369afdf5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1927 @@ +{ + "name": "myaac", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "cypress": "^12.12.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "2.88.11", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", + "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "~6.10.3", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@types/node": { + "version": "14.18.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz", + "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==", + "dev": true + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cypress": { + "version": "12.12.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.12.0.tgz", + "integrity": "sha512-UU5wFQ7SMVCR/hyKok/KmzG6fpZgBHHfrXcHzDmPHWrT+UUetxFzQgt7cxCszlwfozckzwkd22dxMwl/vNkWRw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^2.88.10", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.3.2", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tslib": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.1.tgz", + "integrity": "sha512-KaI6gPil5m9vF7DKaoXxx1ia9fxS4qG5YveErRRVknPDXXriu5M8h48YRjB6h5ZUOKuAKlSJYb0GaDe8I39fRw==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..0e20e9b5 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "cypress": "^12.12.0" + } +} From 2b739c2b4017399df370f2733ff7ba99f794306a Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 08:49:28 +0200 Subject: [PATCH 078/232] Add Cypress workflow --- .github/workflows/cypress.yml | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/cypress.yml diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml new file mode 100644 index 00000000..f81d0293 --- /dev/null +++ b/.github/workflows/cypress.yml @@ -0,0 +1,68 @@ +name: Cypress Test +on: + pull_request: + branches: [develop] + push: + branches: [develop] + +jobs: + cypress: + runs-on: ubuntu-latest + services: + mysql: + image: mysql:latest + env: + MYSQL_ALLOW_EMPTY_PASSWORD: false + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: myaac-tfs-latest + ports: + - 3306/tcp + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + strategy: + fail-fast: false + matrix: + php-versions: [ '7.4', '8.0', '8.1' ] + steps: + - name: Checkout MyAAC + uses: actions/checkout@v3 + + - name: Checkout TFS + uses: actions/checkout@v3 + with: + repository: otland/forgottenserver + + - run: ls -lha + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + # Use composer.json for key, if composer.lock is not committed. + # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Composer dependencies + run: composer install --no-progress --prefer-dist --optimize-autoloader + + - name: Cypress Run + uses: cypress-io/github-action@v5 + env: + URL: localhost + SERVER_PATH: otland-forgottenserver + + - name: Save screenshots + uses: actions/upload-artifact@v3 + if: always() + with: + name: cypress-screenshots + path: cypress/screenshots From 7facf0adad5d058a2ffdcb80a70d30abcdda9fa9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 08:52:05 +0200 Subject: [PATCH 079/232] fix branch --- .github/workflows/cypress.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index f81d0293..be8bbbf7 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -25,11 +25,14 @@ jobs: steps: - name: Checkout MyAAC uses: actions/checkout@v3 + with: + ref: develop - name: Checkout TFS uses: actions/checkout@v3 with: repository: otland/forgottenserver + ref: 1.4 - run: ls -lha - name: Setup PHP From 11f1ad6d76591665caae971d073b57c4e6d61db2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 08:53:49 +0200 Subject: [PATCH 080/232] fix path --- .github/workflows/cypress.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index be8bbbf7..e6836041 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -33,6 +33,7 @@ jobs: with: repository: otland/forgottenserver ref: 1.4 + path: tfs - run: ls -lha - name: Setup PHP From a1d969bbfd4d522c65dbb7a4a6b362fdb5f85f52 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:00:21 +0200 Subject: [PATCH 081/232] fix env --- .github/workflows/cypress.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index e6836041..2d35bf22 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -61,8 +61,8 @@ jobs: - name: Cypress Run uses: cypress-io/github-action@v5 env: - URL: localhost - SERVER_PATH: otland-forgottenserver + CYPRESS_URL: localhost + CYPRESS_SERVER_PATH: otland-forgottenserver - name: Save screenshots uses: actions/upload-artifact@v3 From 75f77ec7a38df8ea8934133a8b41bdedaf4598d0 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:11:04 +0200 Subject: [PATCH 082/232] Fix: Run PHP Server --- .github/workflows/cypress.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 2d35bf22..0ce69768 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -58,10 +58,13 @@ jobs: - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader + - name: Run PHP server + run: nohup php -S localhost:8080 > php.log 2>&1 & + - name: Cypress Run uses: cypress-io/github-action@v5 env: - CYPRESS_URL: localhost + CYPRESS_URL: http://localhost:8080 CYPRESS_SERVER_PATH: otland-forgottenserver - name: Save screenshots From eb73fc4538dcaf5a310a113d22549d28fd8f95e7 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:19:46 +0200 Subject: [PATCH 083/232] try fix cypress --- .github/workflows/cypress.yml | 2 +- cypress/e2e/1-install.cy.js | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 0ce69768..9f921663 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -65,7 +65,7 @@ jobs: uses: cypress-io/github-action@v5 env: CYPRESS_URL: http://localhost:8080 - CYPRESS_SERVER_PATH: otland-forgottenserver + CYPRESS_SERVER_PATH: tfs - name: Save screenshots uses: actions/upload-artifact@v3 diff --git a/cypress/e2e/1-install.cy.js b/cypress/e2e/1-install.cy.js index dffe065a..87179946 100644 --- a/cypress/e2e/1-install.cy.js +++ b/cypress/e2e/1-install.cy.js @@ -73,15 +73,4 @@ describe('Install MyAAC', () => { cy.screenshot('install-finish') }) - - it('Take Screenshot of the Home Page', () => { - cy.wait(1000) - cy.screenshot('home') - }) - - it('Take Screenshot of Create Account page', () => { - cy.visit(Cypress.env('URL') + '/index.php/account/create') - cy.wait(1000) - cy.screenshot('create-account-page') - }) }) From d911b55e25ee0c356cb8c327ce37470d53b30ab2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:24:49 +0200 Subject: [PATCH 084/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 9f921663..710170b2 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -65,7 +65,7 @@ jobs: uses: cypress-io/github-action@v5 env: CYPRESS_URL: http://localhost:8080 - CYPRESS_SERVER_PATH: tfs + CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs - name: Save screenshots uses: actions/upload-artifact@v3 From 80af2cd69170ce333f67c8829a300de6afdf3a77 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:47:39 +0200 Subject: [PATCH 085/232] cypress-workflow: config.lua move + replace values --- .github/workflows/cypress.yml | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 710170b2..3f747bb6 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -14,7 +14,9 @@ jobs: env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: myaac-tfs-latest + MYSQL_DATABASE: myaac-tfs + MYSQL_USER: myaac + MYSQL_PASSWORD: myaac ports: - 3306/tcp options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 @@ -35,6 +37,33 @@ jobs: ref: 1.4 path: tfs + - name: Rename config.lua + run: mv tfs/config.lua.dist tfs/config.lua + + - name: Replace mysqlUser + uses: jacobtomlinson/gha-find-replace@v2 + with: + find: 'mysqlUser = "forgottenserver"' + replace: 'mysqlUser = "myaac"' + regex: false + include: 'config.lua' + + - name: Replace mysqlPassword + uses: jacobtomlinson/gha-find-replace@v2 + with: + find: 'mysqlPassword = ""' + replace: 'mysqlPassword = "myaac"' + regex: false + include: 'config.lua' + + - name: Replace mysqlDatabase + uses: jacobtomlinson/gha-find-replace@v2 + with: + find: 'mysqlDatabase = "forgottenserver"' + replace: 'mysqlDatabase = "myaac-tfs-latest"' + regex: false + include: 'config.lua' + - run: ls -lha - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -65,7 +94,7 @@ jobs: uses: cypress-io/github-action@v5 env: CYPRESS_URL: http://localhost:8080 - CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs + CYPRESS_SERVER_PATH: tfs - name: Save screenshots uses: actions/upload-artifact@v3 From a6e109799a33c412c94b675bce8c4384bf0e9fff Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:48:55 +0200 Subject: [PATCH 086/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 3f747bb6..33bb2d6c 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -60,7 +60,7 @@ jobs: uses: jacobtomlinson/gha-find-replace@v2 with: find: 'mysqlDatabase = "forgottenserver"' - replace: 'mysqlDatabase = "myaac-tfs-latest"' + replace: 'mysqlDatabase = "myaac-tfs"' regex: false include: 'config.lua' From 3fab52296a4f01f86d7f14485723b96f2f0a6243 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:52:11 +0200 Subject: [PATCH 087/232] Update cypress.yml --- .github/workflows/cypress.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 33bb2d6c..512ab8c8 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -37,6 +37,9 @@ jobs: ref: 1.4 path: tfs + - run: ls -lha /home/runner/work/myaac/myaac/tfs + - run: ls -lha /home/runner/work/myaac/myaac/index.php + - name: Rename config.lua run: mv tfs/config.lua.dist tfs/config.lua @@ -94,7 +97,7 @@ jobs: uses: cypress-io/github-action@v5 env: CYPRESS_URL: http://localhost:8080 - CYPRESS_SERVER_PATH: tfs + CYPRESS_SERVER_PATH: /home/runner/work/myaac/myaac/tfs - name: Save screenshots uses: actions/upload-artifact@v3 From d1b30619e2d60e7e2fdc14c0e5a7f88fac2e8b32 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 09:56:49 +0200 Subject: [PATCH 088/232] fix path to config.lua --- .github/workflows/cypress.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 512ab8c8..797a513a 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -49,7 +49,7 @@ jobs: find: 'mysqlUser = "forgottenserver"' replace: 'mysqlUser = "myaac"' regex: false - include: 'config.lua' + include: 'tfs/config.lua' - name: Replace mysqlPassword uses: jacobtomlinson/gha-find-replace@v2 @@ -57,7 +57,7 @@ jobs: find: 'mysqlPassword = ""' replace: 'mysqlPassword = "myaac"' regex: false - include: 'config.lua' + include: 'tfs/config.lua' - name: Replace mysqlDatabase uses: jacobtomlinson/gha-find-replace@v2 @@ -65,7 +65,7 @@ jobs: find: 'mysqlDatabase = "forgottenserver"' replace: 'mysqlDatabase = "myaac-tfs"' regex: false - include: 'config.lua' + include: 'tfs/config.lua' - run: ls -lha - name: Setup PHP From 31ba7800997a2c640e46e2ab580720e6218892c6 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:08:51 +0200 Subject: [PATCH 089/232] Update cypress.yml --- .github/workflows/cypress.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 797a513a..aab128dc 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -37,9 +37,6 @@ jobs: ref: 1.4 path: tfs - - run: ls -lha /home/runner/work/myaac/myaac/tfs - - run: ls -lha /home/runner/work/myaac/myaac/index.php - - name: Rename config.lua run: mv tfs/config.lua.dist tfs/config.lua @@ -67,7 +64,9 @@ jobs: regex: false include: 'tfs/config.lua' - - run: ls -lha + - run: ls -lha /home/runner/work/myaac/myaac/tfs + - run: ls -lha /home/runner/work/myaac/myaac/index.php + - name: Setup PHP uses: shivammathur/setup-php@v2 with: From 317ebf43878f5d5a51475e3546f5087a9266fc6c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:12:28 +0200 Subject: [PATCH 090/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index aab128dc..55517ec2 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -65,7 +65,7 @@ jobs: include: 'tfs/config.lua' - run: ls -lha /home/runner/work/myaac/myaac/tfs - - run: ls -lha /home/runner/work/myaac/myaac/index.php + - run: cat tfs/config.lua - name: Setup PHP uses: shivammathur/setup-php@v2 From b33e39491bd68d32123817a6f55eeaf0df04136b Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:19:13 +0200 Subject: [PATCH 091/232] MySQL needs to be started manually --- .github/workflows/cypress.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 55517ec2..014b65bb 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:latest + image: mysql:8.0 env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: password @@ -25,6 +25,10 @@ jobs: matrix: php-versions: [ '7.4', '8.0', '8.1' ] steps: + - name: Start MySQL + run: | + sudo /etc/init.d/mysql start + - name: Checkout MyAAC uses: actions/checkout@v3 with: From 523f2dee7cc8b7425e8d0592bad3d222e8c18c3d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:21:05 +0200 Subject: [PATCH 092/232] mysqlPass --- .github/workflows/cypress.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 014b65bb..8edba283 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -52,11 +52,11 @@ jobs: regex: false include: 'tfs/config.lua' - - name: Replace mysqlPassword + - name: Replace mysqlPass uses: jacobtomlinson/gha-find-replace@v2 with: - find: 'mysqlPassword = ""' - replace: 'mysqlPassword = "myaac"' + find: 'mysqlPass = ""' + replace: 'mysqlPass = "myaac"' regex: false include: 'tfs/config.lua' From d346a8f73f09735423f3497566f3a265277b7a5e Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:27:38 +0200 Subject: [PATCH 093/232] Update cypress.yml --- .github/workflows/cypress.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 8edba283..6242298f 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:8.0 + image: mysql:latest env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: password @@ -68,9 +68,6 @@ jobs: regex: false include: 'tfs/config.lua' - - run: ls -lha /home/runner/work/myaac/myaac/tfs - - run: cat tfs/config.lua - - name: Setup PHP uses: shivammathur/setup-php@v2 with: From 7039bda359a0d30db1e6569934afe0fe450b4023 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:38:30 +0200 Subject: [PATCH 094/232] Update cypress.yml --- .github/workflows/cypress.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 6242298f..7c198eb0 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -68,6 +68,7 @@ jobs: regex: false include: 'tfs/config.lua' + - run: cat tfs/config.lua - name: Setup PHP uses: shivammathur/setup-php@v2 with: From 2b8c4b3eca191805088e8a426952fb7aa9369f25 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:44:02 +0200 Subject: [PATCH 095/232] test connect with root --- .github/workflows/cypress.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 7c198eb0..a52202a9 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -13,7 +13,7 @@ jobs: image: mysql:latest env: MYSQL_ALLOW_EMPTY_PASSWORD: false - MYSQL_ROOT_PASSWORD: password + MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: myaac-tfs MYSQL_USER: myaac MYSQL_PASSWORD: myaac @@ -48,7 +48,7 @@ jobs: uses: jacobtomlinson/gha-find-replace@v2 with: find: 'mysqlUser = "forgottenserver"' - replace: 'mysqlUser = "myaac"' + replace: 'mysqlUser = "root"' regex: false include: 'tfs/config.lua' @@ -56,7 +56,7 @@ jobs: uses: jacobtomlinson/gha-find-replace@v2 with: find: 'mysqlPass = ""' - replace: 'mysqlPass = "myaac"' + replace: 'mysqlPass = "root"' regex: false include: 'tfs/config.lua' From d60d7f225029691f844f383444e7bd1a27f3a431 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:48:47 +0200 Subject: [PATCH 096/232] test 5.7 mysql --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index a52202a9..6d789eb2 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:latest + image: mysql:5.7 env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: root From 6f7f25bb46c4cd094417598c200a2d964bbbc07f Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 10:54:57 +0200 Subject: [PATCH 097/232] Update cypress.yml --- .github/workflows/cypress.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 6d789eb2..1612a049 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:5.7 + image: mysql:latest env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: root @@ -29,6 +29,8 @@ jobs: run: | sudo /etc/init.d/mysql start + - name: Verify unittest_second DB exists + run: mysql --host 127.0.0.1 --port 3306 -uroot -proot -e "SHOW DATABASES" - name: Checkout MyAAC uses: actions/checkout@v3 with: @@ -68,7 +70,6 @@ jobs: regex: false include: 'tfs/config.lua' - - run: cat tfs/config.lua - name: Setup PHP uses: shivammathur/setup-php@v2 with: From 944457463ecef997b77bd36465aee5f1f7846ad8 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 11:01:44 +0200 Subject: [PATCH 098/232] Update cypress.yml --- .github/workflows/cypress.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 1612a049..e43f0ae0 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -20,10 +20,6 @@ jobs: ports: - 3306/tcp options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - strategy: - fail-fast: false - matrix: - php-versions: [ '7.4', '8.0', '8.1' ] steps: - name: Start MySQL run: | @@ -73,7 +69,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-versions }} + php-version: 8.0 extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql - name: Get composer cache directory From ef37bbcb81779000ca2a7b157bb9b1267f12fa8d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 11:49:24 +0200 Subject: [PATCH 099/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index e43f0ae0..5b027b3e 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:latest + image: mysql:5.7 env: MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: root From f372aeb067ae2b6a6702220fbba50b7b82336409 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:13:23 +0200 Subject: [PATCH 100/232] Update cypress.yml --- .github/workflows/cypress.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 5b027b3e..8c9828b3 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -10,9 +10,8 @@ jobs: runs-on: ubuntu-latest services: mysql: - image: mysql:5.7 + image: mysql:8.0 env: - MYSQL_ALLOW_EMPTY_PASSWORD: false MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: myaac-tfs MYSQL_USER: myaac From e71daa25206ed2a9f7ff24150c7a5a5946e18ab3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:18:51 +0200 Subject: [PATCH 101/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 8c9828b3..01967713 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -13,7 +13,7 @@ jobs: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: myaac-tfs + MYSQL_DATABASE: "myaac-tfs" MYSQL_USER: myaac MYSQL_PASSWORD: myaac ports: From b76a037a94d91598abc005cbac4090c01e28497d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:22:06 +0200 Subject: [PATCH 102/232] last try to fix mysql --- .github/workflows/cypress.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 01967713..3f8e3902 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -13,7 +13,7 @@ jobs: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: "myaac-tfs" + MYSQL_DATABASE: myaac MYSQL_USER: myaac MYSQL_PASSWORD: myaac ports: @@ -61,7 +61,7 @@ jobs: uses: jacobtomlinson/gha-find-replace@v2 with: find: 'mysqlDatabase = "forgottenserver"' - replace: 'mysqlDatabase = "myaac-tfs"' + replace: 'mysqlDatabase = "myaac"' regex: false include: 'tfs/config.lua' From bd031d8980bc59a1418e30968cc88bb7aec2a9ce Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:46:03 +0200 Subject: [PATCH 103/232] create database manually --- .github/workflows/cypress.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 3f8e3902..86834971 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -24,8 +24,13 @@ jobs: run: | sudo /etc/init.d/mysql start + - name: 📌 Initialize database + run: | + mysql -e 'CREATE DATABASE ${{ env.MYSQL_DATABASE }};' -u${{ env.MYSQL_USER }} -p${{ env.MYSQL_PASSWORD }} + - name: Verify unittest_second DB exists run: mysql --host 127.0.0.1 --port 3306 -uroot -proot -e "SHOW DATABASES" + - name: Checkout MyAAC uses: actions/checkout@v3 with: From 4a9fa01eb715acb64f6b57592e18c84716a72d59 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:49:11 +0200 Subject: [PATCH 104/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 86834971..1e0eae08 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -26,7 +26,7 @@ jobs: - name: 📌 Initialize database run: | - mysql -e 'CREATE DATABASE ${{ env.MYSQL_DATABASE }};' -u${{ env.MYSQL_USER }} -p${{ env.MYSQL_PASSWORD }} + mysql -e 'CREATE DATABASE myaac;' -umyaac -pmyaac - name: Verify unittest_second DB exists run: mysql --host 127.0.0.1 --port 3306 -uroot -proot -e "SHOW DATABASES" From 77a2c55c875182bb4b3312b7176fb97fc25f0144 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:50:37 +0200 Subject: [PATCH 105/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 1e0eae08..686aeb89 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -26,7 +26,7 @@ jobs: - name: 📌 Initialize database run: | - mysql -e 'CREATE DATABASE myaac;' -umyaac -pmyaac + mysql -e 'CREATE DATABASE myaac;' -uroot -proot - name: Verify unittest_second DB exists run: mysql --host 127.0.0.1 --port 3306 -uroot -proot -e "SHOW DATABASES" From 6ed15565c8f7a4c4de96fc9aa3b3413edd225f86 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:55:08 +0200 Subject: [PATCH 106/232] Import TFS Schema --- .github/workflows/cypress.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 686aeb89..3e48a016 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -28,8 +28,12 @@ jobs: run: | mysql -e 'CREATE DATABASE myaac;' -uroot -proot - - name: Verify unittest_second DB exists - run: mysql --host 127.0.0.1 --port 3306 -uroot -proot -e "SHOW DATABASES" + - name: Import TFS Schema + run: | + mysql -uroot -proot myaac < tfs/schema.sql + + - name: Verify DB exists + run: mysql -uroot -proot -e "SHOW DATABASES" - name: Checkout MyAAC uses: actions/checkout@v3 From 5aa02055bf25f67cfe923e55c8b0b4515a7cb7ec Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 12:58:28 +0200 Subject: [PATCH 107/232] fix path --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 3e48a016..52f8c4d7 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -30,7 +30,7 @@ jobs: - name: Import TFS Schema run: | - mysql -uroot -proot myaac < tfs/schema.sql + mysql -uroot -proot myaac < /home/runner/work/myaac/myaac/tfs/schema.sql - name: Verify DB exists run: mysql -uroot -proot -e "SHOW DATABASES" From 2f732b8411936710873f404a5b5d718457498d85 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:00:26 +0200 Subject: [PATCH 108/232] wrong position --- .github/workflows/cypress.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 52f8c4d7..5461d006 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -28,10 +28,6 @@ jobs: run: | mysql -e 'CREATE DATABASE myaac;' -uroot -proot - - name: Import TFS Schema - run: | - mysql -uroot -proot myaac < /home/runner/work/myaac/myaac/tfs/schema.sql - - name: Verify DB exists run: mysql -uroot -proot -e "SHOW DATABASES" @@ -47,6 +43,10 @@ jobs: ref: 1.4 path: tfs + - name: Import TFS Schema + run: | + mysql -uroot -proot myaac < tfs/schema.sql + - name: Rename config.lua run: mv tfs/config.lua.dist tfs/config.lua From 4bd761c72609108f9c925e4ad10e7e6d7d43afdb Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:05:29 +0200 Subject: [PATCH 109/232] remove typo --- cypress/e2e/1-install.cy.js | 1 - 1 file changed, 1 deletion(-) diff --git a/cypress/e2e/1-install.cy.js b/cypress/e2e/1-install.cy.js index 87179946..d034a52e 100644 --- a/cypress/e2e/1-install.cy.js +++ b/cypress/e2e/1-install.cy.js @@ -69,7 +69,6 @@ describe('Install MyAAC', () => { cy.get('form').submit() cy.wait(1000); - cy.get('.class', { timeout: 12_000 }).should('be.visible') cy.screenshot('install-finish') }) From 2acec4df1273b168da9ddcd2435c915a787c27f2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:05:35 +0200 Subject: [PATCH 110/232] bring back matrix, wasn't the issue --- .github/workflows/cypress.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 5461d006..3b6756cf 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -19,6 +19,10 @@ jobs: ports: - 3306/tcp options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + strategy: + fail-fast: false + matrix: + php-versions: [ '7.4', '8.0', '8.1' ] steps: - name: Start MySQL run: | @@ -77,7 +81,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.0 + php-version: ${{ matrix.php-versions }} extensions: mbstring, dom, fileinfo, mysql, json, xml, pdo, pdo_mysql - name: Get composer cache directory From dcb9506a1bd1803da112356d0bb3c6ef2b397e49 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:10:14 +0200 Subject: [PATCH 111/232] admin is already created during install --- cypress/e2e/2-create-account.cy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/2-create-account.cy.js b/cypress/e2e/2-create-account.cy.js index 11d87409..9fc95cb0 100644 --- a/cypress/e2e/2-create-account.cy.js +++ b/cypress/e2e/2-create-account.cy.js @@ -10,8 +10,8 @@ describe('Create Account Page', () => { it('Create Test Account', () => { cy.screenshot('create-account-page') - cy.get('#account_input').type('admin') - cy.get('#email').type('admin@example.com') + cy.get('#account_input').type('tester') + cy.get('#email').type('tester@example.com') cy.get('#password').type('test1234') cy.get('#password2').type('test1234') From 5cbb55cfb1820b6b06e2349279a92b1f12e812c6 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:11:39 +0200 Subject: [PATCH 112/232] Upload videos too --- .github/workflows/cypress.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 3b6756cf..f53feaa3 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -113,5 +113,12 @@ jobs: uses: actions/upload-artifact@v3 if: always() with: - name: cypress-screenshots - path: cypress/screenshots + name: cypress-screenshots + path: cypress/screenshots + + - name: Upload Cypress Videos + uses: actions/upload-artifact@v3 + if: always() + with: + name: cypress-videos + path: cypress/videos From 26c895d475de3b6dda8ffd634660c751a4042274 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 13:51:05 +0200 Subject: [PATCH 113/232] Block access to some files [skip ci] --- .htaccess | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index 042cb23a..1c837a33 100644 --- a/.htaccess +++ b/.htaccess @@ -6,10 +6,14 @@ Options -MultiViews + + Require all denied + + RewriteEngine On - #RewriteBase /myaac/ + #RewriteBase /myaac/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d From 480a054f0c859cab85fa3d73ac2afd7f23cc516f Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 14:04:52 +0200 Subject: [PATCH 114/232] Fixed ADMIN_PANEL_FOLDER, can be 100% custom now --- common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.php b/common.php index fff55002..5adc7209 100644 --- a/common.php +++ b/common.php @@ -138,7 +138,7 @@ if(!IS_CLI) { define('SERVER_URL', 'http' . (isset($_SERVER['HTTPS'][0]) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . $baseHost); define('BASE_URL', SERVER_URL . BASE_DIR . '/'); - define('ADMIN_URL', SERVER_URL . BASE_DIR . '/admin/'); + define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/'); //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); From 77e0d28a9d00785094f1654814aa624e31655f2d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 14:09:10 +0200 Subject: [PATCH 115/232] Delete .travis.yml --- .travis.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eba123be..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ - -language: php -php: - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - 8.0 - -cache: - directories: - - $HOME/.composer/cache - -before_script: - - composer require php-parallel-lint/php-parallel-lint --no-suggest --no-progress --no-interaction --no-ansi --quiet --optimize-autoloader - -script: - - php vendor/bin/parallel-lint --no-progress --no-colors --exclude vendor --exclude "system/libs/pot/OTS_DB_PDOQuery.php" . From bc8e5fc14467a108cf9b58a02e420f5404a177ad Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 14:51:33 +0200 Subject: [PATCH 116/232] Update .gitattributes --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index aa70eefb..283fef4e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,7 +3,6 @@ .gitignore export-ignore .github export-ignore .editorconfig export-ignore -.travis.yml export-ignore _config.yml export-ignore release.sh export-ignore From 09a045334c30cc14e75615b0d13ba00caa4090bd Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 14:53:33 +0200 Subject: [PATCH 117/232] Update cypress.yml --- .github/workflows/cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index f53feaa3..f42b459a 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -1,4 +1,4 @@ -name: Cypress Test +name: Cypress on: pull_request: branches: [develop] From 8d98306f8e85bcbc9d5af8e5915c98fb3fec8ba9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 16:12:50 +0200 Subject: [PATCH 118/232] optimize workflow --- .github/workflows/cypress.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index f42b459a..2909555a 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -23,17 +23,13 @@ jobs: fail-fast: false matrix: php-versions: [ '7.4', '8.0', '8.1' ] + name: MyAAC on PHP ${{ matrix.php-versions }} steps: - - name: Start MySQL + - name: 📌 MySQL Start & init & show db run: | sudo /etc/init.d/mysql start - - - name: 📌 Initialize database - run: | mysql -e 'CREATE DATABASE myaac;' -uroot -proot - - - name: Verify DB exists - run: mysql -uroot -proot -e "SHOW DATABASES" + mysql -e "SHOW DATABASES" -uroot -proot - name: Checkout MyAAC uses: actions/checkout@v3 From 067f2af3e5ea836171f1316907cb8f3b01cc18c9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 16:15:39 +0200 Subject: [PATCH 119/232] Wait for success, then screenshot --- cypress/e2e/1-install.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/e2e/1-install.cy.js b/cypress/e2e/1-install.cy.js index d034a52e..84a8f51b 100644 --- a/cypress/e2e/1-install.cy.js +++ b/cypress/e2e/1-install.cy.js @@ -68,7 +68,7 @@ describe('Install MyAAC', () => { cy.get('form').submit() - cy.wait(1000); + cy.contains('[class="alert alert-success"]', 'Congratulations', { timeout: 30000 }).should('be.visible') cy.screenshot('install-finish') }) From ea08c0496373490b766c2697ec2ce4aad56ad90e Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 16:49:28 +0200 Subject: [PATCH 120/232] nothing important --- install/template/template.php | 10 +++++----- system/templates/install.config.html.twig | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/install/template/template.php b/install/template/template.php index 862a97af..5d4afd15 100644 --- a/install/template/template.php +++ b/install/template/template.php @@ -11,7 +11,7 @@
      - + @@ -28,10 +28,10 @@ if ($step == $value) { $progress = ($i == 6) ? 100 : $i * 16; } - - echo '' . ++$i . '. ' . $locale['step_' . $value] . '
    • '; + + echo '
    • ' . ++$i . '. ' . $locale['step_' . $value] . '
    • '; } - + ?>
    @@ -71,4 +71,4 @@

    - \ No newline at end of file + diff --git a/system/templates/install.config.html.twig b/system/templates/install.config.html.twig index a6ba24f7..b25f9dbf 100644 --- a/system/templates/install.config.html.twig +++ b/system/templates/install.config.html.twig @@ -12,7 +12,7 @@ {% for value in ['server_path', 'mail_admin'] %}
    - + {{ locale['step_config_' ~ value ~ '_desc'] }}
    {% endfor %} @@ -43,9 +43,9 @@ {{ locale.step_config_usage_desc }}
    - +
    {{ buttons|raw }}
    - \ No newline at end of file + From bedfc0a2e039d863684afc291477cb7c996e222c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 17:50:38 +0200 Subject: [PATCH 121/232] Update bootstrap to v5.2.3 in install --- install/template/template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/template/template.php b/install/template/template.php index 5d4afd15..8f015f79 100644 --- a/install/template/template.php +++ b/install/template/template.php @@ -4,7 +4,7 @@ MyAAC - <?php echo $locale['installation']; ?> - + From 0187ba49382dc3ba3794027784664b2f53b405bb Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 26 May 2023 22:49:24 +0200 Subject: [PATCH 122/232] New hook: HOOK_ACCOUNT_CREATE_AFTER_PASSWORD for password strength meter --- system/hooks.php | 1 + system/templates/account.create.html.twig | 3 +++ 2 files changed, 4 insertions(+) diff --git a/system/hooks.php b/system/hooks.php index 1aa33283..f089b102 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -40,6 +40,7 @@ define('HOOK_ACCOUNT_CREATE_BEFORE_ACCOUNT', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_ACCOUNT', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_EMAIL', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_COUNTRY', ++$i); +define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORD', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS', ++$i); define('HOOK_ACCOUNT_CREATE_BEFORE_CHARACTER_NAME', ++$i); define('HOOK_ACCOUNT_CREATE_AFTER_CHARACTER_NAME', ++$i); diff --git a/system/templates/account.create.html.twig b/system/templates/account.create.html.twig index 8e885b43..38907c74 100644 --- a/system/templates/account.create.html.twig +++ b/system/templates/account.create.html.twig @@ -96,6 +96,9 @@ {% if errors.password is defined %}{{ errors.password }}{% endif %} + + {{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORD') }} + Repeat password: From 2841f177292bfbf390357aec732f6a84b751233c Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 28 May 2023 23:54:36 +0200 Subject: [PATCH 123/232] fix images base url, uploaded by tinymce --- system/templates/tinymce.html.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/system/templates/tinymce.html.twig b/system/templates/tinymce.html.twig index 880de4f0..adc1e3c9 100644 --- a/system/templates/tinymce.html.twig +++ b/system/templates/tinymce.html.twig @@ -13,10 +13,10 @@ image_advtab: true, images_upload_url: '{{ constant('BASE_URL') }}admin/tools/upload_image.php', images_upload_credentials: true, - // not really sure - do we need those 3 options below? - //relative_urls: false, - //remove_script_host: false, - //document_base_url: "{{ constant('BASE_URL') }}" + + relative_urls: true, + document_base_url: "{{ constant('BASE_URL') }}", + setup: function (ed) { ed.on('NodeChange', function (e) { if (ed.getContent() !== lastContent) { From 83915f080c019c059f48dbc588011d174c389aba Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 28 May 2023 23:56:26 +0200 Subject: [PATCH 124/232] Fixed when page is hidden --- system/router.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/system/router.php b/system/router.php index 879ad727..1a2cab23 100644 --- a/system/router.php +++ b/system/router.php @@ -285,9 +285,10 @@ if(config('backward_support')) { unset($page); -function getDatabasePages() { - global $db; - $pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages'); +function getDatabasePages($withHidden = false): array +{ + global $db, $logged_access; + $pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages WHERE ' . ($withHidden ? '' : '`hidden` != 1 AND ') . '`access` <= ' . $db->quote($logged_access)); $ret = []; if ($pages->rowCount() < 1) { From 080ab56ea94b65276dada37d68414cd5c17a926d Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 28 May 2023 23:56:35 +0200 Subject: [PATCH 125/232] Update functions.php --- system/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/functions.php b/system/functions.php index 97779601..cb280030 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1192,7 +1192,7 @@ function getCustomPageInfo($page) return null; } -function getCustomPage($page, &$success) +function getCustomPage($page, &$success): string { global $db, $twig, $title, $ignore, $logged_access; From 7dc2e404edcd9e3fa3f8c1388d148bbe9c1cccb3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 29 May 2023 00:00:34 +0200 Subject: [PATCH 126/232] Fixed many links to admin panel, if ADMIN_PANEL_FOLDER is changed --- admin/pages/accounts.php | 2 +- admin/pages/phpinfo.php | 2 +- admin/pages/players.php | 2 +- system/pages/news.php | 6 +++--- system/templates/admin.pages.links.html.twig | 8 ++++---- system/templates/characters.html.twig | 4 ++-- system/templates/tinymce.html.twig | 2 +- templates/tibiacom/news.featured_article.html.twig | 8 ++++---- templates/tibiacom/news.tickers.html.twig | 6 +++--- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 759b9361..550ea670 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -10,7 +10,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Account editor'; -$admin_base = BASE_URL . 'admin/?p=accounts'; +$admin_base = ADMIN_URL . '?p=accounts'; $use_datatable = true; if ($config['account_country']) diff --git a/admin/pages/phpinfo.php b/admin/pages/phpinfo.php index bc747a2d..43942bfd 100644 --- a/admin/pages/phpinfo.php +++ b/admin/pages/phpinfo.php @@ -16,4 +16,4 @@ if (!function_exists('phpinfo')) { ?> - + diff --git a/admin/pages/players.php b/admin/pages/players.php index d9a5dece..b32d5445 100644 --- a/admin/pages/players.php +++ b/admin/pages/players.php @@ -10,7 +10,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Player editor'; -$player_base = BASE_URL . 'admin/?p=players'; +$player_base = ADMIN_URL . '?p=players'; $use_datatable = true; require_once LIBS . 'forum.php'; diff --git a/system/pages/news.php b/system/pages/news.php index 92d2e7ab..db04092d 100644 --- a/system/pages/news.php +++ b/system/pages/news.php @@ -182,13 +182,13 @@ if(!$news_cached) $admin_options = ''; if($canEdit) { - $admin_options = '

    + $admin_options = '

    Edit - + Delete - + ' . ($news['hidden'] != 1 ? 'Hide' : 'Show') . ' '; diff --git a/system/templates/admin.pages.links.html.twig b/system/templates/admin.pages.links.html.twig index 135055c0..d8529e3e 100644 --- a/system/templates/admin.pages.links.html.twig +++ b/system/templates/admin.pages.links.html.twig @@ -1,14 +1,14 @@ \ No newline at end of file +
    diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index aad31aa8..6eed98ec 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -11,7 +11,7 @@ {{ hook(constant('HOOK_CHARACTERS_BEFORE_INFORMATIONS')) }} {% if canEdit %} - + Edit {% endif %} @@ -418,7 +418,7 @@ {% endif %} {{ hook(constant('HOOK_CHARACTERS_AFTER_CHARACTERS')) }} {% if canEdit %} - + Edit {% endif %} diff --git a/system/templates/tinymce.html.twig b/system/templates/tinymce.html.twig index adc1e3c9..02ad29bb 100644 --- a/system/templates/tinymce.html.twig +++ b/system/templates/tinymce.html.twig @@ -11,7 +11,7 @@ toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code', resize: 'both', image_advtab: true, - images_upload_url: '{{ constant('BASE_URL') }}admin/tools/upload_image.php', + images_upload_url: '{{ constant('ADMIN_URL') }}tools/upload_image.php', images_upload_credentials: true, relative_urls: true, diff --git a/templates/tibiacom/news.featured_article.html.twig b/templates/tibiacom/news.featured_article.html.twig index ad82dcaf..fa704814 100644 --- a/templates/tibiacom/news.featured_article.html.twig +++ b/templates/tibiacom/news.featured_article.html.twig @@ -20,13 +20,13 @@

    {{ article.title|raw }} {% if canEdit %} - + Edit - + Delete - + {% if article.hidden != 1 %}Hide{% else %}Show{% endif %} @@ -42,4 +42,4 @@

    -
    \ No newline at end of file +
    diff --git a/templates/tibiacom/news.tickers.html.twig b/templates/tibiacom/news.tickers.html.twig index c0cf1cdf..48e62a49 100644 --- a/templates/tibiacom/news.tickers.html.twig +++ b/templates/tibiacom/news.tickers.html.twig @@ -20,15 +20,15 @@
    {{ ticker.body_short|raw }}
    {{ ticker.body|raw }} {% if canEdit %} - + Edit - + Delete - + {% if ticker.hidden != 1 %}Hide{% else %}Show{% endif %} From 7690811da3984a04c0c9080462e56bb818ab52ea Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 29 May 2023 08:46:07 +0200 Subject: [PATCH 127/232] Update install.php --- system/locale/de/install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/locale/de/install.php b/system/locale/de/install.php index 5cb7342e..85be3b16 100644 --- a/system/locale/de/install.php +++ b/system/locale/de/install.php @@ -20,7 +20,7 @@ $locale['not_loaded'] = 'Nicht geladen'; $locale['loading_spinner'] = 'Bitte warten, installieren...'; $locale['importing_spinner'] = 'Bitte warte, Daten werden importiert...'; $locale['please_fill_all'] = 'Bitte füllen Sie alle Felder aus!'; -$locale['already_installed'] = 'MyAAC wurde bereits installiert. Bitte löschen install/ Verzeichnis. Wenn Sie MyAAC neu installieren möchten, löschen Sie die Datei config.local.php aus dem Hauptverzeichnis und aktualisieren Sie die Seite.'; +$locale['already_installed'] = 'MyAAC wurde bereits installiert. Bitte löschen install/ Verzeichnis. Wenn Sie MyAAC neu installieren möchten, löschen Sie die Datei config.local.php aus dem Hauptverzeichnis und aktualisieren Sie die Seite.'; // welcome $locale['step_welcome'] = 'Willkommen'; From 7c2c88f780edf0cee9306588f0830ff2f0e81af1 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 29 May 2023 08:55:26 +0200 Subject: [PATCH 128/232] Add Whoops exception handler (nicer debug info in dev mode) On production = no errors --- CHANGELOG.md | 1 + common.php | 2 - composer.json | 3 +- system/exception.php | 50 +++--------------- system/init.php | 4 ++ system/libs/SensitiveException.php | 3 -- system/templates/exception.html.twig | 79 ---------------------------- 7 files changed, 15 insertions(+), 127 deletions(-) delete mode 100644 system/libs/SensitiveException.php delete mode 100644 system/templates/exception.html.twig diff --git a/CHANGELOG.md b/CHANGELOG.md index 37dc4488..14d61d9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Minimum PHP version for this release is 7.2.5. * support for Account Number * suggest account number option * many new functions, hooks and configurables +* better Exception Handler (Whoops - https://github.com/filp/whoops) ### Changed * Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc. diff --git a/common.php b/common.php index 5adc7209..109bd3ae 100644 --- a/common.php +++ b/common.php @@ -141,8 +141,6 @@ if(!IS_CLI) { define('ADMIN_URL', SERVER_URL . BASE_DIR . '/' . ADMIN_PANEL_FOLDER . '/'); //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); - - require SYSTEM . 'exception.php'; } $autoloadFile = VENDOR . 'autoload.php'; diff --git a/composer.json b/composer.json index cd16bf18..0a17947e 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "twig/twig": "^2.0", "erusev/parsedown": "^1.7", "nikic/fast-route": "^1.3", - "matomo/device-detector": "^6.0" + "matomo/device-detector": "^6.0", + "filp/whoops": "^2.15" } } diff --git a/system/exception.php b/system/exception.php index e46f0d54..9a233000 100644 --- a/system/exception.php +++ b/system/exception.php @@ -1,54 +1,20 @@ * @copyright 2023 MyAAC * @link https://my-aac.org */ -require LIBS . 'SensitiveException.php'; -/** - * @param Exception $exception - */ -function exception_handler($exception) { - $message = $exception->getMessage(); - if($exception instanceof SensitiveException) { - $message = 'This error is sensitive and has been logged into ' . LOGS . 'error.log.
    View this file for more information.'; +$whoops = new \Whoops\Run; - // log error to file - $f = fopen(LOGS . 'error.log', 'ab'); - if(!$f) { - $message = 'We wanted to save detailed informations about this error, but file: ' . LOGS . "error.log couldn't be opened for writing.. so the detailed information couldn't be saved.. are you sure directory system/logs is writable by web server? Correct this, and then refresh this site."; - } - else { - fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $exception->getMessage() . PHP_EOL); - fclose($f); - } - } - - $backtrace_formatted = nl2br($exception->getTraceAsString()); - - // display basic error message without template - // template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right - $template_file = SYSTEM . 'templates/exception.html.twig'; - if(!file_exists($template_file)) { - echo 'Something went terribly wrong..

    '; - echo "$message

    "; - echo 'Backtrace:
    '; - echo $backtrace_formatted; - return; - } - - // display beautiful error message - // the file is .twig.html, but its not really parsed by Twig - // we just replace some values manually - // cause in case Twig throws exception, we can show it too - $content = file_get_contents($template_file); - $content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); - - echo $content; +if(IS_CLI) { + $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); +} +else { + $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); } -set_exception_handler('exception_handler'); +$whoops->register(); diff --git a/system/init.php b/system/init.php index f2ea9ee2..056bbd40 100644 --- a/system/init.php +++ b/system/init.php @@ -18,6 +18,10 @@ if(!isset($config['installed']) || !$config['installed']) { throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.'); } +if(config('env') === 'dev') { + require SYSTEM . 'exception.php'; +} + date_default_timezone_set($config['date_timezone']); // take care of trailing slash at the end if($config['server_path'][strlen($config['server_path']) - 1] !== '/') diff --git a/system/libs/SensitiveException.php b/system/libs/SensitiveException.php deleted file mode 100644 index 58978198..00000000 --- a/system/libs/SensitiveException.php +++ /dev/null @@ -1,3 +0,0 @@ - - - - - - - Something went wrong... - - - - - - - - - - - -
    -

    Whoops something went wrong...

    -
    - Exception class: {{ exceptionClass }}() -

    - {{ message }} -


    - Backtrace:

    - {{ backtrace }} -
    -
    - - - From 9cc60983d06f9349308dc0d4650b314a138108c3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 29 May 2023 08:55:41 +0200 Subject: [PATCH 129/232] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d61d9f..9d157137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Minimum PHP version for this release is 7.2.5. * suggest account number option * many new functions, hooks and configurables * better Exception Handler (Whoops - https://github.com/filp/whoops) +* add Cypress testing ### Changed * Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc. From dce0ac2f8fe58326009366724776120646ee9596 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 29 May 2023 10:09:21 +0200 Subject: [PATCH 130/232] nothing important --- CHANGELOG.md | 3 ++- CREDITS | 2 +- install/steps/5-database.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d157137..4ec987f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Minimum PHP version for this release is 7.2.5. * new Admin Bar showed on top when admin logged in * new page: Server Data, to reload server data * new pages: mass account & teleport tools - * editable changelogs + * changelogs editor * revised Accounts & Players editors * option to add/modify menus with plugins * option to enable/disable plugins @@ -46,6 +46,7 @@ Minimum PHP version for this release is 7.2.5. * Highscores * frags works for TFS 1.x * cached + * creatures * moved pages to Twig: * experience stages * update player_deaths entries on name change diff --git a/CREDITS b/CREDITS index 404de30c..878310df 100644 --- a/CREDITS +++ b/CREDITS @@ -1,3 +1,3 @@ * Gesior.pl (2007 - 2008) -* Slawkens (2009 - 2022) +* Slawkens (2009 - 2023) * Contributors listed in CONTRIBUTORS.txt diff --git a/install/steps/5-database.php b/install/steps/5-database.php index 13a79d56..a133f236 100644 --- a/install/steps/5-database.php +++ b/install/steps/5-database.php @@ -116,7 +116,7 @@ if(!$error) {
    -
    From 1846bf52559495fc6d9ae551c1da4dd7ef826985 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 1 Jun 2023 09:57:20 +0200 Subject: [PATCH 131/232] Change button style (characters - view) was causing issues in other templates --- system/templates/characters.html.twig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 6eed98ec..3bbb0159 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -404,7 +404,8 @@ - + {% set button_name = "View" %} + {{ include('buttons.base.html.twig') }} From ca8db22639c3cc97034c4c3dd314fcf974578145 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 1 Jun 2023 11:23:28 +0200 Subject: [PATCH 132/232] Better news back button --- system/templates/news.back_button.html.twig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/templates/news.back_button.html.twig b/system/templates/news.back_button.html.twig index 7bb86712..42a9c951 100644 --- a/system/templates/news.back_button.html.twig +++ b/system/templates/news.back_button.html.twig @@ -4,10 +4,11 @@ - + {% set button_name = 'Back' %} + {{ include('buttons.base.html.twig') }} -
    \ No newline at end of file +
    From f34e5f2ac02eaf3514ca11fe05a90c4b789d0e50 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 06:37:25 +0200 Subject: [PATCH 133/232] Release 0.9.0-alpha --- CHANGELOG.md | 3 +-- common.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec987f9..399eba44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [0.9.0-alpha - x.x.2023] +## [0.9.0-alpha - 02.06.2023] Minimum PHP version for this release is 7.2.5. @@ -36,7 +36,6 @@ Minimum PHP version for this release is 7.2.5. ### Changed * Composer is now used for external libraries like: Twig, PHPMailer, fast-route etc. * mail support is disabled on fresh install, can be manually enabled by user -* don't show PHP errors on prod * disable add php pages in admin panel for security. Option to disable plugins upload * visitors counter shows now user browser, and also if its bot * changes in required and optional PHP extensions diff --git a/common.php b/common.php index 109bd3ae..16a3d92e 100644 --- a/common.php +++ b/common.php @@ -26,7 +26,7 @@ if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); const MYAAC = true; -const MYAAC_VERSION = '0.9.0-dev'; +const MYAAC_VERSION = '0.9.0-alpha'; const DATABASE_VERSION = 35; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); From 52ac0115562ae0954122959165f187fb6a09957d Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 08:04:13 +0200 Subject: [PATCH 134/232] Ignore cypress in git-export + install composer deps on release --- .gitattributes | 5 +++++ release.sh | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 283fef4e..40090cd9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,4 +6,9 @@ _config.yml export-ignore release.sh export-ignore +# cypress +cypress export-ignore +cypress.config.js export-ignore +cypress.env.json + *.sh text eol=lf diff --git a/release.sh b/release.sh index e720a3a9..8e104ea2 100644 --- a/release.sh +++ b/release.sh @@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then mkdir -p tmp # get myaac from git archive - git archive --format zip --output tmp/myaac.zip master + git archive --format zip --output tmp/myaac.zip 0.9 cd tmp/ || exit @@ -35,6 +35,11 @@ if [ $1 = "prepare" ]; then unzip -q myaac.zip -d $dir rm myaac.zip + cd $dir || exit + + # dependencies + composer install + echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'" exit fi @@ -62,4 +67,4 @@ if [ $1 = "pack" ]; then echo "Done. Released files can be found in 'releases' directory." exit -fi \ No newline at end of file +fi From 1a2e46f09bd628978f9524d80dc4f8d86a7792a5 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 08:04:13 +0200 Subject: [PATCH 135/232] Ignore cypress in git-export + install composer deps on release --- .gitattributes | 5 +++++ release.sh | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 283fef4e..40090cd9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,4 +6,9 @@ _config.yml export-ignore release.sh export-ignore +# cypress +cypress export-ignore +cypress.config.js export-ignore +cypress.env.json + *.sh text eol=lf diff --git a/release.sh b/release.sh index e720a3a9..8e104ea2 100644 --- a/release.sh +++ b/release.sh @@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then mkdir -p tmp # get myaac from git archive - git archive --format zip --output tmp/myaac.zip master + git archive --format zip --output tmp/myaac.zip 0.9 cd tmp/ || exit @@ -35,6 +35,11 @@ if [ $1 = "prepare" ]; then unzip -q myaac.zip -d $dir rm myaac.zip + cd $dir || exit + + # dependencies + composer install + echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'" exit fi @@ -62,4 +67,4 @@ if [ $1 = "pack" ]; then echo "Done. Released files can be found in 'releases' directory." exit -fi \ No newline at end of file +fi From 0f30ebbcea3946bf3a3e3ffa40804dd12d4159b3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 08:05:13 +0200 Subject: [PATCH 136/232] change branch name in release.sh --- release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.sh b/release.sh index 8e104ea2..8d9d7705 100644 --- a/release.sh +++ b/release.sh @@ -22,7 +22,7 @@ if [ $1 = "prepare" ]; then mkdir -p tmp # get myaac from git archive - git archive --format zip --output tmp/myaac.zip 0.9 + git archive --format zip --output tmp/myaac.zip develop cd tmp/ || exit From cd22f8def50ede21e2a8b333664cf332aa130c63 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 15:20:07 +0200 Subject: [PATCH 137/232] Use Whoops only if installed, otherwise use myaac exception handler --- composer.json | 4 +- system/exception.php | 66 ++++++++++++++++++++--- system/libs/SensitiveException.php | 3 ++ system/templates/exception.html.twig | 79 ++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 system/libs/SensitiveException.php create mode 100644 system/templates/exception.html.twig diff --git a/composer.json b/composer.json index 0a17947e..b1300e34 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,9 @@ "twig/twig": "^2.0", "erusev/parsedown": "^1.7", "nikic/fast-route": "^1.3", - "matomo/device-detector": "^6.0", + "matomo/device-detector": "^6.0" + }, + "require-dev": { "filp/whoops": "^2.15" } } diff --git a/system/exception.php b/system/exception.php index 9a233000..077d0f3f 100644 --- a/system/exception.php +++ b/system/exception.php @@ -1,6 +1,6 @@ @@ -8,13 +8,63 @@ * @link https://my-aac.org */ -$whoops = new \Whoops\Run; +if (class_exists(\Whoops\Run::class)) { + $whoops = new \Whoops\Run; + if(IS_CLI) { + $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); + } + else { + $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + } -if(IS_CLI) { - $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); -} -else { - $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + $whoops->register(); + return; } -$whoops->register(); +require LIBS . 'SensitiveException.php'; + +/** + * @param Exception $exception + */ +function exception_handler($exception) { + $message = $exception->getMessage(); + if($exception instanceof SensitiveException) { + $message = 'This error is sensitive and has been logged into ' . LOGS . 'error.log.
    View this file for more information.'; + + // log error to file + $f = fopen(LOGS . 'error.log', 'ab'); + if(!$f) { + $message = 'We wanted to save detailed informations about this error, but file: ' . LOGS . "error.log couldn't be opened for writing.. so the detailed information couldn't be saved.. are you sure directory system/logs is writable by web server? Correct this, and then refresh this site."; + } + else { + fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $exception->getMessage() . PHP_EOL); + fclose($f); + } + } + + $backtrace_formatted = nl2br($exception->getTraceAsString()); + + $message = $message . "

    File: {$exception->getFile()}
    Line: {$exception->getLine()}"; + + // display basic error message without template + // template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right + $template_file = SYSTEM . 'templates/exception.html.twig'; + if(!file_exists($template_file)) { + echo 'Something went terribly wrong..

    '; + echo "$message

    "; + echo 'Backtrace:
    '; + echo $backtrace_formatted; + return; + } + + // display beautiful error message + // the file is .twig.html, but its not really parsed by Twig + // we just replace some values manually + // cause in case Twig throws exception, we can show it too + $content = file_get_contents($template_file); + $content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); + + echo $content; +} + +set_exception_handler('exception_handler'); diff --git a/system/libs/SensitiveException.php b/system/libs/SensitiveException.php new file mode 100644 index 00000000..58978198 --- /dev/null +++ b/system/libs/SensitiveException.php @@ -0,0 +1,3 @@ + + + + + + + Something went wrong... + + + + + + + + + + + +
    +

    Whoops something went wrong...

    +
    + Exception class: {{ exceptionClass }}() +

    + {{ message }} +


    + Backtrace:

    + {{ backtrace }} +
    +
    + + + From 48822b656133165ea1fda587c7813953cf250e8e Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 15:20:07 +0200 Subject: [PATCH 138/232] Use Whoops only if installed, otherwise use myaac exception handler --- composer.json | 4 +- system/exception.php | 66 ++++++++++++++++++++--- system/libs/SensitiveException.php | 3 ++ system/templates/exception.html.twig | 79 ++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 system/libs/SensitiveException.php create mode 100644 system/templates/exception.html.twig diff --git a/composer.json b/composer.json index 0a17947e..b1300e34 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,9 @@ "twig/twig": "^2.0", "erusev/parsedown": "^1.7", "nikic/fast-route": "^1.3", - "matomo/device-detector": "^6.0", + "matomo/device-detector": "^6.0" + }, + "require-dev": { "filp/whoops": "^2.15" } } diff --git a/system/exception.php b/system/exception.php index 9a233000..077d0f3f 100644 --- a/system/exception.php +++ b/system/exception.php @@ -1,6 +1,6 @@ @@ -8,13 +8,63 @@ * @link https://my-aac.org */ -$whoops = new \Whoops\Run; +if (class_exists(\Whoops\Run::class)) { + $whoops = new \Whoops\Run; + if(IS_CLI) { + $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); + } + else { + $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + } -if(IS_CLI) { - $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler); -} -else { - $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + $whoops->register(); + return; } -$whoops->register(); +require LIBS . 'SensitiveException.php'; + +/** + * @param Exception $exception + */ +function exception_handler($exception) { + $message = $exception->getMessage(); + if($exception instanceof SensitiveException) { + $message = 'This error is sensitive and has been logged into ' . LOGS . 'error.log.
    View this file for more information.'; + + // log error to file + $f = fopen(LOGS . 'error.log', 'ab'); + if(!$f) { + $message = 'We wanted to save detailed informations about this error, but file: ' . LOGS . "error.log couldn't be opened for writing.. so the detailed information couldn't be saved.. are you sure directory system/logs is writable by web server? Correct this, and then refresh this site."; + } + else { + fwrite($f, '[' . date(DateTime::RFC1123) . '] ' . $exception->getMessage() . PHP_EOL); + fclose($f); + } + } + + $backtrace_formatted = nl2br($exception->getTraceAsString()); + + $message = $message . "

    File: {$exception->getFile()}
    Line: {$exception->getLine()}"; + + // display basic error message without template + // template is missing, why? probably someone deleted templates dir, or it wasn't downloaded right + $template_file = SYSTEM . 'templates/exception.html.twig'; + if(!file_exists($template_file)) { + echo 'Something went terribly wrong..

    '; + echo "$message

    "; + echo 'Backtrace:
    '; + echo $backtrace_formatted; + return; + } + + // display beautiful error message + // the file is .twig.html, but its not really parsed by Twig + // we just replace some values manually + // cause in case Twig throws exception, we can show it too + $content = file_get_contents($template_file); + $content = str_replace(array('{{ BASE_URL }}', '{{ exceptionClass }}', '{{ message }}', '{{ backtrace }}', '{{ powered_by }}'), array(BASE_URL, get_class($exception), $message, $backtrace_formatted, base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4=')), $content); + + echo $content; +} + +set_exception_handler('exception_handler'); diff --git a/system/libs/SensitiveException.php b/system/libs/SensitiveException.php new file mode 100644 index 00000000..58978198 --- /dev/null +++ b/system/libs/SensitiveException.php @@ -0,0 +1,3 @@ + + + + + + + Something went wrong... + + + + + + + + + + + +
    +

    Whoops something went wrong...

    +
    + Exception class: {{ exceptionClass }}() +

    + {{ message }} +


    + Backtrace:

    + {{ backtrace }} +
    +
    + + + From c247789adf5a829d89c08248eeef23af5347474c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 15:24:10 +0200 Subject: [PATCH 139/232] is not working properly, use full URL instead --- system/templates/exception.html.twig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig index 7a31b4bb..f258830f 100644 --- a/system/templates/exception.html.twig +++ b/system/templates/exception.html.twig @@ -8,9 +8,8 @@ - - - + + From 9868b41a61d47990f2a5139906b164ebfe92160f Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 2 Jun 2023 15:24:10 +0200 Subject: [PATCH 140/232] is not working properly, use full URL instead --- system/templates/exception.html.twig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig index 7a31b4bb..f258830f 100644 --- a/system/templates/exception.html.twig +++ b/system/templates/exception.html.twig @@ -8,9 +8,8 @@ - - - + + From 82092338d67e49b4be1bd81b5ae895e7d6af29be Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 06:47:06 +0200 Subject: [PATCH 141/232] Install composer deps with --no-dev --- release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.sh b/release.sh index 8e104ea2..ff86953d 100644 --- a/release.sh +++ b/release.sh @@ -38,7 +38,7 @@ if [ $1 = "prepare" ]; then cd $dir || exit # dependencies - composer install + composer install --no-dev echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'" exit From 98d4d3fcf05cdcb26424a49122ac273a90738f56 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 06:47:06 +0200 Subject: [PATCH 142/232] Install composer deps with --no-dev --- release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.sh b/release.sh index 8d9d7705..d2dbfe49 100644 --- a/release.sh +++ b/release.sh @@ -38,7 +38,7 @@ if [ $1 = "prepare" ]; then cd $dir || exit # dependencies - composer install + composer install --no-dev echo "Now you can make changes to $dir. When you are ready, type 'release.sh pack'" exit From 17221f5369591a3ee0bbd4e9c4e6f09aaeade73f Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 09:04:24 +0200 Subject: [PATCH 143/232] Rename to .htaccess.dist Causes problems on default setup --- .htaccess => .htaccess.dist | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .htaccess => .htaccess.dist (100%) diff --git a/.htaccess b/.htaccess.dist similarity index 100% rename from .htaccess rename to .htaccess.dist From 5bb3e57b7bbbf51c22644a0e9317b5a1f18a07cc Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 09:04:24 +0200 Subject: [PATCH 144/232] Rename to .htaccess.dist Causes problems on default setup --- .htaccess => .htaccess.dist | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .htaccess => .htaccess.dist (100%) diff --git a/.htaccess b/.htaccess.dist similarity index 100% rename from .htaccess rename to .htaccess.dist From 6e6f4679f45ae20fd20d1e1ee115331400b77fa3 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 12:24:18 +0200 Subject: [PATCH 145/232] Disable reporting on CI --- install/steps/7-finish.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index 656c60fe..0f776b06 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -122,18 +122,21 @@ else { )); if(!isset($_SESSION['installed'])) { - $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); - if (function_exists('curl_version')) - { - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $report_url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_exec($curl); - curl_close($curl); - } - else if (ini_get('allow_url_fopen') ) { - file_get_contents($report_url); + if (!array_key_exists('CI', $_ENV)) { + $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); + if (function_exists('curl_version')) + { + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $report_url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_exec($curl); + curl_close($curl); + } + else if (ini_get('allow_url_fopen') ) { + file_get_contents($report_url); + } } + $_SESSION['installed'] = true; } From b421bf39317dce7a4dcdd278c7e2990bef5defc7 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:38:30 +0200 Subject: [PATCH 146/232] test dump env --- .github/workflows/cypress.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 2909555a..e028af40 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -96,6 +96,9 @@ jobs: - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader + - name: Dump Env + run: php -r "var_dump(getenv());" + - name: Run PHP server run: nohup php -S localhost:8080 > php.log 2>&1 & From 91c8f1f5bca06ab86c4862f6dfc332d99f3b18cf Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:41:16 +0200 Subject: [PATCH 147/232] do not report if CI test 2 --- .github/workflows/cypress.yml | 3 --- install/steps/7-finish.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index e028af40..2909555a 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -96,9 +96,6 @@ jobs: - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - - name: Dump Env - run: php -r "var_dump(getenv());" - - name: Run PHP server run: nohup php -S localhost:8080 > php.log 2>&1 & diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index 0f776b06..f6e1f6c2 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -122,7 +122,7 @@ else { )); if(!isset($_SESSION['installed'])) { - if (!array_key_exists('CI', $_ENV)) { + if (!array_key_exists('CI', getenv())) { $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); if (function_exists('curl_version')) { From aa1403480c22cdf6d7bca9ec46ab3605f7dbf0cd Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:50:14 +0200 Subject: [PATCH 148/232] Update to 0.10.0-dev --- common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.php b/common.php index 109bd3ae..0c56f0ac 100644 --- a/common.php +++ b/common.php @@ -26,7 +26,7 @@ if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); const MYAAC = true; -const MYAAC_VERSION = '0.9.0-dev'; +const MYAAC_VERSION = '0.10.0-dev'; const DATABASE_VERSION = 35; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); From eabe789bbb0427bb833627bf3cd25bfcbb3ac60a Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 12:24:18 +0200 Subject: [PATCH 149/232] Disable reporting on CI --- install/steps/7-finish.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index 656c60fe..0f776b06 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -122,18 +122,21 @@ else { )); if(!isset($_SESSION['installed'])) { - $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); - if (function_exists('curl_version')) - { - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $report_url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_exec($curl); - curl_close($curl); - } - else if (ini_get('allow_url_fopen') ) { - file_get_contents($report_url); + if (!array_key_exists('CI', $_ENV)) { + $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); + if (function_exists('curl_version')) + { + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $report_url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_exec($curl); + curl_close($curl); + } + else if (ini_get('allow_url_fopen') ) { + file_get_contents($report_url); + } } + $_SESSION['installed'] = true; } From 4e22c42b10300ababc2595507e671adeedadbe07 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:38:30 +0200 Subject: [PATCH 150/232] test dump env --- .github/workflows/cypress.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 2909555a..e028af40 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -96,6 +96,9 @@ jobs: - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader + - name: Dump Env + run: php -r "var_dump(getenv());" + - name: Run PHP server run: nohup php -S localhost:8080 > php.log 2>&1 & From c7ce87c4b6949f135c2ce0cec889565c6e67d99b Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:41:16 +0200 Subject: [PATCH 151/232] do not report if CI test 2 --- .github/workflows/cypress.yml | 3 --- install/steps/7-finish.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index e028af40..2909555a 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -96,9 +96,6 @@ jobs: - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - - name: Dump Env - run: php -r "var_dump(getenv());" - - name: Run PHP server run: nohup php -S localhost:8080 > php.log 2>&1 & diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index 0f776b06..f6e1f6c2 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -122,7 +122,7 @@ else { )); if(!isset($_SESSION['installed'])) { - if (!array_key_exists('CI', $_ENV)) { + if (!array_key_exists('CI', getenv())) { $report_url = 'https://my-aac.org/report_install.php?v=' . MYAAC_VERSION . '&b=' . urlencode(BASE_URL); if (function_exists('curl_version')) { From b1d2ac34a26e45d233fd4c049e6ef8bbcf97421b Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 3 Jun 2023 18:51:57 +0200 Subject: [PATCH 152/232] Update branch name --- .github/workflows/cypress.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 2909555a..067c9a6c 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -1,9 +1,9 @@ name: Cypress on: pull_request: - branches: [develop] + branches: [0.9] push: - branches: [develop] + branches: [0.9] jobs: cypress: @@ -34,7 +34,7 @@ jobs: - name: Checkout MyAAC uses: actions/checkout@v3 with: - ref: develop + ref: 0.9 - name: Checkout TFS uses: actions/checkout@v3 From 171c114b0f4838790be918508c98d1b304ff3b94 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 11 Jun 2023 18:57:52 +0200 Subject: [PATCH 153/232] Fix links to edit/delete/hide directly from page --- system/templates/admin.pages.links.html.twig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/templates/admin.pages.links.html.twig b/system/templates/admin.pages.links.html.twig index d8529e3e..459d0623 100644 --- a/system/templates/admin.pages.links.html.twig +++ b/system/templates/admin.pages.links.html.twig @@ -1,12 +1,12 @@
    - + Edit - Delete - {% if page.hidden != 1 %}Hide{% else %}Show{% endif %} From 7d2fc48437ede142ea362251015fe3b39614dfb5 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 11 Jun 2023 18:57:52 +0200 Subject: [PATCH 154/232] Fix links to edit/delete/hide directly from page --- system/templates/admin.pages.links.html.twig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/templates/admin.pages.links.html.twig b/system/templates/admin.pages.links.html.twig index d8529e3e..459d0623 100644 --- a/system/templates/admin.pages.links.html.twig +++ b/system/templates/admin.pages.links.html.twig @@ -1,12 +1,12 @@
    - + Edit - Delete - {% if page.hidden != 1 %}Hide{% else %}Show{% endif %} From 76bfab13038f70ed2fe7935182dc193b6f2b6e0d Mon Sep 17 00:00:00 2001 From: SRNT-GG <95472530+SRNT-GG@users.noreply.github.com> Date: Thu, 15 Jun 2023 20:53:55 +0200 Subject: [PATCH 155/232] WIP - Removing unneccessary closing tags to prevent potential issues. (#223) * Part 1 Removing closing tags when no HTML or other output comes after the last PHP codeblock. * Further removals * nothing --------- Co-authored-by: slawkens --- admin/includes/functions.php | 3 ++- admin/pages/pages.php | 2 -- admin/pages/statistics.php | 1 - admin/pages/version.php | 1 - admin/tools/phpinfo.php | 1 - install/includes/config.php | 1 - install/steps/2-license.php | 1 - install/steps/4-config.php | 1 - system/counter.php | 1 - system/init.php | 2 +- system/item.php | 1 - system/libs/data.php | 1 - system/libs/pot/E_OTS_ErrorCode.php | 2 -- system/libs/pot/E_OTS_Generic.php | 2 -- system/libs/pot/E_OTS_NotAContainer.php | 2 -- system/libs/pot/E_OTS_OTBMError.php | 2 -- system/libs/pot/E_OTS_ReadOnly.php | 2 -- system/libs/pot/IOTS_Cipher.php | 2 -- system/libs/pot/IOTS_DataDisplay.php | 2 -- system/libs/pot/IOTS_Display.php | 2 -- system/libs/pot/IOTS_GuildAction.php | 2 -- system/libs/pot/OTS_Account.php | 2 -- system/libs/pot/OTS_AccountBans_List.php | 2 -- system/libs/pot/OTS_Admin.php | 2 -- system/libs/pot/OTS_Bans_List.php | 2 -- system/libs/pot/OTS_Base_DB.php | 2 -- system/libs/pot/OTS_BinaryTools.php | 2 -- system/libs/pot/OTS_Container.php | 2 -- system/libs/pot/OTS_FileLoader.php | 2 -- system/libs/pot/OTS_Group.php | 2 -- system/libs/pot/OTS_Guild.php | 2 -- system/libs/pot/OTS_GuildRanks_List.php | 2 -- system/libs/pot/OTS_House.php | 2 -- system/libs/pot/OTS_IPBans_List.php | 2 -- system/libs/pot/OTS_InfoRespond.php | 2 -- system/libs/pot/OTS_ItemsList.php | 2 -- system/libs/pot/OTS_MapCoords.php | 2 -- system/libs/pot/OTS_MonstersList.php | 2 -- system/libs/pot/OTS_Player.php | 2 -- system/libs/pot/OTS_PlayerBans_List.php | 2 -- system/libs/pot/OTS_Row_DAO.php | 2 -- system/libs/pot/OTS_SQLField.php | 2 -- system/libs/pot/OTS_ServerInfo.php | 2 -- system/libs/pot/OTS_Spell.php | 2 -- system/libs/pot/OTS_Toolbox.php | 2 -- system/libs/pot/OTS_XTEA.php | 2 -- system/libs/rfc6238.php | 1 - system/libs/validator.php | 1 - system/locale/de/admin.php | 1 - system/locale/de/main.php | 3 +-- system/locale/en/install.php | 1 - system/locale/pl/admin.php | 1 - system/locale/pl/main.php | 2 +- system/locale/pt_br/install.php | 1 - system/locale/sv/admin.php | 1 - system/locale/sv/main.php | 1 - system/migrations/11.php | 1 - system/migrations/13.php | 3 +-- system/migrations/15.php | 1 - system/migrations/17.php | 1 - system/migrations/19.php | 3 +-- system/migrations/2.php | 1 - system/migrations/20.php | 1 - system/migrations/4.php | 3 +-- system/migrations/6.php | 3 +-- system/migrations/8.php | 3 +-- system/pages/account/change_email.php | 1 - system/pages/account/change_name.php | 2 -- system/pages/account/change_sex.php | 2 -- system/pages/account/lost.php | 1 - system/pages/bugtracker.php | 1 - system/pages/faq.php | 1 - system/pages/forum/edit_post.php | 2 -- system/pages/forum/new_thread.php | 2 -- system/pages/gallery.php | 1 - system/pages/guilds/change_description.php | 2 -- system/pages/guilds/change_motd.php | 2 -- system/pages/guilds/cleanup_players.php | 1 - system/pages/guilds/delete_by_admin.php | 2 -- system/pages/guilds/delete_rank.php | 2 -- system/pages/guilds/leave.php | 2 -- system/pages/guilds/pass_leadership.php | 2 -- system/pages/polls.php | 1 - system/pages/server_info.php | 3 --- system/pages/team.php | 1 - templates/tibiacom/index.php | 1 - tools/news_preview.php | 2 -- tools/signature/gesior.php | 3 +-- tools/signature/mango.php | 1 - 89 files changed, 11 insertions(+), 144 deletions(-) diff --git a/admin/includes/functions.php b/admin/includes/functions.php index ab604f76..620272f5 100644 --- a/admin/includes/functions.php +++ b/admin/includes/functions.php @@ -1 +1,2 @@ - \ No newline at end of file + diff --git a/admin/pages/statistics.php b/admin/pages/statistics.php index 17d8118f..b740c217 100644 --- a/admin/pages/statistics.php +++ b/admin/pages/statistics.php @@ -36,4 +36,3 @@ $twig->display('admin.statistics.html.twig', array( 'account_type' => (USE_ACCOUNT_NAME ? 'name' : 'number'), 'points' => $points )); -?> \ No newline at end of file diff --git a/admin/pages/version.php b/admin/pages/version.php index e643e728..64f673c8 100644 --- a/admin/pages/version.php +++ b/admin/pages/version.php @@ -47,4 +47,3 @@ function version_revert($version) $release = $version; return $major . '.' . $minor . '.' . $release; }*/ -?> diff --git a/admin/tools/phpinfo.php b/admin/tools/phpinfo.php index 96a9aad9..cd043279 100644 --- a/admin/tools/phpinfo.php +++ b/admin/tools/phpinfo.php @@ -13,4 +13,3 @@ if(!function_exists('phpinfo')) die('phpinfo() disabled on this web server.'); phpinfo(); -?> diff --git a/install/includes/config.php b/install/includes/config.php index 380fff7d..5d9ae07a 100644 --- a/install/includes/config.php +++ b/install/includes/config.php @@ -38,4 +38,3 @@ if(!isset($error) || !$error) { $error = true; } } -?> \ No newline at end of file diff --git a/install/steps/2-license.php b/install/steps/2-license.php index e84ce0e6..4976dd70 100644 --- a/install/steps/2-license.php +++ b/install/steps/2-license.php @@ -5,4 +5,3 @@ $twig->display('install.license.html.twig', array( 'license' => file_get_contents(BASE . 'LICENSE'), 'buttons' => next_buttons() )); -?> diff --git a/install/steps/4-config.php b/install/steps/4-config.php index b1555201..325b97f1 100644 --- a/install/steps/4-config.php +++ b/install/steps/4-config.php @@ -18,4 +18,3 @@ $twig->display('install.config.html.twig', array( 'errors' => isset($errors) ? $errors : null, 'buttons' => next_buttons() )); -?> \ No newline at end of file diff --git a/system/counter.php b/system/counter.php index ada05903..63905ba2 100644 --- a/system/counter.php +++ b/system/counter.php @@ -51,4 +51,3 @@ else updateDatabaseConfig('views_counter', $views_counter); // update counter } } -?> diff --git a/system/init.php b/system/init.php index 056bbd40..2815f791 100644 --- a/system/init.php +++ b/system/init.php @@ -122,7 +122,7 @@ if(!isset($foundValue)) { $config['data_path'] = $foundValue; unset($foundValue); -// new config values for compability +// new config values for compatibility if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hidden']) == 0) { $config['highscores_ids_hidden'] = array(0); } diff --git a/system/item.php b/system/item.php index 4d213360..66d4bfc5 100644 --- a/system/item.php +++ b/system/item.php @@ -58,4 +58,3 @@ function outputItem($id = 100, $count = 1) $file_name = Items_Images::$outputDir . $file_name . '.gif'; readfile($file_name); } -?> diff --git a/system/libs/data.php b/system/libs/data.php index 64d93f78..af667448 100644 --- a/system/libs/data.php +++ b/system/libs/data.php @@ -41,4 +41,3 @@ class Data return $db->update($this->table, $data, $where); } } -?> diff --git a/system/libs/pot/E_OTS_ErrorCode.php b/system/libs/pot/E_OTS_ErrorCode.php index f5bbd2fc..451e5a07 100644 --- a/system/libs/pot/E_OTS_ErrorCode.php +++ b/system/libs/pot/E_OTS_ErrorCode.php @@ -32,5 +32,3 @@ class E_OTS_ErrorCode extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_Generic.php b/system/libs/pot/E_OTS_Generic.php index 3ca0a914..7a95d675 100644 --- a/system/libs/pot/E_OTS_Generic.php +++ b/system/libs/pot/E_OTS_Generic.php @@ -36,5 +36,3 @@ class E_OTS_Generic extends E_OTS_ErrorCode } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_NotAContainer.php b/system/libs/pot/E_OTS_NotAContainer.php index 3a8d224b..8285691f 100644 --- a/system/libs/pot/E_OTS_NotAContainer.php +++ b/system/libs/pot/E_OTS_NotAContainer.php @@ -22,5 +22,3 @@ class E_OTS_NotAContainer extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_OTBMError.php b/system/libs/pot/E_OTS_OTBMError.php index d84d740c..9ab1228d 100644 --- a/system/libs/pot/E_OTS_OTBMError.php +++ b/system/libs/pot/E_OTS_OTBMError.php @@ -32,5 +32,3 @@ class E_OTS_OTBMError extends E_OTS_ErrorCode } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_ReadOnly.php b/system/libs/pot/E_OTS_ReadOnly.php index 003d12af..5fb3b39b 100644 --- a/system/libs/pot/E_OTS_ReadOnly.php +++ b/system/libs/pot/E_OTS_ReadOnly.php @@ -22,5 +22,3 @@ class E_OTS_ReadOnly extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_Cipher.php b/system/libs/pot/IOTS_Cipher.php index 82044cc8..542b4abb 100644 --- a/system/libs/pot/IOTS_Cipher.php +++ b/system/libs/pot/IOTS_Cipher.php @@ -37,5 +37,3 @@ interface IOTS_Cipher } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_DataDisplay.php b/system/libs/pot/IOTS_DataDisplay.php index 7c5abc2c..359dc1a6 100644 --- a/system/libs/pot/IOTS_DataDisplay.php +++ b/system/libs/pot/IOTS_DataDisplay.php @@ -89,5 +89,3 @@ interface IOTS_DataDisplay } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_Display.php b/system/libs/pot/IOTS_Display.php index cb2d8e90..3b75d537 100644 --- a/system/libs/pot/IOTS_Display.php +++ b/system/libs/pot/IOTS_Display.php @@ -96,5 +96,3 @@ interface IOTS_Display } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_GuildAction.php b/system/libs/pot/IOTS_GuildAction.php index 7ed97f94..680025cd 100644 --- a/system/libs/pot/IOTS_GuildAction.php +++ b/system/libs/pot/IOTS_GuildAction.php @@ -67,5 +67,3 @@ interface IOTS_GuildAction } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Account.php b/system/libs/pot/OTS_Account.php index d5b42961..9a6b39a7 100644 --- a/system/libs/pot/OTS_Account.php +++ b/system/libs/pot/OTS_Account.php @@ -1198,5 +1198,3 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_AccountBans_List.php b/system/libs/pot/OTS_AccountBans_List.php index f3687409..fdd2f923 100644 --- a/system/libs/pot/OTS_AccountBans_List.php +++ b/system/libs/pot/OTS_AccountBans_List.php @@ -34,5 +34,3 @@ class OTS_AccountBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_Admin.php b/system/libs/pot/OTS_Admin.php index 3507e10d..7530d6ef 100644 --- a/system/libs/pot/OTS_Admin.php +++ b/system/libs/pot/OTS_Admin.php @@ -735,5 +735,3 @@ class OTS_Admin } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Bans_List.php b/system/libs/pot/OTS_Bans_List.php index 5f58788e..8eb59df6 100644 --- a/system/libs/pot/OTS_Bans_List.php +++ b/system/libs/pot/OTS_Bans_List.php @@ -100,5 +100,3 @@ class OTS_Bans_List extends OTS_Base_List } } } - -?> diff --git a/system/libs/pot/OTS_Base_DB.php b/system/libs/pot/OTS_Base_DB.php index f97745b4..21d6f756 100644 --- a/system/libs/pot/OTS_Base_DB.php +++ b/system/libs/pot/OTS_Base_DB.php @@ -265,5 +265,3 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_BinaryTools.php b/system/libs/pot/OTS_BinaryTools.php index 7e6a86e5..84fbf54c 100644 --- a/system/libs/pot/OTS_BinaryTools.php +++ b/system/libs/pot/OTS_BinaryTools.php @@ -146,5 +146,3 @@ class OTS_BinaryTools } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Container.php b/system/libs/pot/OTS_Container.php index 7b93570f..ff910401 100644 --- a/system/libs/pot/OTS_Container.php +++ b/system/libs/pot/OTS_Container.php @@ -149,5 +149,3 @@ class OTS_Container extends OTS_Item implements IteratorAggregate } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_FileLoader.php b/system/libs/pot/OTS_FileLoader.php index 8f86712e..77f184f3 100644 --- a/system/libs/pot/OTS_FileLoader.php +++ b/system/libs/pot/OTS_FileLoader.php @@ -357,5 +357,3 @@ class OTS_FileLoader } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Group.php b/system/libs/pot/OTS_Group.php index 19f770f1..d094d365 100644 --- a/system/libs/pot/OTS_Group.php +++ b/system/libs/pot/OTS_Group.php @@ -671,5 +671,3 @@ class OTS_Group extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Guild.php b/system/libs/pot/OTS_Guild.php index 98dd47cf..bab363a8 100644 --- a/system/libs/pot/OTS_Guild.php +++ b/system/libs/pot/OTS_Guild.php @@ -837,5 +837,3 @@ class OTS_Guild extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_GuildRanks_List.php b/system/libs/pot/OTS_GuildRanks_List.php index f2f9e57e..aec6114a 100644 --- a/system/libs/pot/OTS_GuildRanks_List.php +++ b/system/libs/pot/OTS_GuildRanks_List.php @@ -72,5 +72,3 @@ class OTS_GuildRanks_List extends OTS_Base_List } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_House.php b/system/libs/pot/OTS_House.php index e6aca322..12a8f1cb 100644 --- a/system/libs/pot/OTS_House.php +++ b/system/libs/pot/OTS_House.php @@ -529,5 +529,3 @@ class OTS_House extends OTS_Row_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_IPBans_List.php b/system/libs/pot/OTS_IPBans_List.php index dd614e9a..1fdfc0ce 100644 --- a/system/libs/pot/OTS_IPBans_List.php +++ b/system/libs/pot/OTS_IPBans_List.php @@ -34,5 +34,3 @@ class OTS_IPBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_InfoRespond.php b/system/libs/pot/OTS_InfoRespond.php index f64fca05..6e452371 100644 --- a/system/libs/pot/OTS_InfoRespond.php +++ b/system/libs/pot/OTS_InfoRespond.php @@ -387,5 +387,3 @@ class OTS_InfoRespond extends DOMDocument } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_ItemsList.php b/system/libs/pot/OTS_ItemsList.php index 1865117a..30465a9d 100644 --- a/system/libs/pot/OTS_ItemsList.php +++ b/system/libs/pot/OTS_ItemsList.php @@ -676,5 +676,3 @@ class OTS_ItemsList extends OTS_FileLoader implements IteratorAggregate, Countab } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_MapCoords.php b/system/libs/pot/OTS_MapCoords.php index dfe1a1cd..738b0bea 100644 --- a/system/libs/pot/OTS_MapCoords.php +++ b/system/libs/pot/OTS_MapCoords.php @@ -130,5 +130,3 @@ class OTS_MapCoords } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_MonstersList.php b/system/libs/pot/OTS_MonstersList.php index fb51a085..f7d1b2da 100644 --- a/system/libs/pot/OTS_MonstersList.php +++ b/system/libs/pot/OTS_MonstersList.php @@ -299,5 +299,3 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Player.php b/system/libs/pot/OTS_Player.php index 2143c12e..7fd96fec 100644 --- a/system/libs/pot/OTS_Player.php +++ b/system/libs/pot/OTS_Player.php @@ -3627,5 +3627,3 @@ class OTS_Player extends OTS_Row_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_PlayerBans_List.php b/system/libs/pot/OTS_PlayerBans_List.php index 7e06c7ca..f9826f78 100644 --- a/system/libs/pot/OTS_PlayerBans_List.php +++ b/system/libs/pot/OTS_PlayerBans_List.php @@ -34,5 +34,3 @@ class OTS_PlayerBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_Row_DAO.php b/system/libs/pot/OTS_Row_DAO.php index c1a09858..2a0a100c 100644 --- a/system/libs/pot/OTS_Row_DAO.php +++ b/system/libs/pot/OTS_Row_DAO.php @@ -75,5 +75,3 @@ abstract class OTS_Row_DAO extends OTS_Base_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_SQLField.php b/system/libs/pot/OTS_SQLField.php index 2f7ac74e..ba2bb55c 100644 --- a/system/libs/pot/OTS_SQLField.php +++ b/system/libs/pot/OTS_SQLField.php @@ -121,5 +121,3 @@ class OTS_SQLField } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_ServerInfo.php b/system/libs/pot/OTS_ServerInfo.php index eb153c93..fd06749e 100644 --- a/system/libs/pot/OTS_ServerInfo.php +++ b/system/libs/pot/OTS_ServerInfo.php @@ -227,5 +227,3 @@ class OTS_ServerInfo } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Spell.php b/system/libs/pot/OTS_Spell.php index 0ec51bdf..419ee292 100644 --- a/system/libs/pot/OTS_Spell.php +++ b/system/libs/pot/OTS_Spell.php @@ -482,5 +482,3 @@ class OTS_Spell } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Toolbox.php b/system/libs/pot/OTS_Toolbox.php index 4d22d0dd..980e5cb5 100644 --- a/system/libs/pot/OTS_Toolbox.php +++ b/system/libs/pot/OTS_Toolbox.php @@ -113,5 +113,3 @@ class OTS_Toolbox } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_XTEA.php b/system/libs/pot/OTS_XTEA.php index 96ee7553..ff5a1095 100644 --- a/system/libs/pot/OTS_XTEA.php +++ b/system/libs/pot/OTS_XTEA.php @@ -151,5 +151,3 @@ class OTS_XTEA implements IOTS_Cipher } /**#@-*/ - -?> diff --git a/system/libs/rfc6238.php b/system/libs/rfc6238.php index 579f08f2..5effedd3 100644 --- a/system/libs/rfc6238.php +++ b/system/libs/rfc6238.php @@ -282,4 +282,3 @@ class TokenAuth6238 { return $result; } } -?> diff --git a/system/libs/validator.php b/system/libs/validator.php index 38db7068..91f71c24 100644 --- a/system/libs/validator.php +++ b/system/libs/validator.php @@ -451,4 +451,3 @@ class Validator return self::$lastError; } } -?> diff --git a/system/locale/de/admin.php b/system/locale/de/admin.php index 8a128216..dae5fdee 100644 --- a/system/locale/de/admin.php +++ b/system/locale/de/admin.php @@ -6,4 +6,3 @@ * @author Slawkens */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/de/main.php b/system/locale/de/main.php index 3f9b2479..e4482572 100644 --- a/system/locale/de/main.php +++ b/system/locale/de/main.php @@ -11,5 +11,4 @@ $locale['encoding'] = 'utf-8'; $locale['direction']= 'ltr'; $locale['error404'] = 'Diese Seite konnte nicht gefunden werden.'; -$locale['news'] = 'Neuesten Nachrichten'; -?> \ No newline at end of file +$locale['news'] = 'Neuesten Nachrichten'; \ No newline at end of file diff --git a/system/locale/en/install.php b/system/locale/en/install.php index f856dcbf..3de85896 100644 --- a/system/locale/en/install.php +++ b/system/locale/en/install.php @@ -131,4 +131,3 @@ $locale['step_finish_title'] = 'Installation finished!'; $locale['step_finish_desc'] = 'Congratulations! MyAAC is ready to use!
    You can now login to $ADMIN_PANEL$, or visit $HOMEPAGE$.

    Please delete install/ directory.

    Post bugs and suggestions at $LINK$, thanks!'; -?> diff --git a/system/locale/pl/admin.php b/system/locale/pl/admin.php index 91adfc60..8431b438 100644 --- a/system/locale/pl/admin.php +++ b/system/locale/pl/admin.php @@ -6,4 +6,3 @@ * @author Slawkens */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/pl/main.php b/system/locale/pl/main.php index 200bba22..b86b331f 100644 --- a/system/locale/pl/main.php +++ b/system/locale/pl/main.php @@ -12,4 +12,4 @@ $locale['direction']= 'ltr'; $locale['error404'] = 'Strona nie została odnaleziona.'; $locale['news'] = 'Ostatnie newsy'; -$locale['loaded_in_ms'] = 'w $TIME$ ms'; \ No newline at end of file +$locale['loaded_in_ms'] = 'w $TIME$ ms'; diff --git a/system/locale/pt_br/install.php b/system/locale/pt_br/install.php index e47faede..3a9ca9cc 100644 --- a/system/locale/pt_br/install.php +++ b/system/locale/pt_br/install.php @@ -118,4 +118,3 @@ $locale['step_finish'] = 'Finalizar'; $locale['step_finish_title'] = 'Instalação terminada!'; $locale['step_finish_desc'] = 'Parabéns! MyAAC está pronto para uso!
    Agora você pode fazer login em $ADMIN_PANEL$ ou visitar $HOMEPAGE$.

    Por favor remova a pasta install/.

    Postar bugs e sugestões em $LINK$, obrigado!'; -?> diff --git a/system/locale/sv/admin.php b/system/locale/sv/admin.php index 69f4f20a..8fa07f74 100644 --- a/system/locale/sv/admin.php +++ b/system/locale/sv/admin.php @@ -6,4 +6,3 @@ * @author Sizaro */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/sv/main.php b/system/locale/sv/main.php index fc714190..83f6bb84 100644 --- a/system/locale/sv/main.php +++ b/system/locale/sv/main.php @@ -12,4 +12,3 @@ $locale['direction']= 'ltr'; $locale['error404'] = 'Sidan kunde inte hittas.'; $locale['news'] = 'Senaste nyheterna'; -?> \ No newline at end of file diff --git a/system/migrations/11.php b/system/migrations/11.php index dc335577..845f9e67 100644 --- a/system/migrations/11.php +++ b/system/migrations/11.php @@ -17,4 +17,3 @@ 'thumb' => str_replace('/screenshots/', '/gallery/', $item['thumb']), ), array('id' => $item['id'])); } -?> diff --git a/system/migrations/13.php b/system/migrations/13.php index 71d3735c..4eee77f3 100644 --- a/system/migrations/13.php +++ b/system/migrations/13.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'spells', 'spell')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "spells` DROP COLUMN `spell`;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "spells` DROP COLUMN `spell`;"); \ No newline at end of file diff --git a/system/migrations/15.php b/system/migrations/15.php index 28996d8a..971587ec 100644 --- a/system/migrations/15.php +++ b/system/migrations/15.php @@ -8,4 +8,3 @@ if(!$db->hasColumn(TABLE_PREFIX . 'forum_boards', 'guild')) { if(!$db->hasColumn(TABLE_PREFIX . 'forum_boards', 'access')) { $db->query("ALTER TABLE `" . TABLE_PREFIX . "forum_boards` ADD `access` TINYINT(1) NOT NULL DEFAULT 0 AFTER `guild`;"); } -?> \ No newline at end of file diff --git a/system/migrations/17.php b/system/migrations/17.php index e4b1667c..220bc90b 100644 --- a/system/migrations/17.php +++ b/system/migrations/17.php @@ -86,4 +86,3 @@ INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VA INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2); "); } -?> \ No newline at end of file diff --git a/system/migrations/19.php b/system/migrations/19.php index 50baa271..81c818d2 100644 --- a/system/migrations/19.php +++ b/system/migrations/19.php @@ -1,3 +1,2 @@ \ No newline at end of file +// this migration has been removed, but file kept for compatibility diff --git a/system/migrations/2.php b/system/migrations/2.php index db5fd70f..90d9a610 100644 --- a/system/migrations/2.php +++ b/system/migrations/2.php @@ -3,4 +3,3 @@ $db->query("ALTER TABLE `" . TABLE_PREFIX . "movies` MODIFY `title` VARCHAR(100) NOT NULL DEFAULT '';"); $db->query("ALTER TABLE `" . TABLE_PREFIX . "news` MODIFY `title` VARCHAR(100) NOT NULL DEFAULT '';"); $db->query("ALTER TABLE `" . TABLE_PREFIX . "news` MODIFY `body` TEXT NOT NULL DEFAULT '';"); -?> diff --git a/system/migrations/20.php b/system/migrations/20.php index 0533b540..d0012fde 100644 --- a/system/migrations/20.php +++ b/system/migrations/20.php @@ -45,4 +45,3 @@ function databaseMigration20(&$content = '') { file_put_contents($config_file, $content, FILE_APPEND); return true; } -?> \ No newline at end of file diff --git a/system/migrations/4.php b/system/migrations/4.php index 80bbc4a0..db17feb1 100644 --- a/system/migrations/4.php +++ b/system/migrations/4.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'monsters', 'id')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `id` int(11) NOT NULL AUTO_INCREMENT primary key FIRST;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `id` int(11) NOT NULL AUTO_INCREMENT primary key FIRST;"); \ No newline at end of file diff --git a/system/migrations/6.php b/system/migrations/6.php index ed5329d0..e287d55a 100644 --- a/system/migrations/6.php +++ b/system/migrations/6.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'hooks', 'enabled')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "hooks` ADD `enabled` INT(1) NOT NULL DEFAULT 1;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "hooks` ADD `enabled` INT(1) NOT NULL DEFAULT 1;"); \ No newline at end of file diff --git a/system/migrations/8.php b/system/migrations/8.php index a04331a8..4785e23b 100644 --- a/system/migrations/8.php +++ b/system/migrations/8.php @@ -14,5 +14,4 @@ foreach($boards as $id => $board) $db->query('UPDATE `' . TABLE_PREFIX . 'forum_boards` SET `ordering` = ' . $id . ' WHERE `name` = ' . $db->quote($board)); - } -?> \ No newline at end of file + } \ No newline at end of file diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 2368a284..3bc8edd7 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -166,4 +166,3 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) { 'custom_buttons' => $custom_buttons )); } -?> diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index ab7bd326..448e730c 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -112,5 +112,3 @@ else )); } } - -?> diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index c67ac608..868cf24f 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -91,5 +91,3 @@ else )); } } - -?> diff --git a/system/pages/account/lost.php b/system/pages/account/lost.php index a474540c..3ea0957e 100644 --- a/system/pages/account/lost.php +++ b/system/pages/account/lost.php @@ -546,4 +546,3 @@ elseif($action == 'setnewpassword') ' . $twig->render('buttons.submit.html.twig') . '
    '; } -?> diff --git a/system/pages/bugtracker.php b/system/pages/bugtracker.php index a7cffcf0..ac37becd 100644 --- a/system/pages/bugtracker.php +++ b/system/pages/bugtracker.php @@ -339,4 +339,3 @@ $showed = $post = $reply = false; { echo '

    [ADMIN PANEL]'; } -?> diff --git a/system/pages/faq.php b/system/pages/faq.php index f30e7914..5d71aa3c 100644 --- a/system/pages/faq.php +++ b/system/pages/faq.php @@ -185,4 +185,3 @@ class FAQ return !count($errors); } } -?> diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index 45fd675b..d3f95c45 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -114,5 +114,3 @@ 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."; - -?> diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 4db06c63..c3b688ad 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -103,5 +103,3 @@ 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.'; - -?> diff --git a/system/pages/gallery.php b/system/pages/gallery.php index c893ce90..b6e2b07f 100644 --- a/system/pages/gallery.php +++ b/system/pages/gallery.php @@ -312,4 +312,3 @@ class Gallery return !count($errors); } } -?> diff --git a/system/pages/guilds/change_description.php b/system/pages/guilds/change_description.php index b4e787ee..9f6fc0dc 100644 --- a/system/pages/guilds/change_description.php +++ b/system/pages/guilds/change_description.php @@ -72,5 +72,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/change_motd.php b/system/pages/guilds/change_motd.php index c777548d..84581485 100644 --- a/system/pages/guilds/change_motd.php +++ b/system/pages/guilds/change_motd.php @@ -75,5 +75,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/cleanup_players.php b/system/pages/guilds/cleanup_players.php index 30b1e8af..61b1ce49 100644 --- a/system/pages/guilds/cleanup_players.php +++ b/system/pages/guilds/cleanup_players.php @@ -68,4 +68,3 @@ else echo "0 players found."; $twig->display('guilds.back_button.html.twig'); -?> diff --git a/system/pages/guilds/delete_by_admin.php b/system/pages/guilds/delete_by_admin.php index 3e083c8a..7da54aea 100644 --- a/system/pages/guilds/delete_by_admin.php +++ b/system/pages/guilds/delete_by_admin.php @@ -66,5 +66,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/delete_rank.php b/system/pages/guilds/delete_rank.php index 6a8f642c..48eeba4d 100644 --- a/system/pages/guilds/delete_rank.php +++ b/system/pages/guilds/delete_rank.php @@ -125,5 +125,3 @@ if(!empty($guild_errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/leave.php b/system/pages/guilds/leave.php index 892deb89..9a11595d 100644 --- a/system/pages/guilds/leave.php +++ b/system/pages/guilds/leave.php @@ -114,5 +114,3 @@ else )); } } - -?> \ No newline at end of file diff --git a/system/pages/guilds/pass_leadership.php b/system/pages/guilds/pass_leadership.php index 462ac9ec..d5f0ed20 100644 --- a/system/pages/guilds/pass_leadership.php +++ b/system/pages/guilds/pass_leadership.php @@ -117,5 +117,3 @@ if(!empty($guild_errors)) { echo '
    ' . $twig->render('buttons.back.html.twig') . '
    '; } - -?> diff --git a/system/pages/polls.php b/system/pages/polls.php index c31b61cb..dcc781c2 100644 --- a/system/pages/polls.php +++ b/system/pages/polls.php @@ -369,4 +369,3 @@ function getColorByPercent($percent) echo 'This poll doesn\'t exist.
    '; echo '
    Go to list of polls'; } -?> diff --git a/system/pages/server_info.php b/system/pages/server_info.php index 7c2a519e..b750c3ee 100644 --- a/system/pages/server_info.php +++ b/system/pages/server_info.php @@ -108,6 +108,3 @@ $twig->display('serverinfo.html.twig', array( 'finalBanishmentLength' => isset($config['lua']['final_banishment_length']) ? eval('return (' . $config['lua']['final_banishment_length'] . ') / (24 * 60 * 60);') : null, 'ipBanishmentLength' => isset($config['lua']['ip_banishment_length']) ? eval('return (' . $config['lua']['ip_banishment_length'] . ') / (24 * 60 * 60);') : null, )); -?> - - diff --git a/system/pages/team.php b/system/pages/team.php index 2e410e12..fbc0df99 100644 --- a/system/pages/team.php +++ b/system/pages/team.php @@ -74,4 +74,3 @@ foreach($groupList as $id => $group) $twig->display('team.html.twig', array( 'groupmember' => $groupMember )); -?> \ No newline at end of file diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 989a05ca..539453c9 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -459,4 +459,3 @@ function logo_monster() global $config; return str_replace(" ", "", trim(strtolower($config['logo_monster']))); } -?> diff --git a/tools/news_preview.php b/tools/news_preview.php index 7fa1e125..a1709e81 100644 --- a/tools/news_preview.php +++ b/tools/news_preview.php @@ -112,5 +112,3 @@ function error_($desc) { )); exit(); } - -?> \ No newline at end of file diff --git a/tools/signature/gesior.php b/tools/signature/gesior.php index d3b4edce..a9b88a25 100644 --- a/tools/signature/gesior.php +++ b/tools/signature/gesior.php @@ -12,7 +12,7 @@ $vocation = 'Unknown vocation'; if(isset($config['vocations'][$player->getVocation()])) $vocation = $config['vocations'][$player->getVocation()]; - + imagettftext($image , $fontsize, 0, 20, 52, $color, $font, 'Level:'); imagettftext($image , $fontsize, 0, 70, 52, $color, $font, $player->getLevel() . ' ' . $vocation); @@ -26,4 +26,3 @@ imagettftext($image , $fontsize, 0, 100, 95, $color, $font, (($player->getLastLogin() > 0) ? date("j F Y, g:i a", $player->getLastLogin()) : 'Never logged in.')); imagepng($image, SIGNATURES_CACHE . $player->getID() . '.png'); imagedestroy($image); -?> \ No newline at end of file diff --git a/tools/signature/mango.php b/tools/signature/mango.php index acdf37b3..f00f7f18 100644 --- a/tools/signature/mango.php +++ b/tools/signature/mango.php @@ -168,4 +168,3 @@ } $MadGD->save($player->getID()); -?> From 9d664d3577c0e9807926d5ae1e99dd6da6b27df0 Mon Sep 17 00:00:00 2001 From: SRNT-GG <95472530+SRNT-GG@users.noreply.github.com> Date: Thu, 15 Jun 2023 20:53:55 +0200 Subject: [PATCH 156/232] WIP - Removing unneccessary closing tags to prevent potential issues. (#223) * Part 1 Removing closing tags when no HTML or other output comes after the last PHP codeblock. * Further removals * nothing --------- Co-authored-by: slawkens --- admin/includes/functions.php | 3 ++- admin/pages/pages.php | 2 -- admin/pages/statistics.php | 1 - admin/pages/version.php | 1 - admin/tools/phpinfo.php | 1 - install/includes/config.php | 1 - install/steps/2-license.php | 1 - install/steps/4-config.php | 1 - system/counter.php | 1 - system/init.php | 2 +- system/item.php | 1 - system/libs/data.php | 1 - system/libs/pot/E_OTS_ErrorCode.php | 2 -- system/libs/pot/E_OTS_Generic.php | 2 -- system/libs/pot/E_OTS_NotAContainer.php | 2 -- system/libs/pot/E_OTS_OTBMError.php | 2 -- system/libs/pot/E_OTS_ReadOnly.php | 2 -- system/libs/pot/IOTS_Cipher.php | 2 -- system/libs/pot/IOTS_DataDisplay.php | 2 -- system/libs/pot/IOTS_Display.php | 2 -- system/libs/pot/IOTS_GuildAction.php | 2 -- system/libs/pot/OTS_Account.php | 2 -- system/libs/pot/OTS_AccountBans_List.php | 2 -- system/libs/pot/OTS_Admin.php | 2 -- system/libs/pot/OTS_Bans_List.php | 2 -- system/libs/pot/OTS_Base_DB.php | 2 -- system/libs/pot/OTS_BinaryTools.php | 2 -- system/libs/pot/OTS_Container.php | 2 -- system/libs/pot/OTS_FileLoader.php | 2 -- system/libs/pot/OTS_Group.php | 2 -- system/libs/pot/OTS_Guild.php | 2 -- system/libs/pot/OTS_GuildRanks_List.php | 2 -- system/libs/pot/OTS_House.php | 2 -- system/libs/pot/OTS_IPBans_List.php | 2 -- system/libs/pot/OTS_InfoRespond.php | 2 -- system/libs/pot/OTS_ItemsList.php | 2 -- system/libs/pot/OTS_MapCoords.php | 2 -- system/libs/pot/OTS_MonstersList.php | 2 -- system/libs/pot/OTS_Player.php | 2 -- system/libs/pot/OTS_PlayerBans_List.php | 2 -- system/libs/pot/OTS_Row_DAO.php | 2 -- system/libs/pot/OTS_SQLField.php | 2 -- system/libs/pot/OTS_ServerInfo.php | 2 -- system/libs/pot/OTS_Spell.php | 2 -- system/libs/pot/OTS_Toolbox.php | 2 -- system/libs/pot/OTS_XTEA.php | 2 -- system/libs/rfc6238.php | 1 - system/libs/validator.php | 1 - system/locale/de/admin.php | 1 - system/locale/de/main.php | 3 +-- system/locale/en/install.php | 1 - system/locale/pl/admin.php | 1 - system/locale/pl/main.php | 2 +- system/locale/pt_br/install.php | 1 - system/locale/sv/admin.php | 1 - system/locale/sv/main.php | 1 - system/migrations/11.php | 1 - system/migrations/13.php | 3 +-- system/migrations/15.php | 1 - system/migrations/17.php | 1 - system/migrations/19.php | 3 +-- system/migrations/2.php | 1 - system/migrations/20.php | 1 - system/migrations/4.php | 3 +-- system/migrations/6.php | 3 +-- system/migrations/8.php | 3 +-- system/pages/account/change_email.php | 1 - system/pages/account/change_name.php | 2 -- system/pages/account/change_sex.php | 2 -- system/pages/account/lost.php | 1 - system/pages/bugtracker.php | 1 - system/pages/faq.php | 1 - system/pages/forum/edit_post.php | 2 -- system/pages/forum/new_thread.php | 2 -- system/pages/gallery.php | 1 - system/pages/guilds/change_description.php | 2 -- system/pages/guilds/change_motd.php | 2 -- system/pages/guilds/cleanup_players.php | 1 - system/pages/guilds/delete_by_admin.php | 2 -- system/pages/guilds/delete_rank.php | 2 -- system/pages/guilds/leave.php | 2 -- system/pages/guilds/pass_leadership.php | 2 -- system/pages/polls.php | 1 - system/pages/server_info.php | 3 --- system/pages/team.php | 1 - templates/tibiacom/index.php | 1 - tools/news_preview.php | 2 -- tools/signature/gesior.php | 3 +-- tools/signature/mango.php | 1 - 89 files changed, 11 insertions(+), 144 deletions(-) diff --git a/admin/includes/functions.php b/admin/includes/functions.php index ab604f76..620272f5 100644 --- a/admin/includes/functions.php +++ b/admin/includes/functions.php @@ -1 +1,2 @@ - \ No newline at end of file + diff --git a/admin/pages/statistics.php b/admin/pages/statistics.php index 17d8118f..b740c217 100644 --- a/admin/pages/statistics.php +++ b/admin/pages/statistics.php @@ -36,4 +36,3 @@ $twig->display('admin.statistics.html.twig', array( 'account_type' => (USE_ACCOUNT_NAME ? 'name' : 'number'), 'points' => $points )); -?> \ No newline at end of file diff --git a/admin/pages/version.php b/admin/pages/version.php index e643e728..64f673c8 100644 --- a/admin/pages/version.php +++ b/admin/pages/version.php @@ -47,4 +47,3 @@ function version_revert($version) $release = $version; return $major . '.' . $minor . '.' . $release; }*/ -?> diff --git a/admin/tools/phpinfo.php b/admin/tools/phpinfo.php index 96a9aad9..cd043279 100644 --- a/admin/tools/phpinfo.php +++ b/admin/tools/phpinfo.php @@ -13,4 +13,3 @@ if(!function_exists('phpinfo')) die('phpinfo() disabled on this web server.'); phpinfo(); -?> diff --git a/install/includes/config.php b/install/includes/config.php index 380fff7d..5d9ae07a 100644 --- a/install/includes/config.php +++ b/install/includes/config.php @@ -38,4 +38,3 @@ if(!isset($error) || !$error) { $error = true; } } -?> \ No newline at end of file diff --git a/install/steps/2-license.php b/install/steps/2-license.php index e84ce0e6..4976dd70 100644 --- a/install/steps/2-license.php +++ b/install/steps/2-license.php @@ -5,4 +5,3 @@ $twig->display('install.license.html.twig', array( 'license' => file_get_contents(BASE . 'LICENSE'), 'buttons' => next_buttons() )); -?> diff --git a/install/steps/4-config.php b/install/steps/4-config.php index b1555201..325b97f1 100644 --- a/install/steps/4-config.php +++ b/install/steps/4-config.php @@ -18,4 +18,3 @@ $twig->display('install.config.html.twig', array( 'errors' => isset($errors) ? $errors : null, 'buttons' => next_buttons() )); -?> \ No newline at end of file diff --git a/system/counter.php b/system/counter.php index ada05903..63905ba2 100644 --- a/system/counter.php +++ b/system/counter.php @@ -51,4 +51,3 @@ else updateDatabaseConfig('views_counter', $views_counter); // update counter } } -?> diff --git a/system/init.php b/system/init.php index 056bbd40..2815f791 100644 --- a/system/init.php +++ b/system/init.php @@ -122,7 +122,7 @@ if(!isset($foundValue)) { $config['data_path'] = $foundValue; unset($foundValue); -// new config values for compability +// new config values for compatibility if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hidden']) == 0) { $config['highscores_ids_hidden'] = array(0); } diff --git a/system/item.php b/system/item.php index 4d213360..66d4bfc5 100644 --- a/system/item.php +++ b/system/item.php @@ -58,4 +58,3 @@ function outputItem($id = 100, $count = 1) $file_name = Items_Images::$outputDir . $file_name . '.gif'; readfile($file_name); } -?> diff --git a/system/libs/data.php b/system/libs/data.php index 64d93f78..af667448 100644 --- a/system/libs/data.php +++ b/system/libs/data.php @@ -41,4 +41,3 @@ class Data return $db->update($this->table, $data, $where); } } -?> diff --git a/system/libs/pot/E_OTS_ErrorCode.php b/system/libs/pot/E_OTS_ErrorCode.php index f5bbd2fc..451e5a07 100644 --- a/system/libs/pot/E_OTS_ErrorCode.php +++ b/system/libs/pot/E_OTS_ErrorCode.php @@ -32,5 +32,3 @@ class E_OTS_ErrorCode extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_Generic.php b/system/libs/pot/E_OTS_Generic.php index 3ca0a914..7a95d675 100644 --- a/system/libs/pot/E_OTS_Generic.php +++ b/system/libs/pot/E_OTS_Generic.php @@ -36,5 +36,3 @@ class E_OTS_Generic extends E_OTS_ErrorCode } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_NotAContainer.php b/system/libs/pot/E_OTS_NotAContainer.php index 3a8d224b..8285691f 100644 --- a/system/libs/pot/E_OTS_NotAContainer.php +++ b/system/libs/pot/E_OTS_NotAContainer.php @@ -22,5 +22,3 @@ class E_OTS_NotAContainer extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_OTBMError.php b/system/libs/pot/E_OTS_OTBMError.php index d84d740c..9ab1228d 100644 --- a/system/libs/pot/E_OTS_OTBMError.php +++ b/system/libs/pot/E_OTS_OTBMError.php @@ -32,5 +32,3 @@ class E_OTS_OTBMError extends E_OTS_ErrorCode } /**#@-*/ - -?> diff --git a/system/libs/pot/E_OTS_ReadOnly.php b/system/libs/pot/E_OTS_ReadOnly.php index 003d12af..5fb3b39b 100644 --- a/system/libs/pot/E_OTS_ReadOnly.php +++ b/system/libs/pot/E_OTS_ReadOnly.php @@ -22,5 +22,3 @@ class E_OTS_ReadOnly extends Exception } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_Cipher.php b/system/libs/pot/IOTS_Cipher.php index 82044cc8..542b4abb 100644 --- a/system/libs/pot/IOTS_Cipher.php +++ b/system/libs/pot/IOTS_Cipher.php @@ -37,5 +37,3 @@ interface IOTS_Cipher } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_DataDisplay.php b/system/libs/pot/IOTS_DataDisplay.php index 7c5abc2c..359dc1a6 100644 --- a/system/libs/pot/IOTS_DataDisplay.php +++ b/system/libs/pot/IOTS_DataDisplay.php @@ -89,5 +89,3 @@ interface IOTS_DataDisplay } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_Display.php b/system/libs/pot/IOTS_Display.php index cb2d8e90..3b75d537 100644 --- a/system/libs/pot/IOTS_Display.php +++ b/system/libs/pot/IOTS_Display.php @@ -96,5 +96,3 @@ interface IOTS_Display } /**#@-*/ - -?> diff --git a/system/libs/pot/IOTS_GuildAction.php b/system/libs/pot/IOTS_GuildAction.php index 7ed97f94..680025cd 100644 --- a/system/libs/pot/IOTS_GuildAction.php +++ b/system/libs/pot/IOTS_GuildAction.php @@ -67,5 +67,3 @@ interface IOTS_GuildAction } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Account.php b/system/libs/pot/OTS_Account.php index d5b42961..9a6b39a7 100644 --- a/system/libs/pot/OTS_Account.php +++ b/system/libs/pot/OTS_Account.php @@ -1198,5 +1198,3 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_AccountBans_List.php b/system/libs/pot/OTS_AccountBans_List.php index f3687409..fdd2f923 100644 --- a/system/libs/pot/OTS_AccountBans_List.php +++ b/system/libs/pot/OTS_AccountBans_List.php @@ -34,5 +34,3 @@ class OTS_AccountBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_Admin.php b/system/libs/pot/OTS_Admin.php index 3507e10d..7530d6ef 100644 --- a/system/libs/pot/OTS_Admin.php +++ b/system/libs/pot/OTS_Admin.php @@ -735,5 +735,3 @@ class OTS_Admin } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Bans_List.php b/system/libs/pot/OTS_Bans_List.php index 5f58788e..8eb59df6 100644 --- a/system/libs/pot/OTS_Bans_List.php +++ b/system/libs/pot/OTS_Bans_List.php @@ -100,5 +100,3 @@ class OTS_Bans_List extends OTS_Base_List } } } - -?> diff --git a/system/libs/pot/OTS_Base_DB.php b/system/libs/pot/OTS_Base_DB.php index f97745b4..21d6f756 100644 --- a/system/libs/pot/OTS_Base_DB.php +++ b/system/libs/pot/OTS_Base_DB.php @@ -265,5 +265,3 @@ abstract class OTS_Base_DB extends PDO implements IOTS_DB } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_BinaryTools.php b/system/libs/pot/OTS_BinaryTools.php index 7e6a86e5..84fbf54c 100644 --- a/system/libs/pot/OTS_BinaryTools.php +++ b/system/libs/pot/OTS_BinaryTools.php @@ -146,5 +146,3 @@ class OTS_BinaryTools } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Container.php b/system/libs/pot/OTS_Container.php index 7b93570f..ff910401 100644 --- a/system/libs/pot/OTS_Container.php +++ b/system/libs/pot/OTS_Container.php @@ -149,5 +149,3 @@ class OTS_Container extends OTS_Item implements IteratorAggregate } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_FileLoader.php b/system/libs/pot/OTS_FileLoader.php index 8f86712e..77f184f3 100644 --- a/system/libs/pot/OTS_FileLoader.php +++ b/system/libs/pot/OTS_FileLoader.php @@ -357,5 +357,3 @@ class OTS_FileLoader } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Group.php b/system/libs/pot/OTS_Group.php index 19f770f1..d094d365 100644 --- a/system/libs/pot/OTS_Group.php +++ b/system/libs/pot/OTS_Group.php @@ -671,5 +671,3 @@ class OTS_Group extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Guild.php b/system/libs/pot/OTS_Guild.php index 98dd47cf..bab363a8 100644 --- a/system/libs/pot/OTS_Guild.php +++ b/system/libs/pot/OTS_Guild.php @@ -837,5 +837,3 @@ class OTS_Guild extends OTS_Row_DAO implements IteratorAggregate, Countable } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_GuildRanks_List.php b/system/libs/pot/OTS_GuildRanks_List.php index f2f9e57e..aec6114a 100644 --- a/system/libs/pot/OTS_GuildRanks_List.php +++ b/system/libs/pot/OTS_GuildRanks_List.php @@ -72,5 +72,3 @@ class OTS_GuildRanks_List extends OTS_Base_List } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_House.php b/system/libs/pot/OTS_House.php index e6aca322..12a8f1cb 100644 --- a/system/libs/pot/OTS_House.php +++ b/system/libs/pot/OTS_House.php @@ -529,5 +529,3 @@ class OTS_House extends OTS_Row_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_IPBans_List.php b/system/libs/pot/OTS_IPBans_List.php index dd614e9a..1fdfc0ce 100644 --- a/system/libs/pot/OTS_IPBans_List.php +++ b/system/libs/pot/OTS_IPBans_List.php @@ -34,5 +34,3 @@ class OTS_IPBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_InfoRespond.php b/system/libs/pot/OTS_InfoRespond.php index f64fca05..6e452371 100644 --- a/system/libs/pot/OTS_InfoRespond.php +++ b/system/libs/pot/OTS_InfoRespond.php @@ -387,5 +387,3 @@ class OTS_InfoRespond extends DOMDocument } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_ItemsList.php b/system/libs/pot/OTS_ItemsList.php index 1865117a..30465a9d 100644 --- a/system/libs/pot/OTS_ItemsList.php +++ b/system/libs/pot/OTS_ItemsList.php @@ -676,5 +676,3 @@ class OTS_ItemsList extends OTS_FileLoader implements IteratorAggregate, Countab } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_MapCoords.php b/system/libs/pot/OTS_MapCoords.php index dfe1a1cd..738b0bea 100644 --- a/system/libs/pot/OTS_MapCoords.php +++ b/system/libs/pot/OTS_MapCoords.php @@ -130,5 +130,3 @@ class OTS_MapCoords } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_MonstersList.php b/system/libs/pot/OTS_MonstersList.php index fb51a085..f7d1b2da 100644 --- a/system/libs/pot/OTS_MonstersList.php +++ b/system/libs/pot/OTS_MonstersList.php @@ -299,5 +299,3 @@ class OTS_MonstersList implements Iterator, Countable, ArrayAccess } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Player.php b/system/libs/pot/OTS_Player.php index 2143c12e..7fd96fec 100644 --- a/system/libs/pot/OTS_Player.php +++ b/system/libs/pot/OTS_Player.php @@ -3627,5 +3627,3 @@ class OTS_Player extends OTS_Row_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_PlayerBans_List.php b/system/libs/pot/OTS_PlayerBans_List.php index 7e06c7ca..f9826f78 100644 --- a/system/libs/pot/OTS_PlayerBans_List.php +++ b/system/libs/pot/OTS_PlayerBans_List.php @@ -34,5 +34,3 @@ class OTS_PlayerBans_List extends OTS_Bans_List $this->setFilter($filter); } } - -?> diff --git a/system/libs/pot/OTS_Row_DAO.php b/system/libs/pot/OTS_Row_DAO.php index c1a09858..2a0a100c 100644 --- a/system/libs/pot/OTS_Row_DAO.php +++ b/system/libs/pot/OTS_Row_DAO.php @@ -75,5 +75,3 @@ abstract class OTS_Row_DAO extends OTS_Base_DAO } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_SQLField.php b/system/libs/pot/OTS_SQLField.php index 2f7ac74e..ba2bb55c 100644 --- a/system/libs/pot/OTS_SQLField.php +++ b/system/libs/pot/OTS_SQLField.php @@ -121,5 +121,3 @@ class OTS_SQLField } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_ServerInfo.php b/system/libs/pot/OTS_ServerInfo.php index eb153c93..fd06749e 100644 --- a/system/libs/pot/OTS_ServerInfo.php +++ b/system/libs/pot/OTS_ServerInfo.php @@ -227,5 +227,3 @@ class OTS_ServerInfo } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Spell.php b/system/libs/pot/OTS_Spell.php index 0ec51bdf..419ee292 100644 --- a/system/libs/pot/OTS_Spell.php +++ b/system/libs/pot/OTS_Spell.php @@ -482,5 +482,3 @@ class OTS_Spell } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_Toolbox.php b/system/libs/pot/OTS_Toolbox.php index 4d22d0dd..980e5cb5 100644 --- a/system/libs/pot/OTS_Toolbox.php +++ b/system/libs/pot/OTS_Toolbox.php @@ -113,5 +113,3 @@ class OTS_Toolbox } /**#@-*/ - -?> diff --git a/system/libs/pot/OTS_XTEA.php b/system/libs/pot/OTS_XTEA.php index 96ee7553..ff5a1095 100644 --- a/system/libs/pot/OTS_XTEA.php +++ b/system/libs/pot/OTS_XTEA.php @@ -151,5 +151,3 @@ class OTS_XTEA implements IOTS_Cipher } /**#@-*/ - -?> diff --git a/system/libs/rfc6238.php b/system/libs/rfc6238.php index 579f08f2..5effedd3 100644 --- a/system/libs/rfc6238.php +++ b/system/libs/rfc6238.php @@ -282,4 +282,3 @@ class TokenAuth6238 { return $result; } } -?> diff --git a/system/libs/validator.php b/system/libs/validator.php index 38db7068..91f71c24 100644 --- a/system/libs/validator.php +++ b/system/libs/validator.php @@ -451,4 +451,3 @@ class Validator return self::$lastError; } } -?> diff --git a/system/locale/de/admin.php b/system/locale/de/admin.php index 8a128216..dae5fdee 100644 --- a/system/locale/de/admin.php +++ b/system/locale/de/admin.php @@ -6,4 +6,3 @@ * @author Slawkens */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/de/main.php b/system/locale/de/main.php index 3f9b2479..e4482572 100644 --- a/system/locale/de/main.php +++ b/system/locale/de/main.php @@ -11,5 +11,4 @@ $locale['encoding'] = 'utf-8'; $locale['direction']= 'ltr'; $locale['error404'] = 'Diese Seite konnte nicht gefunden werden.'; -$locale['news'] = 'Neuesten Nachrichten'; -?> \ No newline at end of file +$locale['news'] = 'Neuesten Nachrichten'; \ No newline at end of file diff --git a/system/locale/en/install.php b/system/locale/en/install.php index f856dcbf..3de85896 100644 --- a/system/locale/en/install.php +++ b/system/locale/en/install.php @@ -131,4 +131,3 @@ $locale['step_finish_title'] = 'Installation finished!'; $locale['step_finish_desc'] = 'Congratulations! MyAAC is ready to use!
    You can now login to $ADMIN_PANEL$, or visit $HOMEPAGE$.

    Please delete install/ directory.

    Post bugs and suggestions at $LINK$, thanks!'; -?> diff --git a/system/locale/pl/admin.php b/system/locale/pl/admin.php index 91adfc60..8431b438 100644 --- a/system/locale/pl/admin.php +++ b/system/locale/pl/admin.php @@ -6,4 +6,3 @@ * @author Slawkens */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/pl/main.php b/system/locale/pl/main.php index 200bba22..b86b331f 100644 --- a/system/locale/pl/main.php +++ b/system/locale/pl/main.php @@ -12,4 +12,4 @@ $locale['direction']= 'ltr'; $locale['error404'] = 'Strona nie została odnaleziona.'; $locale['news'] = 'Ostatnie newsy'; -$locale['loaded_in_ms'] = 'w $TIME$ ms'; \ No newline at end of file +$locale['loaded_in_ms'] = 'w $TIME$ ms'; diff --git a/system/locale/pt_br/install.php b/system/locale/pt_br/install.php index e47faede..3a9ca9cc 100644 --- a/system/locale/pt_br/install.php +++ b/system/locale/pt_br/install.php @@ -118,4 +118,3 @@ $locale['step_finish'] = 'Finalizar'; $locale['step_finish_title'] = 'Instalação terminada!'; $locale['step_finish_desc'] = 'Parabéns! MyAAC está pronto para uso!
    Agora você pode fazer login em $ADMIN_PANEL$ ou visitar $HOMEPAGE$.

    Por favor remova a pasta install/.

    Postar bugs e sugestões em $LINK$, obrigado!'; -?> diff --git a/system/locale/sv/admin.php b/system/locale/sv/admin.php index 69f4f20a..8fa07f74 100644 --- a/system/locale/sv/admin.php +++ b/system/locale/sv/admin.php @@ -6,4 +6,3 @@ * @author Sizaro */ $locale['title'] = 'MyAAC Admin'; -?> diff --git a/system/locale/sv/main.php b/system/locale/sv/main.php index fc714190..83f6bb84 100644 --- a/system/locale/sv/main.php +++ b/system/locale/sv/main.php @@ -12,4 +12,3 @@ $locale['direction']= 'ltr'; $locale['error404'] = 'Sidan kunde inte hittas.'; $locale['news'] = 'Senaste nyheterna'; -?> \ No newline at end of file diff --git a/system/migrations/11.php b/system/migrations/11.php index dc335577..845f9e67 100644 --- a/system/migrations/11.php +++ b/system/migrations/11.php @@ -17,4 +17,3 @@ 'thumb' => str_replace('/screenshots/', '/gallery/', $item['thumb']), ), array('id' => $item['id'])); } -?> diff --git a/system/migrations/13.php b/system/migrations/13.php index 71d3735c..4eee77f3 100644 --- a/system/migrations/13.php +++ b/system/migrations/13.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'spells', 'spell')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "spells` DROP COLUMN `spell`;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "spells` DROP COLUMN `spell`;"); \ No newline at end of file diff --git a/system/migrations/15.php b/system/migrations/15.php index 28996d8a..971587ec 100644 --- a/system/migrations/15.php +++ b/system/migrations/15.php @@ -8,4 +8,3 @@ if(!$db->hasColumn(TABLE_PREFIX . 'forum_boards', 'guild')) { if(!$db->hasColumn(TABLE_PREFIX . 'forum_boards', 'access')) { $db->query("ALTER TABLE `" . TABLE_PREFIX . "forum_boards` ADD `access` TINYINT(1) NOT NULL DEFAULT 0 AFTER `guild`;"); } -?> \ No newline at end of file diff --git a/system/migrations/17.php b/system/migrations/17.php index e4b1667c..220bc90b 100644 --- a/system/migrations/17.php +++ b/system/migrations/17.php @@ -86,4 +86,3 @@ INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VA INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2); "); } -?> \ No newline at end of file diff --git a/system/migrations/19.php b/system/migrations/19.php index 50baa271..81c818d2 100644 --- a/system/migrations/19.php +++ b/system/migrations/19.php @@ -1,3 +1,2 @@ \ No newline at end of file +// this migration has been removed, but file kept for compatibility diff --git a/system/migrations/2.php b/system/migrations/2.php index db5fd70f..90d9a610 100644 --- a/system/migrations/2.php +++ b/system/migrations/2.php @@ -3,4 +3,3 @@ $db->query("ALTER TABLE `" . TABLE_PREFIX . "movies` MODIFY `title` VARCHAR(100) NOT NULL DEFAULT '';"); $db->query("ALTER TABLE `" . TABLE_PREFIX . "news` MODIFY `title` VARCHAR(100) NOT NULL DEFAULT '';"); $db->query("ALTER TABLE `" . TABLE_PREFIX . "news` MODIFY `body` TEXT NOT NULL DEFAULT '';"); -?> diff --git a/system/migrations/20.php b/system/migrations/20.php index 0533b540..d0012fde 100644 --- a/system/migrations/20.php +++ b/system/migrations/20.php @@ -45,4 +45,3 @@ function databaseMigration20(&$content = '') { file_put_contents($config_file, $content, FILE_APPEND); return true; } -?> \ No newline at end of file diff --git a/system/migrations/4.php b/system/migrations/4.php index 80bbc4a0..db17feb1 100644 --- a/system/migrations/4.php +++ b/system/migrations/4.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'monsters', 'id')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `id` int(11) NOT NULL AUTO_INCREMENT primary key FIRST;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "monsters` ADD `id` int(11) NOT NULL AUTO_INCREMENT primary key FIRST;"); \ No newline at end of file diff --git a/system/migrations/6.php b/system/migrations/6.php index ed5329d0..e287d55a 100644 --- a/system/migrations/6.php +++ b/system/migrations/6.php @@ -1,4 +1,3 @@ hasColumn(TABLE_PREFIX . 'hooks', 'enabled')) - $db->query("ALTER TABLE `" . TABLE_PREFIX . "hooks` ADD `enabled` INT(1) NOT NULL DEFAULT 1;"); -?> \ No newline at end of file + $db->query("ALTER TABLE `" . TABLE_PREFIX . "hooks` ADD `enabled` INT(1) NOT NULL DEFAULT 1;"); \ No newline at end of file diff --git a/system/migrations/8.php b/system/migrations/8.php index a04331a8..4785e23b 100644 --- a/system/migrations/8.php +++ b/system/migrations/8.php @@ -14,5 +14,4 @@ foreach($boards as $id => $board) $db->query('UPDATE `' . TABLE_PREFIX . 'forum_boards` SET `ordering` = ' . $id . ' WHERE `name` = ' . $db->quote($board)); - } -?> \ No newline at end of file + } \ No newline at end of file diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 2368a284..3bc8edd7 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -166,4 +166,3 @@ if(isset($_POST['emailchangecancel']) && $_POST['emailchangecancel'] == 1) { 'custom_buttons' => $custom_buttons )); } -?> diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index ab7bd326..448e730c 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -112,5 +112,3 @@ else )); } } - -?> diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index c67ac608..868cf24f 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -91,5 +91,3 @@ else )); } } - -?> diff --git a/system/pages/account/lost.php b/system/pages/account/lost.php index a474540c..3ea0957e 100644 --- a/system/pages/account/lost.php +++ b/system/pages/account/lost.php @@ -546,4 +546,3 @@ elseif($action == 'setnewpassword') ' . $twig->render('buttons.submit.html.twig') . '
    '; } -?> diff --git a/system/pages/bugtracker.php b/system/pages/bugtracker.php index a7cffcf0..ac37becd 100644 --- a/system/pages/bugtracker.php +++ b/system/pages/bugtracker.php @@ -339,4 +339,3 @@ $showed = $post = $reply = false; { echo '

    [ADMIN PANEL]'; } -?> diff --git a/system/pages/faq.php b/system/pages/faq.php index f30e7914..5d71aa3c 100644 --- a/system/pages/faq.php +++ b/system/pages/faq.php @@ -185,4 +185,3 @@ class FAQ return !count($errors); } } -?> diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index 45fd675b..d3f95c45 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -114,5 +114,3 @@ 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."; - -?> diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 4db06c63..c3b688ad 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -103,5 +103,3 @@ 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.'; - -?> diff --git a/system/pages/gallery.php b/system/pages/gallery.php index c893ce90..b6e2b07f 100644 --- a/system/pages/gallery.php +++ b/system/pages/gallery.php @@ -312,4 +312,3 @@ class Gallery return !count($errors); } } -?> diff --git a/system/pages/guilds/change_description.php b/system/pages/guilds/change_description.php index b4e787ee..9f6fc0dc 100644 --- a/system/pages/guilds/change_description.php +++ b/system/pages/guilds/change_description.php @@ -72,5 +72,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/change_motd.php b/system/pages/guilds/change_motd.php index c777548d..84581485 100644 --- a/system/pages/guilds/change_motd.php +++ b/system/pages/guilds/change_motd.php @@ -75,5 +75,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/cleanup_players.php b/system/pages/guilds/cleanup_players.php index 30b1e8af..61b1ce49 100644 --- a/system/pages/guilds/cleanup_players.php +++ b/system/pages/guilds/cleanup_players.php @@ -68,4 +68,3 @@ else echo "0 players found."; $twig->display('guilds.back_button.html.twig'); -?> diff --git a/system/pages/guilds/delete_by_admin.php b/system/pages/guilds/delete_by_admin.php index 3e083c8a..7da54aea 100644 --- a/system/pages/guilds/delete_by_admin.php +++ b/system/pages/guilds/delete_by_admin.php @@ -66,5 +66,3 @@ if(!empty($errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/delete_rank.php b/system/pages/guilds/delete_rank.php index 6a8f642c..48eeba4d 100644 --- a/system/pages/guilds/delete_rank.php +++ b/system/pages/guilds/delete_rank.php @@ -125,5 +125,3 @@ if(!empty($guild_errors)) { 'action' => '?subtopic=guilds' )); } - -?> diff --git a/system/pages/guilds/leave.php b/system/pages/guilds/leave.php index 892deb89..9a11595d 100644 --- a/system/pages/guilds/leave.php +++ b/system/pages/guilds/leave.php @@ -114,5 +114,3 @@ else )); } } - -?> \ No newline at end of file diff --git a/system/pages/guilds/pass_leadership.php b/system/pages/guilds/pass_leadership.php index 462ac9ec..d5f0ed20 100644 --- a/system/pages/guilds/pass_leadership.php +++ b/system/pages/guilds/pass_leadership.php @@ -117,5 +117,3 @@ if(!empty($guild_errors)) { echo '
    ' . $twig->render('buttons.back.html.twig') . '
    '; } - -?> diff --git a/system/pages/polls.php b/system/pages/polls.php index c31b61cb..dcc781c2 100644 --- a/system/pages/polls.php +++ b/system/pages/polls.php @@ -369,4 +369,3 @@ function getColorByPercent($percent) echo 'This poll doesn\'t exist.
    '; echo '
    Go to list of polls'; } -?> diff --git a/system/pages/server_info.php b/system/pages/server_info.php index 7c2a519e..b750c3ee 100644 --- a/system/pages/server_info.php +++ b/system/pages/server_info.php @@ -108,6 +108,3 @@ $twig->display('serverinfo.html.twig', array( 'finalBanishmentLength' => isset($config['lua']['final_banishment_length']) ? eval('return (' . $config['lua']['final_banishment_length'] . ') / (24 * 60 * 60);') : null, 'ipBanishmentLength' => isset($config['lua']['ip_banishment_length']) ? eval('return (' . $config['lua']['ip_banishment_length'] . ') / (24 * 60 * 60);') : null, )); -?> - - diff --git a/system/pages/team.php b/system/pages/team.php index 2e410e12..fbc0df99 100644 --- a/system/pages/team.php +++ b/system/pages/team.php @@ -74,4 +74,3 @@ foreach($groupList as $id => $group) $twig->display('team.html.twig', array( 'groupmember' => $groupMember )); -?> \ No newline at end of file diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 989a05ca..539453c9 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -459,4 +459,3 @@ function logo_monster() global $config; return str_replace(" ", "", trim(strtolower($config['logo_monster']))); } -?> diff --git a/tools/news_preview.php b/tools/news_preview.php index 7fa1e125..a1709e81 100644 --- a/tools/news_preview.php +++ b/tools/news_preview.php @@ -112,5 +112,3 @@ function error_($desc) { )); exit(); } - -?> \ No newline at end of file diff --git a/tools/signature/gesior.php b/tools/signature/gesior.php index d3b4edce..a9b88a25 100644 --- a/tools/signature/gesior.php +++ b/tools/signature/gesior.php @@ -12,7 +12,7 @@ $vocation = 'Unknown vocation'; if(isset($config['vocations'][$player->getVocation()])) $vocation = $config['vocations'][$player->getVocation()]; - + imagettftext($image , $fontsize, 0, 20, 52, $color, $font, 'Level:'); imagettftext($image , $fontsize, 0, 70, 52, $color, $font, $player->getLevel() . ' ' . $vocation); @@ -26,4 +26,3 @@ imagettftext($image , $fontsize, 0, 100, 95, $color, $font, (($player->getLastLogin() > 0) ? date("j F Y, g:i a", $player->getLastLogin()) : 'Never logged in.')); imagepng($image, SIGNATURES_CACHE . $player->getID() . '.png'); imagedestroy($image); -?> \ No newline at end of file diff --git a/tools/signature/mango.php b/tools/signature/mango.php index acdf37b3..f00f7f18 100644 --- a/tools/signature/mango.php +++ b/tools/signature/mango.php @@ -168,4 +168,3 @@ } $MadGD->save($player->getID()); -?> From cc7703766ef3c11dc635d931fd84a0a3c318397e Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 19 Jun 2023 08:05:58 +0200 Subject: [PATCH 157/232] Patching some changes from master --- system/login.php | 2 +- system/pages/account/change_password.php | 4 +--- system/pages/online.php | 4 ++-- system/templates/characters.html.twig | 2 ++ 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/system/login.php b/system/login.php index 5d55cd18..e018c043 100644 --- a/system/login.php +++ b/system/login.php @@ -10,12 +10,12 @@ defined('MYAAC') or die('Direct access not allowed!'); $logged = false; $logged_flags = 0; +$account_logged = new OTS_Account(); // stay-logged with sessions $current_session = getSession('account'); if($current_session !== false) { - $account_logged = new OTS_Account(); $account_logged->load($current_session); if($account_logged->isLoaded() && $account_logged->getPassword() == getSession('password') //&& (!isset($_SESSION['admin']) || admin()) diff --git a/system/pages/account/change_password.php b/system/pages/account/change_password.php index 01190497..deef3602 100644 --- a/system/pages/account/change_password.php +++ b/system/pages/account/change_password.php @@ -89,6 +89,4 @@ else )); setSession('password', $new_password); } -} - -?> +} \ No newline at end of file diff --git a/system/pages/online.php b/system/pages/online.php index ca629a3b..2d96a405 100644 --- a/system/pages/online.php +++ b/system/pages/online.php @@ -54,9 +54,9 @@ if($config['online_vocations']) { } if($db->hasTable('players_online')) // tfs 1.0 - $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `level`, `vocation`' . $outfit . ', `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players`, `players_online` WHERE `players`.`id` = `players_online`.`player_id` AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $order); + $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players`, `players_online` WHERE `players`.`id` = `players_online`.`player_id` AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $order); else - $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `level`, `vocation`' . $outfit . ', ' . $promotion . ' `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players` WHERE `players`.`online` > 0 AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $order); + $playersOnline = $db->query('SELECT `accounts`.`country`, `players`.`name`, `players`.`level`, `players`.`vocation`' . $outfit . ', ' . $promotion . ' `' . $skull_time . '` as `skulltime`, `' . $skull_type . '` as `skull` FROM `accounts`, `players` WHERE `players`.`online` > 0 AND `accounts`.`id` = `players`.`account_id` ORDER BY ' . $order); $players_data = array(); $players = 0; diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 3bbb0159..94f64803 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -237,11 +237,13 @@ {% endif %} + {{ hook(constant('HOOK_CHARACTERS_AFTER_EQUIPMENT')) }} {{ hook(constant('HOOK_CHARACTERS_BEFORE_DEATHS')) }} + {% if deaths|length > 0 %}
    From 30d62bda3beff0e46f2a1afefdec62284b805de5 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 22 Jun 2023 22:15:18 +0200 Subject: [PATCH 158/232] Better Gesior support --- index.php | 1 + system/compat/pages.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/index.php b/index.php index e15abb21..a093b9bd 100644 --- a/index.php +++ b/index.php @@ -166,6 +166,7 @@ if($config['backward_support']) { $config['site'] = &$config; $config['server'] = &$config['lua']; $config['site']['shop_system'] = $config['gifts_system']; + $config['site']['gallery_page'] = true; if(!isset($config['vdarkborder'])) $config['vdarkborder'] = '#505050'; diff --git a/system/compat/pages.php b/system/compat/pages.php index 3f5d0a0a..5857322d 100644 --- a/system/compat/pages.php +++ b/system/compat/pages.php @@ -10,6 +10,10 @@ defined('MYAAC') or die('Direct access not allowed!'); switch($page) { + case 'adminpanel': + header('Location: ' . ADMIN_URL); + die; + case 'createaccount': $page = 'account/create'; break; @@ -30,6 +34,7 @@ switch($page) $page = 'news'; break; + case 'archive': case 'newsarchive': $page = 'news/archive'; break; From 74433303fbd0ba90db05e953c1e13f234f60b37a Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 22 Jun 2023 22:15:18 +0200 Subject: [PATCH 159/232] Better Gesior support --- index.php | 1 + system/compat/pages.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/index.php b/index.php index e15abb21..a093b9bd 100644 --- a/index.php +++ b/index.php @@ -166,6 +166,7 @@ if($config['backward_support']) { $config['site'] = &$config; $config['server'] = &$config['lua']; $config['site']['shop_system'] = $config['gifts_system']; + $config['site']['gallery_page'] = true; if(!isset($config['vdarkborder'])) $config['vdarkborder'] = '#505050'; diff --git a/system/compat/pages.php b/system/compat/pages.php index 3f5d0a0a..5857322d 100644 --- a/system/compat/pages.php +++ b/system/compat/pages.php @@ -10,6 +10,10 @@ defined('MYAAC') or die('Direct access not allowed!'); switch($page) { + case 'adminpanel': + header('Location: ' . ADMIN_URL); + die; + case 'createaccount': $page = 'account/create'; break; @@ -30,6 +34,7 @@ switch($page) $page = 'news'; break; + case 'archive': case 'newsarchive': $page = 'news/archive'; break; From a7dc71993412bb5687d2524c2db412c9c514b4c2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 25 Jun 2023 08:38:45 +0200 Subject: [PATCH 160/232] small adjustments --- nginx-sample.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-sample.conf b/nginx-sample.conf index 2ae14251..a54f87e5 100644 --- a/nginx-sample.conf +++ b/nginx-sample.conf @@ -32,6 +32,6 @@ server { include snippets/fastcgi-php.conf; fastcgi_read_timeout 240; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; - # for ubuntu 22.04+ it will be php8.1-fpm.-sock + # for ubuntu 22.04+ it will be php8.1-fpm.sock } } From a3bfdc1ec8b4f477e79d3af1cb5cd5cf4bba8296 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 25 Jun 2023 08:38:45 +0200 Subject: [PATCH 161/232] small adjustments --- nginx-sample.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-sample.conf b/nginx-sample.conf index 2ae14251..a54f87e5 100644 --- a/nginx-sample.conf +++ b/nginx-sample.conf @@ -32,6 +32,6 @@ server { include snippets/fastcgi-php.conf; fastcgi_read_timeout 240; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; - # for ubuntu 22.04+ it will be php8.1-fpm.-sock + # for ubuntu 22.04+ it will be php8.1-fpm.sock } } From a81089061443917d7a96037d4c79c08b2f0471a9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 27 Jun 2023 14:50:44 +0200 Subject: [PATCH 162/232] code formatting --- system/templates/account.management.html.twig | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/system/templates/account.management.html.twig b/system/templates/account.management.html.twig index 80d60006..1f8ea2e6 100644 --- a/system/templates/account.management.html.twig +++ b/system/templates/account.management.html.twig @@ -170,7 +170,16 @@ {% for player in players %} {% set i = i + 1 %} - {{ player.getName() }}{{ player.getLevel() }}{{ player.getVocationName() }}{{ config.towns[player.getTownId()] }}{% if player.getLastLogin() > 0 %}{{ player.getLastLogin|date('d F Y (H:i)') }}{% else %}Never.{% endif %}{% if player.isOnline() %}ONLINE{% else %}Offline{% endif %}{% if player.isHidden() %}Hidden{% else %}Visible{% endif %}[Edit] + + {{ player.getName() }} + + {{ player.getLevel() }} + {{ player.getVocationName() }} + {{ config.towns[player.getTownId()] }} + {% if player.getLastLogin() > 0 %}{{ player.getLastLogin|date('d F Y (H:i)') }}{% else %}Never.{% endif %} + {% if player.isOnline() %}ONLINE{% else %}Offline{% endif %} + {% if player.isHidden() %}Hidden{% else %}Visible{% endif %} + [Edit] {% endfor %} From aab62fb724f3ffac6c4e6f39fcc1b9e7ac7b9ad2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 27 Jun 2023 15:02:28 +0200 Subject: [PATCH 163/232] Important fix: Not allow create char if limit is exceeded (by @anyeor ) Could have been used to spam database, now it doesn't ignore deleted characters He is not my brother :P Just same last name --- system/libs/CreateCharacter.php | 2 +- system/templates/account.create_character.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/libs/CreateCharacter.php b/system/libs/CreateCharacter.php index c81893e1..60909c0f 100644 --- a/system/libs/CreateCharacter.php +++ b/system/libs/CreateCharacter.php @@ -138,7 +138,7 @@ class CreateCharacter if(empty($errors)) { - $number_of_players_on_account = $account->getPlayersList(false)->count(); + $number_of_players_on_account = $account->getPlayersList(true)->count(); if($number_of_players_on_account >= config('characters_per_account')) $errors[] = 'You have too many characters on your account ('.$number_of_players_on_account.'/'.config('characters_per_account').')!'; } diff --git a/system/templates/account.create_character.html.twig b/system/templates/account.create_character.html.twig index 8d823b2f..045c749c 100644 --- a/system/templates/account.create_character.html.twig +++ b/system/templates/account.create_character.html.twig @@ -2,7 +2,7 @@ Please choose a name{% if config.character_samples|length > 1 %}, vocation{% end {% if config.character_towns|length > 1 %}, town{% endif %} and sex for your character.
    In any case the name must not violate the naming conventions stated in the {{ config.lua.serverName }} Rules, or your character might get deleted or name locked. -{% if account_logged.getPlayersList(false)|length >= config.characters_per_account %} +{% if account_logged.getPlayersList(true)|length >= config.characters_per_account %} You have maximum number of characters per account on your account. Delete one before you make new. {% endif %}

    From 24ff5684cd85238ca18b4b3ee1924b676d833798 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 27 Jun 2023 17:41:04 +0200 Subject: [PATCH 164/232] More changes to deleted characters (Account, guilds) Account: Cannot change name, comment, gender + Cannot be deleted if owns a guild Guilds: Cannot create, cannot be invited, cannot accept invite, cannot be passed leadership to --- system/libs/pot/OTS_Account.php | 2 +- system/pages/account/change_comment.php | 23 ++++++++++++------- system/pages/account/change_name.php | 6 ++++- system/pages/account/change_sex.php | 8 +++++-- system/pages/account/delete_character.php | 8 +++++++ system/pages/guilds/accept_invite.php | 4 +++- system/pages/guilds/create.php | 8 ++++--- system/pages/guilds/invite.php | 2 ++ system/pages/guilds/pass_leadership.php | 2 ++ .../templates/account.change_name.html.twig | 4 ++-- system/templates/account.management.html.twig | 2 +- .../tibiacom/account.management.html.twig | 2 +- 12 files changed, 51 insertions(+), 20 deletions(-) diff --git a/system/libs/pot/OTS_Account.php b/system/libs/pot/OTS_Account.php index 9a6b39a7..366dccdf 100644 --- a/system/libs/pot/OTS_Account.php +++ b/system/libs/pot/OTS_Account.php @@ -994,7 +994,7 @@ class OTS_Account extends OTS_Row_DAO implements IteratorAggregate, Countable $access = 0; // finds ranks of all characters - foreach($this->getPlayersList() as $player) + foreach($this->getPlayersList(false) as $player) { $rank = $player->getRank(); diff --git a/system/pages/account/change_comment.php b/system/pages/account/change_comment.php index 0f0bc2f1..903ca49d 100644 --- a/system/pages/account/change_comment.php +++ b/system/pages/account/change_comment.php @@ -28,15 +28,22 @@ if($player_name != null) { if ($player->isLoaded()) { $player_account = $player->getAccount(); if ($account_logged->getId() == $player_account->getId()) { + if ($player->isDeleted()) { + $errors[] = 'This character is deleted.'; + $player = null; + } + if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) { - $player->setCustomField("hidden", $new_hideacc); - $player->setCustomField("comment", $new_comment); - $account_logged->logAction('Changed comment for character ' . $player->getName() . '.'); - $twig->display('success.html.twig', array( - 'title' => 'Character Information Changed', - 'description' => 'The character information has been changed.' - )); - $show_form = false; + if(empty($errors)) { + $player->setCustomField("hidden", $new_hideacc); + $player->setCustomField("comment", $new_comment); + $account_logged->logAction('Changed comment for character ' . $player->getName() . '.'); + $twig->display('success.html.twig', array( + 'title' => 'Character Information Changed', + 'description' => 'The character information has been changed.' + )); + $show_form = false; + } } } else { $errors[] = 'Error. Character ' . $player_name . ' is not on your account.'; diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index 448e730c..48b6bb4d 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -50,6 +50,10 @@ else if($player->isLoaded()) { $player_account = $player->getAccount(); if($account_logged->getId() == $player_account->getId()) { + if ($player->isDeleted()) { + $errors[] = 'This character is deleted.'; + } + if($player->isOnline()) { $errors[] = 'This character is online.'; } @@ -91,7 +95,7 @@ else } } else { - $errors[] = 'Character ' . $player_name . ' is not on your account.'; + $errors[] = 'Character is not on your account.'; } } else { diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index 868cf24f..2f944564 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -41,6 +41,10 @@ else $player_account = $player->getAccount(); if($account_logged->getId() == $player_account->getId()) { + if ($player->isDeleted()) { + $errors[] = 'This character is deleted.'; + } + if($player->isOnline()) { $errors[] = 'This character is online.'; } @@ -71,7 +75,7 @@ else } } else { - $errors[] = 'Character '.$player_name.' is not on your account.'; + $errors[] = 'Character is not on your account.'; } } else { @@ -85,7 +89,7 @@ else $twig->display('error_box.html.twig', array('errors' => $errors)); } $twig->display('account.change_sex.html.twig', array( - 'players' => $account_logged->getPlayersList(), + 'players' => $account_logged->getPlayersList(false), 'player_sex' => isset($player) ? $player->getSex() : -1, 'points' => $points )); diff --git a/system/pages/account/delete_character.php b/system/pages/account/delete_character.php index f5894c77..4e74e711 100644 --- a/system/pages/account/delete_character.php +++ b/system/pages/account/delete_character.php @@ -61,6 +61,14 @@ if(isset($_POST['deletecharactersave']) && $_POST['deletecharactersave'] == 1) { } } + $ownerid = 'ownerid'; + if($db->hasColumn('guilds', 'owner_id')) + $ownerid = 'owner_id'; + $guild = $db->query('SELECT `name` FROM `guilds` WHERE `' . $ownerid . '` = '.$player->getId()); + if($guild->rowCount() > 0) { + $errors[] = 'You cannot delete a character when they own a guild.'; + } + if(empty($errors)) { //dont show table "delete character" again $show_form = false; diff --git a/system/pages/guilds/accept_invite.php b/system/pages/guilds/accept_invite.php index 7b013a2c..bc782480 100644 --- a/system/pages/guilds/accept_invite.php +++ b/system/pages/guilds/accept_invite.php @@ -45,6 +45,8 @@ if(isset($_REQUEST['todo']) && $_REQUEST['todo'] == 'save') { $errors[] = 'Character with name ' . $name. ' is not in your account.'; }else if ($player->getRank()->isLoaded()){ $errors[] = 'Character with name '.$name.' is already in guild. You must leave guild before you join other guild.'; + } else if ($player->isDeleted()) { + $errors[] = "Character with name $name has been deleted."; } } } @@ -72,7 +74,7 @@ else { if(empty($errors)) { $acc_invited = false; - $account_players = $account_logged->getPlayers(); + $account_players = $account_logged->getPlayersList(false); include(SYSTEM . 'libs/pot/InvitesDriver.php'); new InvitesDriver($guild); $invited_list = $guild->listInvites(); diff --git a/system/pages/guilds/create.php b/system/pages/guilds/create.php index 9814ade0..d7319fce 100644 --- a/system/pages/guilds/create.php +++ b/system/pages/guilds/create.php @@ -22,7 +22,7 @@ if(!$logged) { $array_of_player_nig = array(); if(empty($guild_errors)) { - $account_players = $account_logged->getPlayers(); + $account_players = $account_logged->getPlayersList(false); foreach($account_players as $player) { $player_rank = $player->getRank(); @@ -73,6 +73,10 @@ if($todo == 'save') } } + if(empty($guild_errors) && $player->isDeleted()) { + $guild_errors[] = "Character $name has been deleted."; + } + if(empty($guild_errors)) { $bad_char = true; @@ -132,5 +136,3 @@ else { 'players' => $array_of_player_nig )); } - -?> diff --git a/system/pages/guilds/invite.php b/system/pages/guilds/invite.php index 09957d2d..8fae8e27 100644 --- a/system/pages/guilds/invite.php +++ b/system/pages/guilds/invite.php @@ -72,6 +72,8 @@ if(isset($_REQUEST['todo']) && $_REQUEST['todo'] == 'save') { $player->find($name); if(!$player->isLoaded()) { $errors[] = 'Player with name ' . $name . ' doesn\'t exist.'; + } else if ($player->isDeleted()) { + $errors[] = "Character with name $name has been deleted."; } else { diff --git a/system/pages/guilds/pass_leadership.php b/system/pages/guilds/pass_leadership.php index d5f0ed20..065e4c3b 100644 --- a/system/pages/guilds/pass_leadership.php +++ b/system/pages/guilds/pass_leadership.php @@ -36,6 +36,8 @@ if(empty($guild_errors)) { $to_player->find($pass_to); if(!$to_player->isLoaded()) { $guild_errors2[] = 'Player with name '.$pass_to.' doesn\'t exist.'; + } else if ($to_player->isDeleted()) { + $guild_errors2[] = "Character with name $pass_to has been deleted."; } if(empty($guild_errors2)) { diff --git a/system/templates/account.change_name.html.twig b/system/templates/account.change_name.html.twig index 255689e3..bd1fa8f0 100644 --- a/system/templates/account.change_name.html.twig +++ b/system/templates/account.change_name.html.twig @@ -25,7 +25,7 @@ To change a name of character select player and choose a new name.
    Character: @@ -74,4 +74,4 @@ To change a name of character select player and choose a new name.
    - \ No newline at end of file + diff --git a/system/templates/account.management.html.twig b/system/templates/account.management.html.twig index 1f8ea2e6..510c90a1 100644 --- a/system/templates/account.management.html.twig +++ b/system/templates/account.management.html.twig @@ -179,7 +179,7 @@ {% if player.getLastLogin() > 0 %}{{ player.getLastLogin|date('d F Y (H:i)') }}{% else %}Never.{% endif %} {% if player.isOnline() %}ONLINE{% else %}Offline{% endif %} {% if player.isHidden() %}Hidden{% else %}Visible{% endif %} - [Edit] + {% if not player.isDeleted() %}[Edit]{% endif %} {% endfor %} diff --git a/templates/tibiacom/account.management.html.twig b/templates/tibiacom/account.management.html.twig index 4b39abd8..7c387c36 100644 --- a/templates/tibiacom/account.management.html.twig +++ b/templates/tibiacom/account.management.html.twig @@ -442,7 +442,7 @@ {% else %} Offline {% endif %} - [Edit] + {% if not player.isDeleted() %}[Edit]{% endif %} {% endfor %} From 36fbae850d3384bf536182aee5c1ef26034e6c10 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 27 Jun 2023 17:44:19 +0200 Subject: [PATCH 165/232] Revert " is not working properly, use full URL instead" This reverts commit fa015b8d39d926aa0bc3ea2f59577afa22174c51. --- system/templates/exception.html.twig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig index f258830f..cd478fd0 100644 --- a/system/templates/exception.html.twig +++ b/system/templates/exception.html.twig @@ -8,8 +8,9 @@ - - + + + From 3ff7b212874a3c2d0084029ea3996b5be053202f Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 27 Jun 2023 18:15:54 +0200 Subject: [PATCH 166/232] Move above, so it works, thanks @Leesneaks --- system/templates/exception.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/exception.html.twig b/system/templates/exception.html.twig index cd478fd0..d6108aa6 100644 --- a/system/templates/exception.html.twig +++ b/system/templates/exception.html.twig @@ -8,9 +8,9 @@ + - From d1953470d9321c586b24aaa106be23f55c92aaad Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 30 Jun 2023 19:32:47 +0200 Subject: [PATCH 171/232] Add word-break on forum thread & reply When someone inserts long word, is will break into multiple lines --- system/templates/forum.new_post.html.twig | 4 ++-- system/templates/forum.show_thread.html.twig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/system/templates/forum.new_post.html.twig b/system/templates/forum.new_post.html.twig index 2af93d37..6220cddb 100644 --- a/system/templates/forum.new_post.html.twig +++ b/system/templates/forum.new_post.html.twig @@ -54,7 +54,7 @@ {% set i = 0 %} {% for thread in threads %} - {{ thread.name }}{{ thread.post|raw }} + {{ thread.name }}{{ thread.post|raw }} {% set i = i + 1 %} {% endfor %} - \ No newline at end of file + diff --git a/system/templates/forum.show_thread.html.twig b/system/templates/forum.show_thread.html.twig index e95774ca..80985d43 100644 --- a/system/templates/forum.show_thread.html.twig +++ b/system/templates/forum.show_thread.html.twig @@ -40,7 +40,7 @@ Page: {{ links_to_pages|raw }}

    Posts: {{ post.author_posts_count }}
    - {{ post.content|raw }} + {{ post.content|raw }} {{ post.date|date('d.m.y H:i:s') }} From 8cf4d0cb0f2f6c89515ac3c080cbb86c8d8072b1 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 30 Jun 2023 19:32:47 +0200 Subject: [PATCH 172/232] Add word-break on forum thread & reply When someone inserts long word, is will break into multiple lines --- system/templates/forum.new_post.html.twig | 4 ++-- system/templates/forum.show_thread.html.twig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/system/templates/forum.new_post.html.twig b/system/templates/forum.new_post.html.twig index 2af93d37..6220cddb 100644 --- a/system/templates/forum.new_post.html.twig +++ b/system/templates/forum.new_post.html.twig @@ -54,7 +54,7 @@ {% set i = 0 %} {% for thread in threads %} - {{ thread.name }}{{ thread.post|raw }} + {{ thread.name }}{{ thread.post|raw }} {% set i = i + 1 %} {% endfor %} - \ No newline at end of file + diff --git a/system/templates/forum.show_thread.html.twig b/system/templates/forum.show_thread.html.twig index e95774ca..80985d43 100644 --- a/system/templates/forum.show_thread.html.twig +++ b/system/templates/forum.show_thread.html.twig @@ -40,7 +40,7 @@ Page: {{ links_to_pages|raw }}

    Posts: {{ post.author_posts_count }}
    - {{ post.content|raw }} + {{ post.content|raw }} {{ post.date|date('d.m.y H:i:s') }} From 5eafff737a9dbfdcaceac3424c129de0c1ec5f77 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 30 Jun 2023 19:52:05 +0200 Subject: [PATCH 173/232] Guilds & Characters: Use CSS word-break: break-all instead of PHP wordwrap Suggested by @anyeor --- system/pages/characters.php | 2 +- system/pages/guilds/list.php | 2 +- system/pages/guilds/show.php | 2 +- system/templates/characters.html.twig | 2 +- system/templates/guilds.list.html.twig | 2 +- system/templates/guilds.view.html.twig | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/system/pages/characters.php b/system/pages/characters.php index 339bcddc..13f88f05 100644 --- a/system/pages/characters.php +++ b/system/pages/characters.php @@ -396,7 +396,7 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil 'rank' => isset($guild_name) ? $rank_of_player->getName() : null, 'link' => isset($guild_name) ? getGuildLink($guild_name) : null ), - 'comment' => !empty($comment) ? wordwrap(nl2br($comment), 60, "
    ", true) : null, + 'comment' => !empty($comment) ? nl2br($comment) : null, 'skills' => isset($skills) ? $skills : null, 'quests_enabled' => $quests_enabled, 'quests' => isset($quests) ? $quests : null, diff --git a/system/pages/guilds/list.php b/system/pages/guilds/list.php index 2b65e15d..e91b644d 100644 --- a/system/pages/guilds/list.php +++ b/system/pages/guilds/list.php @@ -27,7 +27,7 @@ if(count($guilds_list) > 0) $description = $guild->getCustomField('description'); $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
    ', $description, $count); if ($count < $config['guild_description_lines_limit']) - $description = wordwrap(nl2br($description), 60, "
    ", true); + $description = nl2br($description); $guildName = $guild->getName(); $guilds[] = array('name' => $guildName, 'logo' => $guild_logo, 'link' => getGuildLink($guildName, false), 'description' => $description); diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index 47ce89d8..8a519c61 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -86,7 +86,7 @@ if(empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo)) $description = $guild->getCustomField('description'); $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
    ', $description, $count); if($count < $config['guild_description_lines_limit']) - $description = wordwrap(nl2br($description), 60, "
    ", true); + $description = nl2br($description); //$description = $description_with_lines; $guild_owner = $guild->getOwner(); diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 94f64803..4234f2ab 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -142,7 +142,7 @@ {% set rows = rows + 1 %} Comment: - {{ comment|raw }} + {{ comment|raw }} {% endif %} diff --git a/system/templates/guilds.list.html.twig b/system/templates/guilds.list.html.twig index da5016b0..1f7903a6 100644 --- a/system/templates/guilds.list.html.twig +++ b/system/templates/guilds.list.html.twig @@ -44,7 +44,7 @@ - + {{ guild.name }}{% if isAdmin %} - Delete this guild (for ADMIN only!){% endif %}
    diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 6f70aeca..c184605c 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -47,7 +47,7 @@ - - {% if totalRows < 1 %} + {% if highscores|length < 1 %} {% else %} {% set row = 0 %} From df7c82c5712daeccf850f9f2398cb7af2a1933ca Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 19 Jul 2023 11:57:26 +0200 Subject: [PATCH 184/232] Fix highscores if there is only 1 record --- system/pages/highscores.php | 1 - system/templates/highscores.html.twig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/system/pages/highscores.php b/system/pages/highscores.php index 95647893..dd2efa7b 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -311,7 +311,6 @@ if(config('highscores_balance')) /** @var Twig\Environment $twig */ $twig->display('highscores.html.twig', [ 'highscores' => $highscores, - 'totalRows' => $i - 1, 'list' => $list, 'skill' => $skill, 'skillName' => ($skill == SKILL_FRAGS ? 'Frags' : ($skill == SKILL_BALANCE ? 'Balance' : getSkillName($skill))), diff --git a/system/templates/highscores.html.twig b/system/templates/highscores.html.twig index 3b9224e2..2e32b7de 100644 --- a/system/templates/highscores.html.twig +++ b/system/templates/highscores.html.twig @@ -48,7 +48,7 @@ {% endif %} - {% if totalRows < 1 %} + {% if highscores|length < 1 %} {% else %} {% set row = 0 %} From 99c53c75f28f5d9f871c1f9200f750a37f0a223e Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 19 Jul 2023 22:26:47 +0200 Subject: [PATCH 185/232] New guild hooks, for some upcoming big feature ;) --- system/hooks.php | 4 ++++ system/templates/guilds.view.html.twig | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/system/hooks.php b/system/hooks.php index f089b102..69bdcfbd 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -69,6 +69,10 @@ define('HOOK_ADMIN_LOGIN_AFTER_PASSWORD', ++$i); define('HOOK_ADMIN_LOGIN_AFTER_SIGN_IN', ++$i); define('HOOK_ADMIN_ACCOUNTS_SAVE_POST', ++$i); define('HOOK_EMAIL_CONFIRMED', ++$i); +define('HOOK_GUILDS_BEFORE_GUILD_HEADER', ++$i); +define('HOOK_GUILDS_AFTER_GUILD_HEADER', ++$i); +define('HOOK_GUILDS_AFTER_GUILD_INFORMATION', ++$i); +define('HOOK_GUILDS_AFTER_GUILD_MEMBERS', ++$i); define('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', ++$i); const HOOK_FIRST = HOOK_STARTUP; diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 5fef92e7..494b803d 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -1,6 +1,7 @@
    + {{ hook('HOOK_GUILDS_BEFORE_GUILD_HEADER') }}
    +
    {% if descriptions is not empty %} {{ description }} From 2d561f267d129804f0db25d62a5ac5620b9bedd6 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 30 Jun 2023 19:52:20 +0200 Subject: [PATCH 174/232] Fix guild description not shown on guilds page --- system/templates/guilds.view.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index c184605c..c9c385b9 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -49,7 +49,7 @@
    - {% if descriptions is not empty %} + {% if description is not empty %} {{ description }}

    From 3a31a0326c4b1c91e3c446fd0138ef3c402716e2 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 2 Jul 2023 00:26:33 +0200 Subject: [PATCH 175/232] Fix guild description not shown --- system/templates/guilds.view.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 6f70aeca..aff9d540 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -49,7 +49,7 @@
    - {% if descriptions is not empty %} + {% if description is not empty %} {{ description }}

    From c392fa7272c202ce0e3cd016363ce574b39e779f Mon Sep 17 00:00:00 2001 From: slawkens Date: Sun, 2 Jul 2023 13:48:57 +0200 Subject: [PATCH 177/232] Fix guild description on guilds page --- system/templates/guilds.view.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index aff9d540..24b250db 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -50,7 +50,7 @@
    {% if description is not empty %} - {{ description }} + {{ description|raw }}

    {% endif %} From 8cf0e800190818e73319ac4d165de3140888716b Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 7 Jul 2023 14:34:26 +0200 Subject: [PATCH 178/232] Forum: better error messages (Suggested by @anyeor) --- system/functions.php | 8 ++++++++ system/pages/forum.php | 6 ++++-- system/pages/forum/edit_post.php | 21 ++++++++++++++------- system/pages/forum/move_thread.php | 18 +++++++++++------- system/pages/forum/new_post.php | 27 +++++++++++++++++---------- system/pages/forum/new_thread.php | 18 ++++++++++++------ system/pages/forum/remove_post.php | 12 ++++++++---- system/pages/forum/show_board.php | 8 ++++---- system/pages/forum/show_thread.php | 6 ++++-- 9 files changed, 82 insertions(+), 42 deletions(-) diff --git a/system/functions.php b/system/functions.php index cb280030..dbf6466d 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1580,6 +1580,14 @@ function getGuildLogoById($id) return BASE_URL . GUILD_IMAGES_DIR . $logo; } +function displayErrorBoxWithBackButton($errors, $action = null) { + global $twig; + $twig->display('error_box.html.twig', ['errors' => $errors]); + $twig->display('account.back_button.html.twig', [ + 'action' => $action ?: getLink('') + ]); +} + // validator functions require_once LIBS . 'validator.php'; require_once SYSTEM . 'compat/base.php'; diff --git a/system/pages/forum.php b/system/pages/forum.php index 85456f2e..5c9688a6 100644 --- a/system/pages/forum.php +++ b/system/pages/forum.php @@ -17,14 +17,16 @@ $errors = []; if(!empty($action)) { if(!ctype_alnum(str_replace(array('-', '_'), '', $action))) { - error('Error: Action contains illegal characters.'); + $errors[] = 'Error: Action contains illegal characters.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); } else if(file_exists(PAGES . 'forum/' . $action . '.php')) { require PAGES . 'forum/' . $action . '.php'; return; } else { - error('This page does not exists.'); + $errors[] = 'This page does not exists.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); } } diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index d3f95c45..a73920df 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -16,7 +16,8 @@ if(Forum::canPost($account_logged)) { $post_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : false; if(!$post_id) { - echo 'Please enter post id.'; + $errors[] = 'Please enter post id.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } @@ -106,11 +107,17 @@ if(Forum::canPost($account_logged)) )); } } - else - echo '
    You are not an author of this post.'; + else { + $errors[] = 'You are not an author of this post.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } + } + else { + $errors[] = "Post with ID $post_id doesn't exist."; + displayErrorBoxWithBackButton($errors, getLink('forum')); } - else - echo "
    Post with ID " . $post_id . " doesn't exist."; } -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."; +else { + $errors[] = "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."; + displayErrorBoxWithBackButton($errors, getLink('forum')); +} diff --git a/system/pages/forum/move_thread.php b/system/pages/forum/move_thread.php index 8fcb98fb..3c01a13e 100644 --- a/system/pages/forum/move_thread.php +++ b/system/pages/forum/move_thread.php @@ -16,12 +16,13 @@ if(!Forum::isModerator()) { echo 'You are not logged in or you are not moderator.'; } -$save = isset($_REQUEST['save']) ? (int)$_REQUEST['save'] == 1 : false; +$save = isset($_REQUEST['save']) && (int)$_REQUEST['save'] == 1; if($save) { $post_id = (int)$_REQUEST['id']; $board = (int)$_REQUEST['section']; if(!Forum::hasAccess($board)) { - echo "You don't have access to this board."; + $errors[] = "You don't have access to this board."; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } @@ -33,8 +34,10 @@ if($save) { header('Location: ' . getForumBoardLink($nPost['section'])); } } - else - echo 'Post with ID ' . $post_id . ' does not exist.'; + else { + $errors[] = 'Post with ID ' . $post_id . ' does not exist.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } } else { $post_id = (int)$_REQUEST['id']; @@ -60,7 +63,8 @@ else { )); } } - else - echo 'Post with ID ' . $post_id . ' does not exist.'; + else { + $errors[] = 'Post with ID ' . $post_id . ' does not exist.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } } -?> diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index a3e68dff..6ef6e264 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -28,17 +28,20 @@ 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(); $thread_id = isset($_REQUEST['thread_id']) ? (int) $_REQUEST['thread_id'] : 0; if($thread_id == 0) { - echo "Thread with this id doesn't exist."; + $errors[] = "Thread with this id doesn't exist."; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } - $thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id." LIMIT 1")->fetch(); - echo 'Boards >> '.$sections[$thread['section']]['name'].' >> '.$thread['post_topic'].' >> Post new reply

    '.$thread['post_topic'].'

    '; + $thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." LIMIT 1")->fetch(); + if(isset($thread['id']) && Forum::hasAccess($thread['section'])) { + echo 'Boards >> '.$sections[$thread['section']]['name'].' >> '.$thread['post_topic'].' >> Post new reply

    '.$thread['post_topic'].'

    '; + $quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL; $text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL; - $char_id = (int) (isset($_REQUEST['char_id']) ? $_REQUEST['char_id'] : 0); + $char_id = (int) ($_REQUEST['char_id'] ?? 0); $post_topic = isset($_REQUEST['topic']) ? stripslashes(trim($_REQUEST['topic'])) : ''; $smile = (isset($_REQUEST['smile']) ? (int)$_REQUEST['smile'] : 0); $html = (isset($_REQUEST['html']) ? (int)$_REQUEST['html'] : 0); @@ -86,8 +89,8 @@ if(Forum::canPost($account_logged)) if(count($errors) == 0) { $saved = true; - Forum::add_post($thread['id'], $thread['section'], $account_logged->getId(), (int) $char_id, $text, $post_topic, $smile, $html, time(), $_SERVER['REMOTE_ADDR']); - $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `replies`=`replies`+1, `last_post`=".time()." WHERE `id` = ".(int) $thread_id); + Forum::add_post($thread['id'], $thread['section'], $account_logged->getId(), (int) $char_id, $text, $post_topic, $smile, $html); + $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `replies`=`replies`+1, `last_post`=".time()." WHERE `id` = ".$thread_id); $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`post_date` <= ".time()." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id'])->fetch(); $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; header('Location: ' . getForumThreadLink($thread_id, $_page)); @@ -123,10 +126,14 @@ if(Forum::canPost($account_logged)) )); } } - else - echo "Thread with ID " . $thread_id . " doesn't exist."; + else { + $errors[] = "Thread with ID " . $thread_id . " doesn't exist."; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } +} +else { + $errors[] = "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."; + displayErrorBoxWithBackButton($errors, getLink('forum')); } -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'); diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index c3b688ad..6a492114 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -95,11 +95,17 @@ if(Forum::canPost($account_logged)) )); } } - else - echo 'Board with ID ' . $board_id . ' doesn\'t exist.'; + else { + $errors[] = "Board with ID $section_id doesn't exist."; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } + } + else { + $errors[] = 'Please enter section_id.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); } - else - echo 'Please enter section_id.'; } -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.'; +else { + $errors[] = '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.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); +} diff --git a/system/pages/forum/remove_post.php b/system/pages/forum/remove_post.php index bd1e75a4..4469ae77 100644 --- a/system/pages/forum/remove_post.php +++ b/system/pages/forum/remove_post.php @@ -31,8 +31,12 @@ if(Forum::isModerator()) header('Location: ' . getForumThreadLink($post['first_post'], (int) $_page)); } } - else - echo 'Post with ID ' . $id . ' does not exist.'; + else { + $errors[] = 'Post with ID ' . $id . ' does not exist.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); + } +} +else { + $errors[] = 'You are not logged in or you are not moderator.'; +displayErrorBoxWithBackButton($errors, getLink('forum')); } -else - 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 36251d8e..09d6e786 100644 --- a/system/pages/forum/show_board.php +++ b/system/pages/forum/show_board.php @@ -16,12 +16,14 @@ $links_to_pages = ''; $section_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null; if($section_id == null || !isset($sections[$section_id])) { - echo "Board with this id does't exist."; + $errors[] = "Board with this id does't exist."; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } if(!Forum::hasAccess($section_id)) { - echo "You don't have access to this board."; + $errors[] = "You don't have access to this board."; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } @@ -91,5 +93,3 @@ if(isset($last_threads[0])) } else echo '

    No threads in this board.

    '; - -?> diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index e6c8f926..0fe28f09 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -18,12 +18,14 @@ $_page = (int) ($_REQUEST['page'] ?? 0); $thread_starter = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`first_post` AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` LIMIT 1")->fetch(); if(empty($thread_starter['name'])) { - echo 'Thread with this ID does not exits.'; + $errors[] = 'Thread with this ID does not exists.'; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } if(!Forum::hasAccess($thread_starter['section'])) { - echo "You don't have access to view this thread."; + $errors[] = "You don't have access to view this thread."; + displayErrorBoxWithBackButton($errors, getLink('forum')); return; } From e7e9d8e3b96855ffd7b69f1f6088aeda34e41190 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 7 Jul 2023 17:15:13 +0200 Subject: [PATCH 179/232] Shorten some forum code about length --- system/pages/forum/edit_post.php | 26 ++++++++++---------------- system/pages/forum/new_post.php | 12 ++++-------- system/pages/forum/new_thread.php | 21 +++++++-------------- 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index a73920df..b2b37441 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -38,24 +38,18 @@ if(Forum::canPost($account_logged)) $post_topic = stripslashes(trim($_REQUEST['topic'])); $smile = isset($_REQUEST['smile']) ? (int)$_REQUEST['smile'] : 0; $html = isset($_REQUEST['html']) ? (int)$_REQUEST['html'] : 0; - $lenght = 0; - for($i = 0; $i < strlen($post_topic); $i++) - { - if(ord($post_topic[$i]) >= 33 && ord($post_topic[$i]) <= 126) - $lenght++; - } - if(($lenght < 1 || strlen($post_topic) > 60) && $thread['id'] == $thread['first_post']) - $errors[] = 'Too short or too long topic (short: '.$lenght.' long: '.strlen($post_topic).' letters). Minimum 1 letter, maximum 60 letters.'; - $lenght = 0; - for($i = 0; $i < strlen($text); $i++) - { - if(ord($text[$i]) >= 33 && ord($text[$i]) <= 126) - $lenght++; - } - if($lenght < 1 || strlen($text) > 15000) - $errors[] = 'Too short or too long post (short: '.$lenght.' long: '.strlen($text).' letters). Minimum 1 letter, maximum 15000 letters.'; + + $length = strlen($post_topic); + if(($length < 1 || $length > 60) && $thread['id'] == $thread['first_post']) + $errors[] = "Too short or too long topic (Length: $length letters). Minimum 1 letter, maximum 60 letters."; + + $length = strlen($text); + if($length < 1 || $length > 15000) + $errors[] = "Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters."; + if($char_id == 0) $errors[] = 'Please select a character.'; + if(empty($post_topic) && $thread['id'] == $thread['first_post']) $errors[] = 'Thread topic can\'t be empty.'; diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index 6ef6e264..31c88a20 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -54,14 +54,10 @@ if(Forum::canPost($account_logged)) } elseif(isset($_REQUEST['save'])) { - $lenght = 0; - for($i = 0; $i < strlen($text); $i++) - { - if(ord($text[$i]) >= 33 && ord($text[$i]) <= 126) - $lenght++; - } - if($lenght < 1 || strlen($text) > 15000) - $errors[] = 'Too short or too long post (short: '.$lenght.' long: '.strlen($text).' letters). Minimum 1 letter, maximum 15000 letters.'; + $length = strlen($text); + if($length < 1 || strlen($text) > 15000) + $errors[] = 'Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters.'; + if($char_id == 0) $errors[] = 'Please select a character.'; diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 6a492114..33b57feb 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -32,20 +32,13 @@ if(Forum::canPost($account_logged)) if (isset($_REQUEST['save'])) { $errors = array(); - $lenght = 0; - for ($i = 0; $i < strlen($post_topic); $i++) { - if (ord($post_topic[$i]) >= 33 && ord($post_topic[$i]) <= 126) - $lenght++; - } - if ($lenght < 1 || strlen($post_topic) > 60) - $errors[] = 'Too short or too long topic (short: ' . $lenght . ' long: ' . strlen($post_topic) . ' letters). Minimum 1 letter, maximum 60 letters.'; - $lenght = 0; - for ($i = 0; $i < strlen($text); $i++) { - if (ord($text[$i]) >= 33 && ord($text[$i]) <= 126) - $lenght++; - } - if ($lenght < 1 || strlen($text) > 15000) - $errors[] = 'Too short or too long post (short: ' . $lenght . ' long: ' . strlen($text) . ' letters). Minimum 1 letter, maximum 15000 letters.'; + $length = strlen($post_topic); + if ($length < 1 || $length > 60) + $errors[] = "Too short or too long topic (Length: $length letters). Minimum 1 letter, maximum 60 letters."; + + $length = strlen($text); + if ($length < 1 || $length > 15000) + $errors[] = "Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters."; if ($char_id == 0) $errors[] = 'Please select a character.'; From a61cd43c3c93a130a6d5d662f93c54851110e97c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 7 Jul 2023 17:43:28 +0200 Subject: [PATCH 180/232] Forum: nothing important, just formatting --- system/pages/forum/admin.php | 20 ++++---- system/pages/forum/base.php | 14 +++--- system/pages/forum/edit_post.php | 43 ++++++++++-------- system/pages/forum/new_post.php | 73 ++++++++++++++++-------------- system/pages/forum/new_thread.php | 45 ++++++++++++------ system/pages/forum/remove_post.php | 15 +++--- system/pages/forum/show_board.php | 36 ++++++++------- system/pages/forum/show_thread.php | 10 ++-- 8 files changed, 141 insertions(+), 115 deletions(-) diff --git a/system/pages/forum/admin.php b/system/pages/forum/admin.php index 136c627a..e9aa18b2 100644 --- a/system/pages/forum/admin.php +++ b/system/pages/forum/admin.php @@ -14,28 +14,32 @@ $canEdit = Forum::isModerator(); if($canEdit) { $groups = new OTS_Groups_List(); - if(!empty($action)) - { + 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'])) + if(isset($_REQUEST['access'])) { $access = $_REQUEST['access']; + } - if(isset($_REQUEST['guild'])) + if(isset($_REQUEST['guild'])) { $guild = $_REQUEST['guild']; + } - if(isset($_REQUEST['name'])) + if(isset($_REQUEST['name'])) { $name = $_REQUEST['name']; + } - if(isset($_REQUEST['description'])) + if(isset($_REQUEST['description'])) { $description = stripslashes($_REQUEST['description']); + } - $errors = array(); + $errors = []; if($action == 'add_board') { - if(Forum::add_board($name, $description, $access, $guild, $errors)) + if(Forum::add_board($name, $description, $access, $guild, $errors)) { $action = $name = $description = ''; + } } else if($action == 'delete_board') { Forum::delete_board($id, $errors); diff --git a/system/pages/forum/base.php b/system/pages/forum/base.php index fa207ca0..57ae6d17 100644 --- a/system/pages/forum/base.php +++ b/system/pages/forum/base.php @@ -11,10 +11,8 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Forum'; -if(strtolower($config['forum']) != 'site') -{ - if($config['forum'] != '') - { +if(strtolower($config['forum']) != 'site') { + if($config['forum'] != '') { header('Location: ' . $config['forum']); exit; } @@ -23,14 +21,14 @@ if(strtolower($config['forum']) != 'site') return; } -if(!$logged) - echo 'You are not logged in. Log in to post on the forum.

    '; +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) -{ +foreach(getForumBoards() as $section) { $sections[$section['id']] = array( 'id' => $section['id'], 'name' => $section['name'], diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index b2b37441..2df443a0 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -22,17 +22,15 @@ if(Forum::canPost($account_logged)) } $thread = $db->query("SELECT `author_guid`, `author_aid`, `first_post`, `post_topic`, `post_date`, `post_text`, `post_smile`, `post_html`, `id`, `section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post_id." LIMIT 1")->fetch(); - if(isset($thread['id'])) - { + if(isset($thread['id'])) { $first_post = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread['first_post']." LIMIT 1")->fetch(); echo 'Boards >> '.$sections[$thread['section']]['name'].' >> '.$first_post['post_topic'].' >> Edit post'; - if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) - { + + if(Forum::hasAccess($thread['section'] && ($account_logged->getId() == $thread['author_aid'] || Forum::isModerator()))) { $char_id = $post_topic = $text = $smile = $html = null; $players_from_account = $db->query("SELECT `players`.`name`, `players`.`id` FROM `players` WHERE `players`.`account_id` = ".(int) $account_logged->getId())->fetchAll(); $saved = false; - if(isset($_REQUEST['save'])) - { + if(isset($_REQUEST['save'])) { $text = stripslashes(trim($_REQUEST['text'])); $char_id = (int) $_REQUEST['char_id']; $post_topic = stripslashes(trim($_REQUEST['topic'])); @@ -40,28 +38,35 @@ if(Forum::canPost($account_logged)) $html = isset($_REQUEST['html']) ? (int)$_REQUEST['html'] : 0; $length = strlen($post_topic); - if(($length < 1 || $length > 60) && $thread['id'] == $thread['first_post']) + if(($length < 1 || $length > 60) && $thread['id'] == $thread['first_post']) { $errors[] = "Too short or too long topic (Length: $length letters). Minimum 1 letter, maximum 60 letters."; + } $length = strlen($text); - if($length < 1 || $length > 15000) + if($length < 1 || $length > 15000) { $errors[] = "Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters."; + } - if($char_id == 0) + if($char_id == 0) { $errors[] = 'Please select a character.'; + } - if(empty($post_topic) && $thread['id'] == $thread['first_post']) + if(empty($post_topic) && $thread['id'] == $thread['first_post']) { $errors[] = 'Thread topic can\'t be empty.'; + } $player_on_account = false; - if(count($errors) == 0) - { - foreach($players_from_account as $player) - if($char_id == $player['id']) + if(count($errors) == 0) { + foreach($players_from_account as $player) { + if ($char_id == $player['id']) { $player_on_account = true; - if(!$player_on_account) - $errors[] = 'Player with selected ID '.$char_id.' doesn\'t exist or isn\'t on your account'; + } + } + + if(!$player_on_account) { + $errors[] = 'Player with selected ID ' . $char_id . ' doesn\'t exist or isn\'t on your account'; + } } if(count($errors) == 0) { @@ -83,10 +88,10 @@ if(Forum::canPost($account_logged)) $html = (int) $thread['post_html']; } - if(!$saved) - { - if(!empty($errors)) + if(!$saved) { + if(!empty($errors)) { $twig->display('error_box.html.twig', array('errors' => $errors)); + } $twig->display('forum.edit_post.html.twig', array( 'post_id' => $post_id, diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index 31c88a20..d4b605c6 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -12,8 +12,7 @@ defined('MYAAC') or die('Direct access not allowed!'); require __DIR__ . '/base.php'; -if(!$logged) -{ +if(!$logged) { $extra_url = ''; if(isset($_GET['thread_id'])) { $extra_url = '&action=new_post&thread_id=' . $_GET['thread_id']; @@ -23,8 +22,7 @@ if(!$logged) return; } -if(Forum::canPost($account_logged)) -{ +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(); $thread_id = isset($_REQUEST['thread_id']) ? (int) $_REQUEST['thread_id'] : 0; if($thread_id == 0) { @@ -35,43 +33,47 @@ if(Forum::canPost($account_logged)) $thread = $db->query("SELECT `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $thread_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." LIMIT 1")->fetch(); - if(isset($thread['id']) && Forum::hasAccess($thread['section'])) - { + if(isset($thread['id']) && Forum::hasAccess($thread['section'])) { echo 'Boards >> '.$sections[$thread['section']]['name'].' >> '.$thread['post_topic'].' >> Post new reply

    '.$thread['post_topic'].'

    '; $quote = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : NULL; $text = isset($_REQUEST['text']) ? stripslashes(trim($_REQUEST['text'])) : NULL; $char_id = (int) ($_REQUEST['char_id'] ?? 0); $post_topic = isset($_REQUEST['topic']) ? stripslashes(trim($_REQUEST['topic'])) : ''; - $smile = (isset($_REQUEST['smile']) ? (int)$_REQUEST['smile'] : 0); - $html = (isset($_REQUEST['html']) ? (int)$_REQUEST['html'] : 0); + $smile = (int)($_REQUEST['smile'] ?? 0); + $html = (int)($_REQUEST['html'] ?? 0); $saved = false; - if(isset($_REQUEST['quote'])) - { - $quoted_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $quote)->fetchAll(); - if(isset($quoted_post[0]['name'])) - $text = '[i]Originally posted by '.$quoted_post[0]['name'].' on '.date('d.m.y H:i:s', $quoted_post[0]['post_date']).':[/i][quote]'.$quoted_post[0]['post_text'].'[/quote]'; - } - elseif(isset($_REQUEST['save'])) - { - $length = strlen($text); - if($length < 1 || strlen($text) > 15000) - $errors[] = 'Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters.'; - if($char_id == 0) + if(isset($_REQUEST['quote'])) { + $quoted_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` = ".(int) $quote)->fetchAll(); + if(isset($quoted_post[0]['name'])) { + $text = '[i]Originally posted by ' . $quoted_post[0]['name'] . ' on ' . date('d.m.y H:i:s', $quoted_post[0]['post_date']) . ':[/i][quote]' . $quoted_post[0]['post_text'] . '[/quote]'; + } + } + elseif(isset($_REQUEST['save'])) { + $length = strlen($text); + if($length < 1 || strlen($text) > 15000) { + $errors[] = 'Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters.'; + } + + if($char_id == 0) { $errors[] = 'Please select a character.'; + } $player_on_account = false; - if(count($errors) == 0) - { - foreach($players_from_account as $player) - if($char_id == $player['id']) + if(count($errors) == 0) { + foreach($players_from_account as $player) { + if ($char_id == $player['id']) { $player_on_account = true; - if(!$player_on_account) - $errors[] = 'Player with selected ID '.$char_id.' doesn\'t exist or isn\'t on your account'; + } + } + + if(!$player_on_account) { + $errors[] = 'Player with selected ID ' . $char_id . ' doesn\'t exist or isn\'t on your account'; + } } - if(count($errors) == 0) - { + + if(count($errors) == 0) { $last_post = 0; $query = $db->query('SELECT post_date FROM ' . FORUM_TABLE_PREFIX . 'forum ORDER BY post_date DESC LIMIT 1'); if($query->rowCount() > 0) @@ -82,10 +84,10 @@ if(Forum::canPost($account_logged)) if($last_post+$config['forum_post_interval']-time() > 0 && !Forum::isModerator()) $errors[] = 'You can post one time per '.$config['forum_post_interval'].' seconds. Next post after '.($last_post+$config['forum_post_interval']-time()).' second(s).'; } - if(count($errors) == 0) - { + + if(count($errors) == 0) { $saved = true; - Forum::add_post($thread['id'], $thread['section'], $account_logged->getId(), (int) $char_id, $text, $post_topic, $smile, $html); + Forum::add_post($thread['id'], $thread['section'], $account_logged->getId(), $char_id, $text, $post_topic, $smile, $html); $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `replies`=`replies`+1, `last_post`=".time()." WHERE `id` = ".$thread_id); $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`post_date` <= ".time()." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id'])->fetch(); $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; @@ -94,12 +96,13 @@ if(Forum::canPost($account_logged)) } } - if(!$saved) - { - if(!empty($errors)) + if(!$saved) { + if(!empty($errors)) { $twig->display('error_box.html.twig', array('errors' => $errors)); + } $threads = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`post_html`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id." ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`post_date` DESC LIMIT 5")->fetchAll(); + foreach($threads as &$thread) { $player_account = new OTS_Account(); $player_account->load($thread['author_aid']); @@ -128,7 +131,7 @@ if(Forum::canPost($account_logged)) } } else { - $errors[] = "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."; + $errors[] = "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."; displayErrorBoxWithBackButton($errors, getLink('forum')); } diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 33b57feb..faa64ce6 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -12,12 +12,13 @@ defined('MYAAC') or die('Direct access not allowed!'); require __DIR__ . '/base.php'; -if(Forum::canPost($account_logged)) -{ +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(); - $section_id = isset($_REQUEST['section_id']) ? $_REQUEST['section_id'] : null; + $section_id = $_REQUEST['section_id'] ?? null; + if($section_id !== null) { echo 'Boards >> ' . $sections[$section_id]['name'] . ' >> Post new thread
    '; + if(isset($sections[$section_id]['name']) && Forum::hasAccess($section_id)) { if ($sections[$section_id]['closed'] && !Forum::isModerator()) $errors[] = 'You cannot create topic on this board.'; @@ -33,48 +34,64 @@ if(Forum::canPost($account_logged)) $errors = array(); $length = strlen($post_topic); - if ($length < 1 || $length > 60) + if ($length < 1 || $length > 60) { $errors[] = "Too short or too long topic (Length: $length letters). Minimum 1 letter, maximum 60 letters."; + } $length = strlen($text); - if ($length < 1 || $length > 15000) + if ($length < 1 || $length > 15000) { $errors[] = "Too short or too long post (Length: $length letters). Minimum 1 letter, maximum 15000 letters."; + } - if ($char_id == 0) + if ($char_id == 0) { $errors[] = 'Please select a character.'; + } + $player_on_account = false; if (count($errors) == 0) { - foreach ($players_from_account as $player) - if ($char_id == $player['id']) + foreach ($players_from_account as $player) { + if ($char_id == $player['id']) { $player_on_account = true; - if (!$player_on_account) - $errors[] = 'Player with selected ID ' . $char_id . ' doesn\'t exist or isn\'t on your account'; + } + } + + if (!$player_on_account) { + $errors[] = "Player with selected ID $char_id doesn't exist or isn't on your account"; + } } if (count($errors) == 0) { $last_post = 0; $query = $db->query('SELECT `post_date` FROM `' . FORUM_TABLE_PREFIX . 'forum` ORDER BY `post_date` DESC LIMIT 1'); + if ($query->rowCount() > 0) { $query = $query->fetch(); $last_post = $query['post_date']; } - if ($last_post + $config['forum_post_interval'] - time() > 0 && !Forum::isModerator()) - $errors[] = 'You can post one time per ' . $config['forum_post_interval'] . ' seconds. Next post after ' . ($last_post + $config['forum_post_interval'] - time()) . ' second(s).'; + + if ($last_post + config('forum_post_interval') - time() > 0 && !Forum::isModerator()) + $errors[] = 'You can post one time per ' . config('forum_post_interval') . ' seconds. Next post after ' . ($last_post + config('forum_post_interval') - time()) . ' second(s).'; } + if (count($errors) == 0) { $saved = true; - $db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . (int)$char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . (int)$smile . "', '" . (int)$html . "', '" . time() . "', '0', '0', '" . $_SERVER['REMOTE_ADDR'] . "')"); + + $db->query("INSERT INTO `" . FORUM_TABLE_PREFIX . "forum` (`first_post` ,`last_post` ,`section` ,`replies` ,`views` ,`author_aid` ,`author_guid` ,`post_text` ,`post_topic` ,`post_smile`, `post_html` ,`post_date` ,`last_edit_aid` ,`edit_date`, `post_ip`) VALUES ('0', '" . time() . "', '" . (int)$section_id . "', '0', '0', '" . $account_logged->getId() . "', '" . $char_id . "', " . $db->quote($text) . ", " . $db->quote($post_topic) . ", '" . $smile . "', '" . $html . "', '" . time() . "', '0', '0', '" . $_SERVER['REMOTE_ADDR'] . "')"); + $thread_id = $db->lastInsertId(); + $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `first_post`=" . (int)$thread_id . " WHERE `id` = " . (int)$thread_id); header('Location: ' . getForumThreadLink($thread_id)); + echo '
    Thank you for posting.
    GO BACK TO LAST THREAD'; } } if (!$saved) { - if (!empty($errors)) + if (!empty($errors)) { $twig->display('error_box.html.twig', array('errors' => $errors)); + } $twig->display('forum.new_thread.html.twig', array( 'section_id' => $section_id, diff --git a/system/pages/forum/remove_post.php b/system/pages/forum/remove_post.php index 4469ae77..a1e13338 100644 --- a/system/pages/forum/remove_post.php +++ b/system/pages/forum/remove_post.php @@ -12,19 +12,16 @@ defined('MYAAC') or die('Direct access not allowed!'); require __DIR__ . '/base.php'; -if(Forum::isModerator()) -{ +if(Forum::isModerator()) { $id = (int) $_REQUEST['id']; $post = $db->query("SELECT `id`, `first_post`, `section` FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$id." LIMIT 1")->fetch(); - if($post['id'] == $id && Forum::hasAccess($post['section'])) - { - if($post['id'] == $post['first_post']) - { + + if($post['id'] == $id && Forum::hasAccess($post['section'])) { + if($post['id'] == $post['first_post']) { $db->query("DELETE FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `first_post` = ".$post['id']); header('Location: ' . getForumBoardLink($post['section'])); } - else - { + else { $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` < ".$id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $post['first_post'])->fetch(); $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; $db->query("DELETE FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post['id']); @@ -38,5 +35,5 @@ if(Forum::isModerator()) } else { $errors[] = 'You are not logged in or you are not moderator.'; -displayErrorBoxWithBackButton($errors, getLink('forum')); + displayErrorBoxWithBackButton($errors, getLink('forum')); } diff --git a/system/pages/forum/show_board.php b/system/pages/forum/show_board.php index 09d6e786..d3dcd0d5 100644 --- a/system/pages/forum/show_board.php +++ b/system/pages/forum/show_board.php @@ -16,7 +16,7 @@ $links_to_pages = ''; $section_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null; if($section_id == null || !isset($sections[$section_id])) { - $errors[] = "Board with this id does't exist."; + $errors[] = "Board with this id doesn't exist."; displayErrorBoxWithBackButton($errors, getLink('forum')); return; } @@ -29,24 +29,24 @@ if(!Forum::hasAccess($section_id)) { $_page = (int) (isset($_REQUEST['page']) ? $_REQUEST['page'] : 0); $threads_count = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS threads_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id`")->fetch(); -for($i = 0; $i < $threads_count['threads_count'] / $config['forum_threads_per_page']; $i++) -{ +for($i = 0; $i < $threads_count['threads_count'] / $config['forum_threads_per_page']; $i++) { if($i != $_page) $links_to_pages .= ''.($i + 1).' '; else $links_to_pages .= ''.($i + 1).' '; } + echo 'Boards >> '.$sections[$section_id]['name'].''; -if(!$sections[$section_id]['closed'] || Forum::isModerator()) -{ + +if(!$sections[$section_id]['closed'] || Forum::isModerator()) { echo '

    '; } echo '

    Page: '.$links_to_pages.'
    '; -$last_threads = $db->query("SELECT `players`.`id` as `player_id`, `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`last_post`, `" . FORUM_TABLE_PREFIX . "forum`.`replies`, `" . FORUM_TABLE_PREFIX . "forum`.`views`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id` ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`last_post` DESC LIMIT ".$config['forum_threads_per_page']." OFFSET ".($_page * $config['forum_threads_per_page']))->fetchAll(); -if(isset($last_threads[0])) -{ +$last_threads = $db->query("SELECT `players`.`id` as `player_id`, `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`last_post`, `" . FORUM_TABLE_PREFIX . "forum`.`replies`, `" . FORUM_TABLE_PREFIX . "forum`.`views`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".$section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id` ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`last_post` DESC LIMIT ".$config['forum_threads_per_page']." OFFSET ".($_page * $config['forum_threads_per_page']))->fetchAll(); + +if(isset($last_threads[0])) { echo ''; $player = new OTS_Player(); - foreach($last_threads as $thread) - { + foreach($last_threads as $thread) { echo ''; } + echo '
    @@ -58,8 +58,7 @@ if(isset($last_threads[0]))
    '; if(Forum::isModerator()) { echo '[MOVE]'; @@ -75,21 +74,24 @@ if(isset($last_threads[0])) $canEditForum = $player_account->hasFlag(FLAG_CONTENT_FORUM) || $player_account->isAdmin(); echo ''.($canEditForum ? $thread['post_topic'] : htmlspecialchars($thread['post_topic'])) . '
    '.($canEditForum ? substr(strip_tags($thread['post_text']), 0, 50) : htmlspecialchars(substr($thread['post_text'], 0, 50))).'...
    ' . getPlayerLink($thread['name']) . ''.(int) $thread['replies'].''.(int) $thread['views'].''; - if($thread['last_post'] > 0) - { + if($thread['last_post'] > 0) { $last_post = $db->query("SELECT `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id']." AND `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` ORDER BY `post_date` DESC LIMIT 1")->fetch(); if(isset($last_post['name'])) echo date('d.m.y H:i:s', $last_post['post_date']).'
    by ' . getPlayerLink($last_post['name']); else echo 'No posts.'; } - else - echo date('d.m.y H:i:s', $thread['post_date']).'
    by ' . getPlayerLink($thread['name']); + else { + echo date('d.m.y H:i:s', $thread['post_date']) . '
    by ' . getPlayerLink($thread['name']); + } echo '
    '; - if(!$sections[$section_id]['closed'] || Forum::isModerator()) - echo '
    '; + if(!$sections[$section_id]['closed'] || Forum::isModerator()) { + echo '
    '; + } } -else +else { echo '

    No threads in this board.

    '; +} diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index 0fe28f09..dc252560 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -30,22 +30,22 @@ if(!Forum::hasAccess($thread_starter['section'])) { } $posts_count = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id)->fetch(); -for($i = 0; $i < $posts_count['posts_count'] / $config['forum_threads_per_page']; $i++) -{ +for($i = 0; $i < $posts_count['posts_count'] / $config['forum_threads_per_page']; $i++) { if($i != $_page) $links_to_pages .= ''.($i + 1).' '; else $links_to_pages .= ''.($i + 1).' '; } -$posts = $db->query("SELECT `players`.`id` as `player_id`, `" . FORUM_TABLE_PREFIX . "forum`.`id`,`" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`section`,`" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` AS `date`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`post_html`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`last_edit_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`edit_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id." ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`post_date` LIMIT ".$config['forum_posts_per_page']." OFFSET ".($_page * $config['forum_posts_per_page']))->fetchAll(); + +$posts = $db->query("SELECT `players`.`id` as `player_id`, `" . FORUM_TABLE_PREFIX . "forum`.`id`,`" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`section`,`" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` AS `date`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`post_html`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`last_edit_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`edit_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`post_date` LIMIT ".$config['forum_posts_per_page']." OFFSET ".($_page * $config['forum_posts_per_page']))->fetchAll(); + if(isset($posts[0]['player_id'])) { $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `views`=`views`+1 WHERE `id` = ".(int) $thread_id); } $lookaddons = $db->hasColumn('players', 'lookaddons'); $groups = new OTS_Groups_List(); -foreach($posts as &$post) -{ +foreach($posts as &$post) { $post['player'] = new OTS_Player(); $player = $post['player']; $player->load($post['player_id']); From f9d35b719b048d6930957dd4285497c566433ca7 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 11 Jul 2023 11:15:58 +0200 Subject: [PATCH 181/232] Fix: cannot create topic on this board (check wasn't working) --- system/pages/forum/new_thread.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 33b57feb..7dabbfc7 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -30,8 +30,6 @@ if(Forum::canPost($account_logged)) $html = (isset($_REQUEST['html']) ? (int)$_REQUEST['html'] : 0); $saved = false; if (isset($_REQUEST['save'])) { - $errors = array(); - $length = strlen($post_topic); if ($length < 1 || $length > 60) $errors[] = "Too short or too long topic (Length: $length letters). Minimum 1 letter, maximum 60 letters."; From e49690b52b829f65f07200aac8c5f61e4c94fd90 Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 11 Jul 2023 11:17:18 +0200 Subject: [PATCH 182/232] Thanks @anyeor for previous fix --- system/pages/forum/new_thread.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index 7dabbfc7..f19a8ffa 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -15,7 +15,7 @@ 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(); - $section_id = isset($_REQUEST['section_id']) ? $_REQUEST['section_id'] : null; + $section_id = $_REQUEST['section_id'] ?? null; if($section_id !== null) { echo 'Boards >> ' . $sections[$section_id]['name'] . ' >> Post new thread
    '; if(isset($sections[$section_id]['name']) && Forum::hasAccess($section_id)) { From ddb093ec48ea0beaedab6b7b13113b56415a88c1 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 19 Jul 2023 11:57:26 +0200 Subject: [PATCH 183/232] Fix highscores if there is only 1 record --- system/pages/highscores.php | 1 - system/templates/highscores.html.twig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/system/pages/highscores.php b/system/pages/highscores.php index 95647893..dd2efa7b 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -311,7 +311,6 @@ if(config('highscores_balance')) /** @var Twig\Environment $twig */ $twig->display('highscores.html.twig', [ 'highscores' => $highscores, - 'totalRows' => $i - 1, 'list' => $list, 'skill' => $skill, 'skillName' => ($skill == SKILL_FRAGS ? 'Frags' : ($skill == SKILL_BALANCE ? 'Balance' : getSkillName($skill))), diff --git a/system/templates/highscores.html.twig b/system/templates/highscores.html.twig index 3b9224e2..2e32b7de 100644 --- a/system/templates/highscores.html.twig +++ b/system/templates/highscores.html.twig @@ -48,7 +48,7 @@ {% endif %}
    No records yet.
    No records yet.
    @@ -16,7 +17,9 @@
    -
    +
    + + {{ hook('HOOK_GUILDS_AFTER_GUILD_HEADER') }} @@ -83,8 +86,10 @@
    +
    + + {{ hook('HOOK_GUILDS_AFTER_GUILD_INFORMATION') }} -
    @@ -193,7 +198,9 @@
    -
    +
    + + {{ hook('HOOK_GUILDS_AFTER_GUILD_MEMBERS') }}
    @@ -263,9 +270,9 @@
    -
    +
    - {{ hook(constant('HOOK_GUILDS_AFTER_INVITED_CHARACTERS'), { 'guild': guild, 'isLeader': isLeader }) }} + {{ hook('HOOK_GUILDS_AFTER_INVITED_CHARACTERS') }}
    From 9f67cab5036a4eb623927f0b7c11aaddb6ce0908 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 19 Jul 2023 22:40:11 +0200 Subject: [PATCH 186/232] Add twig context for twig hook() function Allows to use variables from template inside the hook file with usage of $context variable --- system/twig.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/twig.php b/system/twig.php index 65e6ded0..4fc7c5ec 100644 --- a/system/twig.php +++ b/system/twig.php @@ -90,15 +90,16 @@ $function = new TwigFunction('truncate', function ($s, $n) { }); $twig->addFunction($function); -$function = new TwigFunction('hook', function ($hook, array $params = []) { +$function = new TwigFunction('hook', function ($context, $hook, array $params = []) { global $hooks; if(is_string($hook)) { $hook = constant($hook); } + $params['context'] = $context; $hooks->trigger($hook, $params); -}); +}, ['needs_context' => true]); $twig->addFunction($function); $function = new TwigFunction('config', function ($key) { From e14df529c0a0c01a18907c112ff09d140bc1a896 Mon Sep 17 00:00:00 2001 From: slawkens Date: Wed, 19 Jul 2023 22:40:39 +0200 Subject: [PATCH 187/232] Revert some change --- system/templates/guilds.view.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/guilds.view.html.twig b/system/templates/guilds.view.html.twig index 494b803d..f3da843e 100644 --- a/system/templates/guilds.view.html.twig +++ b/system/templates/guilds.view.html.twig @@ -272,7 +272,7 @@
    - {{ hook('HOOK_GUILDS_AFTER_INVITED_CHARACTERS') }} + {{ hook('HOOK_GUILDS_AFTER_INVITED_CHARACTERS', { 'guild': guild, 'isLeader': isLeader }) }}
    From 848c5c08878cd280f64f42f34b3bab19251c2d92 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 21 Jul 2023 11:58:18 +0200 Subject: [PATCH 188/232] Change default timezone --- system/templates/install.config.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/templates/install.config.html.twig b/system/templates/install.config.html.twig index b25f9dbf..0776d540 100644 --- a/system/templates/install.config.html.twig +++ b/system/templates/install.config.html.twig @@ -21,7 +21,7 @@ {{ locale.step_config_timezone_desc }} From ca56b4f1012f048c9d82b34962eb05fbd9967145 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 21 Jul 2023 15:12:07 +0200 Subject: [PATCH 189/232] Fix menu cannot remove --- admin/pages/menus.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/admin/pages/menus.php b/admin/pages/menus.php index 20045528..b5e7dbdf 100644 --- a/admin/pages/menus.php +++ b/admin/pages/menus.php @@ -91,7 +91,8 @@ if (isset($_REQUEST['template'])) {
      $menu): + $i = 0; + foreach ($menus[$id] as $menu): ?>
    • @@ -99,7 +100,7 @@ if (isset($_REQUEST['template'])) {
    • -
    From 5fa4890b708319c3eebe559076e877cdc725899b Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 21 Jul 2023 15:54:22 +0200 Subject: [PATCH 190/232] Add support for menu_default_color --- admin/pages/menus.php | 8 ++++++-- system/templates/admin.menus.js.html.twig | 4 ++-- templates/kathrine/config.php | 4 +++- templates/tibiacom/config.php | 2 ++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/admin/pages/menus.php b/admin/pages/menus.php index b5e7dbdf..bd1635a6 100644 --- a/admin/pages/menus.php +++ b/admin/pages/menus.php @@ -46,6 +46,7 @@ if (isset($_REQUEST['template'])) { if ($cache->enabled()) { $cache->delete('template_menus'); } + success('Saved at ' . date('H:i')); } @@ -56,6 +57,7 @@ if (isset($_REQUEST['template'])) { echo 'Cannot find template config.php file.'; return; } + if (!isset($config['menu_categories'])) { echo "No menu categories set in template config.php.
    This template doesn't support dynamic menus."; return; @@ -75,6 +77,7 @@ if (isset($_REQUEST['template'])) { $menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll(); foreach ($menus_db as $menu) { $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); + var_dump($menu['color']); } $last_id = array(); ?> @@ -98,7 +101,7 @@ if (isset($_REQUEST['template'])) { - + display('admin.menus.js.html.twig', array( 'menus' => $menus, - 'last_id' => $last_id + 'last_id' => $last_id, + 'menu_default_color' => $config['menu_default_color'] ?? '#ffffff' )); ?> '); //add input bo + $('#sortable-' + cat).append('
  • '); //add input bo $('#remove-button-' + cat + '-' + id).click(function () { $('#list-' + $(this).attr("id").replace('remove-button-', '')).remove(); }); @@ -69,4 +69,4 @@ ] }); } - \ No newline at end of file + diff --git a/templates/kathrine/config.php b/templates/kathrine/config.php index a53500b1..2de3804e 100644 --- a/templates/kathrine/config.php +++ b/templates/kathrine/config.php @@ -1,8 +1,10 @@ array('id' => 'news', 'name' => 'Latest News'), MENU_CATEGORY_ACCOUNT => array('id' => 'account', 'name' => 'Account'), MENU_CATEGORY_COMMUNITY => array('id' => 'community', 'name' => 'Community'), MENU_CATEGORY_LIBRARY => array('id' => 'library', 'name' => 'Library'), MENU_CATEGORY_SHOP => array('id' => 'shops', 'name' => 'Shop') -); \ No newline at end of file +); diff --git a/templates/tibiacom/config.php b/templates/tibiacom/config.php index 5e529e06..3f3f49d5 100644 --- a/templates/tibiacom/config.php +++ b/templates/tibiacom/config.php @@ -1,4 +1,6 @@ array('id' => 'news', 'name' => 'Latest News'), MENU_CATEGORY_ACCOUNT => array('id' => 'account', 'name' => 'Account'), From 7588904372fe087e414414b86225c3c027d1bd63 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 21 Jul 2023 16:38:10 +0200 Subject: [PATCH 191/232] Remove debugging var_dump --- admin/pages/menus.php | 1 - 1 file changed, 1 deletion(-) diff --git a/admin/pages/menus.php b/admin/pages/menus.php index bd1635a6..1e839d26 100644 --- a/admin/pages/menus.php +++ b/admin/pages/menus.php @@ -77,7 +77,6 @@ if (isset($_REQUEST['template'])) { $menus_db = $db->query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll(); foreach ($menus_db as $menu) { $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); - var_dump($menu['color']); } $last_id = array(); ?> From a9cb017defcedb2d6f3b25aaa0e2470b4568a0cd Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 21 Jul 2023 21:21:59 +0200 Subject: [PATCH 192/232] Fix menu highlighting & opening --- admin/template/template.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/template/template.php b/admin/template/template.php index 70ed5174..9620dd70 100644 --- a/admin/template/template.php +++ b/admin/template/template.php @@ -76,9 +76,9 @@ } else if ($has_child) { $used_menu = null; $nav_construct = ''; - foreach ($menu['link'] as $category => $sub_menu) { + foreach ($menu['link'] as $sub_category => $sub_menu) { $nav_construct .= ' From 3c3ddc457821100bd9d84270794cccfa0018d480 Mon Sep 17 00:00:00 2001 From: Gabriel Pedro Date: Sat, 30 Jul 2022 16:53:19 -0400 Subject: [PATCH 194/232] feat: custom words blocked (#190) * Update config.php * Update validator.php * Update config.php --- config.php | 10 +++++++++- system/libs/validator.php | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/config.php b/config.php index 93228eca..49e8f128 100644 --- a/config.php +++ b/config.php @@ -314,5 +314,13 @@ $config = array( 'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php 'footer_show_load_time' => true, // display load time of the page in the footer - 'npc' => array() + 'npc' => array(), + + // character name blocked + 'character_name_blocked' => array( + 'prefix' => array(), + 'names' => array(), + 'words' => array(), + ), + ); diff --git a/system/libs/validator.php b/system/libs/validator.php index 91f71c24..eb958583 100644 --- a/system/libs/validator.php +++ b/system/libs/validator.php @@ -246,8 +246,12 @@ class Validator global $db, $config; $name_lower = strtolower($name); + $custom_first_words_blocked = []; + if (isset($config['character_name_blocked']['prefix']) && $config['character_name_blocked']['prefix']) { + $custom_first_words_blocked = $config['character_name_blocked']['prefix']; + } - $first_words_blocked = array('admin ', 'administrator ', 'gm ', 'cm ', 'god ','tutor ', "'", '-'); + $first_words_blocked = array_merge($custom_first_words_blocked, array('admin ', 'administrator ', 'gm ', 'cm ', 'god ','tutor ', "'", '-')); foreach($first_words_blocked as $word) { if($word == substr($name_lower, 0, strlen($word))) { @@ -282,7 +286,11 @@ class Validator return false; } - $names_blocked = array('admin', 'administrator', 'gm', 'cm', 'god', 'tutor'); + $custom_names_blocked = []; + if (isset($config['character_name_blocked']['names']) && $config['character_name_blocked']['names']) { + $custom_names_blocked = $config['character_name_blocked']['names']; + } + $names_blocked = array_merge($custom_names_blocked, array('admin', 'administrator', 'gm', 'cm', 'god', 'tutor')); foreach($names_blocked as $word) { if($word == $name_lower) { @@ -291,7 +299,11 @@ class Validator } } - $words_blocked = array('admin', 'administrator', 'gamemaster', 'game master', 'game-master', "game'master", '--', "''","' ", " '", '- ', ' -', "-'", "'-", 'fuck', 'sux', 'suck', 'noob', 'tutor'); + $custom_words_blocked = []; + if (isset($config['character_name_blocked']['words']) && $config['character_name_blocked']['words']) { + $custom_words_blocked = $config['character_name_blocked']['words']; + } + $words_blocked = array_merge($custom_words_blocked, array('admin', 'administrator', 'gamemaster', 'game master', 'game-master', "game'master", '--', "''","' ", " '", '- ', ' -', "-'", "'-", 'fuck', 'sux', 'suck', 'noob', 'tutor')); foreach($words_blocked as $word) { if(!(strpos($name_lower, $word) === false)) { From 4a629b4418a60dfcb16a2d6f3fec121b7c689ec9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 22 Jul 2023 14:03:57 +0200 Subject: [PATCH 195/232] Add protection, nothing important - thrown exception before --- admin/pages/modules/balance.php | 2 ++ admin/pages/modules/coins.php | 2 ++ admin/pages/modules/created.php | 2 ++ admin/pages/modules/lastlogin.php | 2 ++ admin/pages/modules/points.php | 2 ++ 5 files changed, 10 insertions(+) diff --git a/admin/pages/modules/balance.php b/admin/pages/modules/balance.php index 5a2700a1..7c23185b 100644 --- a/admin/pages/modules/balance.php +++ b/admin/pages/modules/balance.php @@ -1,4 +1,6 @@ hasColumn('players', 'balance') ? $db->query('SELECT `balance`, `id`, `name`,`level` FROM `players` ORDER BY `balance` DESC LIMIT 10;') : 0); $twig->display('balance.html.twig', array( diff --git a/admin/pages/modules/coins.php b/admin/pages/modules/coins.php index 3bb0bc61..6e5bc9d3 100644 --- a/admin/pages/modules/coins.php +++ b/admin/pages/modules/coins.php @@ -1,4 +1,6 @@ hasColumn('accounts', 'coins') ? $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;') : 0); $twig->display('coins.html.twig', array( diff --git a/admin/pages/modules/created.php b/admin/pages/modules/created.php index 8a375c3a..4bf88b96 100644 --- a/admin/pages/modules/created.php +++ b/admin/pages/modules/created.php @@ -1,4 +1,6 @@ hasColumn('accounts', 'created') ? $db->query('SELECT `created`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `created` DESC LIMIT 10;') : 0); $twig->display('created.html.twig', array( diff --git a/admin/pages/modules/lastlogin.php b/admin/pages/modules/lastlogin.php index d7a3f43f..a71158bd 100644 --- a/admin/pages/modules/lastlogin.php +++ b/admin/pages/modules/lastlogin.php @@ -1,4 +1,6 @@ hasColumn('players', 'lastlogin') ? $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;') : 0); $twig->display('lastlogin.html.twig', array( 'players' => $players, diff --git a/admin/pages/modules/points.php b/admin/pages/modules/points.php index d1c4b0f3..9308da42 100644 --- a/admin/pages/modules/points.php +++ b/admin/pages/modules/points.php @@ -1,4 +1,6 @@ hasColumn('accounts', 'premium_points') ? $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;') : 0); $twig->display('points.html.twig', array( From 23047aa608238a689da365aa671d93fa4b0e6aa6 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 22 Jul 2023 14:46:20 +0200 Subject: [PATCH 196/232] Fix multiple redirects error in browser --- admin/pages/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pages/login.php b/admin/pages/login.php index 32d8e8b0..8bb25f36 100644 --- a/admin/pages/login.php +++ b/admin/pages/login.php @@ -12,7 +12,7 @@ $title = 'Login'; require PAGES . 'account/login.php'; if ($logged) { - header('Location: ' . ADMIN_URL); + header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); return; } From d3b15a0a3e4db921d253e685cb2ad0af9eeef1c1 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 22 Jul 2023 14:46:20 +0200 Subject: [PATCH 197/232] Fix multiple redirects error in browser --- admin/pages/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pages/login.php b/admin/pages/login.php index 32d8e8b0..8bb25f36 100644 --- a/admin/pages/login.php +++ b/admin/pages/login.php @@ -12,7 +12,7 @@ $title = 'Login'; require PAGES . 'account/login.php'; if ($logged) { - header('Location: ' . ADMIN_URL); + header('Location: ' . (admin() ? ADMIN_URL : BASE_URL)); return; } From 53221a9fd107a4944744d41c0cbf805d679c7ef5 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 29 Jul 2023 07:27:07 +0200 Subject: [PATCH 198/232] There is no more info. That never worked. --- system/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/functions.php b/system/functions.php index dbf6466d..feb24360 100644 --- a/system/functions.php +++ b/system/functions.php @@ -929,8 +929,8 @@ function load_config_lua($filename) $config_file = $filename; if(!@file_exists($config_file)) { - log_append('error.log', '[load_config_file] Fatal error: Cannot load config.lua (' . $filename . '). Error: ' . print_r(error_get_last(), true)); - throw new RuntimeException('ERROR: Cannot find ' . $filename . ' file. More info in system/logs/error.log'); + log_append('error.log', '[load_config_file] Fatal error: Cannot load config.lua (' . $filename . ').'); + throw new RuntimeException('ERROR: Cannot find ' . $filename . ' file.'); } $result = array(); From fcb2fc3002bc404513cdbd3db3a28c8f35e9442b Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 5 Aug 2023 11:57:15 +0200 Subject: [PATCH 199/232] Add .htaccess to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5206d08b..6c1db9b7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ Thumbs.db .DS_Store .idea +# +/.htaccess + # composer composer.lock vendor From 41fa695d8bef0aa3c58c8444465cc0affe66efec Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 5 Aug 2023 19:58:04 +0200 Subject: [PATCH 200/232] Add some functions to compatibility layer of gesioraac --- system/compat/classes.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/system/compat/classes.php b/system/compat/classes.php index 051fbdf2..2009140b 100644 --- a/system/compat/classes.php +++ b/system/compat/classes.php @@ -9,7 +9,30 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -class Player extends OTS_Player {} -class Guild extends OTS_Guild {} +class Account extends OTS_Account { + public function loadById($id) { + $this->load($id); + } + public function loadByName($name) { + $this->find($name); + } +} + +class Player extends OTS_Player { + public function loadById($id) { + $this->load($id); + } + public function loadByName($name) { + $this->find($name); + } +} +class Guild extends OTS_Guild { + public function loadById($id) { + $this->load($id); + } + public function loadByName($name) { + $this->find($name); + } +} class GuildRank extends OTS_GuildRank {} class House extends OTS_House {} From 757ec28028e7e8abfae6bc774dadaec50a373cff Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 5 Aug 2023 19:58:52 +0200 Subject: [PATCH 201/232] Removed deprecated functions: utf8_encode & decode --- system/libs/pot/OTS_ServerInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/libs/pot/OTS_ServerInfo.php b/system/libs/pot/OTS_ServerInfo.php index fd06749e..30a81f7b 100644 --- a/system/libs/pot/OTS_ServerInfo.php +++ b/system/libs/pot/OTS_ServerInfo.php @@ -123,7 +123,7 @@ class OTS_ServerInfo { // loads respond XML $info = new OTS_InfoRespond(); - if(!$info->loadXML( utf8_encode($status->getBuffer()))) + if(!$info->loadXML( $status->getBuffer())) return false; return $info; From aacc12036081cb2b2fa0815ea21c26fd992a3d4d Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 5 Aug 2023 20:52:01 +0200 Subject: [PATCH 202/232] Remove deprecated utf8_decode --- templates/tibiacom/headline.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/tibiacom/headline.php b/templates/tibiacom/headline.php index dbef28a1..85dae0f2 100644 --- a/templates/tibiacom/headline.php +++ b/templates/tibiacom/headline.php @@ -14,7 +14,7 @@ imagecolortransparent($image, imagecolorallocate($image, 0, 0, 0)); // set text $font = getenv('GDFONTPATH') . DIRECTORY_SEPARATOR . 'martel.ttf'; -imagettftext($image, 18, 0, 4, 20, imagecolorallocate($image, 240, 209, 164), $font, utf8_decode($text)); +imagettftext($image, 18, 0, 4, 20, imagecolorallocate($image, 240, 209, 164), $font, $text); // header mime type header('Content-type: image/gif'); From a72d1a3c9ff4171423de86183f6b0d772031cbd4 Mon Sep 17 00:00:00 2001 From: Slawomir Boczek Date: Sat, 5 Aug 2023 21:00:45 +0200 Subject: [PATCH 203/232] Feature: settings (#216) * New admin panel Pages: Options + Config [WIP] * Forgot the plugin example of options * Rename to settings.php * Add Settings Class * New myaac_settings table * Add $limit parameter to $db->select method * Add $member var annotation * Remove useless title_separator from config * Move $menus to menus.php Also fix active link when menu item has subpage * Settings [WIP] New Settings class New Plugins::load() method Move config.php to settings.php MyAAC Settings will have plugin_name = 'core' Add compat_config.php * Change options.php to settings.php * Change name to settings * Add Settings menu * Add Sections + Add setting($key) function Reorganisation * Add email + password fields as type * Update 33.php * add settings migration * php 8 compatibility * add missing hook * Add categories in tabs, move more settings, revert back getPluginSettings Categories and sections are now not numbered Remove example settings plugin * fix typo * Update .gitignore * Add 36th migration for settings table * Execute migrations just after db connect * Update plugins.php * [WIP] Some work on settings Add hidden settings New method: parse, to parse settings from array Move base html to twig template Remove vocation loading from .xml, instead use predefined voc names * Rename * Fix path * [WIP] More work on settings Move more config to settings (mainly mail_* + some other) Remove mail_admin, wasnt used anywhere Add return type to some functions Add Twig settings(key) function Possibility to save setting to db * Add min, max, step to number field option * Re-enable plugin if disabled and already installed * Add Settings menu, including all plugins with settings One change included in previous commit, due to missclick * Nothing important * Better boolean detection * More detailed error message in settings * Lets call it settings.name instead * Add new function: only_if, to hide fields when they are not enabled [WIP] Not fully finished yet * guild_management: show_if * Hide section title on show_if * Fix: check on page load if radio button is checked * Add: show_if - account_mail_verify * nothing important * Rename team_* variables + add to deprecated * Change variable name * Extract Settings:save function * Add settings.callbacks.get * Move forum config to settings * Move status config to settings * Remove whitespaces * More config to settings: account_types, genders, highscores, admin * Move signature config to settings * Move news config to settings * Rename variable * Save config.php in Settings Egg and hen problem solved :) * Test database connection on save settings -> prevents from making website unusable if connection is wrong * Test server_path -> same There is no config.php anymore, just config.local.php, which can be edited manually and also from admin panel * Remove configs from previous commit * Fix create account, if account_create_character_create is enabled * Add more deprecated configs * Add more info into comment * Update 5-database.php * Fix menu highlighting & opening * Update template.php * Enable script option * Reword email settings + move two new settings * add last_kills_limit + move shop * google_analytics_id * add mail_lost_account_interval * Create character blocked words (by @gpedro), just moved to settings * Fix google_analytics * create character name config moved to settings * Fix for install warning - min/max length * New create character checks configurable: block monsters & spells names * fixes * Improve character npc name check * New setting: donate_column + move donate config to settings * Add super fancy No Refresh saving with a toast * Add new possibility: to deny saving setting if condition is not met * Move database settings to separate category * Fix default value displaying * Add database_hash setting * add last_kills_limit to compat config * Move create character blocked names down * Every setting needs to have default * Move rest of config to settings Remove config.php completely Add new settings category: Game Fix account_login_by_email Min textarea size = 2 + adjusted automatically --- admin/includes/settings_menus.php | 35 + admin/index.php | 11 - admin/pages/accounts.php | 4 +- admin/pages/dashboard.php | 7 +- admin/pages/mailer.php | 2 +- admin/pages/pages.php | 4 +- admin/pages/plugins.php | 4 +- admin/pages/settings.php | 56 + admin/pages/visitors.php | 9 +- admin/template/menus.php | 9 +- admin/tools/settings_save.php | 34 + common.php | 18 +- config.php | 326 ---- index.php | 36 +- install/includes/schema.sql | 12 +- install/index.php | 8 +- install/steps/5-database.php | 49 +- install/steps/7-finish.php | 17 + install/tools/7-finish.php | 11 +- login.php | 2 - plugins/example.json | 3 +- system/compat/config.php | 103 ++ system/database.php | 8 +- system/functions.php | 177 +- system/init.php | 72 +- system/libs/CreateCharacter.php | 18 +- system/libs/Settings.php | 598 ++++++ system/libs/forum.php | 4 +- system/libs/plugins.php | 121 +- system/libs/pot/OTS_ServerInfo.php | 28 +- system/libs/validator.php | 107 +- system/migrations/20.php | 54 +- system/migrations/36.php | 14 + system/pages/account/change_name.php | 14 +- system/pages/account/change_password.php | 4 +- system/pages/account/change_sex.php | 10 +- system/pages/account/create.php | 6 +- system/pages/account/lost.php | 8 +- system/pages/account/manage.php | 2 +- system/pages/account/register.php | 2 +- system/pages/account/register_new.php | 16 +- system/pages/characters.php | 4 +- system/pages/creatures.php | 4 +- system/pages/experience_table.php | 4 +- system/pages/forum.php | 6 +- system/pages/forum/base.php | 14 +- system/pages/forum/edit_post.php | 9 +- system/pages/forum/move_thread.php | 5 +- system/pages/forum/new_post.php | 13 +- system/pages/forum/new_thread.php | 11 +- system/pages/forum/remove_post.php | 7 +- system/pages/forum/show_board.php | 9 +- system/pages/forum/show_thread.php | 9 +- system/pages/highscores.php | 46 +- system/pages/team.php | 12 +- system/settings.php | 1638 +++++++++++++++++ system/status.php | 20 +- system/template.php | 11 +- .../templates/account.change_name.html.twig | 2 +- system/templates/account.change_sex.html.twig | 4 +- system/templates/account.create.html.twig | 6 +- .../account.create_character.html.twig | 4 +- ...ccount.generate_new_recovery_key.html.twig | 4 +- system/templates/account.management.html.twig | 8 +- system/templates/admin.settings.html.twig | 105 ++ system/templates/characters.html.twig | 2 +- system/templates/creature.html.twig | 2 +- system/templates/experience_table.html.twig | 6 +- system/templates/google_analytics.html.twig | 4 +- system/templates/install.config.html.twig | 2 +- .../templates/mail.password_changed.html.twig | 2 +- system/templates/team.html.twig | 32 +- system/twig.php | 5 + .../tibiacom/account.management.html.twig | 4 +- templates/tibiacom/index.php | 2 +- tools/css/toastify.min.css | 15 + tools/js/toastify.min.js | 15 + tools/signature/index.php | 14 +- 78 files changed, 3209 insertions(+), 874 deletions(-) create mode 100644 admin/includes/settings_menus.php create mode 100644 admin/pages/settings.php create mode 100644 admin/tools/settings_save.php delete mode 100644 config.php create mode 100644 system/compat/config.php create mode 100644 system/libs/Settings.php create mode 100644 system/migrations/36.php create mode 100644 system/settings.php create mode 100644 system/templates/admin.settings.html.twig create mode 100644 tools/css/toastify.min.css create mode 100644 tools/js/toastify.min.js diff --git a/admin/includes/settings_menus.php b/admin/includes/settings_menus.php new file mode 100644 index 00000000..2ce784fc --- /dev/null +++ b/admin/includes/settings_menus.php @@ -0,0 +1,35 @@ + 'MyAAC', + 'link' => 'settings&plugin=core', + 'icon' => 'list', + 'order' => $order, +]; + +foreach (Plugins::getAllPluginsSettings() as $setting) { + $file = BASE . $setting['settingsFilename']; + if (!file_exists($file)) { + warning('Plugin setting: ' . $file . ' - cannot be loaded.'); + continue; + } + + $order += 10; + + $settings = require $file; + + $settingsMenu[] = [ + 'name' => $settings['name'], + 'link' => 'settings&plugin=' . $setting['pluginFilename'], + 'icon' => 'list', + 'order' => $order, + ]; +} + +unset($settings, $file, $order); + +return $settingsMenu; diff --git a/admin/index.php b/admin/index.php index 60d96d6a..3974f953 100644 --- a/admin/index.php +++ b/admin/index.php @@ -6,10 +6,6 @@ require '../common.php'; const ADMIN_PANEL = true; const MYAAC_ADMIN = true; -if(file_exists(BASE . 'config.local.php')) { - require_once BASE . 'config.local.php'; -} - if(file_exists(BASE . 'install') && (!isset($config['installed']) || !$config['installed'])) { header('Location: ' . BASE_URL . 'install/'); @@ -34,12 +30,6 @@ if(!$db->hasTable('myaac_account_actions')) { throw new RuntimeException('Seems that the table myaac_account_actions of MyAAC doesn\'t exist in the database. This is a fatal error. You can try to reinstall MyAAC by visiting this url.'); } -if(config('env') === 'dev') { - ini_set('display_errors', 1); - ini_set('display_startup_errors', 1); - error_reporting(E_ALL); -} - // event system require_once SYSTEM . 'hooks.php'; $hooks = new Hooks(); @@ -47,7 +37,6 @@ $hooks->load(); require SYSTEM . 'status.php'; require SYSTEM . 'login.php'; -require SYSTEM . 'migrate.php'; require __DIR__ . '/includes/functions.php'; $twig->addGlobal('config', $config); diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 550ea670..68dd7081 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -37,7 +37,7 @@ if ($config['account_country']) { $countries[$code] = $c; } $web_acc = ACCOUNT_WEB_FLAGS; -$acc_type = config('account_types'); +$acc_type = setting('core.account_types'); ?> @@ -361,7 +361,7 @@ else if (isset($_REQUEST['search'])) {
    - getEMail() . '">Send Mail)' : ''); ?> + getEMail() . '">Send Mail)' : ''); ?>
    diff --git a/admin/pages/dashboard.php b/admin/pages/dashboard.php index 53380503..e24b98ad 100644 --- a/admin/pages/dashboard.php +++ b/admin/pages/dashboard.php @@ -47,12 +47,11 @@ $tmp = ''; if (fetchDatabaseConfig('site_closed_message', $tmp)) $closed_message = $tmp; -$configAdminPanelModules = config('admin_panel_modules'); -if (isset($configAdminPanelModules)) { +$settingAdminPanelModules = setting('core.admin_panel_modules'); +if (count($settingAdminPanelModules) > 0) { echo '
    '; - $configAdminPanelModules = explode(',', $configAdminPanelModules); $twig_loader->prependPath(__DIR__ . '/modules/templates'); - foreach ($configAdminPanelModules as $box) { + foreach ($settingAdminPanelModules as $box) { $file = __DIR__ . '/modules/' . $box . '.php'; if (file_exists($file)) { include($file); diff --git a/admin/pages/mailer.php b/admin/pages/mailer.php index ea45eeb0..7d12f14b 100644 --- a/admin/pages/mailer.php +++ b/admin/pages/mailer.php @@ -15,7 +15,7 @@ if (!hasFlag(FLAG_CONTENT_MAILER) && !superAdmin()) { return; } -if (!config('mail_enabled')) { +if (!setting('core.mail_enabled')) { echo 'Mail support disabled in config.'; return; } diff --git a/admin/pages/pages.php b/admin/pages/pages.php index 7f030e47..e2b7acf5 100644 --- a/admin/pages/pages.php +++ b/admin/pages/pages.php @@ -152,8 +152,8 @@ class Pages $errors[] = 'Enable PHP is wrong.'; return false; } - if ($php == 1 && !getBoolean(config('admin_pages_php_enable'))) { - $errors[] = 'PHP pages disabled on this server. To enable go to config.php and change admin_pages_php_enable to "yes".'; + if ($php == 1 && !getBoolean(setting('core.admin_pages_php_enable'))) { + $errors[] = 'PHP pages disabled on this server. To enable go to Settings in Admin Panel and enable Enable PHP Pages.'; return false; } if(!isset($enable_tinymce) || ($enable_tinymce != 0 && $enable_tinymce != 1)) { diff --git a/admin/pages/plugins.php b/admin/pages/plugins.php index f754edf4..be9df2b0 100644 --- a/admin/pages/plugins.php +++ b/admin/pages/plugins.php @@ -13,8 +13,8 @@ $use_datatable = true; require_once LIBS . 'plugins.php'; -if (!getBoolean(config('admin_plugins_manage_enable'))) { - warning('Plugin installation and management is disabled in config.
    If you wish to enable, go to config.php and change admin_plugins_manage_enable to "yes".'); +if (!getBoolean(setting('core.admin_plugins_manage_enable'))) { + warning('Plugin installation and management is disabled in Settings.
    If you wish to enable, go to Settings and enable Enable Plugins Manage.'); } else { $twig->display('admin.plugins.form.html.twig'); diff --git a/admin/pages/settings.php b/admin/pages/settings.php new file mode 100644 index 00000000..5b354c99 --- /dev/null +++ b/admin/pages/settings.php @@ -0,0 +1,56 @@ + + * @copyright 2019 MyAAC + * @link https://my-aac.org + */ +defined('MYAAC') or die('Direct access not allowed!'); +$title = 'Settings'; + +require_once SYSTEM . 'clients.conf.php'; +if (empty($_GET['plugin'])) { + error('Please select plugin from left Panel.'); + return; +} + +$plugin = $_GET['plugin']; + +if($plugin != 'core') { + $pluginSettings = Plugins::getPluginSettings($plugin); + if (!$pluginSettings) { + error('This plugin does not exist or does not have settings defined.'); + return; + } + + $settingsFilePath = BASE . $pluginSettings; +} +else { + $settingsFilePath = SYSTEM . 'settings.php'; +} + +if (!file_exists($settingsFilePath)) { + error("Plugin $plugin does not exist or does not have settings defined."); + return; +} + +$settingsFile = require $settingsFilePath; +if (!is_array($settingsFile)) { + error("Cannot load settings file for plugin $plugin"); + return; +} + +$settingsKeyName = ($plugin == 'core' ? $plugin : $settingsFile['key']); + +$title = ($plugin == 'core' ? 'Settings' : 'Plugin Settings - ' . $plugin); + +$settingsParsed = Settings::display($settingsKeyName, $settingsFile['settings']); + +$twig->display('admin.settings.html.twig', [ + 'settingsParsed' => $settingsParsed['content'], + 'settings' => $settingsFile['settings'], + 'script' => $settingsParsed['script'], + 'settingsKeyName' => $settingsKeyName, +]); diff --git a/admin/pages/visitors.php b/admin/pages/visitors.php index 77626eb0..8ab78521 100644 --- a/admin/pages/visitors.php +++ b/admin/pages/visitors.php @@ -16,7 +16,7 @@ use DeviceDetector\Parser\OperatingSystem; $title = 'Visitors'; $use_datatable = true; -if (!$config['visitors_counter']): ?> +if (!setting('core.visitors_counter')): ?> Visitors counter is disabled.
    You can enable it by editing this configurable in config.local.php file:

    $config['visitors_counter'] = true;

    @@ -25,10 +25,9 @@ if (!$config['visitors_counter']): ?> endif; require SYSTEM . 'libs/visitors.php'; -$visitors = new Visitors($config['visitors_counter_ttl']); +$visitors = new Visitors(setting('core.visitors_counter_ttl')); -function compare($a, $b) -{ +function compare($a, $b): int { return $a['lastvisit'] > $b['lastvisit'] ? -1 : 1; } @@ -61,7 +60,7 @@ foreach ($tmp as &$visitor) { } $twig->display('admin.visitors.html.twig', array( - 'config_visitors_counter_ttl' => $config['visitors_counter_ttl'], + 'config_visitors_counter_ttl' => setting('core.visitors_counter_ttl'), 'visitors' => $tmp )); ?> diff --git a/admin/template/menus.php b/admin/template/menus.php index 460c03dd..ff67a21e 100644 --- a/admin/template/menus.php +++ b/admin/template/menus.php @@ -1,8 +1,11 @@ 'Dashboard', 'icon' => 'tachometer-alt', 'order' => 10, 'link' => 'dashboard'], - ['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' => + ['name' => 'Settings', 'icon' => 'edit', 'order' => 19, 'link' => + require ADMIN . 'includes/settings_menus.php' + ], + ['name' => 'News', 'icon' => 'newspaper', 'order' => 20, 'link' => [ ['name' => 'View', 'link' => 'news', 'icon' => 'list', 'order' => 10], ['name' => 'Add news', 'link' => 'news&action=new&type=1', 'icon' => 'plus', 'order' => 20], @@ -16,7 +19,7 @@ $menus = [ ['name' => 'Add', 'link' => 'changelog&action=new', 'icon' => 'plus', 'order' => 20], ], ], - ['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !config('mail_enabled')], + ['name' => 'Mailer', 'icon' => 'envelope', 'order' => 40, 'link' => 'mailer', 'disabled' => !setting('core.mail_enabled')], ['name' => 'Pages', 'icon' => 'book', 'order' => 50, 'link' => [ ['name' => 'View', 'link' => 'pages', 'icon' => 'list', 'order' => 10], diff --git a/admin/tools/settings_save.php b/admin/tools/settings_save.php new file mode 100644 index 00000000..83be1de3 --- /dev/null +++ b/admin/tools/settings_save.php @@ -0,0 +1,34 @@ +save($_REQUEST['plugin'], $_POST['settings']); + +$errors = $settings->getErrors(); +if (count($errors) > 0) { + http_response_code(500); + die(implode('
    ', $errors)); +} + +echo 'Saved at ' . date('H:i'); diff --git a/common.php b/common.php index 0c56f0ac..c1a89bbd 100644 --- a/common.php +++ b/common.php @@ -27,7 +27,7 @@ if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or highe const MYAAC = true; const MYAAC_VERSION = '0.10.0-dev'; -const DATABASE_VERSION = 35; +const DATABASE_VERSION = 36; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); @@ -143,6 +143,22 @@ if(!IS_CLI) { //define('CURRENT_URL', BASE_URL . $_SERVER['REQUEST_URI']); } +if (file_exists(BASE . 'config.local.php')) { + require BASE . 'config.local.php'; +} + +ini_set('log_errors', 1); +if(@$config['env'] === 'dev') { + ini_set('display_errors', 1); + ini_set('display_startup_errors', 1); + error_reporting(E_ALL); +} +else { + ini_set('display_errors', 0); + ini_set('display_startup_errors', 0); + error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); +} + $autoloadFile = VENDOR . 'autoload.php'; if (!is_file($autoloadFile)) { throw new RuntimeException('The vendor folder is missing. Please download Composer: https://getcomposer.org/download, install it and execute in the main MyAAC directory this command: composer install. Or download MyAAC from GitHub releases, which includes Vendor folder.'); diff --git a/config.php b/config.php deleted file mode 100644 index 49e8f128..00000000 --- a/config.php +++ /dev/null @@ -1,326 +0,0 @@ - - * @copyright 2019 MyAAC - * @link https://my-aac.org - */ - -$config = array( - // directories & files - 'server_path' => '', // path to the server directory (same directory where config file is located) - - /** - * Environment Setting - * - * if you use this script on your live server - set to 'prod' (production) - * if you want to test and debug the script locally, or develop plugins, set to 'dev' (development) - * WARNING: on 'dev' cache is disabled, so site will be significantly slower !!! - * WARNING2: on 'dev' all PHP errors/warnings are displayed - * Recommended: 'prod' cause of speed (page load time is better) - */ - 'env' => 'prod', // 'prod' for production and 'dev' for development - - 'template' => 'kathrine', // template used by website (kathrine, tibiacom) - 'template_allow_change' => true, // allow users to choose their own template while browsing website? - - 'vocations_amount' => 4, // how much basic vocations your server got (without promotion) - - // what client version are you using on this OT? - // used for the Downloads page and some templates aswell - 'client' => 1098, // 954 = client 9.54 - - 'session_prefix' => 'myaac_', // must be unique for every site on your server - 'friendly_urls' => false, // mod_rewrite is required for this, it makes links looks more elegant to eye, and also are SEO friendly (example: https://my-aac.org/guilds/Testing instead of https://my-aac.org/?subtopic=guilds&name=Testing). Remember to rename .htaccess.dist to .htaccess - 'gzip_output' => false, // gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles - - // gesior backward support (templates & pages) - // allows using gesior templates and pages with myaac - // might bring some performance when disabled - 'backward_support' => true, - - // head options (html) - 'meta_description' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', // description of the site - 'meta_keywords' => 'free online game, free multiplayer game, ots, open tibia server', // keywords list separated by commas - - // footer - 'footer' => ''/*'
    Your Server © 2016. All rights reserved.'*/, - - 'language' => 'en', // default language (currently only 'en' available) - 'language_allow_change' => false, - - 'visitors_counter' => true, - 'visitors_counter_ttl' => 10, // how long visitor will be marked as online (in minutes) - 'views_counter' => true, - - // cache system. by default file cache is used - 'cache_engine' => 'auto', // apc, apcu, eaccelerator, xcache, file, auto, or blank to disable. - 'cache_prefix' => 'myaac_', // have to be unique if running more MyAAC instances on the same server (except file system cache) - - // database details (leave blank for auto detect from config.lua) - 'database_host' => '', - 'database_port' => '', // leave blank to default 3306 - 'database_user' => '', - 'database_password' => '', - 'database_name' => '', - 'database_log' => false, // should database queries be logged and saved into system/logs/database.log? - 'database_socket' => '', // set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock) - 'database_persistent' => false, // use database permanent connection (like server), may speed up your site - - // multiworld system (only TFS 0.3) - 'multiworld' => false, // use multiworld system? - 'worlds' => array( // list of worlds - //'1' => 'Your World Name', - //'2' => 'Your Second World Name' - ), - - // images - 'outfit_images_url' => 'https://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit - 'outfit_images_wrong_looktypes' => [75, 126, 127, 266, 302], // this looktypes needs to have different margin-top and margin-left because they are wrong positioned - 'item_images_url' => 'https://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder - 'item_images_extension' => '.gif', - - // creatures - 'creatures_images_url' => 'images/monsters/', // set to images/monsters if you host your own creatures in images folder - 'creatures_images_extension' => '.gif', - 'creatures_images_preview' => false, // set to true to allow picture previews for creatures - 'creatures_items_url' => 'https://tibia.fandom.com/wiki/', // set to website which shows details about items. - 'creatures_loot_percentage' => true, // set to true to show the loot tooltip percent - - // account - 'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager) - 'account_login_by_email' => false, // use email instead of Account Name like in latest Tibia - 'account_login_by_email_fallback' => false, // allow also additionally login by Account Name/Number (for users that might forget their email) - 'account_create_auto_login' => false, // auto login after creating account? - 'account_create_character_create' => true, // allow directly to create character on create account page? - 'account_mail_verify' => false, // force users to confirm their email addresses when registering - 'account_mail_confirmed_reward' => [ // reward users for confirming their E-Mails - // account_mail_verify needs to be enabled too - 'premium_days' => 0, - 'premium_points' => 0, - 'coins' => 0, - 'message' => 'You received %d %s for confirming your E-Mail address.' // example: You received 20 premium points for confirming your E-Mail address. - ], - 'account_mail_unique' => true, // email addresses cannot be duplicated? (one account = one email) - 'account_mail_block_plus_sign' => true, // block email with '+' signs like test+box@gmail.com (help protect against spamming accounts) - 'account_premium_days' => 0, // default premium days on new account - 'account_premium_points' => 0, // default premium points on new account - 'account_welcome_mail' => true, // send welcome email when user registers - 'account_mail_change' => 2, // how many days user need to change email to account - block hackers - 'account_country' => true, // user will be able to set country of origin when registering account, this information will be viewable in others places aswell - 'account_country_recognize' => true, // should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io - 'account_change_character_name' => false, // can user change their character name for premium points? - 'account_change_character_name_points' => 30, // cost of name change - 'account_change_character_sex' => false, // can user change their character sex for premium points? - 'account_change_character_sex_points' => 30, // cost of sex change - 'characters_per_account' => 10, // max. number of characters per account - - // mail - 'mail_enabled' => false, // is aac maker configured to send e-mails? - 'mail_address' => 'no-reply@your-server.org', // server e-mail address (from:) - 'mail_admin' => 'your-address@your-server.org', // admin email address, where mails from contact form will be sent - 'mail_signature' => array( // signature that will be included at the end of every message sent using _mail function - 'plain' => ""/*"--\nMy Server,\nhttp://www.myserver.com"*/, - 'html' => ''/*'
    My Server,\nmyserver.com'*/ - ), - 'smtp_enabled' => false, // send by smtp or mail function (set false if use mail function, set to true if you use GMail or Microsoft Outlook) - 'smtp_host' => '', // mail host. smtp.gmail.com for GMail / smtp-mail.outlook.com for Microsoft Outlook - 'smtp_port' => 25, // 25 (default) / 465 (ssl, GMail) / 587 (tls, Microsoft Outlook) - 'smtp_auth' => true, // need authorization? - 'smtp_user' => 'admin@example.org', // here your email username - 'smtp_pass' => '', - 'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook) - 'smtp_debug' => false, // set true to debug (you will see more info in error.log) - - // - 'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key) - 'generate_new_reckey_price' => 20, // price for new recovery key - 'send_mail_when_change_password' => true, // send e-mail with new password when change password to account - 'send_mail_when_generate_reckey' => true, // send e-mail with rec key (key is displayed on page anyway when generate) - - // you may need to adjust this for older tfs versions - // by removing Community Manager - 'account_types' => [ - 'None', - 'Normal', - 'Tutor', - 'Senior Tutor', - 'Gamemaster', - 'Community Manager', - 'God', - ], - - // genders (aka sex) - 'genders' => array( - 0 => 'Female', - 1 => 'Male' - ), - - // new character config - 'character_samples' => array( // vocations, format: ID_of_vocation => 'Name of Character to copy' - //0 => 'Rook Sample', - 1 => 'Sorcerer Sample', - 2 => 'Druid Sample', - 3 => 'Paladin Sample', - 4 => 'Knight Sample' - ), - - 'use_character_sample_skills' => false, - - // it must show limited number of players after using search in character page - 'characters_search_limit' => 15, - - // town list used when creating character - // won't be displayed if there is only one item (rookgaard for example) - 'character_towns' => array(1), - - // characters length - // This is the minimum and the maximum length that a player can create a character. It is highly recommend the maximum length to be 21. - 'character_name_min_length' => 4, - 'character_name_max_length' => 21, - 'character_name_npc_check' => true, - - // list of towns - // if you use TFS 1.3 with support for 'towns' table in database, then you can ignore this - it will be configured automatically (from MySQL database - Table - towns) - // otherwise it will try to load from your .OTBM map file - // if you don't see towns on website, then you need to fill this out - 'towns' => array( - 0 => 'No town', - 1 => 'Sample town' - ), - - // guilds - 'guild_management' => true, // enable guild management system on the site? - 'guild_need_level' => 1, // min. level to form a guild - 'guild_need_premium' => true, // require premium account to form a guild? - 'guild_image_size_kb' => 80, // maximum size of the guild logo image in KB (kilobytes) - 'guild_description_default' => 'New guild. Leader must edit this text :)', - 'guild_description_chars_limit' => 1000, // limit of guild description - 'guild_description_lines_limit' => 6, // limit of lines, if description has more lines it will be showed as long text, without 'enters' - 'guild_motd_chars_limit' => 150, // limit of MOTD (message of the day) that is shown later in the game on the guild channel - - // online page - 'online_record' => true, // display players record? - 'online_vocations' => false, // display vocation statistics? - 'online_vocations_images' => false, // display vocation images? - 'online_skulls' => false, // display skull images - 'online_outfit' => true, - 'online_afk' => false, - - // support list page - 'team_style' => 2, // 1/2 (1 - normal table, 2 - in boxes, grouped by group id) - 'team_display_status' => true, - 'team_display_lastlogin' => true, - 'team_display_world' => false, - 'team_display_outfit' => true, - - // bans page - 'bans_per_page' => 20, - - // highscores page - 'highscores_vocation_box' => true, // show 'Choose a vocation' box on the highscores (allowing peoples to sort highscores by vocation)? - 'highscores_vocation' => true, // show player vocation under his nickname? - 'highscores_frags' => false, // show 'Frags' tab (best fraggers on the server)? - 'highscores_balance' => false, // show 'Balance' tab (richest players on the server) - 'highscores_outfit' => true, // show player outfit? - 'highscores_country_box' => false, // doesnt work yet! (not implemented) - 'highscores_groups_hidden' => 3, // this group id and higher won't be shown on the highscores - 'highscores_ids_hidden' => array(0), // this ids of players will be hidden on the highscores (should be ids of samples) - 'highscores_per_page' => 100, // how many records per page on highscores - 'highscores_cache_ttl' => 15, // how often to update highscores from database in minutes (default 15 minutes) - - // characters page - 'characters' => array( // what things to display on character view page (true/false in each option) - 'level' => true, - 'experience' => false, - 'magic_level' => false, - 'balance' => false, - 'marriage_info' => true, // only 0.3 - 'outfit' => true, - 'creation_date' => true, - 'quests' => true, - 'skills' => true, - 'equipment' => true, - 'frags' => false, - 'deleted' => false, // should deleted characters from same account be still listed on the list of characters? When enabled it will show that character is "[DELETED]" - ), - 'quests' => array( - //'Some Quest' => 123, - //'Some Quest Two' => 456, - ), // quests list (displayed in character view), name => storage - 'signature_enabled' => true, - 'signature_type' => 'tibian', // signature engine to use: tibian, mango, gesior - 'signature_cache_time' => 5, // how long to store cached file (in minutes), default 5 minutes - 'signature_browser_cache' => 60, // how long to cache by browser (in minutes), default 1 hour - - // news page - 'news_limit' => 5, // limit of news on the latest news page - 'news_ticker_limit' => 5, // limit of news in tickers (mini news) (0 to disable) - 'news_date_format' => 'j.n.Y', // check php manual date() function for more info about this - 'news_author' => true, // show author of the news - - // gifts/shop system - 'gifts_system' => false, - - // support/system - 'bug_report' => true, // this configurable has no effect, its always enabled - - // forum - 'forum' => 'site', // link to the server forum, set to "site" if you want to use build in forum system, otherwise leave empty if you aren't going to use any forum - 'forum_level_required' => 0, // level required to post, 0 to disable - 'forum_post_interval' => 30, // in seconds - 'forum_posts_per_page' => 20, - 'forum_threads_per_page' => 20, - // uncomment to force use table for forum - //'forum_table_prefix' => 'z_', // what forum mysql table to use, z_ (for gesior old forum) or myaac_ (for myaac) - - // last kills - 'last_kills_limit' => 50, // max. number of deaths shown on the last kills page - - // status, took automatically from config file if empty - 'status_enabled' => true, // you can disable status checking by settings this to "false" - 'status_ip' => '', - 'status_port' => '', - 'status_timeout' => 2.0, // how long to wait for the initial response from the server (default: 2 seconds) - - // how often to connect to server and update status (default: every minute) - // if your status timeout in config.lua is bigger, that it will be used instead - // when server is offline, it will be checked every time web refreshes, ignoring this variable - 'status_interval' => 60, - - // admin panel - 'admin_plugins_manage_enable' => 'yes', // you can disable possibility to upload and uninstall plugins, for security - // enable support for plain php pages in admin panel, for security - // existing pages still will be working, so you need to delete them manually - 'admin_pages_php_enable' => 'no', - 'admin_panel_modules' => 'statistics,web_status,server_status,lastlogin,created,points,coins,balance', // default - statistics,web_status,server_status,lastlogin,created,points,coins,balance - - // other - 'anonymous_usage_statistics' => true, - 'email_lai_sec_interval' => 60, // time in seconds between e-mails to one account from lost account interface, block spam - 'google_analytics_id' => '', // e.g.: UA-XXXXXXX-X - 'experiencetable_columns' => 3, // how many columns to display in experience table page. * experiencetable_rows, 5 = 500 (will show up to 500 level) - 'experiencetable_rows' => 200, // till how many levels in one column - 'date_timezone' => 'Europe/Berlin', // more info at http://php.net/manual/en/timezones.php - 'footer_show_load_time' => true, // display load time of the page in the footer - - 'npc' => array(), - - // character name blocked - 'character_name_blocked' => array( - 'prefix' => array(), - 'names' => array(), - 'words' => array(), - ), - -); diff --git a/index.php b/index.php index a093b9bd..5ead45b9 100644 --- a/index.php +++ b/index.php @@ -56,22 +56,6 @@ if(preg_match("/^(.*)\.(gif|jpg|png|jpeg|tiff|bmp|css|js|less|map|html|zip|rar|g exit; } -if(file_exists(BASE . 'config.local.php')) { - require_once BASE . 'config.local.php'; -} - -ini_set('log_errors', 1); -if(config('env') === 'dev') { - ini_set('display_errors', 1); - ini_set('display_startup_errors', 1); - error_reporting(E_ALL); -} -else { - ini_set('display_errors', 0); - ini_set('display_startup_errors', 0); - error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); -} - if((!isset($config['installed']) || !$config['installed']) && file_exists(BASE . 'install')) { header('Location: ' . BASE_URL . 'install/'); @@ -100,13 +84,11 @@ $twig->addGlobal('status', $status); require_once SYSTEM . 'router.php'; -require SYSTEM . 'migrate.php'; - $hooks->trigger(HOOK_STARTUP); // anonymous usage statistics // sent only when user agrees -if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_statistics']) { +if(setting('core.anonymous_usage_statistics')) { $report_time = 30 * 24 * 60 * 60; // report one time per 30 days $should_report = true; @@ -139,17 +121,16 @@ if(isset($config['anonymous_usage_statistics']) && $config['anonymous_usage_stat } } -if($config['views_counter']) +if(setting('core.views_counter')) require_once SYSTEM . 'counter.php'; -if($config['visitors_counter']) -{ +if(setting('core.visitors_counter')) { require_once SYSTEM . 'libs/visitors.php'; - $visitors = new Visitors($config['visitors_counter_ttl']); + $visitors = new Visitors(setting('core.visitors_counter_ttl')); } // backward support for gesior -if($config['backward_support']) { +if(setting('core.backward_support')) { define('INITIALIZED', true); $SQL = $db; $layout_header = template_header(); @@ -165,7 +146,7 @@ if($config['backward_support']) { $config['site'] = &$config; $config['server'] = &$config['lua']; - $config['site']['shop_system'] = $config['gifts_system']; + $config['site']['shop_system'] = setting('core.gifts_system'); $config['site']['gallery_page'] = true; if(!isset($config['vdarkborder'])) @@ -179,8 +160,9 @@ if($config['backward_support']) { $config['site']['serverinfo_page'] = true; $config['site']['screenshot_page'] = true; - if($config['forum'] != '') - $config['forum_link'] = (strtolower($config['forum']) === 'site' ? getLink('forum') : $config['forum']); + $forumSetting = setting('core.forum'); + if($forumSetting != '') + $config['forum_link'] = (strtolower($forumSetting) === 'site' ? getLink('forum') : $forumSetting); foreach($status as $key => $value) $config['status']['serverStatus_' . $key] = $value; diff --git a/install/includes/schema.sql b/install/includes/schema.sql index 83f4c051..21776dc8 100644 --- a/install/includes/schema.sql +++ b/install/includes/schema.sql @@ -1,4 +1,4 @@ -SET @myaac_database_version = 35; +SET @myaac_database_version = 36; CREATE TABLE `myaac_account_actions` ( @@ -303,6 +303,16 @@ CREATE TABLE `myaac_gallery` INSERT INTO `myaac_gallery` (`id`, `ordering`, `comment`, `image`, `thumb`, `author`) VALUES (NULL, 1, 'Demon', 'images/gallery/demon.jpg', 'images/gallery/demon_thumb.gif', 'MyAAC'); +CREATE TABLE `myaac_settings` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL DEFAULT '', + `key` VARCHAR(255) NOT NULL DEFAULT '', + `value` TEXT NOT NULL, + PRIMARY KEY (`id`), + KEY `key` (`key`) +) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; + CREATE TABLE `myaac_spells` ( `id` INT(11) NOT NULL AUTO_INCREMENT, diff --git a/install/index.php b/install/index.php index 021bd184..22440101 100644 --- a/install/index.php +++ b/install/index.php @@ -12,9 +12,7 @@ require SYSTEM . 'functions.php'; require BASE . 'install/includes/functions.php'; require BASE . 'install/includes/locale.php'; require SYSTEM . 'clients.conf.php'; - -if(file_exists(BASE . 'config.local.php')) - require BASE . 'config.local.php'; +require LIBS . 'settings.php'; // ignore undefined index from Twig autoloader $config['env'] = 'prod'; @@ -91,10 +89,6 @@ if($step == 'database') { break; } } - else if($key == 'mail_admin' && !Validator::email($value)) { - $errors[] = $locale['step_config_mail_admin_error']; - break; - } else if($key == 'timezone' && !in_array($value, DateTimeZone::listIdentifiers())) { $errors[] = $locale['step_config_timezone_error']; break; diff --git a/install/steps/5-database.php b/install/steps/5-database.php index a133f236..5ebe18d9 100644 --- a/install/steps/5-database.php +++ b/install/steps/5-database.php @@ -11,16 +11,12 @@ if(!isset($_SESSION['var_server_path'])) { } if(!$error) { - $content = " 'prod', + ]; + foreach($_SESSION as $key => $value) { if(strpos($key, 'var_') !== false) @@ -32,17 +28,14 @@ if(!$error) { $value .= '/'; } - if($key === 'var_usage') { - $content .= '$config[\'anonymous_usage_statistics\'] = ' . ((int)$value == 1 ? 'true' : 'false') . ';'; - $content .= PHP_EOL; - } - else if(!in_array($key, array('var_account', 'var_account_id', 'var_password', 'var_step', 'var_email', 'var_player_name'), true)) { - $content .= '$config[\'' . str_replace('var_', '', $key) . '\'] = \'' . $value . '\';'; - $content .= PHP_EOL; + if(!in_array($key, ['var_usage', 'var_date_timezone', 'var_client', 'var_account', 'var_account_id', 'var_password', 'var_password_confirm', 'var_step', 'var_email', 'var_player_name'], true)) { + $configToSave[str_replace('var_', '', $key)] = $value; } } } + $configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); + require BASE . 'install/includes/config.php'; if(!$error) { @@ -79,31 +72,17 @@ if(!$error) { 'message' => $locale['loading_spinner'] )); - if(!Validator::email($_SESSION['var_mail_admin'])) { - error($locale['step_config_mail_admin_error']); - $error = true; - } - - $content .= '$config[\'session_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';'; - $content .= PHP_EOL; - $content .= '$config[\'cache_prefix\'] = \'myaac_' . generateRandomString(8, true, false, true, false) . '_\';'; - - $saved = true; - if(!$error) { - $saved = file_put_contents(BASE . 'config.local.php', $content); - } - + $content = ''; + $saved = Settings::saveConfig($configToSave, BASE . 'config.local.php', $content); if($saved) { success($locale['step_database_config_saved']); - if(!$error) { - $_SESSION['saved'] = true; - } + $_SESSION['saved'] = true; } else { $_SESSION['config_content'] = $content; unset($_SESSION['saved']); - $locale['step_database_error_file'] = str_replace('$FILE$', '' . BASE . 'config.local.php', $locale['step_database_error_file']); + $locale['step_database_error_file'] = str_replace('$FILE$', '' . BASE . 'config.php', $locale['step_database_error_file']); error($locale['step_database_error_file'] . '
    '); } diff --git a/install/steps/7-finish.php b/install/steps/7-finish.php index f6e1f6c2..7ab77185 100644 --- a/install/steps/7-finish.php +++ b/install/steps/7-finish.php @@ -116,6 +116,23 @@ else { } } + $settings = Settings::getInstance(); + foreach($_SESSION as $key => $value) { + if (in_array($key, ['var_usage', 'var_date_timezone', 'var_client'])) { + if ($key == 'var_usage') { + $key = 'anonymous_usage_statistics'; + $value = ((int)$value == 1 ? 'true' : 'false'); + } elseif ($key == 'var_date_timezone') { + $key = 'date_timezone'; + } elseif ($key == 'var_client') { + $key = 'client'; + } + + $settings->updateInDatabase('core', $key, $value); + } + } + success('Settings saved.'); + $twig->display('install.installer.html.twig', array( 'url' => 'tools/7-finish.php', 'message' => $locale['importing_spinner'] diff --git a/install/tools/7-finish.php b/install/tools/7-finish.php index 3d98b570..22772714 100644 --- a/install/tools/7-finish.php +++ b/install/tools/7-finish.php @@ -11,11 +11,11 @@ ini_set('max_execution_time', 300); ob_implicit_flush(); ob_end_flush(); header('X-Accel-Buffering: no'); - +/* if(isset($config['installed']) && $config['installed'] && !isset($_SESSION['saved'])) { warning($locale['already_installed']); return; -} +}*/ require SYSTEM . 'init.php'; @@ -51,13 +51,6 @@ DataLoader::load(); // update config.highscores_ids_hidden require_once SYSTEM . 'migrations/20.php'; -$database_migration_20 = true; -$content = ''; -if(!databaseMigration20($content)) { - $locale['step_database_error_file'] = str_replace('$FILE$', '' . BASE . 'config.local.php', $locale['step_database_error_file']); - warning($locale['step_database_error_file'] . '
    - '); -} // add z_polls tables require_once SYSTEM . 'migrations/22.php'; diff --git a/login.php b/login.php index 3ab0b5e9..6fb43f38 100644 --- a/login.php +++ b/login.php @@ -1,7 +1,5 @@ 'database_hash', + //'language', + 'visitors_counter', + 'visitors_counter_ttl', + 'views_counter', + 'outfit_images_url', + 'outfit_images_wrong_looktypes', + 'item_images_url', + 'account_country', + 'towns', + 'quests', + 'character_samples', + 'character_towns', + 'characters_per_account', + 'characters_search_limit', + 'news_author', + 'news_limit', + 'news_ticker_limit', + 'news_date_format', + 'highscores_groups_hidden', + 'highscores_ids_hidden', + 'online_record', + 'online_vocations', + 'online_vocations_images', + 'online_skulls', + 'online_outfit', + 'online_afk', + 'team_display_outfit' => 'team_outfit', + 'team_display_status' => 'team_status', + 'team_display_world' => 'team_world', + 'team_display_lastlogin' => 'team_lastlogin', + 'last_kills_limit', + 'multiworld', + 'forum', + 'signature_enabled', + 'signature_type', + 'signature_cache_time', + 'signature_browser_cache', + 'gifts_system', + 'status_enabled', + 'status_ip', + 'status_port', + 'mail_enabled', + 'account_login_by_email', + 'account_login_by_email_fallback', + 'account_mail_verify', + 'account_create_character_create', + 'account_change_character_name', + 'account_change_character_name_points' => 'account_change_character_name_price', + 'account_change_character_sex', + 'account_change_character_sex_points' => 'account_change_character_name_price', +]; + +foreach ($deprecatedConfig as $key => $value) { + config( + [ + (is_string($key) ? $key : $value), + setting('core.'.$value) + ] + ); + + //var_dump($settings['core.'.$value]['value']); +} + +$deprecatedConfigCharacters = [ + 'level', + 'experience', + 'magic_level', + 'balance', + 'marriage_info' => 'marriage', + 'outfit', + 'creation_date', + 'quests', + 'skills', + 'equipment', + 'frags', + 'deleted', +]; + +$tmp = []; +foreach ($deprecatedConfigCharacters as $key => $value) { + $tmp[(is_string($key) ? $key : $value)] = setting('core.characters_'.$value); +} + +config(['characters', $tmp]); +unset($tmp); diff --git a/system/database.php b/system/database.php index 41be6c87..e50e8568 100644 --- a/system/database.php +++ b/system/database.php @@ -9,7 +9,11 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -if(!isset($config['database_user'][0], $config['database_password'][0], $config['database_name'][0])) +if (!isset($config['database_overwrite'])) { + $config['database_overwrite'] = false; +} + +if(!$config['database_overwrite'] && !isset($config['database_user'][0], $config['database_password'][0], $config['database_name'][0])) { if(isset($config['lua']['sqlType'])) {// tfs 0.3 if(isset($config['lua']['mysqlHost'])) {// tfs 0.2 @@ -116,4 +120,4 @@ catch(PDOException $error) { '
  • MySQL is not configured propertly in config.lua.
  • ' . '
  • MySQL server is not running.
  • ' . '' . $error->getMessage()); -} \ No newline at end of file +} diff --git a/system/functions.php b/system/functions.php index feb24360..11803c69 100644 --- a/system/functions.php +++ b/system/functions.php @@ -32,55 +32,49 @@ function message($message, $type, $return) return true; } function success($message, $return = false) { - return message($message, 'success', $return); + return message($message, 'success', $return); } function warning($message, $return = false) { - return message($message, 'warning', $return); + return message($message, 'warning', $return); } function note($message, $return = false) { - return message($message, 'note', $return); + return message($message, 'note', $return); } function error($message, $return = false) { - return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); + return message($message, ((defined('MYAAC_INSTALL') || defined('MYAAC_ADMIN')) ? 'danger' : 'error'), $return); } -function longToIp($ip) +function longToIp($ip): string { $exp = explode(".", long2ip($ip)); return $exp[3].".".$exp[2].".".$exp[1].".".$exp[0]; } -function generateLink($url, $name, $blank = false) { +function generateLink($url, $name, $blank = false): string { return '' . $name . ''; } -function getFullLink($page, $name, $blank = false) { +function getFullLink($page, $name, $blank = false): string { return generateLink(getLink($page), $name, $blank); } -function getLink($page, $action = null) -{ - global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . $page . ($action ? '/' . $action : ''); +function getLink($page, $action = null): string { + return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . $page . ($action ? '/' . $action : ''); } -function internalLayoutLink($page, $action = null) {return getLink($page, $action);} - -function getForumThreadLink($thread_id, $page = NULL) -{ - global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : ''); +function internalLayoutLink($page, $action = null): string { + return getLink($page, $action); } -function getForumBoardLink($board_id, $page = NULL) -{ - global $config; - return BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : ''); +function getForumThreadLink($thread_id, $page = NULL): string { + return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/thread/' . (int)$thread_id . (isset($page) ? '/' . $page : ''); } -function getPlayerLink($name, $generate = true) -{ - global $config; +function getForumBoardLink($board_id, $page = NULL): string { + return BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'forum/board/' . (int)$board_id . (isset($page) ? '/' . $page : ''); +} +function getPlayerLink($name, $generate = true): string +{ if(is_numeric($name)) { $player = new OTS_Player(); @@ -89,25 +83,23 @@ function getPlayerLink($name, $generate = true) $name = $player->getName(); } - $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'characters/' . urlencode($name); + $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'characters/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); } -function getMonsterLink($name, $generate = true) +function getMonsterLink($name, $generate = true): string { - global $config; - - $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'creatures/' . urlencode($name); + $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'creatures/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); } -function getHouseLink($name, $generate = true) +function getHouseLink($name, $generate = true): string { - global $db, $config; + global $db; if(is_numeric($name)) { @@ -117,16 +109,14 @@ function getHouseLink($name, $generate = true) $name = $house->fetchColumn(); } - $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'houses/' . urlencode($name); + $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); } -function getGuildLink($name, $generate = true) +function getGuildLink($name, $generate = true): string { - global $config; - if(is_numeric($name)) { $name = getGuildNameById($name); if ($name === false) { @@ -134,7 +124,7 @@ function getGuildLink($name, $generate = true) } } - $url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . 'guilds/' . urlencode($name); + $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name); if(!$generate) return $url; return generateLink($url, $name); @@ -180,7 +170,7 @@ function getItemRarity($chance) { return ''; } -function getFlagImage($country) +function getFlagImage($country): string { if(!isset($country[0])) return ''; @@ -202,7 +192,7 @@ function getFlagImage($country) * @param mixed $v Variable to check. * @return bool Value boolean status. */ -function getBoolean($v) +function getBoolean($v): bool { if(is_bool($v)) { return $v; @@ -225,7 +215,7 @@ function getBoolean($v) * @param bool $special Should special characters by used? * @return string Generated string. */ -function generateRandomString($length, $lowCase = true, $upCase = false, $numeric = false, $special = false) +function generateRandomString($length, $lowCase = true, $upCase = false, $numeric = false, $special = false): string { $characters = ''; if($lowCase) @@ -465,7 +455,7 @@ function tickers() * Types: head_start, head_end, body_start, body_end, center_top * */ -function template_place_holder($type) +function template_place_holder($type): string { global $twig, $template_place_holders; $ret = ''; @@ -489,7 +479,7 @@ function template_place_holder($type) /** * Returns content to be used by templates. */ -function template_header($is_admin = false) +function template_header($is_admin = false): string { global $title_full, $config, $twig; $charset = isset($config['charset']) ? $config['charset'] : 'utf-8'; @@ -506,29 +496,32 @@ function template_header($is_admin = false) /** * Returns footer content to be used by templates. */ -function template_footer() +function template_footer(): string { - global $config, $views_counter; + global $views_counter; $ret = ''; - if(admin()) + if(admin()) { $ret .= generateLink(ADMIN_URL, 'Admin Panel', true); + } - if($config['visitors_counter']) - { + if(setting('core.visitors_counter')) { global $visitors; $amount = $visitors->getAmountVisitors(); $ret .= '
    Currently there ' . ($amount > 1 ? 'are' : 'is') . ' ' . $amount . ' visitor' . ($amount > 1 ? 's' : '') . '.'; } - if($config['views_counter']) + if(setting('core.views_counter')) { $ret .= '
    Page has been viewed ' . $views_counter . ' times.'; + } - if(config('footer_show_load_time')) { + if(setting('core.footer_load_time')) { $ret .= '
    Load time: ' . round(microtime(true) - START_TIME, 4) . ' seconds.'; } - if(isset($config['footer'][0])) - $ret .= '
    ' . $config['footer']; + $settingFooter = setting('core.footer'); + if(isset($settingFooter[0])) { + $ret .= '
    ' . $settingFooter; + } // please respect my work and help spreading the word, thanks! return $ret . '
    ' . base64_decode('UG93ZXJlZCBieSA8YSBocmVmPSJodHRwOi8vbXktYWFjLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPk15QUFDLjwvYT4='); @@ -536,8 +529,8 @@ function template_footer() function template_ga_code() { - global $config, $twig; - if(!isset($config['google_analytics_id'][0])) + global $twig; + if(!isset(setting('core.google_analytics_id')[0])) return ''; return $twig->render('google_analytics.html.twig'); @@ -822,7 +815,7 @@ function getWorldName($id) /** * Mailing users. - * $config['mail_enabled'] have to be enabled. + * Mailing has to be enabled in settings (in Admin Panel). * * @param string $to Recipient email address. * @param string $subject Subject of the message. @@ -834,8 +827,9 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) { global $mailer, $config; - if (!config('mail_enabled')) { - log_append('mailer-error.log', '_mail() function has been used, but config.mail_enabled is disabled.'); + if (!setting('core.mail_enabled')) { + log_append('mailer-error.log', '_mail() function has been used, but Mail Support is disabled.'); + return false; } if(!$mailer) @@ -847,47 +841,60 @@ function _mail($to, $subject, $body, $altBody = '', $add_html_tags = true) $mailer->clearAllRecipients(); } - $signature_html = ''; - if(isset($config['mail_signature']['html'])) - $signature_html = $config['mail_signature']['html']; - + $signature_html = setting('core.mail_signature_html'); if($add_html_tags && isset($body[0])) $tmp_body = '' . $body . '

    ' . $signature_html . ''; else $tmp_body = $body . '

    ' . $signature_html; - if($config['smtp_enabled']) + define('MAIL_MAIL', 0); + define('MAIL_SMTP', 1); + + $mailOption = setting('core.mail_option'); + if($mailOption == MAIL_SMTP) { $mailer->isSMTP(); - $mailer->Host = $config['smtp_host']; - $mailer->Port = (int)$config['smtp_port']; - $mailer->SMTPAuth = $config['smtp_auth']; - $mailer->Username = $config['smtp_user']; - $mailer->Password = $config['smtp_pass']; - $mailer->SMTPSecure = isset($config['smtp_secure']) ? $config['smtp_secure'] : ''; + $mailer->Host = setting('core.smtp_host'); + $mailer->Port = setting('core.smtp_port'); + $mailer->SMTPAuth = setting('core.smtp_auth'); + $mailer->Username = setting('core.smtp_user'); + $mailer->Password = setting('core.smtp_pass'); + + define('SMTP_SECURITY_NONE', 0); + define('SMTP_SECURITY_SSL', 1); + define('SMTP_SECURITY_TLS', 2); + + $security = setting('core.smtp_security'); + + $tmp = ''; + if ($security === SMTP_SECURITY_SSL) { + $tmp = 'ssl'; + } + else if ($security == SMTP_SECURITY_TLS) { + $tmp = 'tls'; + } + + $mailer->SMTPSecure = $tmp; } else { $mailer->isMail(); } $mailer->isHTML(isset($body[0]) > 0); - $mailer->From = $config['mail_address']; - $mailer->Sender = $config['mail_address']; + $mailer->From = setting('core.mail_address'); + $mailer->Sender = setting('core.mail_address'); $mailer->CharSet = 'utf-8'; $mailer->FromName = $config['lua']['serverName']; $mailer->Subject = $subject; $mailer->addAddress($to); $mailer->Body = $tmp_body; - if(config('smtp_debug')) { + if(setting('core.smtp_debug')) { $mailer->SMTPDebug = 2; $mailer->Debugoutput = 'echo'; } - $signature_plain = ''; - if(isset($config['mail_signature']['plain'])) - $signature_plain = $config['mail_signature']['plain']; - + $signature_plain = setting('core.mail_signature_plain'); if(isset($altBody[0])) { $mailer->AltBody = $altBody . $signature_plain; } @@ -1047,7 +1054,7 @@ function getTopPlayers($limit = 5) { $deleted = 'deletion'; $is_tfs10 = $db->hasTable('players_online'); - $players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . config('highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll(); + $players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . setting('core.highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll(); if($is_tfs10) { foreach($players as &$player) { @@ -1100,6 +1107,9 @@ function deleteDirectory($dir, $ignore = array(), $contentOnly = false) { function config($key) { global $config; if (is_array($key)) { + if (is_null($key[1])) { + unset($config[$key[0]]); + } return $config[$key[0]] = $key[1]; } @@ -1115,6 +1125,21 @@ function configLua($key) { return @$config['lua'][$key]; } +function setting($key) +{ + $settings = Settings::getInstance(); + + if (is_array($key)) { + if (is_null($key[1])) { + unset($settings[$key[0]]); + } + + return $settings[$key[0]] = $key[1]; + } + + return $settings[$key]['value']; +} + function clearCache() { require_once LIBS . 'news.php'; @@ -1483,8 +1508,8 @@ function right($str, $length) { } function getCreatureImgPath($creature){ - $creature_path = config('creatures_images_url'); - $creature_gfx_name = trim(strtolower($creature)) . config('creatures_images_extension'); + $creature_path = config('monsters_images_url'); + $creature_gfx_name = trim(strtolower($creature)) . config('monsters_images_extension'); if (!file_exists($creature_path . $creature_gfx_name)) { $creature_gfx_name = str_replace(" ", "", $creature_gfx_name); if (file_exists($creature_path . $creature_gfx_name)) { diff --git a/system/init.php b/system/init.php index 2815f791..c941f4d4 100644 --- a/system/init.php +++ b/system/init.php @@ -9,11 +9,6 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -// load configuration -require_once BASE . 'config.php'; -if(file_exists(BASE . 'config.local.php')) // user customizations - require BASE . 'config.local.php'; - if(!isset($config['installed']) || !$config['installed']) { throw new RuntimeException('MyAAC has not been installed yet or there was error during installation. Please install again.'); } @@ -22,13 +17,16 @@ if(config('env') === 'dev') { require SYSTEM . 'exception.php'; } -date_default_timezone_set($config['date_timezone']); +if(empty($config['server_path'])) { + throw new RuntimeException('Server Path has been not set. Go to config.php and set it.'); +} + // take care of trailing slash at the end if($config['server_path'][strlen($config['server_path']) - 1] !== '/') $config['server_path'] .= '/'; // enable gzip compression if supported by the browser -if($config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler')) +if(isset($config['gzip_output']) && $config['gzip_output'] && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && function_exists('ob_gzhandler')) ob_start('ob_gzhandler'); // cache @@ -96,9 +94,6 @@ if(isset($config['lua']['servername'])) if(isset($config['lua']['houserentperiod'])) $config['lua']['houseRentPeriod'] = $config['lua']['houserentperiod']; -if($config['item_images_url'][strlen($config['item_images_url']) - 1] !== '/') - $config['item_images_url'] .= '/'; - // localize data/ directory based on data directory set in config.lua foreach(array('dataDirectory', 'data_directory', 'datadir') as $key) { if(!isset($config['lua'][$key][0])) { @@ -122,51 +117,34 @@ if(!isset($foundValue)) { $config['data_path'] = $foundValue; unset($foundValue); -// new config values for compatibility -if(!isset($config['highscores_ids_hidden']) || count($config['highscores_ids_hidden']) == 0) { - $config['highscores_ids_hidden'] = array(0); -} - -$config['account_create_character_create'] = config('account_create_character_create') && (!config('mail_enabled') || !config('account_mail_verify')); - // POT require_once SYSTEM . 'libs/pot/OTS.php'; $ots = POT::getInstance(); require_once SYSTEM . 'database.php'; +// execute migrations +require SYSTEM . 'migrate.php'; + +// settings +require_once LIBS . 'Settings.php'; +$settings = Settings::getInstance(); +$settings->load(); + +// deprecated config values +require_once SYSTEM . 'compat/config.php'; + +date_default_timezone_set(setting('core.date_timezone')); + +$config['account_create_character_create'] = config('account_create_character_create') && (!setting('core.mail_enabled') || !config('account_mail_verify')); + +$settingsItemImagesURL = setting('core.item_images_url'); +if($settingsItemImagesURL[strlen($settingsItemImagesURL) - 1] !== '/') { + setting(['core.item_images_url', $settingsItemImagesURL . '/']); +} + define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name')); define('USE_ACCOUNT_NUMBER', $db->hasColumn('accounts', 'number')); define('USE_ACCOUNT_SALT', $db->hasColumn('accounts', 'salt')); -// load vocation names -$tmp = ''; -if($cache->enabled() && $cache->fetch('vocations', $tmp)) { - $config['vocations'] = unserialize($tmp); -} -else { - if(!class_exists('DOMDocument')) { - throw new RuntimeException('Please install PHP xml extension. MyAAC will not work without it.'); - } - - $vocations = new DOMDocument(); - $file = $config['data_path'] . 'XML/vocations.xml'; - if(!@file_exists($file)) - $file = $config['data_path'] . 'vocations.xml'; - - if(!$vocations->load($file)) - throw new RuntimeException('ERROR: Cannot load vocations.xml - the file is malformed. Check the file with xml syntax validator.'); - - $config['vocations'] = array(); - foreach($vocations->getElementsByTagName('vocation') as $vocation) { - $id = $vocation->getAttribute('id'); - $config['vocations'][$id] = $vocation->getAttribute('name'); - } - - if($cache->enabled()) { - $cache->set('vocations', serialize($config['vocations']), 120); - } -} -unset($tmp, $id, $vocation); - require LIBS . 'Towns.php'; Towns::load(); diff --git a/system/libs/CreateCharacter.php b/system/libs/CreateCharacter.php index 60909c0f..8ec6993a 100644 --- a/system/libs/CreateCharacter.php +++ b/system/libs/CreateCharacter.php @@ -18,8 +18,8 @@ class CreateCharacter */ public function checkName($name, &$errors) { - $minLength = config('character_name_min_length'); - $maxLength = config('character_name_max_length'); + $minLength = setting('core.create_character_name_min_length'); + $maxLength = setting('core.create_character_name_max_length'); if(empty($name)) { $errors['name'] = 'Please enter a name for your character!'; @@ -149,7 +149,7 @@ class CreateCharacter $char_to_copy = new OTS_Player(); $char_to_copy->find($char_to_copy_name); if(!$char_to_copy->isLoaded()) - $errors[] = 'Wrong characters configuration. Try again or contact with admin. ADMIN: Edit file config.php and set valid characters to copy names. Character to copy: '.$char_to_copy_name.' doesn\'t exist.'; + $errors[] = 'Wrong characters configuration. Try again or contact with admin. ADMIN: Go to Admin Panel -> Settings -> Create Character and set valid characters to copy names. Character to copy: '.$char_to_copy_name.' doesn\'t exist.'; } if(!empty($errors)) { @@ -195,7 +195,7 @@ class CreateCharacter for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) { $value = 10; - if (config('use_character_sample_skills')) { + if (setting('core.use_character_sample_skills')) { $value = $char_to_copy->getSkill($skill); } @@ -239,14 +239,14 @@ class CreateCharacter } if($db->hasTable('player_skills')) { - for($i=0; $i<7; $i++) { + for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) { $value = 10; - if (config('use_character_sample_skills')) { - $value = $char_to_copy->getSkill($i); + if (setting('core.use_character_sample_skills')) { + $value = $char_to_copy->getSkill($skill); } - $skillExists = $db->query('SELECT `skillid` FROM `player_skills` WHERE `player_id` = ' . $player->getId() . ' AND `skillid` = ' . $i); + $skillExists = $db->query('SELECT `skillid` FROM `player_skills` WHERE `player_id` = ' . $player->getId() . ' AND `skillid` = ' . $skill); if($skillExists->rowCount() <= 0) { - $db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$i.', ' . $value . ', 0)'); + $db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$skill.', ' . $value . ', 0)'); } } } diff --git a/system/libs/Settings.php b/system/libs/Settings.php new file mode 100644 index 00000000..7e1d07f5 --- /dev/null +++ b/system/libs/Settings.php @@ -0,0 +1,598 @@ + + * @copyright 2020 MyAAC + * @link https://my-aac.org + */ + +class Settings implements ArrayAccess +{ + static private $instance; + private $settingsFile = []; + private $settingsDatabase = []; + private $cache = []; + private $valuesAsked = []; + private $errors = []; + + /** + * @return Settings + */ + public static function getInstance(): Settings + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + public function load() + { + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $tmp = ''; + if ($cache->fetch('settings', $tmp)) { + $this->settingsDatabase = unserialize($tmp); + return; + } + } + + global $db; + $settings = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'settings`'); + + if($settings->rowCount() > 0) { + foreach ($settings->fetchAll(PDO::FETCH_ASSOC) as $setting) { + $this->settingsDatabase[$setting['name']][$setting['key']] = $setting['value']; + } + } + + if ($cache->enabled()) { + $cache->set('settings', serialize($this->settingsDatabase), 600); + } + } + + public function save($pluginName, $values) { + global $db; + + if (!isset($this->settingsFile[$pluginName])) { + throw new RuntimeException('Error on save settings: plugin does not exist'); + } + + $settings = $this->settingsFile[$pluginName]; + if (isset($settings['callbacks']['beforeSave'])) { + if (!$settings['callbacks']['beforeSave']($settings, $values)) { + return false; + } + } + + $this->errors = []; + $db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($pluginName) . ';'); + foreach ($values as $key => $value) { + $errorMessage = ''; + if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) { + $this->errors[] = $errorMessage; + continue; + } + + try { + $db->insert(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key, 'value' => $value]); + } catch (PDOException $error) { + $this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage(); + } + } + + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $cache->delete('settings'); + } + + return true; + } + + public function updateInDatabase($pluginName, $key, $value) + { + global $db; + $db->update(TABLE_PREFIX . 'settings', ['value' => $value], ['name' => $pluginName, 'key' => $key]); + } + + public function deleteFromDatabase($pluginName, $key = null) + { + global $db; + + if (!isset($key)) { + $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName], -1); + } + else { + $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key]); + } + } + + public static function display($plugin, $settings): array + { + global $db; + + $query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($plugin) . ';'; + $query = $db->query($query); + + $settingsDb = []; + if($query->rowCount() > 0) { + foreach($query->fetchAll(PDO::FETCH_ASSOC) as $value) { + $settingsDb[$value['key']] = $value['value']; + } + } + + $config = []; + require BASE . 'config.local.php'; + + foreach ($config as $key => $value) { + if (is_bool($value)) { + $settingsDb[$key] = $value ? 'true' : 'false'; + } + else { + $settingsDb[$key] = (string)$value; + } + } + + $javascript = ''; + ob_start(); + ?> + +
    + ' . ($type ? 'Yes' : 'No') . ' '; + }; + + $i = 0; + $j = 0; + foreach($settings as $key => $setting) { + if ($setting['type'] === 'category') { + if ($j++ !== 0) { // close previous category + echo '
    '; + } + ?> +
    + '; + } + ?> +

    + + + + + + + + + + + + + + + + + +
    NameValueDescription
    + '; + } + + else if($setting['type'] === 'textarea') { + $value = ($settingsDb[$key] ?? ($setting['default'] ?? '')); + $valueWithSpaces = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value))); + $rows = count($valueWithSpaces); + if ($rows < 2) { + $rows = 2; // always min 2 rows for textarea + } + echo ''; + } + + else if ($setting['type'] === 'options') { + if ($setting['options'] === '$templates') { + $templates = []; + foreach (get_templates() as $value) { + $templates[$value] = $value; + } + + $setting['options'] = $templates; + } + + else if($setting['options'] === '$clients') { + $clients = []; + foreach((array)config('clients') as $client) { + + $client_version = (string)($client / 100); + if(strpos($client_version, '.') === false) + $client_version .= '.0'; + + $clients[$client] = $client_version; + } + + $setting['options'] = $clients; + } + else if ($setting['options'] == '$timezones') { + $timezones = []; + foreach (DateTimeZone::listIdentifiers() as $value) { + $timezones[$value] = $value; + } + + $setting['options'] = $timezones; + } + + else { + if (is_string($setting['options'])) { + $setting['options'] = explode(',', $setting['options']); + foreach ($setting['options'] as &$option) { + $option = trim($option); + } + } + } + + echo ''; + } + + if (!isset($setting['hidden']) || !$setting['hidden']) { + ?> + +
    '; + echo 'Default: '; + + if ($setting['type'] === 'boolean') { + echo ($setting['default'] ? 'Yes' : 'No'); + } + else if (in_array($setting['type'], ['text', 'number', 'email', 'password', 'textarea'])) { + echo $setting['default']; + } + else if ($setting['type'] === 'options') { + if (!empty($setting['default'])) { + echo $setting['options'][$setting['default']]; + } + } + ?>
    +
    +
    +
    + + ob_get_clean(), 'script' => $javascript]; + } + + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + throw new \RuntimeException("Settings: You cannot set empty offset with value: $value!"); + } + + $this->loadPlugin($offset); + + $pluginKeyName = $this->valuesAsked['pluginKeyName']; + $key = $this->valuesAsked['key']; + + // remove whole plugin settings + if (!isset($value)) { + $this->offsetUnset($offset); + $this->deleteFromDatabase($pluginKeyName, $key); + return; + } + + $this->settingsDatabase[$pluginKeyName][$key] = $value; + $this->updateInDatabase($pluginKeyName, $key, $value); + } + + #[\ReturnTypeWillChange] + public function offsetExists($offset): bool + { + $this->loadPlugin($offset); + + $pluginKeyName = $this->valuesAsked['pluginKeyName']; + $key = $this->valuesAsked['key']; + + // remove specified plugin settings (all) + if(is_null($key)) { + return isset($this->settingsDatabase[$offset]); + } + + return isset($this->settingsDatabase[$pluginKeyName][$key]); + } + + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + $this->loadPlugin($offset); + + $pluginKeyName = $this->valuesAsked['pluginKeyName']; + $key = $this->valuesAsked['key']; + + if (isset($this->cache[$offset])) { + unset($this->cache[$offset]); + } + + // remove specified plugin settings (all) + if(!isset($key)) { + unset($this->settingsFile[$pluginKeyName]); + unset($this->settingsDatabase[$pluginKeyName]); + $this->deleteFromDatabase($pluginKeyName); + return; + } + + unset($this->settingsFile[$pluginKeyName]['settings'][$key]); + unset($this->settingsDatabase[$pluginKeyName][$key]); + $this->deleteFromDatabase($pluginKeyName, $key); + } + + /** + * Get settings + * Usage: $setting['plugin_name.key'] + * Example: $settings['shop_system.paypal_email'] + * + * @param mixed $offset + * @return array|mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + // try cache hit + if(isset($this->cache[$offset])) { + return $this->cache[$offset]; + } + + $this->loadPlugin($offset); + + $pluginKeyName = $this->valuesAsked['pluginKeyName']; + $key = $this->valuesAsked['key']; + + // return specified plugin settings (all) + if(!isset($key)) { + if (!isset($this->settingsFile[$pluginKeyName]['settings'])) { + throw new RuntimeException('Unknown plugin settings: ' . $pluginKeyName); + } + return $this->settingsFile[$pluginKeyName]['settings']; + } + + $ret = []; + if(isset($this->settingsFile[$pluginKeyName]['settings'][$key])) { + $ret = $this->settingsFile[$pluginKeyName]['settings'][$key]; + } + + if(isset($this->settingsDatabase[$pluginKeyName][$key])) { + $value = $this->settingsDatabase[$pluginKeyName][$key]; + + $ret['value'] = $value; + } + else { + $ret['value'] = $this->settingsFile[$pluginKeyName]['settings'][$key]['default']; + } + + if(isset($ret['type'])) { + switch($ret['type']) { + case 'boolean': + $ret['value'] = getBoolean($ret['value']); + break; + + case 'number': + if (!isset($ret['step']) || (int)$ret['step'] == 1) { + $ret['value'] = (int)$ret['value']; + } + break; + + default: + break; + } + } + + if (isset($ret['callbacks']['get'])) { + $ret['value'] = $ret['callbacks']['get']($ret['value']); + } + + $this->cache[$offset] = $ret; + return $ret; + } + + private function updateValuesAsked($offset) + { + $pluginKeyName = $offset; + if (strpos($offset, '.')) { + $explode = explode('.', $offset, 2); + + $pluginKeyName = $explode[0]; + $key = $explode[1]; + + $this->valuesAsked = ['pluginKeyName' => $pluginKeyName, 'key' => $key]; + } + else { + $this->valuesAsked = ['pluginKeyName' => $pluginKeyName, 'key' => null]; + } + } + + private function loadPlugin($offset) + { + $this->updateValuesAsked($offset); + + $pluginKeyName = $this->valuesAsked['pluginKeyName']; + $key = $this->valuesAsked['key']; + + if (!isset($this->settingsFile[$pluginKeyName])) { + if ($pluginKeyName === 'core') { + $settingsFilePath = SYSTEM . 'settings.php'; + } else { + //$pluginSettings = Plugins::getPluginSettings($pluginKeyName); + $settings = Plugins::getAllPluginsSettings(); + if (!isset($settings[$pluginKeyName])) { + warning("Setting $pluginKeyName does not exist or does not have settings defined."); + return; + } + + $settingsFilePath = BASE . $settings[$pluginKeyName]['settingsFilename']; + } + + if (!file_exists($settingsFilePath)) { + throw new \RuntimeException('Failed to load settings file for plugin: ' . $pluginKeyName); + } + + $this->settingsFile[$pluginKeyName] = require $settingsFilePath; + } + } + + public static function saveConfig($config, $filename, &$content = '') + { + $content = " $value) { + $content .= "\$config['$key'] = "; + $content .= var_export($value, true); + $content .= ';' . PHP_EOL; + } + + $success = file_put_contents($filename, $content); + + // we saved new config.php, need to revalidate cache (only if opcache is enabled) + if (function_exists('opcache_invalidate')) { + opcache_invalidate($filename); + } + + return $success; + } + + public static function testDatabaseConnection($config): bool + { + $user = null; + $password = null; + $dns = []; + + if( isset($config['database_name']) ) { + $dns[] = 'dbname=' . $config['database_name']; + } + + if( isset($config['database_user']) ) { + $user = $config['database_user']; + } + + if( isset($config['database_password']) ) { + $password = $config['database_password']; + } + + if( isset($config['database_host']) ) { + $dns[] = 'host=' . $config['database_host']; + } + + if( isset($config['database_port']) ) { + $dns[] = 'port=' . $config['database_port']; + } + + try { + $connectionTest = new PDO('mysql:' . implode(';', $dns), $user, $password); + $connectionTest->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } + catch(PDOException $error) { + error('MySQL connection failed. Settings has been reverted.'); + error($error->getMessage()); + return false; + } + + return true; + } + + public function getErrors() { + return $this->errors; + } +} diff --git a/system/libs/forum.php b/system/libs/forum.php index 4922a9c3..c7f303f7 100644 --- a/system/libs/forum.php +++ b/system/libs/forum.php @@ -10,7 +10,7 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -$configForumTablePrefix = config('forum_table_prefix'); +$configForumTablePrefix = setting('core.forum_table_prefix'); if(null !== $configForumTablePrefix && !empty(trim($configForumTablePrefix))) { if(!in_array($configForumTablePrefix, array('myaac_', 'z_'))) { throw new RuntimeException('Invalid value for forum_table_prefix in config.php. Can be only: "myaac_" or "z_".'); @@ -47,7 +47,7 @@ class Forum return $db->query( 'SELECT `id` FROM `players` WHERE `account_id` = ' . $db->quote($account->getId()) . - ' AND `level` >= ' . $db->quote($config['forum_level_required']) . + ' AND `level` >= ' . $db->quote(setting('core.forum_level_required')) . ' LIMIT 1')->rowCount() > 0; } diff --git a/system/libs/plugins.php b/system/libs/plugins.php index c3b548dc..c2b8f594 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -168,6 +168,36 @@ class Plugins { return $hooks; } + public static function getAllPluginsSettings() + { + $cache = Cache::getInstance(); + if ($cache->enabled()) { + $tmp = ''; + if ($cache->fetch('plugins_settings', $tmp)) { + return unserialize($tmp); + } + } + + $settings = []; + foreach (self::getAllPluginsJson() as $plugin) { + if (isset($plugin['settings'])) { + $settingsFile = require BASE . $plugin['settings']; + if (!isset($settingsFile['key'])) { + warning("Settings file for plugin - {$plugin['name']} does not contain 'key' field"); + continue; + } + + $settings[$settingsFile['key']] = ['pluginFilename' => $plugin['filename'], 'settingsFilename' => $plugin['settings']]; + } + } + + if ($cache->enabled()) { + $cache->set('plugins_settings', serialize($settings), 600); // cache for 10 minutes + } + + return $settings; + } + public static function getAllPluginsJson($disabled = false) { $cache = Cache::getInstance(); @@ -180,30 +210,66 @@ class Plugins { $plugins = []; foreach (get_plugins($disabled) as $filename) { - $string = file_get_contents(PLUGINS . $filename . '.json'); - $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.'; + $plugin = self::getPluginJson($filename); + + if (!$plugin) { continue; } + $plugin['filename'] = $filename; $plugins[] = $plugin; } if ($cache->enabled()) { - $cache->set('plugins', serialize($plugins), 600); + $cache->set('plugins', serialize($plugins), 600); // cache for 10 minutes } return $plugins; } - public static function install($file) { + public static function getPluginSettings($filename) + { + $plugin_json = self::getPluginJson($filename); + if (!$plugin_json) { + return false; + } + + if (!isset($plugin_json['settings']) || !file_exists(BASE . $plugin_json['settings'])) { + return false; + } + + return $plugin_json['settings']; + } + + public static function getPluginJson($filename = null) + { + if(!isset($filename)) { + return self::$plugin_json; + } + + $pathToPlugin = PLUGINS . $filename . '.json'; + if (!file_exists($pathToPlugin)) { + self::$warnings[] = "Cannot load $filename.json. File doesn't exist."; + return false; + } + + $string = file_get_contents($pathToPlugin); + $plugin_json = json_decode($string, true); + if ($plugin_json == null) { + self::$warnings[] = "Cannot load $filename.json. File might be not a valid json code."; + return false; + } + + if (isset($plugin_json['enabled']) && !getBoolean($plugin_json['enabled'])) { + self::$warnings[] = 'Skipping ' . $filename . '... The plugin is disabled.'; + return false; + } + + return $plugin_json; + } + + public static function install($file): bool + { global $db; if(!\class_exists('ZipArchive')) { @@ -242,6 +308,12 @@ class Plugins { return false; } + $pluginFilename = str_replace('.json', '', basename($json_file)); + if (self::existDisabled($pluginFilename)) { + success('The plugin already existed, but was disabled. It has been enabled again and will be now reinstalled.'); + self::enable($pluginFilename); + } + $string = file_get_contents($file_name); $plugin_json = json_decode($string, true); self::$plugin_json = $plugin_json; @@ -442,13 +514,23 @@ class Plugins { return false; } - public static function enable($pluginFileName): bool + public static function isEnabled($pluginFileName): bool { + $filenameJson = $pluginFileName . '.json'; + return !is_file(PLUGINS . 'disabled.' . $filenameJson) && is_file(PLUGINS . $filenameJson); + } + + public static function existDisabled($pluginFileName): bool + { + $filenameJson = $pluginFileName . '.json'; + return is_file(PLUGINS . 'disabled.' . $filenameJson); + } + + public static function enable($pluginFileName): bool { return self::enableDisable($pluginFileName, true); } - public static function disable($pluginFileName): bool - { + public static function disable($pluginFileName): bool { return self::enableDisable($pluginFileName, false); } @@ -526,7 +608,8 @@ class Plugins { return false; } - public static function is_installed($plugin_name, $version) { + public static function is_installed($plugin_name, $version): bool + { $filename = BASE . 'plugins/' . $plugin_name . '.json'; if(!file_exists($filename)) { return false; @@ -534,7 +617,7 @@ class Plugins { $string = file_get_contents($filename); $plugin_info = json_decode($string, true); - if($plugin_info == false) { + if(!$plugin_info) { return false; } @@ -557,10 +640,6 @@ class Plugins { return self::$error; } - public static function getPluginJson() { - return self::$plugin_json; - } - /** * Install menus * Helper function for plugins diff --git a/system/libs/pot/OTS_ServerInfo.php b/system/libs/pot/OTS_ServerInfo.php index 30a81f7b..eebe0d2e 100644 --- a/system/libs/pot/OTS_ServerInfo.php +++ b/system/libs/pot/OTS_ServerInfo.php @@ -14,7 +14,7 @@ /** * Various server status querying methods. - * + * * @package POT * @property-read OTS_InfoRespond|bool $status status() method wrapper. * @property-read OTS_ServerStatus|bool $info Full info() method wrapper. @@ -23,21 +23,21 @@ class OTS_ServerInfo { /** * Server address. - * + * * @var string */ private $server; /** * Connection port. - * + * * @var int */ private $port; /** * Creates handler for new server. - * + * * @param string $server Server IP/domain. * @param int $port OTServ port. */ @@ -49,7 +49,7 @@ class OTS_ServerInfo /** * Sends packet to server. - * + * * @param OTS_Buffer|string $packet Buffer to send. * @return OTS_Buffer|null Respond buffer (null if server is offline). * @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream. @@ -57,7 +57,7 @@ class OTS_ServerInfo private function send(OTS_Buffer $packet) { // connects to server - $socket = @fsockopen($this->server, $this->port, $error, $message, config('status_timeout')); + $socket = @fsockopen($this->server, $this->port, $error, $message, setting('core.status_timeout')); // if connected then checking statistics if($socket) @@ -75,7 +75,7 @@ class OTS_ServerInfo // reads respond //$data = stream_get_contents($socket); - $data = ''; + $data = ''; while (!feof($socket)) $data .= fgets($socket, 1024); @@ -97,11 +97,11 @@ class OTS_ServerInfo /** * Queries server status. - * + * *

    * Sends 'info' packet to OTS server and return output. Returns {@link OTS_InfoRespond OTS_InfoRespond} (wrapper for XML data) with results or false if server is online. *

    - * + * * @return OTS_InfoRespond|bool Respond content document (false when server is offline). * @throws DOMException On DOM operation error. * @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream. @@ -135,11 +135,11 @@ class OTS_ServerInfo /** * Queries server information. - * + * *

    * This method uses binary info protocol. It provides more infromation then {@link OTS_Toolbox::serverStatus() XML way}. *

    - * + * * @param int $flags Requested info flags. * @return OTS_ServerStatus|bool Respond content document (false when server is offline). * @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream. @@ -169,11 +169,11 @@ class OTS_ServerInfo /** * Checks player online status. - * + * *

    * This method uses binary info protocol. *

    - * + * * @param string $name Player name. * @return bool True if player is online, false if player or server is online. * @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream. @@ -204,7 +204,7 @@ class OTS_ServerInfo /** * Magic PHP5 method. - * + * * @param string $name Property name. * @param mixed $value Property value. * @throws OutOfBoundsException For non-supported properties. diff --git a/system/libs/validator.php b/system/libs/validator.php index eb958583..e7bffd6a 100644 --- a/system/libs/validator.php +++ b/system/libs/validator.php @@ -117,7 +117,7 @@ class Validator return false; } - if(config('account_mail_block_plus_sign')) { + if(setting('core.account_mail_block_plus_sign')) { $explode = explode('@', $email); if(isset($explode[0]) && (strpos($explode[0],'+') !== false)) { self::$lastError = 'Please do not use plus (+) sign in your e-mail.'; @@ -180,15 +180,16 @@ class Validator return false; } - $minLength = config('character_name_min_length'); - $maxLength = config('character_name_max_length'); - // installer doesn't know config.php yet // that's why we need to ignore the nulls - if(is_null($minLength) || is_null($maxLength)) { + if(defined('MYAAC_INSTALL')) { $minLength = 4; $maxLength = 21; } + else { + $minLength = setting('core.create_character_name_min_length'); + $maxLength = setting('core.create_character_name_max_length'); + } $length = strlen($name); if($length < $minLength) @@ -221,16 +222,6 @@ class Validator return false; } - $npcCheck = config('character_name_npc_check'); - if ($npcCheck) { - require_once LIBS . 'npc.php'; - NPCS::load(); - if(NPCS::$npcs && in_array(strtolower($name), NPCS::$npcs)) { - self::$lastError = "Invalid name format. Do not use NPC Names"; - return false; - } - } - return true; } @@ -246,14 +237,9 @@ class Validator global $db, $config; $name_lower = strtolower($name); - $custom_first_words_blocked = []; - if (isset($config['character_name_blocked']['prefix']) && $config['character_name_blocked']['prefix']) { - $custom_first_words_blocked = $config['character_name_blocked']['prefix']; - } - $first_words_blocked = array_merge($custom_first_words_blocked, array('admin ', 'administrator ', 'gm ', 'cm ', 'god ','tutor ', "'", '-')); - foreach($first_words_blocked as $word) - { + $first_words_blocked = array_merge(["'", '-'], setting('core.create_character_name_blocked_prefix')); + foreach($first_words_blocked as $word) { if($word == substr($name_lower, 0, strlen($word))) { self::$lastError = 'Your name contains blocked words.'; return false; @@ -275,8 +261,7 @@ class Validator return false; } - if(preg_match('/ {2,}/', $name)) - { + if(preg_match('/ {2,}/', $name)) { self::$lastError = 'Invalid character name format. Use only A-Z and numbers 0-9 and no double spaces.'; return false; } @@ -286,26 +271,16 @@ class Validator return false; } - $custom_names_blocked = []; - if (isset($config['character_name_blocked']['names']) && $config['character_name_blocked']['names']) { - $custom_names_blocked = $config['character_name_blocked']['names']; - } - $names_blocked = array_merge($custom_names_blocked, array('admin', 'administrator', 'gm', 'cm', 'god', 'tutor')); - foreach($names_blocked as $word) - { + $names_blocked = setting('core.create_character_name_blocked_names'); + foreach($names_blocked as $word) { if($word == $name_lower) { self::$lastError = 'Your name contains blocked words.'; return false; } } - $custom_words_blocked = []; - if (isset($config['character_name_blocked']['words']) && $config['character_name_blocked']['words']) { - $custom_words_blocked = $config['character_name_blocked']['words']; - } - $words_blocked = array_merge($custom_words_blocked, array('admin', 'administrator', 'gamemaster', 'game master', 'game-master', "game'master", '--', "''","' ", " '", '- ', ' -', "-'", "'-", 'fuck', 'sux', 'suck', 'noob', 'tutor')); - foreach($words_blocked as $word) - { + $words_blocked = array_merge(['--', "''","' ", " '", '- ', ' -', "-'", "'-"], setting('core.create_character_name_blocked_words')); + foreach($words_blocked as $word) { if(!(strpos($name_lower, $word) === false)) { self::$lastError = 'Your name contains illegal words.'; return false; @@ -321,7 +296,7 @@ class Validator } } - //check if was namelocked previously + // check if was namelocked previously if($db->hasTable('player_namelocks') && $db->hasColumn('player_namelocks', 'name')) { $namelock = $db->query('SELECT `player_id` FROM `player_namelocks` WHERE `name` = ' . $db->quote($name)); if($namelock->rowCount() > 0) { @@ -330,39 +305,41 @@ class Validator } } - $monsters = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'monsters` WHERE `name` LIKE ' . $db->quote($name_lower)); - if($monsters->rowCount() > 0) { - self::$lastError = 'Your name cannot contains monster name.'; - return false; - } - - $spells_name = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'spells` WHERE `name` LIKE ' . $db->quote($name_lower)); - if($spells_name->rowCount() > 0) { - self::$lastError = 'Your name cannot contains spell name.'; - return false; - } - - $spells_words = $db->query('SELECT `words` FROM `' . TABLE_PREFIX . 'spells` WHERE `words` = ' . $db->quote($name_lower)); - if($spells_words->rowCount() > 0) { - self::$lastError = 'Your name cannot contains spell name.'; - return false; - } - - if(isset($config['npc'])) - { - if(in_array($name_lower, $config['npc'])) { - self::$lastError = 'Your name cannot contains NPC name.'; + $monstersCheck = setting('core.create_character_name_monsters_check'); + if ($monstersCheck) { + $monsters = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'monsters` WHERE `name` LIKE ' . $db->quote($name_lower)); + if ($monsters->rowCount() > 0) { + self::$lastError = 'Your name cannot contains monster name.'; return false; } } - $npcCheck = config('character_name_npc_check'); + $spellsCheck = setting('core.create_character_name_spells_check'); + if ($spellsCheck) { + $spells_name = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'spells` WHERE `name` LIKE ' . $db->quote($name_lower)); + if ($spells_name->rowCount() > 0) { + self::$lastError = 'Your name cannot contains spell name.'; + return false; + } + + $spells_words = $db->query('SELECT `words` FROM `' . TABLE_PREFIX . 'spells` WHERE `words` = ' . $db->quote($name_lower)); + if ($spells_words->rowCount() > 0) { + self::$lastError = 'Your name cannot contains spell name.'; + return false; + } + } + + $npcCheck = setting('core.create_character_name_npc_check'); if ($npcCheck) { require_once LIBS . 'npc.php'; NPCS::load(); - if(NPCS::$npcs && in_array($name_lower, NPCS::$npcs)) { - self::$lastError = "Invalid name format. Do not use NPC Names"; - return false; + if(NPCS::$npcs) { + foreach (NPCs::$npcs as $npc) { + if(strpos($name_lower, $npc) !== false) { + self::$lastError = 'Your name cannot contains NPC name.'; + return false; + } + } } } diff --git a/system/migrations/20.php b/system/migrations/20.php index d0012fde..b0e09471 100644 --- a/system/migrations/20.php +++ b/system/migrations/20.php @@ -1,47 +1,15 @@ query("SELECT `id` FROM `players` WHERE (`name` = " . $db->quote("Rook Sample") . " OR `name` = " . $db->quote("Sorcerer Sample") . " OR `name` = " . $db->quote("Druid Sample") . " OR `name` = " . $db->quote("Paladin Sample") . " OR `name` = " . $db->quote("Knight Sample") . " OR `name` = " . $db->quote("Account Manager") . ") ORDER BY `id`;"); + +$highscores_ignored_ids = array(); +if($query->rowCount() > 0) { + foreach($query->fetchAll() as $result) + $highscores_ignored_ids[] = $result['id']; +} +else { + $highscores_ignored_ids[] = 0; } -function databaseMigration20(&$content = '') { - global $db; - - $config_file = BASE . 'config.local.php'; - if(!is_writable($config_file)) { // we can't do anything, just ignore - return false; - } - - $content_of_file = trim(file_get_contents($config_file)); - if(strpos($content_of_file, 'highscores_ids_hidden') !== false) { // already present - return true; - } - - $query = $db->query("SELECT `id` FROM `players` WHERE (`name` = " . $db->quote("Rook Sample") . " OR `name` = " . $db->quote("Sorcerer Sample") . " OR `name` = " . $db->quote("Druid Sample") . " OR `name` = " . $db->quote("Paladin Sample") . " OR `name` = " . $db->quote("Knight Sample") . " OR `name` = " . $db->quote("Account Manager") . ") ORDER BY `id`;"); - - $highscores_ignored_ids = array(); - if($query->rowCount() > 0) { - foreach($query->fetchAll() as $result) - $highscores_ignored_ids[] = $result['id']; - } - else { - $highscores_ignored_ids[] = 0; - } - - $php_on_end = substr($content_of_file, -2, 2) == '?>'; - $content = PHP_EOL; - if($php_on_end) { - $content .= ''; - } - - file_put_contents($config_file, $content, FILE_APPEND); - return true; -} +$settings = Settings::getInstance(); +$settings->updateInDatabase('core', 'highscores_ids_hidden', implode(', ', $highscores_ignored_ids)); diff --git a/system/migrations/36.php b/system/migrations/36.php new file mode 100644 index 00000000..d88e9d28 --- /dev/null +++ b/system/migrations/36.php @@ -0,0 +1,14 @@ +hasTable(TABLE_PREFIX . 'settings')) { + $db->exec("CREATE TABLE `" . TABLE_PREFIX . "settings` + ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL DEFAULT '', + `key` VARCHAR(255) NOT NULL DEFAULT '', + `value` TEXT NOT NULL, + PRIMARY KEY (`id`), + KEY `key` (`key`) + ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8;"); +} diff --git a/system/pages/account/change_name.php b/system/pages/account/change_name.php index 48b6bb4d..ef82b9ad 100644 --- a/system/pages/account/change_name.php +++ b/system/pages/account/change_name.php @@ -19,17 +19,17 @@ if(!$logged) { $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'])) +if((!setting('core.account_change_character_name'))) echo 'Changing character name for premium points is disabled on this server.'; else { - $points = $account_logged->getCustomField('premium_points'); + $points = $account_logged->getCustomField(setting('core.donate_column')); if(isset($_POST['changenamesave']) && $_POST['changenamesave'] == 1) { - if($points < $config['account_change_character_name_points']) - $errors[] = 'You need ' . $config['account_change_character_name_points'] . ' premium points to change name. You have '.$points.' premium points.'; + if($points < setting('core.account_change_character_name_price')) + $errors[] = 'You need ' . setting('core.account_change_character_name_price') . ' premium points to change name. You have '.$points.' premium points.'; - $minLength = config('character_name_min_length'); - $maxLength = config('character_name_max_length'); + $minLength = setting('core.create_character_name_min_length'); + $maxLength = setting('core.create_character_name_max_length'); if(empty($errors) && empty($name)) $errors[] = 'Please enter a new name for your character!'; @@ -86,7 +86,7 @@ else } } - $account_logged->setCustomField("premium_points", $points - $config['account_change_character_name_points']); + $account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_name_price')); $account_logged->logAction('Changed name from ' . $old_name . ' to ' . $player->getName() . '.'); $twig->display('success.html.twig', array( 'title' => 'Character Name Changed', diff --git a/system/pages/account/change_password.php b/system/pages/account/change_password.php index deef3602..95e15159 100644 --- a/system/pages/account/change_password.php +++ b/system/pages/account/change_password.php @@ -69,7 +69,7 @@ else $account_logged->logAction('Account password changed.'); $message = ''; - if($config['mail_enabled'] && $config['send_mail_when_change_password']) { + if(setting('core.mail_enabled') && setting('core.mail_send_when_change_password')) { $mailBody = $twig->render('mail.password_changed.html.twig', array( 'new_password' => $org_pass, 'ip' => get_browser_real_ip(), @@ -89,4 +89,4 @@ else )); setSession('password', $new_password); } -} \ No newline at end of file +} diff --git a/system/pages/account/change_sex.php b/system/pages/account/change_sex.php index 2f944564..7e43b6ff 100644 --- a/system/pages/account/change_sex.php +++ b/system/pages/account/change_sex.php @@ -20,14 +20,14 @@ if(!$logged) { $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; -if((!$config['account_change_character_sex'])) +if((!setting('core.account_change_character_sex'))) echo 'You cant change your character sex'; else { - $points = $account_logged->getCustomField('premium_points'); + $points = $account_logged->getCustomField(setting('core.donate_column')); if(isset($_POST['changesexsave']) && $_POST['changesexsave'] == 1) { - if($points < $config['account_change_character_sex_points']) - $errors[] = 'You need ' . $config['account_change_character_sex_points'] . ' premium points to change sex. You have '.$points.' premium points.'; + if($points < setting('core.account_change_character_sex_price')) + $errors[] = 'You need ' . setting('core.account_change_character_sex_price') . ' premium points to change sex. You have '.$points.' premium points.'; if(empty($errors) && !isset($config['genders'][$new_sex])) { $errors[] = 'This sex is invalid.'; @@ -66,7 +66,7 @@ else $new_sex_str = $config['genders'][$new_sex]; $player->save(); - $account_logged->setCustomField("premium_points", $points - $config['account_change_character_name_points']); + $account_logged->setCustomField(setting('core.donate_column'), $points - setting('core.account_change_character_name_price')); $account_logged->logAction('Changed sex on character ' . $player->getName() . ' from ' . $old_sex_str . ' to ' . $new_sex_str . '.'); $twig->display('success.html.twig', array( 'title' => 'Character Sex Changed', diff --git a/system/pages/account/create.php b/system/pages/account/create.php index dd7c7713..2aa7c544 100644 --- a/system/pages/account/create.php +++ b/system/pages/account/create.php @@ -219,7 +219,7 @@ if($save) $tmp_account = (USE_ACCOUNT_NAME ? $account_name : $account_id); } - if($config['mail_enabled'] && $config['account_mail_verify']) + if(setting('core.mail_enabled') && $config['account_mail_verify']) { $hash = md5(generateRandomString(16, true, true) . $email); $new_account->setCustomField('email_hash', $hash); @@ -294,7 +294,7 @@ if($save) 'custom_buttons' => config('account_create_character_create') ? '' : null )); - if($config['mail_enabled'] && $config['account_welcome_mail']) + if(setting('core.mail_enabled') && $config['account_welcome_mail']) { $mailBody = $twig->render('account.welcome_mail.html.twig', array( 'account' => $tmp_account @@ -313,7 +313,7 @@ if($save) } $country_recognized = null; -if($config['account_country_recognize']) { +if(setting('core.account_country_recognize')) { $country_session = getSession('country'); if($country_session !== false) { // get from session $country_recognized = $country_session; diff --git a/system/pages/account/lost.php b/system/pages/account/lost.php index 3ea0957e..664cee9c 100644 --- a/system/pages/account/lost.php +++ b/system/pages/account/lost.php @@ -11,7 +11,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Lost Account Interface'; -if(!$config['mail_enabled']) +if(!setting('core.mail_enabled')) { echo 'Account maker is not configured to send e-mails, you can\'t use Lost Account Interface. Contact with admin to get help.'; return; @@ -59,7 +59,7 @@ elseif($action == 'step1' && $action_type == 'email') $minutesleft = floor($insec / 60); $secondsleft = $insec - ($minutesleft * 60); $timeleft = $minutesleft.' minutes '.$secondsleft.' seconds'; - echo 'Account of selected character ('.$nick.') received e-mail in last '.ceil($config['email_lai_sec_interval'] / 60).' minutes. You must wait '.$timeleft.' before you can use Lost Account Interface again.'; + echo 'Account of selected character ('.$nick.') received e-mail in last '.ceil(setting('core.mail_lost_account_interval') / 60).' minutes. You must wait '.$timeleft.' before you can use Lost Account Interface again.'; } } else @@ -104,7 +104,7 @@ elseif($action == 'sendcode') if(_mail($account_mail, $config['lua']['serverName'].' - Recover your account', $mailBody)) { $account->setCustomField('email_code', $newcode); - $account->setCustomField('email_next', (time() + $config['email_lai_sec_interval'])); + $account->setCustomField('email_next', (time() + setting('core.mail_lost_account_interval'))); echo '
    Details about steps required to recover your account has been sent to ' . $account_mail . '. You should receive this email within 15 minutes. Please check your inbox/spam directory.'; } else @@ -122,7 +122,7 @@ elseif($action == 'sendcode') $minutesleft = floor($insec / 60); $secondsleft = $insec - ($minutesleft * 60); $timeleft = $minutesleft.' minutes '.$secondsleft.' seconds'; - echo 'Account of selected character ('.$nick.') received e-mail in last '.ceil($config['email_lai_sec_interval'] / 60).' minutes. You must wait '.$timeleft.' before you can use Lost Account Interface again.'; + echo 'Account of selected character ('.$nick.') received e-mail in last '.ceil(setting('core.mail_lost_account_interval') / 60).' minutes. You must wait '.$timeleft.' before you can use Lost Account Interface again.'; } } else diff --git a/system/pages/account/manage.php b/system/pages/account/manage.php index b2af3cee..c4a8402a 100644 --- a/system/pages/account/manage.php +++ b/system/pages/account/manage.php @@ -35,7 +35,7 @@ if(empty($recovery_key)) $account_registered = 'No'; else { - if($config['generate_new_reckey'] && $config['mail_enabled']) + if(setting('core.account_generate_new_reckey') && setting('core.mail_enabled')) $account_registered = 'Yes ( Buy new Recovery Key )'; else $account_registered = 'Yes'; diff --git a/system/pages/account/register.php b/system/pages/account/register.php index 1d16d905..f33f0b17 100644 --- a/system/pages/account/register.php +++ b/system/pages/account/register.php @@ -31,7 +31,7 @@ if(isset($_POST['registeraccountsave']) && $_POST['registeraccountsave'] == "1") $account_logged->logAction('Generated recovery key.'); $message = ''; - if($config['mail_enabled'] && $config['send_mail_when_generate_reckey']) + if(setting('core.mail_enabled') && setting('core.mail_send_when_generate_reckey')) { $mailBody = $twig->render('mail.account.register.html.twig', array( 'recovery_key' => $new_rec_key diff --git a/system/pages/account/register_new.php b/system/pages/account/register_new.php index fb2e8ea3..04e8bf33 100644 --- a/system/pages/account/register_new.php +++ b/system/pages/account/register_new.php @@ -21,18 +21,18 @@ if(isset($_POST['reg_password'])) $reg_password = encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $_POST['reg_password']); $reckey = $account_logged->getCustomField('key'); -if((!$config['generate_new_reckey'] || !$config['mail_enabled']) || empty($reckey)) { +if((!setting('core.account_generate_new_reckey') || !setting('core.mail_enabled')) || empty($reckey)) { $errors[] = 'You cant get new recovery key.'; $twig->display('error_box.html.twig', array('errors' => $errors)); } else { - $points = $account_logged->getCustomField('premium_points'); + $points = $account_logged->getCustomField(setting('core.donate_column')); if(isset($_POST['registeraccountsave']) && $_POST['registeraccountsave'] == '1') { if($reg_password == $account_logged->getPassword()) { - if($points >= $config['generate_new_reckey_price']) + if($points >= setting('core.account_generate_new_reckey_price')) { $show_form = false; $new_rec_key = generateRandomString(10, false, true, true); @@ -43,10 +43,10 @@ else if(_mail($account_logged->getEMail(), $config['lua']['serverName']." - new recovery key", $mailBody)) { - $account_logged->setCustomField("key", $new_rec_key); - $account_logged->setCustomField("premium_points", $account_logged->getCustomField("premium_points") - $config['generate_new_reckey_price']); - $account_logged->logAction('Generated new recovery key for ' . $config['generate_new_reckey_price'] . ' premium points.'); - $message = '
    Your recovery key were send on email address '.$account_logged->getEMail().' for '.$config['generate_new_reckey_price'].' premium points.'; + $account_logged->setCustomField('key', $new_rec_key); + $account_logged->setCustomField(setting('core.donate_column'), $account_logged->getCustomField(setting('core.donate_column')) - setting('core.account_generate_new_reckey_price')); + $account_logged->logAction('Generated new recovery key for ' . setting('core.account_generate_new_reckey_price') . ' premium points.'); + $message = '
    Your recovery key were send on email address '.$account_logged->getEMail().' for '.setting('core.account_generate_new_reckey_price').' premium points.'; } else $message = '

    An error occurred while sending email ( '.$account_logged->getEMail().' ) with recovery key! Recovery key not changed. Try again later. For Admin: More info can be found in system/logs/mailer-error.log

    '; @@ -57,7 +57,7 @@ else )); } else - $errors[] = 'You need '.$config['generate_new_reckey_price'].' premium points to generate new recovery key. You have '.$points.' premium points.'; + $errors[] = 'You need ' . setting('core.account_generate_new_reckey_price') . ' premium points to generate new recovery key. You have '.$points.' premium points.'; } else $errors[] = 'Wrong password to account.'; diff --git a/system/pages/characters.php b/system/pages/characters.php index 13f88f05..62cb2759 100644 --- a/system/pages/characters.php +++ b/system/pages/characters.php @@ -340,8 +340,8 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil } // signature - if($config['signature_enabled']) { - $signature_url = BASE_URL . ($config['friendly_urls'] ? '' : 'index.php/') . urlencode($player->getName()) . '.png'; + if(setting('core.signature_enabled')) { + $signature_url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . urlencode($player->getName()) . '.png'; } $hidden = $player->isHidden(); diff --git a/system/pages/creatures.php b/system/pages/creatures.php index f87b6f28..9e472738 100644 --- a/system/pages/creatures.php +++ b/system/pages/creatures.php @@ -14,7 +14,7 @@ $title = 'Creatures'; if (empty($_REQUEST['name'])) { // display list of monsters - $preview = config('creatures_images_preview'); + $preview = config('monsters_images_preview'); $creatures = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 '.(empty($_REQUEST['boss']) ? '': 'AND `rewardboss` = 1').' ORDER BY name asc')->fetchAll(); if ($preview) { @@ -62,7 +62,7 @@ if (isset($creature['name'])) { $item['name'] = getItemNameById($item['id']); $item['rarity_chance'] = round($item['chance'] / 1000, 2); $item['rarity'] = getItemRarity($item['chance']); - $item['tooltip'] = ucfirst($item['name']) . '
    Chance: ' . $item['rarity'] . (config('creatures_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
    Max count: ' . $item['count']; + $item['tooltip'] = ucfirst($item['name']) . '
    Chance: ' . $item['rarity'] . (config('monsters_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
    Max count: ' . $item['count']; } $creature['loot'] = isset($loot) ? $loot : null; diff --git a/system/pages/experience_table.php b/system/pages/experience_table.php index d8ed39dc..e45b7714 100644 --- a/system/pages/experience_table.php +++ b/system/pages/experience_table.php @@ -11,9 +11,9 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Experience Table'; $experience = array(); -$columns = $config['experiencetable_columns']; +$columns = setting('core.experience_table_columns'); for($i = 0; $i < $columns; $i++) { - for($level = $i * $config['experiencetable_rows'] + 1; $level < $i * $config['experiencetable_rows'] + ($config['experiencetable_rows'] + 1); $level++) { + for($level = $i * setting('core.experience_table_rows') + 1; $level < $i * setting('core.experience_table_rows') + (setting('core.experience_table_rows') + 1); $level++) { $experience[$level] = OTS_Toolbox::experienceForLevel($level); } } diff --git a/system/pages/forum.php b/system/pages/forum.php index 5c9688a6..e5b68ed0 100644 --- a/system/pages/forum.php +++ b/system/pages/forum.php @@ -10,7 +10,11 @@ */ defined('MYAAC') or exit; -require __DIR__ . '/forum/base.php'; +$ret = require __DIR__ . '/forum/base.php'; +if ($ret === false) { + return; +} + require __DIR__ . '/forum/admin.php'; $errors = []; diff --git a/system/pages/forum/base.php b/system/pages/forum/base.php index 57ae6d17..de449692 100644 --- a/system/pages/forum/base.php +++ b/system/pages/forum/base.php @@ -11,22 +11,24 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Forum'; -if(strtolower($config['forum']) != 'site') { - if($config['forum'] != '') { - header('Location: ' . $config['forum']); +require_once LIBS . 'forum.php'; + +$forumSetting = setting('core.forum'); +if(strtolower($forumSetting) != 'site') { + if($forumSetting != '') { + header('Location: ' . $forumSetting); exit; } echo 'Forum is disabled on this site.'; - return; + return false; } if(!$logged) { echo 'You are not logged in. Log in to post on the forum.

    '; + return false; } -require_once LIBS . 'forum.php'; - $sections = array(); foreach(getForumBoards() as $section) { $sections[$section['id']] = array( diff --git a/system/pages/forum/edit_post.php b/system/pages/forum/edit_post.php index 2df443a0..539ca7e0 100644 --- a/system/pages/forum/edit_post.php +++ b/system/pages/forum/edit_post.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} if(Forum::canPost($account_logged)) { @@ -75,7 +78,7 @@ if(Forum::canPost($account_logged)) $char_id = $thread['author_guid']; $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `author_guid` = ".(int) $char_id.", `post_text` = ".$db->quote($text).", `post_topic` = ".$db->quote($post_topic).", `post_smile` = ".$smile.", `post_html` = ".$html.", `last_edit_aid` = ".(int) $account_logged->getId().",`edit_date` = ".time()." WHERE `id` = ".(int) $thread['id']); $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`post_date` <= ".$thread['post_date']." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['first_post'])->fetch(); - $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; + $_page = (int) ceil($post_page['posts_count'] / setting('core.forum_threads_per_page')) - 1; header('Location: ' . getForumThreadLink($thread['first_post'], $_page)); echo '
    Thank you for editing post.
    GO BACK TO LAST THREAD'; } @@ -117,6 +120,6 @@ if(Forum::canPost($account_logged)) } } else { - $errors[] = "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."; + $errors[] = "Your account is banned, deleted or you don't have any player with level " . setting('core.forum_level_required') . " on your account. You can't post."; displayErrorBoxWithBackButton($errors, getLink('forum')); } diff --git a/system/pages/forum/move_thread.php b/system/pages/forum/move_thread.php index 3c01a13e..45d14683 100644 --- a/system/pages/forum/move_thread.php +++ b/system/pages/forum/move_thread.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} if(!Forum::isModerator()) { echo 'You are not logged in or you are not moderator.'; diff --git a/system/pages/forum/new_post.php b/system/pages/forum/new_post.php index d4b605c6..dd027984 100644 --- a/system/pages/forum/new_post.php +++ b/system/pages/forum/new_post.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} if(!$logged) { $extra_url = ''; @@ -81,8 +84,8 @@ if(Forum::canPost($account_logged)) { $query = $query->fetch(); $last_post = $query['post_date']; } - if($last_post+$config['forum_post_interval']-time() > 0 && !Forum::isModerator()) - $errors[] = 'You can post one time per '.$config['forum_post_interval'].' seconds. Next post after '.($last_post+$config['forum_post_interval']-time()).' second(s).'; + if($last_post+setting('core.forum_post_interval')-time() > 0 && !Forum::isModerator()) + $errors[] = 'You can post one time per ' . setting('core.forum_post_interval') . ' seconds. Next post after '.($last_post + setting('core.forum_post_interval')-time()).' second(s).'; } if(count($errors) == 0) { @@ -90,7 +93,7 @@ if(Forum::canPost($account_logged)) { Forum::add_post($thread['id'], $thread['section'], $account_logged->getId(), $char_id, $text, $post_topic, $smile, $html); $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `replies`=`replies`+1, `last_post`=".time()." WHERE `id` = ".$thread_id); $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`post_date` <= ".time()." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread['id'])->fetch(); - $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; + $_page = (int) ceil($post_page['posts_count'] / setting('core.forum_threads_per_page')) - 1; header('Location: ' . getForumThreadLink($thread_id, $_page)); echo '
    Thank you for posting.
    GO BACK TO LAST THREAD'; } @@ -131,7 +134,7 @@ if(Forum::canPost($account_logged)) { } } else { - $errors[] = "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."; + $errors[] = "Your account is banned, deleted or you don't have any player with level " . setting('core.forum_level_required') . " on your account. You can't post."; displayErrorBoxWithBackButton($errors, getLink('forum')); } diff --git a/system/pages/forum/new_thread.php b/system/pages/forum/new_thread.php index b864c448..9dfe82a1 100644 --- a/system/pages/forum/new_thread.php +++ b/system/pages/forum/new_thread.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + 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(); @@ -67,8 +70,8 @@ if(Forum::canPost($account_logged)) { $last_post = $query['post_date']; } - if ($last_post + config('forum_post_interval') - time() > 0 && !Forum::isModerator()) - $errors[] = 'You can post one time per ' . config('forum_post_interval') . ' seconds. Next post after ' . ($last_post + config('forum_post_interval') - time()) . ' second(s).'; + if ($last_post + setting('core.forum_post_interval') - time() > 0 && !Forum::isModerator()) + $errors[] = 'You can post one time per ' . setting('core.forum_post_interval') . ' seconds. Next post after ' . ($last_post + setting('core.forum_post_interval') - time()) . ' second(s).'; } if (count($errors) == 0) { @@ -113,6 +116,6 @@ if(Forum::canPost($account_logged)) { } } else { - $errors[] = '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.'; + $errors[] = 'Your account is banned, deleted or you don\'t have any player with level '.setting('core.forum_level_required').' on your account. You can\'t post.'; displayErrorBoxWithBackButton($errors, getLink('forum')); } diff --git a/system/pages/forum/remove_post.php b/system/pages/forum/remove_post.php index a1e13338..c3f2d46f 100644 --- a/system/pages/forum/remove_post.php +++ b/system/pages/forum/remove_post.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} if(Forum::isModerator()) { $id = (int) $_REQUEST['id']; @@ -23,7 +26,7 @@ if(Forum::isModerator()) { } else { $post_page = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`id` < ".$id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $post['first_post'])->fetch(); - $_page = (int) ceil($post_page['posts_count'] / $config['forum_threads_per_page']) - 1; + $_page = (int) ceil($post_page['posts_count'] / setting('core.forum_threads_per_page')) - 1; $db->query("DELETE FROM `" . FORUM_TABLE_PREFIX . "forum` WHERE `id` = ".$post['id']); header('Location: ' . getForumThreadLink($post['first_post'], (int) $_page)); } diff --git a/system/pages/forum/show_board.php b/system/pages/forum/show_board.php index d3dcd0d5..4e37984c 100644 --- a/system/pages/forum/show_board.php +++ b/system/pages/forum/show_board.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} $links_to_pages = ''; $section_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null; @@ -29,7 +32,7 @@ if(!Forum::hasAccess($section_id)) { $_page = (int) (isset($_REQUEST['page']) ? $_REQUEST['page'] : 0); $threads_count = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS threads_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".(int) $section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id`")->fetch(); -for($i = 0; $i < $threads_count['threads_count'] / $config['forum_threads_per_page']; $i++) { +for($i = 0; $i < $threads_count['threads_count'] / setting('core.forum_threads_per_page'); $i++) { if($i != $_page) $links_to_pages .= ''.($i + 1).' '; else @@ -44,7 +47,7 @@ if(!$sections[$section_id]['closed'] || Forum::isModerator()) { } echo '

    Page: '.$links_to_pages.'
    '; -$last_threads = $db->query("SELECT `players`.`id` as `player_id`, `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`last_post`, `" . FORUM_TABLE_PREFIX . "forum`.`replies`, `" . FORUM_TABLE_PREFIX . "forum`.`views`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".$section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id` ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`last_post` DESC LIMIT ".$config['forum_threads_per_page']." OFFSET ".($_page * $config['forum_threads_per_page']))->fetchAll(); +$last_threads = $db->query("SELECT `players`.`id` as `player_id`, `players`.`name`, `" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`id`, `" . FORUM_TABLE_PREFIX . "forum`.`last_post`, `" . FORUM_TABLE_PREFIX . "forum`.`replies`, `" . FORUM_TABLE_PREFIX . "forum`.`views`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`section` = ".$section_id." AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = `" . FORUM_TABLE_PREFIX . "forum`.`id` ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`last_post` DESC LIMIT ".setting('core.forum_threads_per_page')." OFFSET ".($_page * setting('core.forum_threads_per_page')))->fetchAll(); if(isset($last_threads[0])) { echo ' diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index dc252560..263683ee 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -10,7 +10,10 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -require __DIR__ . '/base.php'; +$ret = require __DIR__ . '/base.php'; +if ($ret === false) { + return; +} $links_to_pages = ''; $thread_id = (int) $_REQUEST['id']; @@ -30,14 +33,14 @@ if(!Forum::hasAccess($thread_starter['section'])) { } $posts_count = $db->query("SELECT COUNT(`" . FORUM_TABLE_PREFIX . "forum`.`id`) AS posts_count FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".(int) $thread_id)->fetch(); -for($i = 0; $i < $posts_count['posts_count'] / $config['forum_threads_per_page']; $i++) { +for($i = 0; $i < $posts_count['posts_count'] / setting('core.forum_threads_per_page'); $i++) { if($i != $_page) $links_to_pages .= ''.($i + 1).' '; else $links_to_pages .= ''.($i + 1).' '; } -$posts = $db->query("SELECT `players`.`id` as `player_id`, `" . FORUM_TABLE_PREFIX . "forum`.`id`,`" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`section`,`" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` AS `date`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`post_html`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`last_edit_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`edit_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`post_date` LIMIT ".$config['forum_posts_per_page']." OFFSET ".($_page * $config['forum_posts_per_page']))->fetchAll(); +$posts = $db->query("SELECT `players`.`id` as `player_id`, `" . FORUM_TABLE_PREFIX . "forum`.`id`,`" . FORUM_TABLE_PREFIX . "forum`.`first_post`, `" . FORUM_TABLE_PREFIX . "forum`.`section`,`" . FORUM_TABLE_PREFIX . "forum`.`post_text`, `" . FORUM_TABLE_PREFIX . "forum`.`post_topic`, `" . FORUM_TABLE_PREFIX . "forum`.`post_date` AS `date`, `" . FORUM_TABLE_PREFIX . "forum`.`post_smile`, `" . FORUM_TABLE_PREFIX . "forum`.`post_html`, `" . FORUM_TABLE_PREFIX . "forum`.`author_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`author_guid`, `" . FORUM_TABLE_PREFIX . "forum`.`last_edit_aid`, `" . FORUM_TABLE_PREFIX . "forum`.`edit_date` FROM `players`, `" . FORUM_TABLE_PREFIX . "forum` WHERE `players`.`id` = `" . FORUM_TABLE_PREFIX . "forum`.`author_guid` AND `" . FORUM_TABLE_PREFIX . "forum`.`first_post` = ".$thread_id." ORDER BY `" . FORUM_TABLE_PREFIX . "forum`.`post_date` LIMIT " . setting('core.forum_posts_per_page') . " OFFSET ".($_page * setting('core.forum_posts_per_page')))->fetchAll(); if(isset($posts[0]['player_id'])) { $db->query("UPDATE `" . FORUM_TABLE_PREFIX . "forum` SET `views`=`views`+1 WHERE `id` = ".(int) $thread_id); diff --git a/system/pages/highscores.php b/system/pages/highscores.php index dd2efa7b..fe8533c7 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -11,8 +11,8 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Highscores'; -$configHighscoresCountryBox = config('highscores_country_box'); -if(config('account_country') && $configHighscoresCountryBox) +$settingHighscoresCountryBox = setting('core.highscores_country_box'); +if(config('account_country') && $settingHighscoresCountryBox) require SYSTEM . 'countries.conf.php'; $list = $_GET['list'] ?? 'experience'; @@ -25,11 +25,11 @@ if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) { $add_sql = ''; -$configHighscoresVocationBox = config('highscores_vocation_box'); +$settingHighscoresVocationBox = setting('core.highscores_vocation_box'); $configVocations = config('vocations'); $configVocationsAmount = config('vocations_amount'); -if($configHighscoresVocationBox && $vocation !== 'all') +if($settingHighscoresVocationBox && $vocation !== 'all') { foreach($configVocations as $id => $name) { if(strtolower($name) == $vocation) { @@ -99,12 +99,12 @@ else break; case 'frags': - if(config('highscores_frags')) + if(setting('core.highscores_frags')) $skill = SKILL_FRAGS; break; case 'balance': - if(config('highscores_balance')) + if(setting('core.highscores_balance')) $skill = SKILL_BALANCE; break; } @@ -125,9 +125,9 @@ if($db->hasColumn('players', 'deletion')) $outfit_addons = false; $outfit = ''; -$configHighscoresOutfit = config('highscores_outfit'); +$settingHighscoresOutfit = setting('core.highscores_outfit'); -if($configHighscoresOutfit) { +if($settingHighscoresOutfit) { $outfit = ', lookbody, lookfeet, lookhead, looklegs, looktype'; if($db->hasColumn('players', 'lookaddons')) { $outfit .= ', lookaddons'; @@ -135,7 +135,7 @@ if($configHighscoresOutfit) { } } -$configHighscoresPerPage = config('highscores_per_page'); +$configHighscoresPerPage = setting('core.highscores_per_page'); $limit = $configHighscoresPerPage + 1; $needReCache = true; @@ -164,15 +164,15 @@ if (!isset($highscores) || empty($highscores)) { POT::SKILL_FISH => 'skill_fishing', ); - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,vocation' . $promotion . $outfit . ', ' . $skill_ids[$skill] . ' as value FROM accounts,players WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . config('highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY ' . $skill_ids[$skill] . ' DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,vocation' . $promotion . $outfit . ', ' . $skill_ids[$skill] . ' as value FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY ' . $skill_ids[$skill] . ' DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); } else - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',value,level,vocation' . $promotion . $outfit . ' FROM accounts,players,player_skills WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . config('highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_skills.player_id AND player_skills.skillid = ' . $skill . ' AND accounts.id = players.account_id ORDER BY value DESC, count DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',value,level,vocation' . $promotion . $outfit . ' FROM accounts,players,player_skills WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_skills.player_id AND player_skills.skillid = ' . $skill . ' AND accounts.id = players.account_id ORDER BY value DESC, count DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); } else if ($skill == SKILL_FRAGS) // frags { if ($db->hasTable('player_killers')) { $highscores = $db->query('SELECT accounts.country, players.id, players.name' . $online . ',level, vocation' . $promotion . $outfit . ', COUNT(`player_killers`.`player_id`) as value' . ' FROM `accounts`, `players`, `player_killers` ' . - ' WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . config('highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_killers.player_id AND accounts.id = players.account_id' . + ' WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_killers.player_id AND accounts.id = players.account_id' . ' GROUP BY `player_id`' . ' ORDER BY value DESC' . ' LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); @@ -183,9 +183,9 @@ if (!isset($highscores) || empty($highscores)) { FROM `players` p LEFT JOIN `accounts` a ON `a`.`id` = `p`.`account_id` LEFT JOIN `player_deaths` pd ON `pd`.`killed_by` = `p`.`name` - WHERE `p`.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') + WHERE `p`.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `p`.' . $deleted . ' = 0 - AND `p`.group_id < ' . config('highscores_groups_hidden') . ' ' . $add_sql . ' + AND `p`.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND `pd`.`unjustified` = 1 GROUP BY `killed_by` ORDER BY value DESC @@ -193,19 +193,19 @@ if (!isset($highscores) || empty($highscores)) { } } else if ($skill == SKILL_BALANCE) // balance { - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,balance as value,vocation' . $promotion . $outfit . ' FROM accounts,players WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . config('highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY value DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,balance as value,vocation' . $promotion . $outfit . ' FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY value DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); } else { if ($skill == POT::SKILL__MAGLEVEL) { - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',maglevel,level,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . config('highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY maglevel DESC, manaspent DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',maglevel,level,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY maglevel DESC, manaspent DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); } else { // level - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,experience,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', config('highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . config('highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY level DESC, experience DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,experience,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY level DESC, experience DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); $list = 'experience'; } } } if ($cache->enabled() && $needReCache) { - $cache->set($cacheKey, serialize($highscores), config('highscores_cache_ttl') * 60); + $cache->set($cacheKey, serialize($highscores), setting('core.highscores_cache_ttl') * 60); } $online_exist = false; @@ -227,7 +227,7 @@ if($db->hasTable('players_online') && count($players) > 0) { $show_link_to_next_page = false; $i = 0; -$configHighscoresVocation = config('highscores_vocation'); +$settingHighscoresVocation = setting('core.highscores_vocation'); foreach($highscores as $id => &$player) { @@ -248,7 +248,7 @@ foreach($highscores as $id => &$player) $player['experience'] = number_format($player['experience']); } - if($configHighscoresVocation) { + if($settingHighscoresVocation) { if(isset($player['promotion'])) { if((int)$player['promotion'] > 0) { $player['vocation'] += ($player['promotion'] * $configVocationsAmount); @@ -266,7 +266,7 @@ foreach($highscores as $id => &$player) $player['link'] = getPlayerLink($player['name'], false); $player['flag'] = getFlagImage($player['country']); - if($configHighscoresOutfit) { + if($settingHighscoresOutfit) { $player['outfit'] = ''; } $player['rank'] = $offset + $i; @@ -302,10 +302,10 @@ $types = array( 'fishing' => 'Fishing', ); -if(config('highscores_frags')) { +if(setting('core.highscores_frags')) { $types['frags'] = 'Frags'; } -if(config('highscores_balance')) +if(setting('core.highscores_balance')) $types['balance'] = 'Balance'; /** @var Twig\Environment $twig */ diff --git a/system/pages/team.php b/system/pages/team.php index fbc0df99..b1fd15dc 100644 --- a/system/pages/team.php +++ b/system/pages/team.php @@ -23,7 +23,7 @@ if(!$groups->count()) $outfit_addons = false; $outfit = ''; -if($config['team_display_outfit']) { +if(setting('core.team_outfit')) { $outfit = ', lookbody, lookfeet, lookhead, looklegs, looktype'; if($db->hasColumn('players', 'lookaddons')) { $outfit .= ', lookaddons'; @@ -56,12 +56,12 @@ foreach($groupList as $id => $group) $members[] = array( 'group_name' => $group->getName(), 'player' => $member, - 'outfit' => $config['team_display_outfit'] ? $config['outfit_images_url'] . '?id=' . $member->getLookType() . ($outfit_addons ? '&addons=' . $member->getLookAddons() : '') . '&head=' . $member->getLookHead() . '&body=' . $member->getLookBody() . '&legs=' . $member->getLookLegs() . '&feet=' . $member->getLookFeet() : null, - 'status' => $config['team_display_status'] ? $member->isOnline() : null, + 'outfit' => setting('core.team_outfit') ? setting('core.outfit_images_url') . '?id=' . $member->getLookType() . ($outfit_addons ? '&addons=' . $member->getLookAddons() : '') . '&head=' . $member->getLookHead() . '&body=' . $member->getLookBody() . '&legs=' . $member->getLookLegs() . '&feet=' . $member->getLookFeet() : null, + 'status' => setting('core.team_status') ? $member->isOnline() : null, 'link' => getPlayerLink($member->getName()), - 'flag_image' => $config['account_country'] ? getFlagImage($member->getAccount()->getCountry()) : null, - 'world_name' => ($config['multiworld'] || $config['team_display_world']) ? getWorldName($member->getWorldId()) : null, - 'last_login' => $config['team_display_lastlogin'] ? $lastLogin : null + 'flag_image' => setting('core.account_country') ? getFlagImage($member->getAccount()->getCountry()) : null, + 'world_name' => (setting('core.multiworld') || setting('core.team_world')) ? getWorldName($member->getWorldId()) : null, + 'last_login' => setting('core.team_lastlogin') ? $lastLogin : null ); } diff --git a/system/settings.php b/system/settings.php new file mode 100644 index 00000000..83a1d85e --- /dev/null +++ b/system/settings.php @@ -0,0 +1,1638 @@ + 'MyAAC', + 'settings' => + [ + [ + 'type' => 'category', + 'title' => 'General' + ], + [ + 'type' => 'section', + 'title' => 'General' + ], + 'env' => [ + 'name' => 'App Environment', + 'type' => 'options', + 'options' => ['prod' => 'Production', 'dev' => 'Development'], + 'desc' => 'if you use this script on your live server - set production
    ' . + '* if you want to test and debug the script locally, or develop plugins, set to development
    ' . + '* WARNING: on "development" cache is disabled, so site will be significantly slower !!!
    ' . + '* WARNING2: on "development" all PHP errors/warnings are displayed
    ' . + '* Recommended: "production" cause of speed (page load time is better)', + 'default' => 'prod', + 'is_config' => true, + ], + 'server_path' => [ + 'name' => 'Server Path', + 'type' => 'text', + 'desc' => 'Path to the server directory (same directory where config file is located)', + 'default' => '', + 'is_config' => true, + ], + 'date_timezone' => [ + 'name' => 'Date Timezone', + 'type' => 'options', + 'options' => '$timezones', + 'desc' => 'Timezone of the server, more info at http://php.net/manual/en/timezones.php', + 'default' => 'Europe/Warsaw', + ], + 'friendly_urls' => [ + 'name' => 'Friendly URLs', + 'type' => 'boolean', + 'desc' => 'It makes links looks more elegant to eye, and also are SEO friendly

    ' . + 'yes: http://example.net/guilds/Testing
    ' . + 'no: http://example.net/index.php/guilds/Testing

    ' . + 'apache2: mod_rewrite is required for this + remember to rename .htaccess.dist to .htaccess
    ' . + 'nginx: check included nginx-sample.conf', + 'default' => false, + ], + 'gzip_output' => [ + 'name' => 'gzip Output', + 'type' => 'boolean', + 'desc' => 'gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles', + 'default' => false, + 'is_config' => true, + ], + 'google_analytics_id' => [ + 'name' => 'Google Analytics ID', + 'type' => 'text', + 'desc' => 'Format: UA-XXXXXXX-X', + 'default' => '', + ], + [ + 'type' => 'section', + 'title' => 'Template' + ], + 'template' => [ + 'name' => 'Template Name', + 'type' => 'options', + 'options' => '$templates', + 'desc' => 'Name of the template used by website', + 'default' => 'kathrine', + ], + 'template_allow_change' => [ + 'name' => 'Template Allow Change', + 'type' => 'boolean', + 'desc' => 'Allow changing template of the website by showing a special select in the part of website', + 'default' => true, + ], + [ + 'type' => 'section', + 'title' => escapeHtml('') . ' - Header' + ], + 'charset' => [ + 'name' => 'Meta Charset', + 'type' => 'text', + 'desc' => 'Charset used in ' . escapeHtml(''), + 'default' => 'utf-8', + ], + 'meta_description' => [ + 'name' => 'Meta Description', + 'type' => 'textarea', + 'desc' => 'description of the site in ' . escapeHtml(''), + 'default' => 'Tibia is a free massive multiplayer online role playing game (MMORPG).', + ], + 'meta_keywords' => [ + 'name' => 'Meta Keywords', + 'type' => 'textarea', + 'desc' => 'keywords list separated by commas', + 'default' => 'free online game, free multiplayer game, ots, open tibia server', + ], + [ + 'type' => 'section', + 'title' => 'Footer' + ], + 'footer' => [ + 'name' => 'Custom Text', + 'type' => 'textarea', + 'desc' => 'Text displayed in the footer.
    For example: ' . escapeHtml('
    ') . 'Your Server © 2023. All rights reserved.
    ', + 'default' => '', + ], + 'footer_load_time' => [ + 'name' => 'Load Time', + 'type' => 'boolean', + 'desc' => 'Display load time of the page in the footer', + 'default' => true, + ], + // do we really want this? I'm leaving it for consideration + /* + 'footer_powered_by' => [ + 'name' => 'Display Powered by MyAAC', + 'type' => 'boolean', + 'desc' => 'Do you want to show Powered by MyAAC slogan in the footer?', + 'default' => true, + ], + */ + /*'language' => [ + 'name' => 'Language', + 'type' => 'options', + 'options' => ['en' => 'English'], + 'desc' => 'default language (currently only English available)', + 'default' => 'en', + ],*/ + /*'language_allow_change' => [ + 'name' => 'Language Allow Change', + 'type' => 'boolean', + 'default' => false, + 'desc' => 'default language (currently only English available)' + ],*/ + [ + 'type' => 'section', + 'title' => 'Counters' + ], + 'visitors_counter' => [ + 'name' => 'Visitors Counter', + 'type' => 'boolean', + 'desc' => 'Enable Visitors Counter? It will show list of online members on the website in Admin Panel', + 'default' => true, + ], + 'visitors_counter_ttl' => [ + 'name' => 'Visitors Counter TTL', + 'type' => 'number', + 'desc' => 'Time To Live for Visitors Counter. In other words - how long user will be marked as online. In Minutes', + 'default' => 10, + 'show_if' => [ + 'visitors_counter', '=', 'true' + ] + ], + 'views_counter' => [ + 'name' => 'Views Counter', + 'type' => 'boolean', + 'desc' => 'Enable Views Counter? It will show how many times the website has been viewed by users', + 'default' => true, + ], + [ + 'type' => 'section', + 'title' => 'Misc' + ], + 'cache_engine' => [ + 'name' => 'Cache Engine', + 'type' => 'options', + 'options' => ['auto' => 'Auto', 'file' => 'Files', 'apc' => 'APC', 'apcu' => 'APCu', 'eaccelerator' => 'eAccelerator', 'disable' => 'Disable'], + 'desc' => 'Auto is most reasonable. It will detect the best cache engine', + 'default' => 'auto', + 'is_config' => true, + ], + 'cache_prefix' => [ + 'name' => 'Cache Prefix', + 'type' => 'text', + 'desc' => 'Have to be unique if running more MyAAC instances on the same server (except file system cache)', + 'default' => 'myaac_' . generateRandomString(8, true, false, true), + 'is_config' => true, + ], + 'session_prefix' => [ + 'name' => 'Session Prefix', + 'type' => 'text', + 'desc' => 'must be unique for every site on your server', + 'default' => 'myaac_', + ], + 'backward_support' => [ + 'name' => 'Gesior Backward Support', + 'type' => 'boolean', + 'desc' => 'gesior backward support (templates & pages)
    ' . + 'allows using gesior templates and pages with myaac
    ' . + 'might bring some performance when disabled', + 'default' => true, + ], + 'anonymous_usage_statistics' => [ + 'name' => 'Anonymous Usage Statistics', + 'type' => 'boolean', + 'desc' => 'Allow MyAAC to report anonymous usage statistics to developers? The data is sent only once per 30 days and is fully confidential. It won\'t affect the performance of your website', + 'default' => true, + ], + [ + 'type' => 'category', + 'title' => 'Game', + ], + [ + 'type' => 'section', + 'title' => 'Game' + ], + 'client' => [ + 'name' => 'Client Version', + 'type' => 'options', + 'options' => '$clients', + 'desc' => 'what client version are you using on this OT?
    used for the Downloads page and some templates aswell', + 'default' => 710 + ], + 'towns' => [ + 'name' => 'Towns', + 'type' => 'textarea', + 'desc' => "if you use TFS 1.3 with support for 'towns' table in database, then you can ignore this - it will be configured automatically (from MySQL database - Table - towns)
    " . + "otherwise it will try to load from your .OTBM map file
    " . + "if you don't see towns on website, then you need to fill this out", + 'default' => "0=No Town\n1=Sample Town", + 'callbacks' => [ + 'get' => function ($value) { + $ret = []; + $towns = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value))); + + foreach ($towns as $town) { + if (empty($town)) { + continue; + } + + $explode = explode('=', $town); + $ret[$explode[0]] = $explode[1]; + } + + return $ret; + }, + ], + ], + 'genders' => [ + 'name' => 'Genders (aka sex)', + 'type' => 'textarea', + 'desc' => 'Separated with comma', + 'default' => 'Female, Male', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + 'account_types' => [ + 'name' => 'Account Types', + 'type' => 'textarea', + 'desc' => 'Separated with comma, you may need to adjust this for older tfs versions by removing Community Manager', + 'default' => 'None, Normal, Tutor, Senior Tutor, Gamemaster, Community Manager, God', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + 'vocations_amount' => [ + 'name' => 'Vocations Amount', + 'type' => 'number', + 'desc' => 'How much basic vocations your server got (without promotion)', + 'default' => 4, + ], + 'vocations' => [ + 'name' => 'Vocation Names', + 'type' => 'textarea', + 'desc' => 'Separated by comma ,', + 'default' => 'None, Sorcerer, Druid, Paladin, Knight, Master Sorcerer, Elder Druid,Royal Paladin, Elite Knight', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + [ + 'type' => 'category', + 'title' => 'Database', + ], + [ + 'type' => 'section', + 'title' => 'Database', + ], + 'database_overwrite' => [ + 'name' => 'Database Manual', + 'type' => 'boolean', + 'desc' => 'Manual database configuration. Enable if you want to manually enter database details. If set to no - it will get from config.lua', + 'default' => false, + 'is_config' => true, + ], + 'database_host' => [ + 'name' => 'Database Host', + 'type' => 'text', + 'default' => '127.0.0.1', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_port' => [ + 'name' => 'Database Port', + 'type' => 'number', + 'default' => 3306, + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_user' => [ + 'name' => 'Database User', + 'type' => 'text', + 'default' => '', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_password' => [ + 'name' => 'Database Password', + 'type' => 'text', + 'default' => '', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_name' => [ + 'name' => 'Database Name', + 'type' => 'text', + 'default' => '', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_socket' => [ + 'name' => 'Database Socket', + 'desc' => 'Set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock)', + 'type' => 'text', + 'default' => '', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_hash' => [ + 'name' => 'Database Hashing Algorithm', + 'desc' => 'Hashing algorithm: sha1 or md5 are most common', + 'type' => 'text', + 'default' => 'sha1', + 'show_if' => [ + 'database_overwrite', '=', 'true' + ], + 'is_config' => true, + ], + 'database_log' => [ + 'name' => 'Database Log', + 'desc' => 'Should database queries be logged and saved into system/logs/database.log?', + 'type' => 'boolean', + 'default' => false, + 'is_config' => true, + ], + 'database_persistent' => [ + 'name' => 'Database Persistent Connection', + 'desc' => 'Use database permanent connection (like server), may speed up your site', + 'type' => 'boolean', + 'default' => false, + 'is_config' => true, + ], + [ + 'type' => 'category', + 'title' => 'Mailing', + ], + [ + 'type' => 'section', + 'title' => 'Mailing' + ], + 'mail_enabled' => [ + 'name' => 'Mailing enabled', + 'type' => 'boolean', + 'desc' => 'Is AAC configured to send e-mails?', + 'default' => false, + /*'script' => <<<'SCRIPT' + +SCRIPT,*/ + ], + 'mail_address' => [ + 'name' => 'Mail Address', + 'type' => 'email', + 'desc' => 'Server e-mail address (from:)', + 'default' => 'no-reply@your-server.org', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ], + ], + /*'mail_admin' => [ + 'name' => 'Mail Admin Address', + 'type' => 'email', + 'desc' => 'Admin email address, where mails from contact form will be sent', + 'default' => 'your-address@your-server.org', + ],*/ + 'mail_signature_plain' => [ + 'name' => 'Mail Signature (Plain)', + 'type' => 'textarea', + 'desc' => 'Signature that will be included at the end of every message sent.
    In Normal Format!', + 'default' => '-- +Sent by MyAAC, +https://my-aac.org', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'mail_signature_html' => [ + 'name' => 'Mail Signature (HTML)', + 'type' => 'textarea', + 'desc' => 'Signature that will be included at the end of every message sent.
    In HTML Format!', + 'default' => escapeHtml('
    +Sent by MyAAC,
    +my-aac.org'), + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'section_smtp' => [ + 'type' => 'section', + 'title' => 'SMTP (Mail Server)', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'mail_option' => [ + 'name' => 'Mail Option', + 'type' => 'options', + 'options' => [0 => 'Mail (PHP Built-in)', 1 => 'SMTP (Gmail or Microsoft Outlook)'], + 'desc' => 'Mail sender. Set to SMTP if using Gmail or Microsoft Outlook, or any other provider', + 'default' => 0, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_host' => [ + 'name' => 'SMTP Host', + 'type' => 'text', + 'desc' => 'SMTP mail host. smtp.gmail.com for GMail / smtp-mail.outlook.com for Microsoft Outlook', + 'default' => '', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_port' => [ + 'name' => 'SMTP Host', + 'type' => 'number', + 'desc' => '25 (default) / 465 (ssl, GMail) / 587 (tls, Microsoft Outlook)', + 'default' => 25, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_auth' => [ + 'name' => 'SMTP Auth', + 'type' => 'boolean', + 'desc' => 'Need authorization for Server? In normal situation, almost always Yes.', + 'default' => true, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_user' => [ + 'name' => 'SMTP Username', + 'type' => 'text', + 'desc' => 'Here your email username to authenticate with SMTP', + 'default' => 'admin@example.org', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_pass' => [ + 'name' => 'SMTP Password', + 'type' => 'password', + 'desc' => 'Here your email password to authenticate with SMTP', + 'default' => '', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_security' => [ + 'name' => 'SMTP Security', + 'type' => 'options', + 'options' => ['None', 'SSL', 'TLS'], + 'desc' => 'What kind of encryption to use on the SMTP connection', + 'default' => 0, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'smtp_debug' => [ + 'name' => 'SMTP Debug', + 'type' => 'boolean', + 'desc' => 'Activate to see more logs about mailing errors in error.log', + 'default' => false, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ] + ], + 'mail_other' => [ + 'type' => 'section', + 'title' => 'Account E-Mails', + 'show_if' => [ + 'mail_enabled', '=', 'true' + ], + ], + 'account_welcome_mail' => [ + 'name' => 'Account Welcome E-Mail', + 'type' => 'boolean', + 'desc' => 'Send welcome e-mail when user registers', + 'default' => true, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ], + ], + 'account_mail_verify' => [ + 'name' => 'Account E-Mail Verify', + 'type' => 'boolean', + 'desc' => 'Force users to confirm their e-mail addresses when registering account', + 'default' => false, + 'show_if' => [ + 'mail_enabled', '=', 'true' + ], + ], + 'mail_send_when_change_password' => [ + 'name' => 'Change Password E-Mail', + 'type' => 'boolean', + 'desc' => 'Send e-mail with new password when change password to account', + 'default' => true, + 'show_if' => [ + 'mail_enabled', '=', 'true', + ], + ], + 'mail_send_when_generate_reckey' => [ + 'name' => 'Generate Recovery Key E-Mail', + 'type' => 'boolean', + 'desc' => 'Send e-mail with recovery key (key is displayed on page anyway when generate)', + 'default' => true, + 'show_if' => [ + 'mail_enabled', '=', 'true', + ], + ], + 'mail_lost_account_interval' => [ + 'name' => 'Mail Lost Interface Interval', + 'type' => 'number', + 'desc' => 'Time in seconds between e-mails to one account from lost account interface, block spam', + 'default' => 60, + 'show_if' => [ + 'mail_enabled', '=', 'true', + ], + ], + [ + 'type' => 'category', + 'title' => 'Accounts', + ], + [ + 'type' => 'section', + 'title' => 'Accounts Settings' + ], + 'account_management' => [ + 'name' => 'Enable Account Management', + 'type' => 'boolean', + 'desc' => "disable if you're using other method to manage users (fe. tfs account manager)", + 'default' => true, + ], + 'account_login_by_email' => [ + 'name' => 'Account Login By E-Mail', + 'type' => 'boolean', + 'desc' => "use email instead of Account Name like in latest Tibia", + 'default' => true, + ], + 'account_login_by_email_fallback' => [ + 'name' => 'Account Login By E-Mail Fallback', + 'type' => 'boolean', + 'desc' => "allow also additionally login by Account Name/Number (for users that might forget their email). Works only if Account Login By E-Mail is also enabled", + 'default' => false, + 'show_if' => [ + 'account_login_by_email', '=', 'true' + ], + ], + 'account_create_auto_login' => [ + 'name' => 'Account Create Auto Login', + 'type' => 'boolean', + 'desc' => 'Auto login after creating account?', + 'default' => false, + ], + 'account_create_character_create' => [ + 'name' => 'Account Create Character Create', + 'type' => 'boolean', + 'desc' => 'Allow to create character directly on create account page?', + 'default' => true, + ], + 'account_mail_unique' => [ + 'name' => 'Account Mail Unique', + 'type' => 'boolean', + 'desc' => 'Email addresses cannot be duplicated? (one account = one email)', + 'default' => true, + ], + 'account_premium_days' => [ + 'name' => 'Default Account Premium Days', + 'type' => 'number', + 'desc' => 'Default premium days on new account', + 'default' => 0, + ], + 'account_premium_points' => [ + 'name' => 'Default Account Premium Points', + 'type' => 'number', + 'desc' => 'Default premium points on new account', + 'default' => 0, + ], + 'account_mail_change' => [ + 'name' => 'Account Mail Change Days', + 'type' => 'number', + 'desc' => 'How many days user need to change email to account - block hackers', + 'default' => 2, + ], + 'account_mail_block_plus_sign' => [ + 'name' => 'Account Mail Block Plus Sign (+)', + 'type' => 'boolean', + 'desc' => "Block E-Mails with '+' signs like test+box@gmail.com (help protect against spamming accounts)", + 'default' => true, + ], + 'account_country' => [ + 'name' => 'Account Country', + 'type' => 'boolean', + 'desc' => 'User will be able to set country of origin when registering account, this information will be viewable in others places as well', + 'default' => true, + ], + 'account_country_recognize' => [ + 'name' => 'Auto Recognize Account Country', + 'type' => 'boolean', + 'desc' => 'should country of user be automatically recognized by his IP? This makes an external API call to http://ipinfo.io', + 'default' => true, + ], + 'characters_per_account' => [ + 'name' => 'Characters per Account', + 'type' => 'number', + 'desc' => 'Max. number of characters per account', + 'default' => 10, + ], + 'create_character' => [ + 'type' => 'section', + 'title' => 'Create Character', + ], + 'character_samples' => [ + 'name' => 'Character Samples', + 'type' => 'textarea', + 'desc' => "Character Samples used when creating character.
    " . + "Format: ID_of_vocation =Name of Character to copy
    " . + "For Rook use - 0=Rook Sample", + 'default' => "1=Sorcerer Sample\n2=Druid Sample\n3=Paladin Sample\n4=Knight Sample", + 'callbacks' => [ + 'get' => function ($value) { + $ret = []; + $vocs = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value))); + + foreach ($vocs as $voc) { + if (empty($voc)) { + continue; + } + + $explode = explode('=', $voc); + $ret[$explode[0]] = $explode[1]; + } + + return $ret; + }, + ], + ], + 'character_towns' => [ + 'name' => 'Towns List', + 'type' => 'text', + 'desc' => "Towns List used when creating character separated by comma (,). Won't be displayed if there is only one item (rookgaard for example)", + 'default' => '1,2', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + 'create_character_name_min_length' => [ + 'name' => 'Name Min Length', + 'type' => 'number', + 'desc' => '', + 'default' => 4, + ], + 'create_character_name_max_length' => [ + 'name' => 'Name Max Length', + 'type' => 'number', + 'desc' => 'It is highly recommend the maximum length to be 21', + 'default' => 21, + ], + 'create_character_name_blocked_prefix' => [ + 'name' => 'Create Character Name Blocked Prefix', + 'type' => 'textarea', + 'desc' => 'Space after is important!', + 'default' => 'admin ,administrator ,gm ,cm ,god ,tutor', + 'callbacks' => [ + 'get' => function ($value) { + return explode(',', $value); + }, + ], + ], + 'create_character_name_blocked_names' => [ + 'name' => 'Create Character Name Blocked Names', + 'type' => 'textarea', + 'desc' => 'Separated by comma (,)', + 'default' => 'admin,administrator,gm,cm,god,tutor', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + 'create_character_name_blocked_words' => [ + 'name' => 'Create Character Name Blocked Words', + 'type' => 'textarea', + 'desc' => 'Separated by comma (,)', + 'default' => "admin,administrator,gamemaster,game master,game-master,game'master,fuck,sux,suck,noob,tutor", + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + 'create_character_name_monsters_check' => [ + 'name' => 'Block Monsters Names', + 'type' => 'boolean', + 'desc' => 'Should monsters names be blocked when creating character?', + 'default' => true, + ], + 'create_character_name_npc_check' => [ + 'name' => 'Block NPC Names', + 'type' => 'boolean', + 'desc' => 'Should NPC names be blocked when creating character?', + 'default' => true, + ], + 'create_character_name_spells_check' => [ + 'name' => 'Block Spells Names', + 'type' => 'boolean', + 'desc' => 'Should spells names and words be blocked when creating character?', + 'default' => true, + ], + 'use_character_sample_skills' => [ + 'name' => 'Use Character Sample Skills', + 'type' => 'boolean', + 'desc' => 'No = default skill = 10, yes - use sample skills', + 'default' => false, + ], + 'account_mail_confirmed_reward' => [ + 'type' => 'section', + 'title' => 'Reward Users for confirming their E-Mails. Works only with Account Mail Verify enabled', + 'show_if' => [ + 'account_mail_verify', '=', 'true' + ], + ], + 'account_mail_confirmed_reward_premium_days' => [ + 'name' => 'Reward Premium Days', + 'type' => 'number', + 'desc' => '0 to disable', + 'default' => 0, + 'show_if' => [ + 'account_mail_verify', '=', 'true' + ], + ], + 'account_mail_confirmed_reward_premium_points' => [ + 'name' => 'Reward Premium Points', + 'type' => 'number', + 'desc' => '0 to disable', + 'default' => 0, + 'show_if' => [ + 'account_mail_verify', '=', 'true' + ], + ], + 'account_mail_confirmed_reward_coins' => [ + 'name' => 'Reward Coins', + 'type' => 'number', + 'desc' => '0 to disable. Works only with servers that supports coins', + 'default' => 0, + 'show_if' => [ + 'account_mail_verify', '=', 'true' + ], + ], + [ + 'type' => 'category', + 'title' => 'Guilds', + ], + [ + 'type' => 'section', + 'title' => 'Guilds' + ], + 'guild_management' => [ + 'name' => 'Enable Guilds Management', + 'type' => 'boolean', + 'desc' => 'Enable guild management system on the site', + 'default' => true, + ], + 'guild_need_level' => [ + 'name' => 'Guild Need Level', + 'type' => 'number', + 'desc' => 'Min. level to form a guild', + 'default' => 1, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_need_premium' => [ + 'name' => 'Guild Need Premium', + 'type' => 'boolean', + 'desc' => 'Require premium account to form a guild?', + 'default' => true, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_image_size_kb' => [ + 'name' => 'Guild Image Size', + 'type' => 'number', + 'desc' => 'Maximum size of the guild logo image in KB (kilobytes)', + 'default' => 80, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_description_default' => [ + 'name' => 'Default Guild Description', + 'type' => 'text', + 'desc' => 'Default description set on new guild', + 'default' => 'New guild. Leader must edit this text :)', + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_description_chars_limit' => [ + 'name' => 'Guild Description Characters Limit', + 'type' => 'number', + 'desc' => 'How many characters can be in guild description', + 'default' => 1000, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_description_lines_limit' => [ + 'name' => 'Guild Description Lines Limit', + 'type' => 'number', + 'desc' => "Limit of lines, if description has more lines it will be showed as long text, without 'enters'", + 'default' => 6, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + 'guild_motd_chars_limit' => [ + 'name' => 'Guild MOTD Characters Limit', + 'type' => 'number', + 'desc' => 'Limit of MOTD (message of the day) that is shown later in the game on the guild channel', + 'default' => 150, + 'show_if' => [ + 'guild_management', '=', 'true', + ], + ], + [ + 'type' => 'category', + 'title' => 'Pages', + ], + [ + 'type' => 'section', + 'title' => 'News Page', + ], + 'news_author' => [ + 'name' => 'News Author', + 'type' => 'boolean', + 'desc' => 'Show author of the news', + 'default' => true, + ], + 'news_limit' => [ + 'name' => 'News Limit', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Limit of news on the latest news page (0 to disable)', + 'default' => 5, + ], + 'news_ticker_limit' => [ + 'name' => 'News Ticker Limit', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Limit of news in tickers (mini news) (0 to disable)', + 'default' => 5, + ], + 'news_date_format' => [ + 'name' => 'News Date Format', + 'type' => 'text', + 'desc' => 'Check php manual date() function for more info about this', + 'default' => 'j.n.Y', + ], + [ + 'type' => 'section', + 'title' => 'Forum' + ], + 'forum' => [ + 'name' => 'Forum', + 'type' => 'text', + 'desc' => 'Do you want to use built-in forum feature? Enter "site" if you want to use built-in forum feature, if you want use custom forum - enter URL here, otherwise leave empty (to disable)', + 'default' => 'site', + ], + 'forum_level_required' => [ + 'name' => 'Forum Level Required', + 'type' => 'number', + 'desc' => 'Level required to post on forum. 0 to disable', + 'min' => 0, + 'max' => 99999999999, + 'default' => 0, + 'show_if' => [ + 'forum', '=', 'site', + ], + ], + 'forum_post_interval' => [ + 'name' => 'Forum Post Interval', + 'type' => 'number', + 'desc' => 'How often user can post on forum, in seconds', + 'min' => 0, + 'max' => 99999999999, + 'default' => 30, + 'show_if' => [ + 'forum', '=', 'site', + ], + ], + 'forum_posts_per_page' => [ + 'name' => 'Forum Posts per Page', + 'type' => 'number', + 'desc' => 'How many posts per page', + 'min' => 0, + 'max' => 99999999999, + 'default' => 20, + 'show_if' => [ + 'forum', '=', 'site', + ], + ], + 'forum_threads_per_page' => [ + 'name' => 'Forum Threads per Page', + 'type' => 'number', + 'desc' => 'How many threads per page', + 'min' => 0, + 'max' => 99999999999, + 'default' => 20, + 'show_if' => [ + 'forum', '=', 'site', + ], + ], + 'forum_table_prefix' => [ + 'name' => 'Forum Table Prefix', + 'type' => 'text', + 'desc' => 'What forum mysql table to use, z_ (for gesior old forum) or myaac_ (for myaac)', + 'default' => 'myaac_', + 'show_if' => [ + 'forum', '=', 'site', + ], + ], + [ + 'type' => 'section', + 'title' => 'Highscores Page', + ], + 'highscores_per_page' => [ + 'name' => 'Highscores per Page', + 'type' => 'number', + 'min' => 1, + 'desc' => 'How many records per page on highscores', + 'default' => 100, + ], + 'highscores_cache_ttl' => [ + 'name' => 'Highscores Cache TTL (in minutes)', + 'type' => 'number', + 'min' => 1, + 'desc' => 'How often to update highscores from database in minutes (default 15 minutes). Too low may cause lags on website.', + 'default' => 15, + ], + 'highscores_vocation_box' => [ + 'name' => 'Display Vocation Box', + 'type' => 'boolean', + 'desc' => 'show "Choose a vocation" box on the highscores (allowing peoples to sort highscores by vocation)?', + 'default' => true, + ], + 'highscores_vocation' => [ + 'name' => 'Display Vocation', + 'type' => 'boolean', + 'desc' => 'Show player vocation under his nickname?', + 'default' => true, + ], + 'highscores_frags' => [ + 'name' => 'Display Top Frags', + 'type' => 'boolean', + 'desc' => 'Show "Frags" tab (best fraggers on the server)?', + 'default' => false, + ], + 'highscores_balance' => [ + 'name' => 'Display Balance', + 'type' => 'boolean', + 'desc' => 'Show "Balance" tab (richest players on the server)?', + 'default' => false, + ], + 'highscores_outfit' => [ + 'name' => 'Display Player Outfit', + 'type' => 'boolean', + 'desc' => 'Show player outfit?', + 'default' => true, + ], + 'highscores_country_box' => [ // not implemented yet + 'name' => 'Display Country Box', + 'type' => 'hidden', + 'desc' => 'Show player outfit?', + 'default' => false, + ], + 'highscores_groups_hidden' => [ + 'name' => 'Hidden Groups', + 'type' => 'number', + 'desc' => "This group id and higher won't be shown on highscores", + 'default' => 3, + ], + 'highscores_ids_hidden' => [ + 'name' => 'Hidden IDs of players', + 'type' => 'textarea', + 'desc' => "this ids of players will be hidden on the highscores (should be ids of samples)", + 'default' => '0', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + [ + 'type' => 'section', + 'title' => 'Characters Page', + ], + 'characters_search_limit' => [ + 'name' => 'Characters Search Limit', + 'type' => 'number', + 'desc' => "How many characters (players) to show when using search function", + 'default' => 15, + ], + 'characters_level' => [ + 'name' => 'Display Level', + 'type' => 'boolean', + 'desc' => 'Show characters level', + 'default' => true, + ], + 'characters_experience' => [ + 'name' => 'Display Experience', + 'type' => 'boolean', + 'desc' => 'Show characters experience points', + 'default' => false, + ], + 'characters_magic_level' => [ + 'name' => 'Display Magic Level', + 'type' => 'boolean', + 'desc' => 'Show characters magic level', + 'default' => false, + ], + 'characters_balance' => [ + 'name' => 'Display Balance', + 'type' => 'boolean', + 'desc' => 'Show characters bank balance', + 'default' => false, + ], + 'characters_marriage' => [ + 'name' => 'Display Marriage', + 'type' => 'boolean', + 'desc' => 'Show characters marriage info. Works only in TFS 0.3', + 'default' => true, + ], + 'characters_outfit' => [ + 'name' => 'Display Outfit', + 'type' => 'boolean', + 'desc' => 'Show characters outfit', + 'default' => true, + ], + 'characters_creation_date' => [ + 'name' => 'Display Creation Date', + 'type' => 'boolean', + 'desc' => 'Show characters date of creation', + 'default' => true, + ], + 'characters_quests' => [ + 'name' => 'Display Quests', + 'type' => 'boolean', + 'desc' => 'Show characters quests. Can be configured below', + 'default' => true, + ], + 'quests' => [ + 'name' => 'Quests List', + 'type' => 'textarea', + 'desc' => 'Character Quests List. Format: NameOfQuest=StorageValue', + 'default' => "Some Quest=123\nSome Quest Two=456", + 'show_if' => [ + 'characters_quests', '=', 'true' + ], + 'callbacks' => [ + 'get' => function ($value) { + $ret = []; + $quests = array_map('trim', preg_split('/\r\n|\r|\n/', trim($value))); + + foreach ($quests as $quest) { + if (empty($quest)) { + continue; + } + + $explode = explode('=', $quest); + $ret[$explode[0]] = $explode[1]; + } + + return $ret; + }, + ], + ], + 'characters_skills' => [ + 'name' => 'Display Skills', + 'type' => 'boolean', + 'desc' => 'Show characters skills', + 'default' => true, + ], + 'characters_equipment' => [ + 'name' => 'Display Equipment', + 'type' => 'boolean', + 'desc' => 'Show characters equipment', + 'default' => true, + ], + 'characters_frags' => [ + 'name' => 'Display Frags', + 'type' => 'boolean', + 'desc' => 'Show characters frags', + 'default' => false, + ], + 'characters_deleted' => [ + 'name' => 'Display Deleted', + 'type' => 'boolean', + 'desc' => 'Should deleted characters from same account be still listed on the list of characters? When enabled it will show that character is "[DELETED]', + 'default' => false, + ], + [ + 'type' => 'section', + 'title' => 'Online Page' + ], + 'online_record' => [ + 'name' => 'Display Players Record', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + 'online_vocations' => [ + 'name' => 'Display Vocation Statistics', + 'type' => 'boolean', + 'desc' => '', + 'default' => false, + ], + 'online_vocations_images' => [ + 'name' => 'Display Vocation Images', + 'type' => 'boolean', + 'desc' => 'Only if Display Vocation Statistics enabled', + 'default' => true, + ], + 'online_skulls' => [ + 'name' => 'Display Skull Images', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + 'online_outfit' => [ + 'name' => 'Display Player Outfit', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + 'online_afk' => [ + 'name' => 'Display AFK Players', + 'type' => 'boolean', + 'desc' => '', + 'default' => false, + ], + [ + 'type' => 'section', + 'title' => 'Team Page' + ], + 'team_style' => [ + 'name' => 'Style', + 'type' => 'options', + 'desc' => '', + 'options' => ['normal table', 'in boxes, grouped by group id'], + 'default' => 1, + ], + 'team_status' => [ + 'name' => 'Display Online Status', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + 'team_lastlogin' => [ + 'name' => 'Display Last Login', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + 'team_world' => [ + 'name' => 'Display World', + 'type' => 'boolean', + 'desc' => '', + 'default' => false, + ], + 'team_outfit' => [ + 'name' => 'Display Outfit', + 'type' => 'boolean', + 'desc' => '', + 'default' => true, + ], + [ + 'type' => 'section', + 'title' => 'Bans Page' + ], + 'bans_per_page' => [ + 'name' => 'Bans per Page', + 'type' => 'number', + 'min' => 1, + 'default' => 20, + 'desc' => '', + ], + [ + 'type' => 'section', + 'title' => 'Last Kills Page' + ], + 'last_kills_limit' => [ + 'name' => 'Last Kills Limit', + 'type' => 'number', + 'desc' => 'Max. number of kills shown on the last kills page', + 'default' => 50, + ], + [ + 'type' => 'section', + 'title' => 'Experience Table Page' + ], + 'experience_table_columns' => [ + 'name' => 'Columns', + 'type' => 'number', + 'desc' => 'How many columns to display in experience table page, * rows, 5 = 500 (will show up to 500 level)', + 'default' => 3, + ], + 'experience_table_rows' => [ + 'name' => 'Rows', + 'type' => 'number', + 'desc' => 'Till how many levels in one column', + 'default' => 200, + ], + [ + 'type' => 'category', + 'title' => 'Images', + ], + [ + 'type' => 'section', + 'title' => 'Signatures' + ], + 'signature_enabled' => [ + 'name' => 'Enable Signatures', + 'type' => 'boolean', + 'desc' => 'Signature is a small picture with character info and server to paste on forums etc. It can be viewed on characters page, when enabled.', + 'default' => true, + ], + 'signature_type' => [ + 'name' => 'Signature Type', + 'type' => 'options', + 'options' => ['tibian' => 'tibian', 'mango' => 'mango', 'gesior' => 'gesior'], + 'desc' => 'Signature engine to use', + 'default' => 'tibian', + 'show_if' => [ + 'signature_enabled', '=', 'true' + ], + ], + 'signature_cache_time' => [ + 'name' => 'Signature Cache Time', + 'type' => 'number', + 'min' => 1, + 'desc' => 'How long to store cached file (in minutes)', + 'default' => 5, + 'show_if' => [ + 'signature_enabled', '=', 'true', + ], + ], + 'signature_browser_cache' => [ + 'name' => 'Signature Browser Cache Time', + 'type' => 'number', + 'min' => 1, + 'desc' => 'How long to cache by browser (in minutes)', + 'default' => 60, + 'show_if' => [ + 'signature_enabled', '=', 'true', + ], + ], + [ + 'type' => 'section', + 'title' => 'Item Images' + ], + 'item_images_url' => [ + 'name' => 'Item Images URL', + 'type' => 'text', + 'desc' => 'Set to images/items if you host your own items in images folder', + 'default' => 'http://item-images.ots.me/1092/', + ], + 'item_images_extension' => [ + 'name' => 'Item Images File Extension', + 'type' => 'text', + 'desc' => '', + 'default' => '.gif', + ], + [ + 'type' => 'section', + 'title' => 'Outfit Images' + ], + 'outfit_images_url' => [ + 'name' => 'Outfit Images URL', + 'type' => 'text', + 'desc' => 'Set to animoutfit.php for animated outfit', + 'default' => 'http://outfit-images.ots.me/outfit.php', + ], + 'outfit_images_wrong_looktypes' => [ + 'name' => 'Outfit Images Wrong Looktypes', + 'type' => 'text', + 'desc' => 'This looktypes needs to have different margin-top and margin-left because they are wrong positioned', + 'default' => '75, 126, 127, 266, 302', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + [ + 'type' => 'section', + 'title' => 'Monster Images' + ], + 'monsters_images_url' => [ + 'name' => 'Monsters Images URL', + 'type' => 'text', + 'desc' => 'Set to images/monsters/ if you host your own creatures in images folder', + 'default' => 'images/monsters/', + ], + 'monsters_images_extension' => [ + 'name' => 'Monsters Images File Extension', + 'type' => 'text', + 'desc' => '', + 'default' => '.gif', + ], + 'monsters_images_preview' => [ + 'name' => 'Monsters Images Preview', + 'type' => 'boolean', + 'desc' => 'Set to yes to allow picture previews for creatures', + 'default' => false, + ], + 'monsters_items_url' => [ + 'name' => 'Monsters Items URL', + 'type' => 'text', + 'desc' => 'Set to website which shows details about items', + 'default' => 'https://tibia.fandom.com/wiki/', + ], + 'monsters_loot_percentage' => [ + 'name' => 'Monsters Items URL', + 'type' => 'boolean', + 'desc' => 'Set to yes to show the loot tooltip percent', + 'default' => true, + ], + // this is hidden, because no implemented yet + 'multiworld' => [ + 'hidden' => true, + 'type' => 'boolean', + 'default' => false, + ], + [ + 'type' => 'category', + 'title' => 'Status', + ], + [ + 'type' => 'section', + 'title' => 'Server Status' + ], + 'status_enabled' => [ + 'name' => 'Enable Server Status', + 'type' => 'boolean', + 'desc' => 'You can disable status checking here', + 'default' => true, + ], + 'status_ip' => [ + 'name' => 'Status IP', + 'type' => 'text', + 'desc' => 'Leave empty to get automatically from config', + 'default' => '127.0.0.1', + 'show_if' => [ + 'status_enabled', '=', 'true', + ] + ], + 'status_port' => [ + 'name' => 'Status Port', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Leave empty to get automatically from config', + 'default' => 7171, + 'show_if' => [ + 'status_enabled', '=', 'true', + ] + ], + 'status_timeout' => [ + 'name' => 'Status Timeout', + 'type' => 'number', + 'min' => 0, + 'max' => 10, // more than 10 seconds waiting makes no sense + 'step' => 0.1, + 'desc' => 'How long to wait for the initial response from the server', + 'default' => 2.0, + 'show_if' => [ + 'status_enabled', '=', 'true', + ] + ], + 'status_interval' => [ + 'name' => 'Status Interval', + 'type' => 'number', + 'min' => 0, + 'desc' => 'How often to connect to server and update status.
    If your status timeout in config.lua is bigger, that it will be used instead. When server is offline, it will be checked every time web refreshes, ignoring this variable', + 'default' => 60, + 'show_if' => [ + 'status_enabled', '=', 'true', + ] + ], + [ + 'type' => 'category', + 'title' => 'Admin', + ], + [ + 'type' => 'section', + 'title' => 'Admin Panel' + ], + 'admin_plugins_manage_enable' => [ + 'name' => 'Enable Plugins Manage', + 'type' => 'boolean', + 'desc' => 'You can disable possibility to upload, enable/disable and uninstall plugins, for security', + 'default' => true, + ], + 'admin_pages_php_enable' => [ + 'name' => 'Enable PHP Pages', + 'type' => 'boolean', + 'desc' => 'You can disable support for plain php pages in admin panel, for security.
    Existing pages still will be working, so you need to delete them manually', + 'default' => false, + ], + 'admin_panel_modules' => [ + 'name' => 'Modules Enabled', + 'type' => 'textarea', + 'desc' => 'What modules will be shown on Admin Panel Dashboard page', + 'default' => 'statistics,web_status,server_status,lastlogin,created,points,coins,balance', + 'callbacks' => [ + 'get' => function ($value) { + return array_map('trim', explode(',', $value)); + }, + ], + ], + [ + 'type' => 'category', + 'title' => 'Shop', + ], + [ + 'type' => 'section', + 'title' => 'Gifts/shop system' + ], + 'gifts_system' => [ + 'name' => 'Enable gifts system', + 'desc' => 'Plugin needs to be installed', + 'type' => 'boolean', + 'default' => false, + ], + 'donate_column' => [ + 'name' => 'Donate Column', + 'type' => 'options', + 'desc' => 'What to give to player after donation - what column in accounts table to use.', + 'options' => ['premium_points' => 'Premium Points', 'coins' => 'Coins'], + 'default' => 'premium_points', + 'callbacks' => [ + 'beforeSave' => function($key, $value, &$errorMessage) { + global $db; + if ($value == 'coins' && !$db->hasColumn('accounts', 'coins')) { + $errorMessage = "Shop: Donate Column: Cannot set column to coins, because it doesn't exist in database."; + return false; + } + return true; + } + ] + ], + 'account_generate_new_reckey' => [ + 'name' => 'Allow Generate New Key', + 'desc' => "Allow to generate new key for premium points. The player will receive e-mail with new rec key (not display on page, hacker can't generate rec key)", + 'type' => 'boolean', + 'default' => false, + ], + 'account_generate_new_reckey_price' => [ + 'name' => 'Generate New Key Price', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Price for new recovery key', + 'default' => 20, + 'show_if' => [ + 'account_generate_new_reckey', '=', 'true', + ], + ], + 'account_change_character_name' => [ + 'name' => 'Allow Change Name', + 'desc' => 'Can user change their character name for premium points?', + 'type' => 'boolean', + 'default' => false, + ], + 'account_change_character_name_price' => [ + 'name' => 'Change Name Price', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Cost of name change', + 'default' => 30, + 'show_if' => [ + 'account_change_character_name', '=', 'true', + ], + ], + 'account_change_character_sex' => [ + 'name' => 'Allow Change Sex', + 'desc' => 'Can user change their character sex for premium points?', + 'type' => 'boolean', + 'default' => false, + ], + 'account_change_character_sex_price' => [ + 'name' => 'Change Sex Price', + 'type' => 'number', + 'min' => 0, + 'desc' => 'Cost of change sex', + 'default' => 30, + 'show_if' => [ + 'account_change_character_sex', '=', 'true', + ], + ], + ], + 'callbacks' => [ + 'beforeSave' => function(&$settings, &$values) { + global $config; + + $configToSave = []; + + $server_path = ''; + $database = []; + foreach ($settings['settings'] as $key => $value) { + if (isset($value['is_config']) && getBoolean($value['is_config'])) { + if ($value['type'] === 'boolean') { + $values[$key] = ($values[$key] === 'true'); + } + elseif ($value['type'] === 'number') { + $values[$key] = (int)$values[$key]; + } + //elseif ($value['type'] === 'options') { + // + //} + + $configToSave[$key] = $values[$key]; + + if ($key == 'server_path') { + $server_path = $values[$key]; + } + elseif (strpos($key, 'database_') !== false) { + $database[$key] = $values[$key]; + } + + unset($settings[$key]); + unset($values[$key]); + } + } + + if($server_path[strlen($server_path) - 1] != '/') + $server_path .= '/'; + + // test config.lua existence + // if fail - revert the setting and inform the user + if (!file_exists($server_path . 'config.lua')) { + error('Server Path is invalid - cannot find config.lua in the directory. Setting have been reverted.'); + $configToSave['server_path'] = $config['server_path']; + } + + // test database connection + // if fail - revert the setting and inform the user + if ($database['database_overwrite'] && !Settings::testDatabaseConnection($database)) { + foreach ($database as $key => $value) { + if (!in_array($key, ['database_log', 'database_persistent'])) { // ignore these two + $configToSave[$key] = $config[$key]; + } + } + } + + return Settings::saveConfig($configToSave, BASE . 'config.local.php'); + }, + ], +]; + diff --git a/system/status.php b/system/status.php index 86cba2ed..310e4127 100644 --- a/system/status.php +++ b/system/status.php @@ -17,7 +17,7 @@ $status['lastCheck'] = 0; $status['uptime'] = '0h 0m'; $status['monsters'] = 0; -if(config('status_enabled') === false) { +if(setting('core.status_enabled') === false) { return; } @@ -37,9 +37,10 @@ else if(isset($config['lua']['status_port'])) { } // ip check -if(isset($config['status_ip'][0])) +$settingIP = setting('core.status_ip'); +if(isset($settingIP[0])) { - $status_ip = $config['status_ip']; + $status_ip = $settingIP; } elseif(!isset($status_ip[0])) // try localhost if no ip specified { @@ -48,10 +49,11 @@ elseif(!isset($status_ip[0])) // try localhost if no ip specified // port check $status_port = $config['lua']['statusPort']; -if(isset($config['status_port'][0])) { - $status_port = $config['status_port']; +$settingPort = setting('core.status_port'); +if(isset($settingPort[0])) { + $status_port = $settingPort; } -elseif(!isset($status_port[0])) // try 7171 if no ip specified +elseif(!isset($status_port[0])) // try 7171 if no port specified { $status_port = 7171; } @@ -94,9 +96,9 @@ if(isset($config['lua']['statustimeout'])) // get status timeout from server config $status_timeout = eval('return ' . $config['lua']['statusTimeout'] . ';') / 1000 + 1; -$status_interval = @$config['status_interval']; -if($status_interval && $status_timeout < $config['status_interval']) { - $status_timeout = $config['status_interval']; +$status_interval = setting('core.status_interval'); +if($status_interval && $status_timeout < $status_interval) { + $status_timeout = $status_interval; } if($status['lastCheck'] + $status_timeout < time()) { diff --git a/system/template.php b/system/template.php index 72ae3792..a01939a4 100644 --- a/system/template.php +++ b/system/template.php @@ -10,8 +10,8 @@ defined('MYAAC') or die('Direct access not allowed!'); // template -$template_name = $config['template']; -if($config['template_allow_change']) +$template_name = setting('core.template'); +if(setting('core.template_allow_change')) { if(isset($_GET['template'])) { @@ -111,12 +111,13 @@ $template['link_screenshots'] = getLink('gallery'); $template['link_movies'] = getLink('videos'); $template['link_gifts_history'] = getLink('gifts', 'history'); -if($config['forum'] != '') +$forumSetting = setting('core.forum'); +if($forumSetting != '') { - if(strtolower($config['forum']) == 'site') + if(strtolower($forumSetting) == 'site') $template['link_forum'] = ""; else - $template['link_forum'] = ""; + $template['link_forum'] = ""; } $twig->addGlobal('template_path', $template_path); diff --git a/system/templates/account.change_name.html.twig b/system/templates/account.change_name.html.twig index bd1fa8f0..76c038d4 100644 --- a/system/templates/account.change_name.html.twig +++ b/system/templates/account.change_name.html.twig @@ -1,5 +1,5 @@ To change a name of character select player and choose a new name.
    -Change name cost {{ config.account_change_character_name_points }} premium points. You have {{ points }} premium points.

    +Change name cost {{ setting('core.account_change_character_name_price') }} premium points. You have {{ points }} premium points.

    diff --git a/system/templates/account.change_sex.html.twig b/system/templates/account.change_sex.html.twig index 07ea83e9..24141f61 100644 --- a/system/templates/account.change_sex.html.twig +++ b/system/templates/account.change_sex.html.twig @@ -1,5 +1,5 @@ To change a sex of character select player and choose a new sex.
    -Change sex cost {{ config.account_change_character_sex_points }} premium points. You have {{ points }} premium points.

    +Change sex cost {{ setting('core.account_change_character_sex_price') }} premium points. You have {{ points }} premium points.

    @@ -73,4 +73,4 @@ To change a sex of character select player and choose a new sex.
    - \ No newline at end of file + diff --git a/system/templates/account.create.html.twig b/system/templates/account.create.html.twig index 38907c74..a43d6e7d 100644 --- a/system/templates/account.create.html.twig +++ b/system/templates/account.create.html.twig @@ -59,7 +59,7 @@ {% if errors.email is defined %}{{ errors.email }}{% endif %} - {% if config.mail_enabled and config.account_mail_verify %} + {% if setting('core.mail_enabled') and config.account_mail_verify %} Please use real address!
    We will send a link to validate your Email.
    {% endif %} @@ -122,7 +122,7 @@ {{ hook('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1') }} - {% if (not config.mail_enabled or not config.account_mail_verify) and config.account_create_character_create %} + {% if (not setting('core.mail_enabled') or not config.account_mail_verify) and config.account_create_character_create %}
    @@ -140,7 +140,7 @@ Character Name: - +
    diff --git a/system/templates/account.create_character.html.twig b/system/templates/account.create_character.html.twig index 045c749c..acb57f5c 100644 --- a/system/templates/account.create_character.html.twig +++ b/system/templates/account.create_character.html.twig @@ -45,7 +45,7 @@ In any case the name must not violate the naming conventions stated in the
    - +
    @@ -145,4 +145,4 @@ In any case the name must not violate the naming conventions stated in the
    - \ No newline at end of file + diff --git a/system/templates/account.generate_new_recovery_key.html.twig b/system/templates/account.generate_new_recovery_key.html.twig index f1ec611b..6f3e5c50 100644 --- a/system/templates/account.generate_new_recovery_key.html.twig +++ b/system/templates/account.generate_new_recovery_key.html.twig @@ -1,5 +1,5 @@ To generate new recovery key for your account please enter your password.
    -New recovery key cost {{ config.generate_new_reckey_price }} Premium Points. You have {{ points }} premium points. You will receive e-mail with this recovery key.
    +New recovery key cost {{ setting('core.account_generate_new_reckey_price') }} Premium Points. You have {{ points }} premium points. You will receive e-mail with this recovery key.
    @@ -56,4 +56,4 @@ To generate new recovery key for your account please enter your password.
    - \ No newline at end of file + diff --git a/system/templates/account.management.html.twig b/system/templates/account.management.html.twig index 510c90a1..95fc0975 100644 --- a/system/templates/account.management.html.twig +++ b/system/templates/account.management.html.twig @@ -39,10 +39,10 @@ {% for name, link in menus %}
    {{ name }} {% endfor %} - {% if config.account_change_character_name %} + {% if setting('core.account_change_character_name') %} Change Name {% endif %} - {% if config.account_change_character_sex %} + {% if setting('core.account_change_character_sex') %} Change Sex {% endif %} Logout @@ -192,7 +192,7 @@ {% include('buttons.base.html.twig') %} - {% if config.account_change_character_name %} + {% if setting('core.account_change_character_name') %}
    {% set button_name = 'Change Name' %} @@ -200,7 +200,7 @@
    {% endif %} - {% if config.account_change_character_sex %} + {% if setting('core.account_change_character_sex') %}
    {% set button_name = 'Change Sex' %} diff --git a/system/templates/admin.settings.html.twig b/system/templates/admin.settings.html.twig new file mode 100644 index 00000000..e5d3ef9b --- /dev/null +++ b/system/templates/admin.settings.html.twig @@ -0,0 +1,105 @@ +
    +
    +
    Settings
    +
    +
    + +
    +
    +
    +
    + +
    +
    + {{ settingsParsed|raw }} +
    +
    +
    + +
    +
    + + +{{ script|raw }} + + + + diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 4234f2ab..9553d20c 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -284,7 +284,7 @@ {{ hook(constant('HOOK_CHARACTERS_BEFORE_SIGNATURE')) }} - {% if config.signature_enabled %} + {% if setting('core.signature_enabled') %} \ No newline at end of file + diff --git a/system/templates/install.config.html.twig b/system/templates/install.config.html.twig index 0776d540..ab4fc361 100644 --- a/system/templates/install.config.html.twig +++ b/system/templates/install.config.html.twig @@ -9,7 +9,7 @@
    - {% for value in ['server_path', 'mail_admin'] %} + {% for value in ['server_path'] %}
    diff --git a/system/templates/mail.password_changed.html.twig b/system/templates/mail.password_changed.html.twig index d87601f0..a43af3a2 100644 --- a/system/templates/mail.password_changed.html.twig +++ b/system/templates/mail.password_changed.html.twig @@ -4,4 +4,4 @@ The request was made on {{ "now"|date("F j, Y, g:i a") }} by a user with the IP:

    The new password is: {{ new_password }}

    -If this was you, please ignore this email. If it was not you, please contact our support department at {{ config.mail_admin }}. \ No newline at end of file +If this was you, please ignore this email. If it was not you, please contact our support department. diff --git a/system/templates/team.html.twig b/system/templates/team.html.twig index bbbe35cd..a979e670 100644 --- a/system/templates/team.html.twig +++ b/system/templates/team.html.twig @@ -25,7 +25,7 @@ Group - {% if config.team_display_outfit %} + {% if setting('core.team_outfit') %} Outfit @@ -35,19 +35,19 @@ Name - {% if config.team_display_status %} + {% if setting('core.team_status') %} Status {% endif %} - {% if (config.multiworld or config.team_display_world) %} + {% if (setting('core.multiworld') or setting('core.team_world')) %} World {% endif %} - {% if config.team_display_lastlogin %} + {% if setting('core.team_lastlogin') %} Last login @@ -61,7 +61,7 @@ {{ group.group_name|capitalize }} - {% if config.team_display_outfit %} + {% if setting('core.team_outfit') %} player outfit @@ -74,7 +74,7 @@ {{ member.link|raw }} - {% if config.team_display_status %} + {% if setting('core.team_status') %} {% if member.status %} Online @@ -84,13 +84,13 @@ {% endif %} - {% if (config.multiworld or config.team_display_world) %} + {% if (setting('core.multiworld') or setting('core.team_world')) %} {{ member.world_name }} {% endif %} - {% if config.team_display_lastlogin %} + {% if setting('core.team_lastlogin') %} {{ member.last_login }} @@ -107,7 +107,7 @@ - {% if config.team_display_outfit %} + {% if setting('core.team_outfit') %} @@ -117,19 +117,19 @@ Name - {% if config.team_display_status %} + {% if setting('core.team_status') %} {% endif %} - {% if (config.multiworld or config.team_display_world) %} + {% if (setting('core.multiworld') or setting('core.team_world')) %} {% endif %} - {% if config.team_display_lastlogin %} + {% if setting('core.team_lastlogin') %} @@ -139,7 +139,7 @@ {% for member in group.members %} {% set i = i + 1 %} - {% if config.team_display_outfit %} + {% if setting('core.team_outfit') %} @@ -152,7 +152,7 @@ {{ member.link|raw }} - {% if config.team_display_status %} + {% if setting('core.team_status') %} {% endif %} - {% if (config.multiworld or config.team_display_world) %} + {% if (setting('core.multiworld') or setting('core.team_world')) %} {% endif %} - {% if config.team_display_lastlogin %} + {% if setting('core.team_lastlogin') %} diff --git a/system/twig.php b/system/twig.php index 4fc7c5ec..5eb35c68 100644 --- a/system/twig.php +++ b/system/twig.php @@ -107,6 +107,11 @@ $function = new TwigFunction('config', function ($key) { }); $twig->addFunction($function); +$function = new TwigFunction('setting', function ($key) { + return setting($key); +}); +$twig->addFunction($function); + $function = new TwigFunction('getCustomPage', function ($name) { $success = false; return getCustomPage($name, $success); diff --git a/templates/tibiacom/account.management.html.twig b/templates/tibiacom/account.management.html.twig index 7c387c36..e1106e8c 100644 --- a/templates/tibiacom/account.management.html.twig +++ b/templates/tibiacom/account.management.html.twig @@ -470,7 +470,7 @@
    Outfit Status World Last login
    player outfit {% if member.status %} Online @@ -162,13 +162,13 @@ {{ member.world_name }} {{ member.last_login }}
    - {% if config.account_change_character_name %} + {% if setting('core.account_change_character_name') %} @@ -483,7 +483,7 @@
    {% endif %} - {% if config.account_change_character_sex %} + {% if setting('core.account_change_character_sex') %} diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 539453c9..6bb5f445 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -289,7 +289,7 @@ if(isset($config['boxes'])) logoartworklogoartworklogoartwork - logoartwork + logoartwork
    diff --git a/tools/css/toastify.min.css b/tools/css/toastify.min.css new file mode 100644 index 00000000..427c25bc --- /dev/null +++ b/tools/css/toastify.min.css @@ -0,0 +1,15 @@ +/** + * Minified by jsDelivr using clean-css v5.3.0. + * Original file: /npm/toastify-js@1.12.0/src/toastify.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +/*! + * Toastify js 1.12.0 + * https://github.com/apvarun/toastify-js + * @license MIT licensed + * + * Copyright (C) 2018 Varun A P + */ +.toastify{padding:12px 20px;color:#fff;display:inline-block;box-shadow:0 3px 6px -1px rgba(0,0,0,.12),0 10px 36px -4px rgba(77,96,232,.3);background:-webkit-linear-gradient(315deg,#73a5ff,#5477f5);background:linear-gradient(135deg,#73a5ff,#5477f5);position:fixed;opacity:0;transition:all .4s cubic-bezier(.215, .61, .355, 1);border-radius:2px;cursor:pointer;text-decoration:none;max-width:calc(50% - 20px);z-index:2147483647}.toastify.on{opacity:1}.toast-close{background:0 0;border:0;color:#fff;cursor:pointer;font-family:inherit;font-size:1em;opacity:.4;padding:0 5px}.toastify-right{right:15px}.toastify-left{left:15px}.toastify-top{top:-150px}.toastify-bottom{bottom:-150px}.toastify-rounded{border-radius:25px}.toastify-avatar{width:1.5em;height:1.5em;margin:-7px 5px;border-radius:2px}.toastify-center{margin-left:auto;margin-right:auto;left:0;right:0;max-width:fit-content;max-width:-moz-fit-content}@media only screen and (max-width:360px){.toastify-left,.toastify-right{margin-left:auto;margin-right:auto;left:0;right:0;max-width:fit-content}} +/*# sourceMappingURL=/sm/cb4335d1b03e933ed85cb59fffa60cf51f07567ed09831438c60f59afd166464.map */ \ No newline at end of file diff --git a/tools/js/toastify.min.js b/tools/js/toastify.min.js new file mode 100644 index 00000000..29af3859 --- /dev/null +++ b/tools/js/toastify.min.js @@ -0,0 +1,15 @@ +/** + * Minified by jsDelivr using Terser v5.14.1. + * Original file: /npm/toastify-js@1.12.0/src/toastify.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +/*! + * Toastify js 1.12.0 + * https://github.com/apvarun/toastify-js + * @license MIT licensed + * + * Copyright (C) 2018 Varun A P + */ +!function(t,o){"object"==typeof module&&module.exports?module.exports=o():t.Toastify=o()}(this,(function(t){var o=function(t){return new o.lib.init(t)};function i(t,o){return o.offset[t]?isNaN(o.offset[t])?o.offset[t]:o.offset[t]+"px":"0px"}function s(t,o){return!(!t||"string"!=typeof o)&&!!(t.className&&t.className.trim().split(/\s+/gi).indexOf(o)>-1)}return o.defaults={oldestFirst:!0,text:"Toastify is awesome!",node:void 0,duration:3e3,selector:void 0,callback:function(){},destination:void 0,newWindow:!1,close:!1,gravity:"toastify-top",positionLeft:!1,position:"",backgroundColor:"",avatar:"",className:"",stopOnFocus:!0,onClick:function(){},offset:{x:0,y:0},escapeMarkup:!0,ariaLive:"polite",style:{background:""}},o.lib=o.prototype={toastify:"1.12.0",constructor:o,init:function(t){return t||(t={}),this.options={},this.toastElement=null,this.options.text=t.text||o.defaults.text,this.options.node=t.node||o.defaults.node,this.options.duration=0===t.duration?0:t.duration||o.defaults.duration,this.options.selector=t.selector||o.defaults.selector,this.options.callback=t.callback||o.defaults.callback,this.options.destination=t.destination||o.defaults.destination,this.options.newWindow=t.newWindow||o.defaults.newWindow,this.options.close=t.close||o.defaults.close,this.options.gravity="bottom"===t.gravity?"toastify-bottom":o.defaults.gravity,this.options.positionLeft=t.positionLeft||o.defaults.positionLeft,this.options.position=t.position||o.defaults.position,this.options.backgroundColor=t.backgroundColor||o.defaults.backgroundColor,this.options.avatar=t.avatar||o.defaults.avatar,this.options.className=t.className||o.defaults.className,this.options.stopOnFocus=void 0===t.stopOnFocus?o.defaults.stopOnFocus:t.stopOnFocus,this.options.onClick=t.onClick||o.defaults.onClick,this.options.offset=t.offset||o.defaults.offset,this.options.escapeMarkup=void 0!==t.escapeMarkup?t.escapeMarkup:o.defaults.escapeMarkup,this.options.ariaLive=t.ariaLive||o.defaults.ariaLive,this.options.style=t.style||o.defaults.style,t.backgroundColor&&(this.options.style.background=t.backgroundColor),this},buildToast:function(){if(!this.options)throw"Toastify is not initialized";var t=document.createElement("div");for(var o in t.className="toastify on "+this.options.className,this.options.position?t.className+=" toastify-"+this.options.position:!0===this.options.positionLeft?(t.className+=" toastify-left",console.warn("Property `positionLeft` will be depreciated in further versions. Please use `position` instead.")):t.className+=" toastify-right",t.className+=" "+this.options.gravity,this.options.backgroundColor&&console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'),this.options.style)t.style[o]=this.options.style[o];if(this.options.ariaLive&&t.setAttribute("aria-live",this.options.ariaLive),this.options.node&&this.options.node.nodeType===Node.ELEMENT_NODE)t.appendChild(this.options.node);else if(this.options.escapeMarkup?t.innerText=this.options.text:t.innerHTML=this.options.text,""!==this.options.avatar){var s=document.createElement("img");s.src=this.options.avatar,s.className="toastify-avatar","left"==this.options.position||!0===this.options.positionLeft?t.appendChild(s):t.insertAdjacentElement("afterbegin",s)}if(!0===this.options.close){var e=document.createElement("button");e.type="button",e.setAttribute("aria-label","Close"),e.className="toast-close",e.innerHTML="✖",e.addEventListener("click",function(t){t.stopPropagation(),this.removeElement(this.toastElement),window.clearTimeout(this.toastElement.timeOutValue)}.bind(this));var n=window.innerWidth>0?window.innerWidth:screen.width;("left"==this.options.position||!0===this.options.positionLeft)&&n>360?t.insertAdjacentElement("afterbegin",e):t.appendChild(e)}if(this.options.stopOnFocus&&this.options.duration>0){var a=this;t.addEventListener("mouseover",(function(o){window.clearTimeout(t.timeOutValue)})),t.addEventListener("mouseleave",(function(){t.timeOutValue=window.setTimeout((function(){a.removeElement(t)}),a.options.duration)}))}if(void 0!==this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),!0===this.options.newWindow?window.open(this.options.destination,"_blank"):window.location=this.options.destination}.bind(this)),"function"==typeof this.options.onClick&&void 0===this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),this.options.onClick()}.bind(this)),"object"==typeof this.options.offset){var l=i("x",this.options),r=i("y",this.options),p="left"==this.options.position?l:"-"+l,d="toastify-top"==this.options.gravity?r:"-"+r;t.style.transform="translate("+p+","+d+")"}return t},showToast:function(){var t;if(this.toastElement=this.buildToast(),!(t="string"==typeof this.options.selector?document.getElementById(this.options.selector):this.options.selector instanceof HTMLElement||"undefined"!=typeof ShadowRoot&&this.options.selector instanceof ShadowRoot?this.options.selector:document.body))throw"Root element is not defined";var i=o.defaults.oldestFirst?t.firstChild:t.lastChild;return t.insertBefore(this.toastElement,i),o.reposition(),this.options.duration>0&&(this.toastElement.timeOutValue=window.setTimeout(function(){this.removeElement(this.toastElement)}.bind(this),this.options.duration)),this},hideToast:function(){this.toastElement.timeOutValue&&clearTimeout(this.toastElement.timeOutValue),this.removeElement(this.toastElement)},removeElement:function(t){t.className=t.className.replace(" on",""),window.setTimeout(function(){this.options.node&&this.options.node.parentNode&&this.options.node.parentNode.removeChild(this.options.node),t.parentNode&&t.parentNode.removeChild(t),this.options.callback.call(t),o.reposition()}.bind(this),400)}},o.reposition=function(){for(var t,o={top:15,bottom:15},i={top:15,bottom:15},e={top:15,bottom:15},n=document.getElementsByClassName("toastify"),a=0;a0?window.innerWidth:screen.width)<=360?(n[a].style[t]=e[t]+"px",e[t]+=l+15):!0===s(n[a],"toastify-left")?(n[a].style[t]=o[t]+"px",o[t]+=l+15):(n[a].style[t]=i[t]+"px",i[t]+=l+15)}return this},o.lib.init.prototype=o.lib,o})); +//# sourceMappingURL=/sm/e1ebbfe1bf0b0061f0726ebc83434e1c2f8308e6354c415fd05ecccdaad47617.map \ No newline at end of file diff --git a/tools/signature/index.php b/tools/signature/index.php index e3e33303..f196781e 100644 --- a/tools/signature/index.php +++ b/tools/signature/index.php @@ -21,12 +21,14 @@ define('SIGNATURES_IMAGES', SIGNATURES . 'images/'); define('SIGNATURES_ITEMS', BASE . 'images/items/'); - if(!$config['signature_enabled']) + if(!setting('core.signature_enabled')) { die('Signatures are disabled on this server.'); + } - $file = trim(strtolower($config['signature_type'])) . '.php'; - if(!file_exists($file)) - die('ERROR: Wrong signature_type in config.'); + $file = trim(strtolower(setting('core.signature_type'))) . '.php'; + if(!file_exists($file)) { + die('ERROR: Wrong signature_type in Settings.'); + } putenv('GDFONTPATH=' . SIGNATURES_FONTS); @@ -52,7 +54,7 @@ } $cached = SIGNATURES_CACHE.$player->getId() . '.png'; - if(file_exists($cached) && (time() < (filemtime($cached) + (60 * $config['signature_cache_time'])))) + if(file_exists($cached) && (time() < (filemtime($cached) + (60 * setting('core.signature_cache_time'))))) { header( 'Content-type: image/png' ); readfile( SIGNATURES_CACHE.$player->getId().'.png' ); @@ -61,7 +63,7 @@ require $file; header('Content-type: image/png'); - $seconds_to_cache = $config['signature_browser_cache'] * 60; + $seconds_to_cache = setting('core.signature_browser_cache') * 60; $ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT"; header('Expires: ' . $ts); header('Pragma: cache'); From 23266e05ed5445437c183dc64aaa00728b3dbc52 Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 10 Aug 2023 12:02:43 +0200 Subject: [PATCH 204/232] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8edd3cbc..f1567d74 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Official website: https://my-aac.org ### Requirements - - PHP 5.6 or later + - PHP 7.2.5 or later - MySQL database - PDO PHP Extension - XML PHP Extension - - ZIP PHP Extension + - (optional) ZIP PHP Extension - (optional) mod_rewrite to use friendly_urls ### Installation From 7bab8f033c93cfd5560b6cb6545ddcad3882a8fe Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 10 Aug 2023 13:00:18 +0200 Subject: [PATCH 205/232] Allow hook file to be callable --- system/hooks.php | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/system/hooks.php b/system/hooks.php index 69bdcfbd..81bbeac9 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -91,15 +91,25 @@ class Hook public function execute($params) { - extract($params); - /*if(is_callable($this->_callback)) - { - $tmp = $this->_callback; - $ret = $tmp($params); - }*/ - global $db, $config, $template_path, $ots, $content, $twig; - $ret = include BASE . $this->_file; + + if(is_callable($this->_file)) + { + $params['db'] = $db; + $params['config'] = $config; + $params['template_path'] = $template_path; + $params['ots'] = $ots; + $params['content'] = $content; + $params['twig'] = $twig; + + $tmp = $this->_file; + $ret = $tmp($params); + } + else { + extract($params); + + $ret = include BASE . $this->_file; + } return !isset($ret) || $ret == 1 || $ret; } From 16ebc1f577c833e4ef0cd2b00ad0eadf206c8bbb Mon Sep 17 00:00:00 2001 From: slawkens Date: Thu, 10 Aug 2023 13:05:17 +0200 Subject: [PATCH 206/232] Update functions.php --- system/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/functions.php b/system/functions.php index 11803c69..75234685 100644 --- a/system/functions.php +++ b/system/functions.php @@ -482,7 +482,7 @@ function template_place_holder($type): string function template_header($is_admin = false): string { global $title_full, $config, $twig; - $charset = isset($config['charset']) ? $config['charset'] : 'utf-8'; + $charset = $config['charset'] ?? 'utf-8'; return $twig->render('templates.header.html.twig', [ From 98335b8cc0dbc9c6130fbb8e688e08a4469ac37d Mon Sep 17 00:00:00 2001 From: Gabriel Pedro Date: Fri, 11 Aug 2023 01:39:17 -0300 Subject: [PATCH 207/232] feat: add more tests (#229) --- cypress/e2e/3-check-public-pages.cy.js | 174 ++++++++++++++++++++++ cypress/e2e/4-check-protected-pages.cy.js | 81 ++++++++++ package.json | 3 + 3 files changed, 258 insertions(+) create mode 100644 cypress/e2e/3-check-public-pages.cy.js create mode 100644 cypress/e2e/4-check-protected-pages.cy.js diff --git a/cypress/e2e/3-check-public-pages.cy.js b/cypress/e2e/3-check-public-pages.cy.js new file mode 100644 index 00000000..577275ad --- /dev/null +++ b/cypress/e2e/3-check-public-pages.cy.js @@ -0,0 +1,174 @@ +describe('Check Public Pages', () => { + + /// news + it('Go to news page', () => { + cy.visit({ + url: Cypress.env('URL') + '/news', + method: 'GET', + }) + }) + + it('Go to news archive page', () => { + cy.visit({ + url: Cypress.env('URL') + '/news/archive', + method: 'GET', + }) + }) + + it('Go to changelog page', () => { + cy.visit({ + url: Cypress.env('URL') + '/changelog', + method: 'GET', + }) + }) + + /// account management + it('Go to account manage page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/manage', + method: 'GET', + }) + }) + + it('Go to account create page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/create', + method: 'GET', + }) + }) + + it('Go to account lost page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/lost', + method: 'GET', + }) + }) + + it('Go to rules page', () => { + cy.visit({ + url: Cypress.env('URL') + '/rules', + method: 'GET', + }) + }) + + // community + it('Go to online page', () => { + cy.visit({ + url: Cypress.env('URL') + '/online', + method: 'GET', + }) + }) + + it('Go to characters list page', () => { + cy.visit({ + url: Cypress.env('URL') + '/characters', + method: 'GET', + }) + }) + + it('Go to guilds page', () => { + cy.visit({ + url: Cypress.env('URL') + '/guilds', + method: 'GET', + }) + }) + + it('Go to highscores page', () => { + cy.visit({ + url: Cypress.env('URL') + '/highscores', + method: 'GET', + }) + }) + + it('Go to last kills page', () => { + cy.visit({ + url: Cypress.env('URL') + '/lastkills', + method: 'GET', + }) + }) + + it('Go to houses page', () => { + cy.visit({ + url: Cypress.env('URL') + '/houses', + method: 'GET', + }) + }) + + it('Go to bans page', () => { + cy.visit({ + url: Cypress.env('URL') + '/bans', + method: 'GET', + }) + }) + + it('Go to forum page', () => { + cy.visit({ + url: Cypress.env('URL') + '/forum', + method: 'GET', + }) + }) + + it('Go to team page', () => { + cy.visit({ + url: Cypress.env('URL') + '/team', + method: 'GET', + }) + }) + + // library + it('Go to creatures page', () => { + cy.visit({ + url: Cypress.env('URL') + '/creatures', + method: 'GET', + }) + }) + + it('Go to spells page', () => { + cy.visit({ + url: Cypress.env('URL') + '/spells', + method: 'GET', + }) + }) + + it('Go to server info page', () => { + cy.visit({ + url: Cypress.env('URL') + '/serverInfo', + method: 'GET', + }) + }) + + it('Go to commands page', () => { + cy.visit({ + url: Cypress.env('URL') + '/commands', + method: 'GET', + }) + }) + + it('Go to downloads page', () => { + cy.visit({ + url: Cypress.env('URL') + '/downloads', + method: 'GET', + }) + }) + + it('Go to gallery page', () => { + cy.visit({ + url: Cypress.env('URL') + '/gallery', + method: 'GET', + }) + }) + + it('Go to experience table page', () => { + cy.visit({ + url: Cypress.env('URL') + '/experienceTable', + method: 'GET', + }) + }) + + it('Go to faq page', () => { + cy.visit({ + url: Cypress.env('URL') + '/faq', + method: 'GET', + }) + }) +}) diff --git a/cypress/e2e/4-check-protected-pages.cy.js b/cypress/e2e/4-check-protected-pages.cy.js new file mode 100644 index 00000000..c3c4b4c6 --- /dev/null +++ b/cypress/e2e/4-check-protected-pages.cy.js @@ -0,0 +1,81 @@ +const REQUIRED_LOGIN_MESSAGE = 'Please enter your account name and your password.'; +const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.'; + +describe('Check Protected Pages', () => { + + // character actions + it('Go to accouht character creation page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/character/create', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht character deletion page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/character/delete', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + // account actions + it('Go to accouht email change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/email', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht password change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/password', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht info change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/info', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht logout change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/logout', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + // guild actions + it('Go to guild creation page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=create', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + + it('Go to guilds cleanup players action page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_players', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + + it('Go to guilds cleanup guilds action page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_guilds', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + +}) diff --git a/package.json b/package.json index 0e20e9b5..25a88c5c 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,7 @@ { + "scripts": { + "cypress:open": "cypress open" + }, "devDependencies": { "cypress": "^12.12.0" } From cfc4f3601ba7c6043e6655c74e84e752764798f4 Mon Sep 17 00:00:00 2001 From: Gabriel Pedro Date: Fri, 11 Aug 2023 01:39:17 -0300 Subject: [PATCH 208/232] feat: add more tests (#229) --- cypress/e2e/3-check-public-pages.cy.js | 174 ++++++++++++++++++++++ cypress/e2e/4-check-protected-pages.cy.js | 81 ++++++++++ package.json | 3 + 3 files changed, 258 insertions(+) create mode 100644 cypress/e2e/3-check-public-pages.cy.js create mode 100644 cypress/e2e/4-check-protected-pages.cy.js diff --git a/cypress/e2e/3-check-public-pages.cy.js b/cypress/e2e/3-check-public-pages.cy.js new file mode 100644 index 00000000..577275ad --- /dev/null +++ b/cypress/e2e/3-check-public-pages.cy.js @@ -0,0 +1,174 @@ +describe('Check Public Pages', () => { + + /// news + it('Go to news page', () => { + cy.visit({ + url: Cypress.env('URL') + '/news', + method: 'GET', + }) + }) + + it('Go to news archive page', () => { + cy.visit({ + url: Cypress.env('URL') + '/news/archive', + method: 'GET', + }) + }) + + it('Go to changelog page', () => { + cy.visit({ + url: Cypress.env('URL') + '/changelog', + method: 'GET', + }) + }) + + /// account management + it('Go to account manage page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/manage', + method: 'GET', + }) + }) + + it('Go to account create page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/create', + method: 'GET', + }) + }) + + it('Go to account lost page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/lost', + method: 'GET', + }) + }) + + it('Go to rules page', () => { + cy.visit({ + url: Cypress.env('URL') + '/rules', + method: 'GET', + }) + }) + + // community + it('Go to online page', () => { + cy.visit({ + url: Cypress.env('URL') + '/online', + method: 'GET', + }) + }) + + it('Go to characters list page', () => { + cy.visit({ + url: Cypress.env('URL') + '/characters', + method: 'GET', + }) + }) + + it('Go to guilds page', () => { + cy.visit({ + url: Cypress.env('URL') + '/guilds', + method: 'GET', + }) + }) + + it('Go to highscores page', () => { + cy.visit({ + url: Cypress.env('URL') + '/highscores', + method: 'GET', + }) + }) + + it('Go to last kills page', () => { + cy.visit({ + url: Cypress.env('URL') + '/lastkills', + method: 'GET', + }) + }) + + it('Go to houses page', () => { + cy.visit({ + url: Cypress.env('URL') + '/houses', + method: 'GET', + }) + }) + + it('Go to bans page', () => { + cy.visit({ + url: Cypress.env('URL') + '/bans', + method: 'GET', + }) + }) + + it('Go to forum page', () => { + cy.visit({ + url: Cypress.env('URL') + '/forum', + method: 'GET', + }) + }) + + it('Go to team page', () => { + cy.visit({ + url: Cypress.env('URL') + '/team', + method: 'GET', + }) + }) + + // library + it('Go to creatures page', () => { + cy.visit({ + url: Cypress.env('URL') + '/creatures', + method: 'GET', + }) + }) + + it('Go to spells page', () => { + cy.visit({ + url: Cypress.env('URL') + '/spells', + method: 'GET', + }) + }) + + it('Go to server info page', () => { + cy.visit({ + url: Cypress.env('URL') + '/serverInfo', + method: 'GET', + }) + }) + + it('Go to commands page', () => { + cy.visit({ + url: Cypress.env('URL') + '/commands', + method: 'GET', + }) + }) + + it('Go to downloads page', () => { + cy.visit({ + url: Cypress.env('URL') + '/downloads', + method: 'GET', + }) + }) + + it('Go to gallery page', () => { + cy.visit({ + url: Cypress.env('URL') + '/gallery', + method: 'GET', + }) + }) + + it('Go to experience table page', () => { + cy.visit({ + url: Cypress.env('URL') + '/experienceTable', + method: 'GET', + }) + }) + + it('Go to faq page', () => { + cy.visit({ + url: Cypress.env('URL') + '/faq', + method: 'GET', + }) + }) +}) diff --git a/cypress/e2e/4-check-protected-pages.cy.js b/cypress/e2e/4-check-protected-pages.cy.js new file mode 100644 index 00000000..c3c4b4c6 --- /dev/null +++ b/cypress/e2e/4-check-protected-pages.cy.js @@ -0,0 +1,81 @@ +const REQUIRED_LOGIN_MESSAGE = 'Please enter your account name and your password.'; +const YOU_ARE_NOT_LOGGEDIN = 'You are not logged in.'; + +describe('Check Protected Pages', () => { + + // character actions + it('Go to accouht character creation page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/character/create', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht character deletion page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/character/delete', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + // account actions + it('Go to accouht email change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/email', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht password change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/password', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht info change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/info', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + it('Go to accouht logout change page', () => { + cy.visit({ + url: Cypress.env('URL') + '/account/logout', + method: 'GET', + }) + cy.contains(REQUIRED_LOGIN_MESSAGE) + }) + + // guild actions + it('Go to guild creation page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=create', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + + it('Go to guilds cleanup players action page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_players', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + + it('Go to guilds cleanup guilds action page', () => { + cy.visit({ + url: Cypress.env('URL') + '/?subtopic=guilds&action=cleanup_guilds', + method: 'GET', + }) + cy.contains(YOU_ARE_NOT_LOGGEDIN) + }) + +}) diff --git a/package.json b/package.json index 0e20e9b5..25a88c5c 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,7 @@ { + "scripts": { + "cypress:open": "cypress open" + }, "devDependencies": { "cypress": "^12.12.0" } From d8f1bf0a50d7e5b54efe13c3363796c544390369 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 11 Aug 2023 18:52:11 +0200 Subject: [PATCH 209/232] Fix exception when monster doesn't have look defined --- system/libs/pot/OTS_Monster.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/libs/pot/OTS_Monster.php b/system/libs/pot/OTS_Monster.php index a7e079ac..244a0229 100644 --- a/system/libs/pot/OTS_Monster.php +++ b/system/libs/pot/OTS_Monster.php @@ -276,7 +276,7 @@ class OTS_Monster extends DOMDocument /** * Returns look of the monster. - * + * * @return array Look with all the attributes of the look. * @throws DOMException On DOM operation error. */ @@ -286,6 +286,10 @@ class OTS_Monster extends DOMDocument $element = $this->documentElement->getElementsByTagName('look')->item(0); + if (!$element) { + return $look; + } + $look['type'] = $element->getAttribute('type'); $look['typeex'] = $element->getAttribute('typeex'); $look['head'] = $element->getAttribute('head'); From a70daa88305400a58d8eae5f1d3bee3837009c6c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 11 Aug 2023 22:11:10 +0200 Subject: [PATCH 210/232] Add version support table + fix badges --- README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f1567d74..17d732b2 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,22 @@ # [MyAAC](https://my-aac.org) -[![Build Status Master](https://img.shields.io/travis/slawkens/myaac/master)](https://travis-ci.org/github/slawkens/myaac) -[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license) -[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases) -[![PHP Versions](https://img.shields.io/travis/php-v/slawkens/myaac/master)](https://github.com/slawkens/myaac/blob/d8b3b4135827ee17e3c6d41f08a925e718c587ed/.travis.yml#L3) -[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus) -[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed) - MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP. It is a fork of the [Gesior](https://github.com/gesior/Gesior2012) project. It supports only MySQL databases. Official website: https://my-aac.org +[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/slawkens/myaac/cypress.yml)](https://github.com/slawkens/myaac/actions) +[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license) +[![Downloads Count](https://img.shields.io/github/downloads/slawkens/myaac/total)](https://github.com/slawkens/myaac/releases) +[![OpenTibia Discord](https://img.shields.io/discord/288399552581468162)](https://discord.gg/2J39Wus) +[![Closed Issues](https://img.shields.io/github/issues-closed-raw/slawkens/myaac)](https://github.com/slawkens/myaac/issues?q=is%3Aissue+is%3Aclosed) + +| Version | Status | Branch | Requirements | +|:-----------|:------------------------------------------|:--------|:---------------| +| **0.10.x** | **Active development** | develop | **PHP >= 8.0** | +| 0.9.x | Active support | 0.9 | PHP >= 7.2.5 | +| 0.8.x | Active support | master | PHP >= 7.2.5 | +| 0.7.x | End Of Life | 0.7 | PHP >= 5.3.3 | + ### Requirements - PHP 7.2.5 or later From 538723c4052d5d42984f7bda1e986caf91560eb9 Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 11 Aug 2023 22:16:07 +0200 Subject: [PATCH 211/232] Added JetBrains logo + notice, thanks for support! --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 17d732b2..127892a1 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,13 @@ Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our w ### Other Notes - If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org +If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org + +## Project supported by JetBrains + +Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects. + +[![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/slawkens) ### License From 0f38a677b12b280f9740d05433198e73be0849af Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 11 Aug 2023 22:20:00 +0200 Subject: [PATCH 212/232] Require PHP min 8.0, older versions are EOL --- README.md | 2 +- common.php | 2 +- composer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 127892a1..3597df17 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Official website: https://my-aac.org ### Requirements - - PHP 7.2.5 or later + - PHP 8.0 or later - MySQL database - PDO PHP Extension - XML PHP Extension diff --git a/common.php b/common.php index c1a89bbd..13cdabb7 100644 --- a/common.php +++ b/common.php @@ -23,7 +23,7 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ -if (version_compare(phpversion(), '7.2.5', '<')) die('PHP version 7.2.5 or higher is required.'); +if (version_compare(phpversion(), '8.0', '<')) die('PHP version 8.0 or higher is required.'); const MYAAC = true; const MYAAC_VERSION = '0.10.0-dev'; diff --git a/composer.json b/composer.json index b1300e34..91260d71 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "require": { - "php": "^7.2.5 || ^8.0", + "php": "^8.0", "ext-pdo": "*", "ext-pdo_mysql": "*", "ext-json": "*", From cfbcabbfdb5c94ca9f5489a222b16cdf82201a0d Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 12 Aug 2023 08:13:29 +0200 Subject: [PATCH 213/232] Fix accounts editor store_history column not found --- admin/pages/accounts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 550ea670..0c58d94e 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -272,7 +272,7 @@ else if (isset($_REQUEST['search'])) { hasTable('store_history')) : ?> + if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) : ?> @@ -523,7 +523,7 @@ else if (isset($_REQUEST['search'])) { } ?>
    hasTable('store_history')) { ?> + if ($db->hasTable('store_history') && $db->hasColumn('store_history', 'time')) { ?>
    query('SELECT * FROM `store_history` WHERE `account_id` = "' . $account->getId() . '" ORDER BY `time` DESC')->fetchAll(); ?>
    From b49c24716245baf5ec774c59709604311ef6db08 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 12 Aug 2023 12:23:03 +0200 Subject: [PATCH 214/232] Remove items generator, there are better ones made in JS This one wasn't working with newer files anyways --- system/item.php | 60 -------- system/libs/items_images.php | 265 ----------------------------------- tools/item.php | 7 - tools/signature/mango.php | 5 - 4 files changed, 337 deletions(-) delete mode 100644 system/item.php delete mode 100644 system/libs/items_images.php delete mode 100644 tools/item.php diff --git a/system/item.php b/system/item.php deleted file mode 100644 index 66d4bfc5..00000000 --- a/system/item.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright 2019 MyAAC - * @link https://my-aac.org - */ -defined('MYAAC') or die('Direct access not allowed!'); -require_once SYSTEM . 'libs/items_images.php'; - -Items_Images::$files = array( - 'otb' => SYSTEM . 'data/items.otb', - 'spr' => SYSTEM . 'data/Tibia.spr', - 'dat' => SYSTEM . 'data/Tibia.dat' -); -Items_Images::$outputDir = BASE . 'images/items/'; - -function generateItem($id = 100, $count = 1) { - Items_Images::generate($id, $count); -} - -function itemImageExists($id, $count = 1) -{ - if(!isset($id)) - throw new RuntimeException('ERROR - itemImageExists: id has been not set!'); - - $file_name = $id; - if($count > 1) - $file_name .= '-' . $count; - - $file_name = Items_Images::$outputDir . $file_name . '.gif'; - return file_exists($file_name); -} - -function outputItem($id = 100, $count = 1) -{ - if(!(int)$count) - $count = 1; - - if(!itemImageExists($id, $count)) - { - //echo 'plik istnieje'; - Items_Images::generate($id, $count); - } - - $expires = 60 * 60 * 24 * 30; // 30 days - header('Content-type: image/gif'); - header('Cache-Control: public'); - header('Cache-Control: maxage=' . $expires); - header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT'); - - $file_name = $id; - if($count > 1) - $file_name .= '-' . $count; - - $file_name = Items_Images::$outputDir . $file_name . '.gif'; - readfile($file_name); -} diff --git a/system/libs/items_images.php b/system/libs/items_images.php deleted file mode 100644 index f2a917f9..00000000 --- a/system/libs/items_images.php +++ /dev/null @@ -1,265 +0,0 @@ - - * @copyright 2019 MyAAC - * @link https://my-aac.org - */ -defined('MYAAC') or die('Direct access not allowed!'); - -if ( !function_exists( 'stackId' ) ) -{ - function stackId( $count ) - { - if ( $count >= 50 ) - $stack = 8; - elseif ( $count >= 25 ) - $stack = 7; - elseif ( $count >= 10 ) - $stack = 6; - elseif ( $count >= 5 ) - $stack = 5; - elseif ( $count >= 4 ) - $stack = 4; - elseif ( $count >= 3 ) - $stack = 3; - elseif ( $count >= 2 ) - $stack = 2; - else - $stack = 1; - - return $stack; - } -} - -class Items_Images -{ - public static $outputDir = ''; - public static $files = array(); - - private static $otb, $dat, $spr; - private static $lastItem; - private static $loaded = false; - - public function __destruct() - { - if(self::$otb) - fclose(self::$otb); - if(self::$dat) - fclose(self::$dat); - if(self::$spr) - fclose(self::$spr); - } - - public static function generate($id = 100, $count = 1) - { - if(!self::$loaded) - self::load(); - - $originalId = $id; - if($id < 100) - return false; - //die('ID cannot be lower than 100.'); - - rewind(self::$otb); - rewind(self::$dat); - rewind(self::$spr); - - $nostand = false; - $init = false; - $originalId = $id; - - // parse info from otb - while( false !== ( $char = fgetc( self::$otb ) ) ) - { - $byte = HEX_PREFIX.bin2hex( $char ); - - if ( $byte == 0xFE ) - $init = true; - elseif ( $byte == 0x10 and $init ) { - extract( unpack( 'x2/Ssid', fread( self::$otb, 4 ) ) ); - - if ( $id == $sid ) { - if ( HEX_PREFIX.bin2hex( fread( self::$otb, 1 ) ) == 0x11 ) { - extract( unpack( 'x2/Sid', fread( self::$otb, 4 ) ) ); - break; - } - } - $init = false; - } - } - - self::$lastItem = array_sum( unpack( 'x4/S*', fread( self::$dat, 12 ))); - if($id > self::$lastItem) - return false; - - //ini_set('max_execution_time', 300); - // parse info from dat - for( $i = 100; $i <= $id; $i++ ) { - while( ( $byte = HEX_PREFIX.bin2hex( fgetc( self::$dat ) ) ) != 0xFF ) { - $offset = 0; - switch( $byte ) { - case 0x00: - case 0x09: - case 0x0A: - case 0x1A: - case 0x1D: - case 0x1E: - $offset = 2; - break; - - case 0x16: - case 0x19: - $offset = 4; - break; - - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x17: - case 0x18: - case 0x1B: - case 0x1C: - case 0x1F: - case 0x20: - break; - - default: - return false; #trigger_error( sprintf( 'Unknown .DAT byte %s (previous byte: %s; address %x)', $byte, $prev, ftell( $dat ), E_USER_ERROR ) ); - break; - } - - $prev = $byte; - fseek( self::$dat, $offset, SEEK_CUR ); - } - extract( unpack( 'Cwidth/Cheight', fread( self::$dat, 2 ) ) ); - - if ( $width > 1 or $height > 1 ) { - fseek( self::$dat, 1, SEEK_CUR ); - $nostand = true; - } - - $sprites_c = array_product( unpack( 'C*', fread( self::$dat, 5 ) ) ) * $width * $height; - $sprites = unpack( 'S*', fread( self::$dat, 2 * $sprites_c ) ); - } - - if ( array_key_exists( stackId( $count ), $sprites ) ) { - $sprites = (array) $sprites[stackId( $count )]; - } - else { - $sprites = (array) $sprites[array_rand( $sprites ) ]; - } - - fseek( self::$spr, 6 ); - - $sprite = imagecreatetruecolor( 32 * $width, 32 * $height ); - imagecolortransparent( $sprite, imagecolorallocate( $sprite, 0, 0, 0 ) ); - - foreach( $sprites as $key => $value ) { - fseek( self::$spr, 6 + ( $value - 1 ) * 4 ); - extract( unpack( 'Laddress', fread( self::$spr, 4 ) ) ); - - fseek( self::$spr, $address + 3 ); - extract( unpack( 'Ssize', fread( self::$spr, 2 ) ) ); - - list( $num, $bit ) = array( 0, 0 ); - - while( $bit < $size ) { - $pixels = unpack( 'Strans/Scolored', fread( self::$spr, 4 ) ); - $num += $pixels['trans']; - for( $i = 0; $i < $pixels['colored']; $i++ ) - { - extract( unpack( 'Cred/Cgreen/Cblue', fread( self::$spr, 3 ) ) ); - - $red = ( $red == 0 ? ( $green == 0 ? ( $blue == 0 ? 1 : $red ) : $red ) : $red ); - - imagesetpixel( $sprite, - $num % 32 + ( $key % 2 == 1 ? 32 : 0 ), - $num / 32 + ( $key % 4 != 1 and $key % 4 != 0 ? 32 : 0 ), - imagecolorallocate( $sprite, $red, $green, $blue ) ); - - $num++; - } - - $bit += 4 + 3 * $pixels['colored']; - } - } - - if ( $count >= 2 ) { - if ( $count > 100 ) - $count = 100; - - $font = 3; - $length = imagefontwidth( $font ) * strlen( $count ); - - $pos = array( - 'x' => ( 32 * $width ) - ( $length + 1 ), - 'y' => ( 32 * $height ) - 13 - ); - imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - imagestring( $sprite, $font, $pos['x'], $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - - imagestring( $sprite, $font, $pos['x'], $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) ); - - imagestring( $sprite, $font, $pos['x'], $pos['y'], $count, imagecolorallocate( $sprite, 219, 219, 219 ) ); - } - - $imagePath = self::$outputDir . ($count > 1 ? $originalId . '-' . $count : $originalId ) . '.gif'; - - // save image - imagegif($sprite, $imagePath); - } - - public static function load() - { - if(!defined( 'HEX_PREFIX')) - define('HEX_PREFIX', '0x'); - - self::$otb = fopen(self::$files['otb'], 'rb'); - self::$dat = fopen(self::$files['dat'], 'rb'); - self::$spr = fopen(self::$files['spr'], 'rb'); - - if(!self::$otb || !self::$dat || !self::$spr) - throw new RuntimeException('ERROR: Cannot load data files.'); - /* - if ( $nostand ) - { - for( $i = 0; $i < count( $sprites ) / 4; $i++ ) - { - $sprites = array_merge( (array) $sprites, array_reverse( array_slice( $sprites, $i * 4, 4 ) ) ); - } - } - else - { - $sprites = (array) $sprites[array_rand( $sprites ) ]; - } - */ - - self::$loaded = true; - } - - public static function loaded() { - return self::$loaded; - } -} diff --git a/tools/item.php b/tools/item.php deleted file mode 100644 index b2da8a2f..00000000 --- a/tools/item.php +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/tools/signature/mango.php b/tools/signature/mango.php index f00f7f18..07da96d5 100644 --- a/tools/signature/mango.php +++ b/tools/signature/mango.php @@ -15,11 +15,6 @@ return ( 50 / 3 ) * pow( $level, 3 ) - ( 100 * pow( $level, 2 ) ) + ( ( 850 / 3 ) * $level ) - 200; } - /** Sprite settings **/ - $spr_path = SIGNATURES_DATA.'Tibia.spr'; - $dat_path = SIGNATURES_DATA.'Tibia.dat'; - $otb_path = SIGNATURES_DATA.'items.otb'; - $background = 'default.png'; if ( !file_exists( SIGNATURES_BACKGROUNDS.$background ) ) { From 3dd493b79002656549ae7e11cce14b862714d32d Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 12 Aug 2023 13:21:08 +0200 Subject: [PATCH 215/232] banned_by is player_id. type = 2 is namelock in tfs 0.3 --- system/pages/bans.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/system/pages/bans.php b/system/pages/bans.php index 48e5fdc1..f862183b 100644 --- a/system/pages/bans.php +++ b/system/pages/bans.php @@ -50,7 +50,8 @@ if(!$bansQuery->rowCount()) $nextPage = false; $i = 0; -$bans = $bansQuery->fetchAll(); +$bans = $bansQuery->fetchAll(PDO::FETCH_ASSOC); + foreach ($bans as $id => &$ban) { if(++$i > $configBansPerPage) @@ -69,11 +70,22 @@ foreach ($bans as $id => &$ban) $accountId = $ban['account_id']; } - $ban['player'] = getPlayerLink(getPlayerNameByAccount($accountId)); - + $playerName = 'Unknown'; if ($configBans['hasType']) { $ban['type'] = getBanType($ban['type']); + + if ($ban['type'] == 2) { // namelock + $playerName = getPlayerNameById($accountId); + } + else { + $playerName = getPlayerNameByAccount($accountId); + } } + else { + $playerName = getPlayerNameByAccount($accountId); + } + + $ban['player'] = getPlayerLink($playerName); $expiresColumn = 'expires_at'; if ($db->hasColumn('bans', 'expires')) { @@ -104,7 +116,7 @@ foreach ($bans as $id => &$ban) } } else { - $addedBy = getPlayerLink(getPlayerNameByAccount($ban['banned_by'])); + $addedBy = getPlayerLink(getPlayerNameById($ban['banned_by'])); } if ($db->hasColumn('bans', 'added')) { From a1ecdd228d1d7ce9133b5b1d0de1d63161db5764 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 12 Aug 2023 13:34:25 +0200 Subject: [PATCH 216/232] Fixes in getPlayerNameByAccountId + add getPlayerNameById --- system/functions.php | 65 +++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/system/functions.php b/system/functions.php index feb24360..ee26a5fe 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1362,39 +1362,48 @@ function getChangelogWhere($v) return 'unknown'; } -function getPlayerNameByAccount($id) + +function getPlayerNameByAccountId($id) { - global $vowels, $ots, $db; - if(is_numeric($id)) - { - $player = new OTS_Player(); - $player->load($id); - if($player->isLoaded()) - return $player->getName(); - else - { - $playerQuery = $db->query('SELECT `id` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch(); + global $db; - $tmp = "*Error*"; - /* - $acco = new OTS_Account(); - $acco->load($id); - if(!$acco->isLoaded()) - return "Unknown name"; + if (!is_numeric($id)) { + return ''; + } - foreach($acco->getPlayersList() as $p) - { - $player= new OTS_Player(); - $player->find($p);*/ - $player->load($playerQuery['id']); - //echo 'id gracza = ' . $p . '
    '; - if($player->isLoaded()) - $tmp = $player->getName(); - // break; - //} + $account = new OTS_Account(); + $account->load($id); + if ($account->isLoaded()) { + $query = $db->query('SELECT `name` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch(); - return $tmp; + if (!$query || !$query->rowCount()) { + return ''; } + + return $query->fetch(PDO::FETCH_ASSOC)['name']; + } + + return ''; +} + +function getPlayerNameByAccount($account) { + if (is_numeric($account)) { + return getPlayerNameByAccountId($account); + } + + return ''; +} + +function getPlayerNameById($id) +{ + if (!is_numeric($id)) { + return ''; + } + + $player = new OTS_Player(); + $player->load($id); + if ($player->isLoaded()) { + return $player->getName(); } return ''; From 2991696a606c56ab6a805ad5eedc6914c27ca1e7 Mon Sep 17 00:00:00 2001 From: slawkens Date: Sat, 12 Aug 2023 13:34:53 +0200 Subject: [PATCH 217/232] typo --- system/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/functions.php b/system/functions.php index ee26a5fe..16984bd4 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1374,7 +1374,7 @@ function getPlayerNameByAccountId($id) $account = new OTS_Account(); $account->load($id); if ($account->isLoaded()) { - $query = $db->query('SELECT `name` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;')->fetch(); + $query = $db->query('SELECT `name` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;'); if (!$query || !$query->rowCount()) { return ''; From 370cc554ad49c320821363023043f4a64d4f9e0b Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 15 Aug 2023 22:00:57 +0200 Subject: [PATCH 218/232] Fix success & error class (bootstrap) --- system/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/functions.php b/system/functions.php index 16984bd4..da7b0988 100644 --- a/system/functions.php +++ b/system/functions.php @@ -1411,13 +1411,13 @@ function getPlayerNameById($id) function echo_success($message) { - echo '
    ' . $message . '
    '; + echo '
    ' . $message . '
    '; } function echo_error($message) { global $error; - echo '
    ' . $message . '
    '; + echo '
    ' . $message . '
    '; $error = true; } From 1f95a415aaa7f40f25035807af18f5396f0f56fc Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 15 Aug 2023 22:06:09 +0200 Subject: [PATCH 219/232] Fix tabs --- system/templates/highscores.html.twig | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/system/templates/highscores.html.twig b/system/templates/highscores.html.twig index 2e32b7de..ddef7ef2 100644 --- a/system/templates/highscores.html.twig +++ b/system/templates/highscores.html.twig @@ -5,27 +5,27 @@

    Ranking for {{ skillName }}{% if vocation is not null %} ({{ vocation }}){% endif %} on {{ config.lua.serverName }}


    - - - - + + + +
    Filters - - - - - -
    Filters + + + + + +
    From fc0d13437aa62ecac17a8a1db590452addc4105f Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 15 Aug 2023 22:17:34 +0200 Subject: [PATCH 220/232] Fix highscores show vocation --- system/compat/config.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/compat/config.php b/system/compat/config.php index 9748e07b..22e2fced 100644 --- a/system/compat/config.php +++ b/system/compat/config.php @@ -36,6 +36,9 @@ $deprecatedConfig = [ 'news_date_format', 'highscores_groups_hidden', 'highscores_ids_hidden', + 'highscores_vocation_box', + 'highscores_vocation', + 'highscores_outfit', 'online_record', 'online_vocations', 'online_vocations_images', From eb416e18cc4d7a42a0d06c9494b5189ccbe4f2ef Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 15 Aug 2023 22:28:52 +0200 Subject: [PATCH 221/232] Add missing guild_ settings to config compat --- system/compat/config.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/system/compat/config.php b/system/compat/config.php index 22e2fced..bf56f92a 100644 --- a/system/compat/config.php +++ b/system/compat/config.php @@ -34,6 +34,13 @@ $deprecatedConfig = [ 'news_limit', 'news_ticker_limit', 'news_date_format', + 'guild_management', + 'guild_need_level', + 'guild_need_premium', + 'guild_image_size_kb', + 'guild_description_default', + 'guild_description_chars_limit', + 'guild_motd_chars_limit', 'highscores_groups_hidden', 'highscores_ids_hidden', 'highscores_vocation_box', From 7cea023965a791e44d1d9e95a9c4a61e42b828da Mon Sep 17 00:00:00 2001 From: slawkens Date: Tue, 15 Aug 2023 22:33:37 +0200 Subject: [PATCH 222/232] Remove item.php include (was removed in last commits) --- system/pages/characters.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/pages/characters.php b/system/pages/characters.php index 62cb2759..3411c043 100644 --- a/system/pages/characters.php +++ b/system/pages/characters.php @@ -11,8 +11,6 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Characters'; -require_once SYSTEM . 'item.php'; - $groups = new OTS_Groups_List(); function generate_search_form($autofocus = false) { From 627369bbdec83156291ca65b8b83a170b793e384 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 21 Aug 2023 09:01:50 +0200 Subject: [PATCH 223/232] Add some variable to config.local.php on install --- install/steps/5-database.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/steps/5-database.php b/install/steps/5-database.php index 5ebe18d9..b75608fc 100644 --- a/install/steps/5-database.php +++ b/install/steps/5-database.php @@ -34,6 +34,8 @@ if(!$error) { } } + $configToSave['gzip_output'] = false; + $configToSave['cache_engine'] = 'auto'; $configToSave['cache_prefix'] = 'myaac_' . generateRandomString(8, true, false, true); require BASE . 'install/includes/config.php'; From 30fe42939dc0557757261ac326208106ef5e2517 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 21 Aug 2023 09:38:23 +0200 Subject: [PATCH 224/232] Fix FAQ actions --- system/router.php | 1 + system/routes.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/system/router.php b/system/router.php index 1a2cab23..3f7abd25 100644 --- a/system/router.php +++ b/system/router.php @@ -206,6 +206,7 @@ else { $_REQUEST = array_merge($_REQUEST, $vars); $_GET = array_merge($_GET, $vars); + extract($vars); if (strpos($path, '__database__/') !== false) { $pageName = str_replace('__database__/', '', $path); diff --git a/system/routes.php b/system/routes.php index 5d93bd1b..53c121a5 100644 --- a/system/routes.php +++ b/system/routes.php @@ -34,7 +34,7 @@ return [ ['GET', 'changelog[/{page:int}]', 'changelog.php'], [['GET', 'POST'], 'creatures[/{name:string}]', 'creatures.php'], - ['GET', 'faq[/{action:string}]', 'faq.php'], + [['GET', 'POST'], 'faq[/{action:string}]', 'faq.php'], [['GET', 'POST'], 'forum/{action:string}[/]', 'forum.php'], ['GET', 'forum/board/{id:int}[/]', 'forum/show_board.php'], From e15b57f96773100cf604cceeaa7a95a757030c81 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 21 Aug 2023 09:43:44 +0200 Subject: [PATCH 225/232] Ignore gallery --- .gitignore | 6 ++++++ images/gallery/index.html | 0 2 files changed, 6 insertions(+) create mode 100644 images/gallery/index.html diff --git a/.gitignore b/.gitignore index 6c1db9b7..b4d564e9 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,12 @@ images/guilds/* images/editor/* !images/editor/index.html +# gallery images +images/gallery/* +!images/gallery/index.html +!images/gallery/demon.jpg +!images/gallery/demon_thumb.gif + # cache system/cache/* !system/cache/index.html diff --git a/images/gallery/index.html b/images/gallery/index.html new file mode 100644 index 00000000..e69de29b From a692607c5e84a703d7dcf0aecd7913a6573989ac Mon Sep 17 00:00:00 2001 From: Gabriel Pedro Date: Mon, 21 Aug 2023 04:16:58 -0400 Subject: [PATCH 226/232] feat: replace POT Query Builder to Eloquent ORM (#230) * wip * wip * wip * wip * wip * fix: reusing pdo connection from pot * wip * wip * wip * wip * move files In future, all classes will be in src/ folder * Replace namespace name, for future * Remove duplicated exception * Fix towns from db * Fix spells page * Add default FAQ question + FAQ model * feat: reset colors in menus * Add confirm + save button at the top (menus) * Do not insert duplicated FAQ on install * Refactor install menus * Fix changelogs showing * Fix menu update, only with specified template name * Fix account create -> missing compat * Fix bans_per_page * banned_by is player_id. type = 2 is namelock in tfs 0.3 * Add getPlayerNameById, fix getPlayerNameByAccount * Change link name * Order by lastlogin * fix: query optimize * wip * wip * wip * wip * wip * wip * wip * Refactor notepad.php, class was useless * This is showing error, if the updated rows = 0 * Fix success & error class (bootstrap) * Uncomment require migrate.php * Some distro have owner_id * Update Player.php --------- Co-authored-by: slawkens --- admin/pages/accounts.php | 30 +- admin/pages/changelog.php | 5 +- admin/pages/mass_account.php | 18 +- admin/pages/mass_teleport.php | 37 +-- admin/pages/menus.php | 50 +++- admin/pages/modules/balance.php | 9 +- admin/pages/modules/coins.php | 9 +- admin/pages/modules/created.php | 11 +- admin/pages/modules/lastlogin.php | 10 +- admin/pages/modules/points.php | 9 +- admin/pages/modules/statistics.php | 21 +- .../pages/modules/templates/created.html.twig | 4 +- admin/pages/notepad.php | 55 ++-- admin/pages/pages.php | 96 +++---- admin/pages/players.php | 28 +- admin/pages/statistics.php | 31 +-- composer.json | 8 +- install/includes/schema.sql | 64 ----- install/tools/7-finish.php | 12 + login.php | 100 +++---- system/compat/config.php | 3 + system/database.php | 40 ++- system/functions.php | 257 +++++++++--------- system/init.php | 2 + system/libs/CreateCharacter.php | 7 +- system/libs/Settings.php | 46 ++-- system/libs/Towns.php | 13 +- system/libs/changelog.php | 69 +++-- system/libs/creatures.php | 21 +- system/libs/items.php | 14 +- system/libs/news.php | 51 +++- system/libs/plugins.php | 9 +- system/libs/spells.php | 17 +- system/libs/validator.php | 13 +- system/libs/visitors.php | 23 +- system/libs/weapons.php | 18 +- system/migrations/1.php | 2 +- system/migrations/17.php | 73 +---- system/pages/account/change_comment.php | 51 ++-- system/pages/account/change_info.php | 18 +- system/pages/account/confirm_email.php | 11 +- system/pages/bans.php | 4 +- system/pages/bugtracker.php | 69 +++-- system/pages/changelog.php | 4 +- system/pages/creatures.php | 11 +- system/pages/faq.php | 89 +++--- system/pages/gallery.php | 57 ++-- system/pages/highscores.php | 120 ++++---- system/pages/online.php | 20 +- system/pages/records.php | 12 +- system/pages/spells.php | 9 +- system/router.php | 18 +- system/src/Models/Account.php | 69 +++++ system/src/Models/AccountVipList.php | 21 ++ system/src/Models/BoostedCreature.php | 16 ++ system/src/Models/BugTracker.php | 15 + system/src/Models/Changelog.php | 16 ++ system/src/Models/Config.php | 14 + system/src/Models/FAQ.php | 14 + system/src/Models/Gallery.php | 13 + system/src/Models/Guild.php | 33 +++ system/src/Models/GuildInvite.php | 22 ++ system/src/Models/GuildMembership.php | 27 ++ system/src/Models/GuildRank.php | 17 ++ system/src/Models/House.php | 16 ++ system/src/Models/Menu.php | 14 + system/src/Models/Monster.php | 15 + system/src/Models/News.php | 22 ++ system/src/Models/Notepad.php | 20 ++ system/src/Models/Pages.php | 30 ++ system/src/Models/Player.php | 138 ++++++++++ system/src/Models/PlayerDeath.php | 25 ++ system/src/Models/PlayerDepotItem.php | 16 ++ system/src/Models/PlayerKillers.php | 16 ++ system/src/Models/PlayerOnline.php | 16 ++ system/src/Models/PlayerSkill.php | 16 ++ system/src/Models/PlayerSpell.php | 16 ++ system/src/Models/PlayerStorage.php | 16 ++ system/src/Models/PlayerVipList.php | 21 ++ system/src/Models/Playeritem.php | 17 ++ system/src/Models/ServerConfig.php | 14 + system/src/Models/ServerRecord.php | 14 + system/src/Models/Settings.php | 14 + system/src/Models/Spell.php | 15 + system/src/Models/Town.php | 15 + system/src/Models/Visitor.php | 15 + system/src/Models/Weapon.php | 15 + system/status.php | 37 +-- system/template.php | 15 +- .../account.change_comment.html.twig | 12 +- system/templates/admin.notepad.html.twig | 2 +- templates/kathrine/menus.php | 44 +++ templates/tibiacom/boxes/gallery.php | 9 +- templates/tibiacom/menus.php | 46 ++++ tools/validate.php | 6 +- 95 files changed, 1809 insertions(+), 933 deletions(-) create mode 100644 system/src/Models/Account.php create mode 100644 system/src/Models/AccountVipList.php create mode 100644 system/src/Models/BoostedCreature.php create mode 100644 system/src/Models/BugTracker.php create mode 100644 system/src/Models/Changelog.php create mode 100644 system/src/Models/Config.php create mode 100644 system/src/Models/FAQ.php create mode 100644 system/src/Models/Gallery.php create mode 100644 system/src/Models/Guild.php create mode 100644 system/src/Models/GuildInvite.php create mode 100644 system/src/Models/GuildMembership.php create mode 100644 system/src/Models/GuildRank.php create mode 100644 system/src/Models/House.php create mode 100644 system/src/Models/Menu.php create mode 100644 system/src/Models/Monster.php create mode 100644 system/src/Models/News.php create mode 100644 system/src/Models/Notepad.php create mode 100644 system/src/Models/Pages.php create mode 100644 system/src/Models/Player.php create mode 100644 system/src/Models/PlayerDeath.php create mode 100644 system/src/Models/PlayerDepotItem.php create mode 100644 system/src/Models/PlayerKillers.php create mode 100644 system/src/Models/PlayerOnline.php create mode 100644 system/src/Models/PlayerSkill.php create mode 100644 system/src/Models/PlayerSpell.php create mode 100644 system/src/Models/PlayerStorage.php create mode 100644 system/src/Models/PlayerVipList.php create mode 100644 system/src/Models/Playeritem.php create mode 100644 system/src/Models/ServerConfig.php create mode 100644 system/src/Models/ServerRecord.php create mode 100644 system/src/Models/Settings.php create mode 100644 system/src/Models/Spell.php create mode 100644 system/src/Models/Town.php create mode 100644 system/src/Models/Visitor.php create mode 100644 system/src/Models/Weapon.php create mode 100644 templates/kathrine/menus.php create mode 100644 templates/tibiacom/menus.php diff --git a/admin/pages/accounts.php b/admin/pages/accounts.php index 5ec18d8d..7f47b3d0 100644 --- a/admin/pages/accounts.php +++ b/admin/pages/accounts.php @@ -7,6 +7,9 @@ * @copyright 2020 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Player; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Account editor'; @@ -424,8 +427,7 @@ else if (isset($_REQUEST['search'])) {
    isLoaded()) { - $account_players = $account->getPlayersList(); - $account_players->orderBy('id'); + $account_players = Player::where('account_id', $account->getId())->orderBy('id')->get(); if (isset($account_players)) { ?>
    @@ -438,25 +440,13 @@ else if (isset($_REQUEST['search'])) { - $player): - $i++; - $player_vocation = $player->getVocation(); - $player_promotion = $player->getPromotion(); - if (isset($player_promotion)) { - if ((int)$player_promotion > 0) - $player_vocation += ($player_promotion * $config['vocations_amount']); - } - - if (isset($config['vocations'][$player_vocation])) { - $vocation_name = $config['vocations'][$player_vocation]; - } ?> + $player): ?> - - - - - + + + + + diff --git a/admin/pages/changelog.php b/admin/pages/changelog.php index 4456344d..3d5cad64 100644 --- a/admin/pages/changelog.php +++ b/admin/pages/changelog.php @@ -8,6 +8,9 @@ * @copyright 2020 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Changelog as ModelsChangelog; + defined('MYAAC') or die('Direct access not allowed!'); if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) { @@ -78,7 +81,7 @@ if(!empty($action)) error(implode(", ", $errors)); } -$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` ORDER BY `id` DESC')->fetchAll(); +$changelogs = ModelsChangelog::orderBy('id')->get()->toArray(); $i = 0; diff --git a/admin/pages/mass_account.php b/admin/pages/mass_account.php index 507ef877..63bec54c 100644 --- a/admin/pages/mass_account.php +++ b/admin/pages/mass_account.php @@ -9,6 +9,9 @@ * @copyright 2020 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Account; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Mass Account Actions'; @@ -26,15 +29,14 @@ function admin_give_points($points) return; } + $statement = $db->prepare('UPDATE `accounts` SET `premium_points` = `premium_points` + :points'); if (!$statement) { displayMessage('Failed to prepare query statement.'); return; } - if (!$statement->execute([ - 'points' => $points - ])) { + if (!Account::query()->increment('premium_points', $points)) { displayMessage('Failed to add points.'); return; } @@ -50,15 +52,7 @@ function admin_give_coins($coins) return; } - $statement = $db->prepare('UPDATE `accounts` SET `coins` = `coins` + :coins'); - if (!$statement) { - displayMessage('Failed to prepare query statement.'); - return; - } - - if (!$statement->execute([ - 'coins' => $coins - ])) { + if (!Account::query()->increment('coins', $coins)) { displayMessage('Failed to add coins.'); return; } diff --git a/admin/pages/mass_teleport.php b/admin/pages/mass_teleport.php index 972975e2..5027fa1c 100644 --- a/admin/pages/mass_teleport.php +++ b/admin/pages/mass_teleport.php @@ -8,22 +8,19 @@ * @copyright 2020 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Player; +use MyAAC\Models\PlayerOnline; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Mass Teleport Actions'; function admin_teleport_position($x, $y, $z) { - global $db; - $statement = $db->prepare('UPDATE `players` SET `posx` = :x, `posy` = :y, `posz` = :z'); - if (!$statement) { - displayMessage('Failed to prepare query statement.'); - return; - } - - if (!$statement->execute([ - 'x' => $x, 'y' => $y, 'z' => $z + if (!Player::query()->update([ + 'posx' => $x, 'posy' => $y, 'posz' => $z ])) { - displayMessage('Failed to execute query.'); + displayMessage('Failed to execute query. Probably already updated.'); return; } @@ -31,17 +28,10 @@ function admin_teleport_position($x, $y, $z) { } function admin_teleport_town($town_id) { - global $db; - $statement = $db->prepare('UPDATE `players` SET `town_id` = :town_id'); - if (!$statement) { - displayMessage('Failed to prepare query statement.'); - return; - } - - if (!$statement->execute([ - 'town_id' => $town_id + if (!Player::query()->update([ + 'town_id' => $town_id, ])) { - displayMessage('Failed to execute query.'); + displayMessage('Failed to execute query. Probably already updated.'); return; } @@ -58,13 +48,12 @@ if (isset($_POST['action']) && $_POST['action']) { $playersOnline = 0; if($db->hasTable('players_online')) {// tfs 1.0 - $query = $db->query('SELECT count(*) AS `count` FROM `players_online`'); + $playersOnline = PlayerOnline::count(); } else { - $query = $db->query('SELECT count(*) AS `count` FROM `players` WHERE `players`.`online` > 0'); + $playersOnline = Player::online()->count(); } - $playersOnline = $query->fetch(PDO::FETCH_ASSOC); - if ($playersOnline['count'] > 0) { + if ($playersOnline > 0) { displayMessage('Please, close the server before execute this action otherwise players will not be affected.'); return; } diff --git a/admin/pages/menus.php b/admin/pages/menus.php index 1e839d26..a0b492df 100644 --- a/admin/pages/menus.php +++ b/admin/pages/menus.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Menu; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Menus'; @@ -28,14 +31,22 @@ if (isset($_REQUEST['template'])) { return; } - $db->query('DELETE FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template)); + Menu::where('template', $template)->delete(); foreach ($post_menu as $category => $menus) { foreach ($menus as $i => $menu) { if (empty($menu)) // don't save empty menu item continue; try { - $db->insert(TABLE_PREFIX . 'menu', array('template' => $template, 'name' => $menu, 'link' => $post_menu_link[$category][$i], 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, 'color' => str_replace('#', '', $post_menu_color[$category][$i]), 'category' => $category, 'ordering' => $i)); + Menu::create([ + 'template' => $template, + 'name' => $menu, + 'link' => $post_menu_link[$category][$i], + 'blank' => $post_menu_blank[$category][$i] == 'on' ? 1 : 0, + 'color' => str_replace('#', '', $post_menu_color[$category][$i]), + 'category' => $category, + 'ordering' => $i + ]); } catch (PDOException $error) { warning('Error while adding menu item (' . $menu . '): ' . $error->getMessage()); } @@ -58,6 +69,15 @@ if (isset($_REQUEST['template'])) { return; } + if (isset($_REQUEST['reset_colors'])) { + if (isset($config['menu_default_color'])) { + Menu::where('template', $template)->update(['color' => str_replace('#', '', $config['menu_default_color'])]); + } + else { + warning('There is no default color defined, cannot reset colors.'); + } + } + if (!isset($config['menu_categories'])) { echo "No menu categories set in template config.php.
    This template doesn't support dynamic menus."; return; @@ -71,17 +91,29 @@ if (isset($_REQUEST['template'])) { Hint: Add links to external sites using: http:// or https:// prefix.
    Not all templates support blank and colorful links.

    + + + + + +
    + query('SELECT `name`, `link`, `blank`, `color`, `category`, `ordering` FROM `' . TABLE_PREFIX . 'menu` WHERE `enabled` = 1 AND `template` = ' . $db->quote($template) . ' ORDER BY `ordering` ASC;')->fetchAll(); - foreach ($menus_db as $menu) { - $menus[$menu['category']][] = array('name' => $menu['name'], 'link' => $menu['link'], 'blank' => $menu['blank'], 'color' => $menu['color'], 'ordering' => $menu['ordering']); - } + $menus = Menu::query() + ->select('name', 'link', 'blank', 'color', 'category', 'ordering') + ->where('enabled', 1) + ->where('template', $template) + ->orderBy('ordering') + ->get() + ->groupBy('category') + ->toArray(); + $last_id = array(); ?> +

    $cat): ?>
    @@ -113,7 +145,7 @@ if (isset($_REQUEST['template'])) {
    - + Cancel'; ?> @@ -129,7 +161,7 @@ if (isset($_REQUEST['template'])) { ?> query('SELECT `template` FROM `' . TABLE_PREFIX . 'menu` GROUP BY `template`;')->fetchAll(); + $templates = Menu::select('template')->distinct()->get()->toArray(); foreach ($templates as $key => $value) { $file = TEMPLATES . $value['template'] . '/config.php'; if (!file_exists($file)) { diff --git a/admin/pages/modules/balance.php b/admin/pages/modules/balance.php index 7c23185b..d700ef16 100644 --- a/admin/pages/modules/balance.php +++ b/admin/pages/modules/balance.php @@ -1,7 +1,14 @@ hasColumn('players', 'balance') ? $db->query('SELECT `balance`, `id`, `name`,`level` FROM `players` ORDER BY `balance` DESC LIMIT 10;') : 0); +$balance = 0; + +if ($db->hasColumn('players', 'balance')) { + $balance = Player::orderByDesc('balance')->limit(10)->get(['balance', 'id','name', 'level'])->toArray(); +} $twig->display('balance.html.twig', array( 'balance' => $balance diff --git a/admin/pages/modules/coins.php b/admin/pages/modules/coins.php index 6e5bc9d3..725c2e45 100644 --- a/admin/pages/modules/coins.php +++ b/admin/pages/modules/coins.php @@ -1,7 +1,14 @@ hasColumn('accounts', 'coins') ? $db->query('SELECT `coins`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `coins` DESC LIMIT 10;') : 0); +$coins = 0; + +if ($db->hasColumn('accounts', 'coins')) { + $coins = Account::orderByDesc('coins')->limit(10)->get(['coins', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray(); +} $twig->display('coins.html.twig', array( 'coins' => $coins diff --git a/admin/pages/modules/created.php b/admin/pages/modules/created.php index 4bf88b96..cc72d660 100644 --- a/admin/pages/modules/created.php +++ b/admin/pages/modules/created.php @@ -1,8 +1,15 @@ hasColumn('accounts', 'created') ? $db->query('SELECT `created`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `created` DESC LIMIT 10;') : 0); +$accounts = 0; + +if ($db->hasColumn('accounts', 'created')) { + $accounts = Account::orderByDesc('created')->limit(10)->get(['created', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray(); +} $twig->display('created.html.twig', array( - 'players' => $players, + 'accounts' => $accounts, )); diff --git a/admin/pages/modules/lastlogin.php b/admin/pages/modules/lastlogin.php index a71158bd..7fae3469 100644 --- a/admin/pages/modules/lastlogin.php +++ b/admin/pages/modules/lastlogin.php @@ -1,7 +1,15 @@ hasColumn('players', 'lastlogin') ? $db->query('SELECT name, level, lastlogin FROM players ORDER BY lastlogin DESC LIMIT 10;') : 0); +$players = 0; + +if ($db->hasColumn('players', 'lastlogin')) { + $players = Player::orderByDesc('lastlogin')->limit(10)->get(['name', 'level', 'lastlogin'])->toArray(); +} + $twig->display('lastlogin.html.twig', array( 'players' => $players, )); diff --git a/admin/pages/modules/points.php b/admin/pages/modules/points.php index 9308da42..e0f13c89 100644 --- a/admin/pages/modules/points.php +++ b/admin/pages/modules/points.php @@ -1,7 +1,14 @@ hasColumn('accounts', 'premium_points') ? $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;') : 0); +$points = 0; + +if ($db->hasColumn('accounts', 'premium_points')) { + $coins = Account::orderByDesc('premium_points')->limit(10)->get(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')])->toArray(); +} $twig->display('points.html.twig', array( 'points' => $points, diff --git a/admin/pages/modules/statistics.php b/admin/pages/modules/statistics.php index ad3ea675..b8a474f3 100644 --- a/admin/pages/modules/statistics.php +++ b/admin/pages/modules/statistics.php @@ -1,11 +1,20 @@ query('SELECT - (SELECT COUNT(*) FROM `accounts`) as total_accounts, - (SELECT COUNT(*) FROM `players`) as total_players, - (SELECT COUNT(*) FROM `guilds`) as total_guilds, - (SELECT COUNT(*) FROM `' . TABLE_PREFIX . 'monsters`) as total_monsters, - (SELECT COUNT(*) FROM `houses`) as total_houses;')->fetch(); +$count = $eloquentConnection->query() + ->select([ + 'total_accounts' => Account::selectRaw('COUNT(id)'), + 'total_players' => Player::selectRaw('COUNT(id)'), + 'total_guilds' => Guild::selectRaw('COUNT(id)'), + 'total_monsters' => Monster::selectRaw('COUNT(id)'), + 'total_houses' => House::selectRaw('COUNT(id)'), + ])->first(); $twig->display('statistics.html.twig', array( 'count' => $count, diff --git a/admin/pages/modules/templates/created.html.twig b/admin/pages/modules/templates/created.html.twig index 352b3f52..862e6f18 100644 --- a/admin/pages/modules/templates/created.html.twig +++ b/admin/pages/modules/templates/created.html.twig @@ -1,4 +1,4 @@ -{% if players is iterable %} +{% if accounts is iterable %}
    @@ -15,7 +15,7 @@
    {% set i = 0 %} - {% for result in players %} + {% for result in accounts %} {% set i = i + 1 %} diff --git a/admin/pages/notepad.php b/admin/pages/notepad.php index d7296441..c18d837e 100644 --- a/admin/pages/notepad.php +++ b/admin/pages/notepad.php @@ -7,46 +7,33 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Notepad as ModelsNotepad; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Notepad'; -$notepad_content = Notepad::get($account_logged->getId()); +/** + * @var $account_logged OTS_Account + */ +$_content = ''; +$notepad = ModelsNotepad::where('account_id', $account_logged->getId())->first(); if (isset($_POST['content'])) { $_content = html_entity_decode(stripslashes($_POST['content'])); - if (!$notepad_content) - Notepad::create($account_logged->getId(), $_content); - else - Notepad::update($account_logged->getId(), $_content); + if (!$notepad) { + ModelsNotepad::create([ + 'account_id' => $account_logged->getId(), + 'content' => $_content + ]); + } + else { + ModelsNotepad::where('account_id', $account_logged->getId())->update(['content' => $_content]); + } - echo '
    Saved at ' . date('H:i') . '
    '; + success('Saved at ' . date('H:i')); } else { - if ($notepad_content !== false) - $_content = $notepad_content; + if ($notepad) + $_content = $notepad->content; } -$twig->display('admin.notepad.html.twig', array('content' => isset($_content) ? $_content : null)); - -class Notepad -{ - static public function get($account_id) - { - global $db; - $query = $db->select(TABLE_PREFIX . 'notepad', array('account_id' => $account_id)); - if ($query !== false) - return $query['content']; - - return false; - } - - static public function create($account_id, $content = '') - { - global $db; - $db->insert(TABLE_PREFIX . 'notepad', array('account_id' => $account_id, 'content' => $content)); - } - - static public function update($account_id, $content = '') - { - global $db; - $db->update(TABLE_PREFIX . 'notepad', array('content' => $content), array('account_id' => $account_id)); - } -} \ No newline at end of file +$twig->display('admin.notepad.html.twig', ['content' => $_content]); diff --git a/admin/pages/pages.php b/admin/pages/pages.php index e2b7acf5..6be569f3 100644 --- a/admin/pages/pages.php +++ b/admin/pages/pages.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Pages as ModelsPages; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Pages'; $use_datatable = true; @@ -94,19 +97,15 @@ if (!empty($action)) { error(implode(", ", $errors)); } -$query = - $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'pages')); - -$pages = array(); -foreach ($query as $_page) { - $pages[] = array( - 'link' => getFullLink($_page['name'], $_page['name'], true), - 'title' => substr($_page['title'], 0, 20), - 'php' => $_page['php'] == '1', - 'id' => $_page['id'], - 'hidden' => $_page['hidden'] - ); -} +$pages = ModelsPages::all()->map(function ($e) { + return [ + 'link' => getFullLink($e->name, $e->name, true), + 'title' => substr($e->title, 0, 20), + 'php' => $e->php == '1', + 'id' => $e->id, + 'hidden' => $e->hidden + ]; +})->toArray(); $twig->display('admin.pages.form.html.twig', array( 'action' => $action, @@ -170,10 +169,10 @@ class Pages static public function get($id) { - global $db; - $query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); - if ($query !== false) - return $query; + $row = ModelsPages::find($id); + if ($row) { + return $row->toArray(); + } return false; } @@ -184,20 +183,16 @@ class Pages return false; } - global $db; - $query = $db->select(TABLE_PREFIX . 'pages', array('name' => $name)); - if ($query === false) - $db->insert(TABLE_PREFIX . 'pages', - array( - 'name' => $name, - 'title' => $title, - 'body' => $body, - 'player_id' => $player_id, - 'php' => $php ? '1' : '0', - 'enable_tinymce' => $enable_tinymce ? '1' : '0', - 'access' => $access - ) - ); + if (!ModelsPages::where('name', $name)->exists()) + ModelsPages::create([ + 'name' => $name, + 'title' => $title, + 'body' => $body, + 'player_id' => $player_id, + 'php' => $php ? '1' : '0', + 'enable_tinymce' => $enable_tinymce ? '1' : '0', + 'access' => $access + ]); else $errors[] = 'Page with this link already exists.'; @@ -210,28 +205,25 @@ class Pages return false; } - global $db; - $db->update(TABLE_PREFIX . 'pages', - array( - 'name' => $name, - 'title' => $title, - 'body' => $body, - 'player_id' => $player_id, - 'php' => $php ? '1' : '0', - 'enable_tinymce' => $enable_tinymce ? '1' : '0', - 'access' => $access - ), - array('id' => $id)); - + ModelsPages::where('id', $id)->update([ + 'name' => $name, + 'title' => $title, + 'body' => $body, + 'player_id' => $player_id, + 'php' => $php ? '1' : '0', + 'enable_tinymce' => $enable_tinymce ? '1' : '0', + 'access' => $access + ]); return true; } static public function delete($id, &$errors) { - global $db; if (isset($id)) { - if ($db->select(TABLE_PREFIX . 'pages', array('id' => $id)) !== false) - $db->delete(TABLE_PREFIX . 'pages', array('id' => $id)); + $row = ModelsPages::find($id); + if ($row) { + $row->delete(); + } else $errors[] = 'Page with id ' . $id . ' does not exists.'; } else @@ -242,12 +234,12 @@ class Pages static public function toggleHidden($id, &$errors, &$status) { - global $db; if (isset($id)) { - $query = $db->select(TABLE_PREFIX . 'pages', array('id' => $id)); - if ($query !== false) { - $db->update(TABLE_PREFIX . 'pages', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - $status = $query['hidden']; + $row = ModelsPages::find($id); + if ($row) { + $row->hidden = $row->hidden == 1 ? 0 : 1; + $row->save(); + $status = $row->hidden; } else { $errors[] = 'Page with id ' . $id . ' does not exists.'; diff --git a/admin/pages/players.php b/admin/pages/players.php index b32d5445..48b0f1f5 100644 --- a/admin/pages/players.php +++ b/admin/pages/players.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Player; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Player editor'; @@ -744,8 +747,7 @@ else if (isset($_REQUEST['search'])) {
    isLoaded()) { - $account_players = $account->getPlayersList(); - $account_players->orderBy('id'); + $account_players = Player::where('account_id', $account->getId())->orderBy('id')->get(); if (isset($account_players)) { ?>
    getName(); ?>getLevel(); ?>name; ?>level; ?>vocation_name; ?>
    {{ i }}
    @@ -758,23 +760,13 @@ else if (isset($_REQUEST['search'])) { - $player): - $player_vocation = $player->getVocation(); - $player_promotion = $player->getPromotion(); - if (isset($player_promotion)) { - if ((int)$player_promotion > 0) - $player_vocation += ($player_promotion * $config['vocations_amount']); - } - - if (isset($config['vocations'][$player_vocation])) { - $vocation_name = $config['vocations'][$player_vocation]; - } ?> + $player): ?> - - - - - + + + + + diff --git a/admin/pages/statistics.php b/admin/pages/statistics.php index b740c217..6b921f42 100644 --- a/admin/pages/statistics.php +++ b/admin/pages/statistics.php @@ -7,26 +7,25 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Account; +use MyAAC\Models\Guild; +use MyAAC\Models\House; +use MyAAC\Models\Player; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Statistics'; -$query = $db->query('SELECT count(*) as `how_much` FROM `accounts`;'); -$query = $query->fetch(); -$total_accounts = $query['how_much']; +$total_accounts = Account::count(); +$total_players = Player::count(); +$total_guilds = Guild::count(); +$total_houses = House::count(); -$query = $db->query('SELECT count(*) as `how_much` FROM `players`;'); -$query = $query->fetch(); -$total_players = $query['how_much']; - -$query = $db->query('SELECT count(*) as `how_much` FROM `guilds`;'); -$query = $query->fetch(); -$total_guilds = $query['how_much']; - -$query = $db->query('SELECT count(*) as `how_much` FROM `houses`;'); -$query = $query->fetch(); -$total_houses = $query['how_much']; - -$points = $db->query('SELECT `premium_points`, `' . (USE_ACCOUNT_NAME ? 'name' : 'id') . '` as `name` FROM `accounts` ORDER BY `premium_points` DESC LIMIT 10;'); +$points = Account::select(['premium_points', (USE_ACCOUNT_NAME ? 'name' : 'id')]) + ->orderByDesc('premium_points') + ->limit(10) + ->get() + ->toArray(); $twig->display('admin.statistics.html.twig', array( 'total_accounts' => $total_accounts, diff --git a/composer.json b/composer.json index 91260d71..52fd0820 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,15 @@ "twig/twig": "^2.0", "erusev/parsedown": "^1.7", "nikic/fast-route": "^1.3", - "matomo/device-detector": "^6.0" + "matomo/device-detector": "^6.0", + "illuminate/database": "^10.18" }, "require-dev": { "filp/whoops": "^2.15" + }, + "autoload": { + "psr-4": { + "MyAAC\\": "system/src" + } } } diff --git a/install/includes/schema.sql b/install/includes/schema.sql index 21776dc8..2645d1a9 100644 --- a/install/includes/schema.sql +++ b/install/includes/schema.sql @@ -127,70 +127,6 @@ CREATE TABLE `myaac_menu` PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; -/* MENU_CATEGORY_NEWS kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2); -/* MENU_CATEGORY_ACCOUNT kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5); -/* MENU_CATEGORY_COMMUNITY kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8); -/* MENU_CATEGORY_LIBRARY kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6); -/* MENU_CATEGORY_SHOP kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2); -/* MENU_CATEGORY_NEWS tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2); -/* MENU_CATEGORY_ACCOUNT tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5); -/* MENU_CATEGORY_COMMUNITY tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8); -/* MENU_CATEGORY_FORUM tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0); -/* MENU_CATEGORY_LIBRARY tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6); /* MENU_CATEGORY_SHOP tibiacom */ INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0); INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1); diff --git a/install/tools/7-finish.php b/install/tools/7-finish.php index 22772714..85c8768b 100644 --- a/install/tools/7-finish.php +++ b/install/tools/7-finish.php @@ -45,6 +45,10 @@ if($success) { success($locale['step_database_imported_players']); } +require_once LIBS . 'plugins.php'; +Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php'); +Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php'); + require LIBS . 'DataLoader.php'; DataLoader::setLocale($locale); DataLoader::load(); @@ -59,6 +63,14 @@ require_once SYSTEM . 'migrations/22.php'; require_once SYSTEM . 'migrations/27.php'; require_once SYSTEM . 'migrations/30.php'; +use MyAAC\Models\FAQ as ModelsFAQ; +if(ModelsFAQ::count() == 0) { + ModelsFAQ::create([ + 'question' => 'What is this?', + 'answer' => 'This is website for OTS powered by MyAAC.', + ]); +} + $locale['step_finish_desc'] = str_replace('$ADMIN_PANEL$', generateLink(str_replace('tools/', '',ADMIN_URL), $locale['step_finish_admin_panel'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$HOMEPAGE$', generateLink(str_replace('tools/', '', BASE_URL), $locale['step_finish_homepage'], true), $locale['step_finish_desc']); $locale['step_finish_desc'] = str_replace('$LINK$', generateLink('https://my-aac.org', 'https://my-aac.org', true), $locale['step_finish_desc']); diff --git a/login.php b/login.php index 6fb43f38..c342a8e9 100644 --- a/login.php +++ b/login.php @@ -1,4 +1,8 @@ type ?? ''; switch ($action) { case 'cacheinfo': - $playersonline = $db->query("select count(*) from `players_online`")->fetchAll(); + $playersonline = PlayerOnline::count(); die(json_encode([ - 'playersonline' => (intval($playersonline[0][0])), + 'playersonline' => $playersonline, 'twitchstreams' => 0, 'twitchviewer' => 0, 'gamingyoutubestreams' => 0, @@ -79,13 +83,11 @@ switch ($action) { die(json_encode(['eventlist' => $eventlist, 'lastupdatetimestamp' => time()])); case 'boostedcreature': - $boostDB = $db->query("select * from " . $db->tableName('boosted_creature'))->fetchAll(); - foreach ($boostDB as $Tableboost) { + $boostedCreature = BoostedCreature::latest(); die(json_encode([ 'boostedcreature' => true, - 'raceid' => intval($Tableboost['raceid']) + 'raceid' => $boostedCreature->raceid ])); - } break; case 'login': @@ -112,29 +114,32 @@ switch ($action) { ]; $characters = []; - $account = new OTS_Account(); $inputEmail = $request->email ?? false; $inputAccountName = $request->accountname ?? false; $inputToken = $request->token ?? false; + $account = Account::query(); if ($inputEmail != false) { // login by email - $account->findByEmail($request->email); + $account->where('email', $inputEmail); } else if($inputAccountName != false) { // login by account name - $account->find($inputAccountName); + $account->where('name', $inputAccountName); } - $current_password = encrypt((USE_ACCOUNT_SALT ? $account->getCustomField('salt') : '') . $request->password); - - if (!$account->isLoaded() || $account->getPassword() != $current_password) { + $account = $account->first(); + if (!$account) { + sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); + } + + $current_password = encrypt((USE_ACCOUNT_SALT ? $account->salt : '') . $request->password); + if (!$account || $account->password != $current_password) { sendError(($inputEmail != false ? 'Email' : 'Account name') . ' or password is not correct.'); } - //log_append('test.log', var_export($account->getCustomField('secret'), true)); $accountHasSecret = false; if (fieldExist('secret', 'accounts')) { - $accountSecret = $account->getCustomField('secret'); + $accountSecret = $account->secret; if ($accountSecret != null && $accountSecret != '') { $accountHasSecret = true; if ($inputToken === false) { @@ -159,18 +164,9 @@ switch ($action) { $columns .= ', istutorial'; } - $players = $db->query("select {$columns} from players where account_id = " . $account->getId() . " AND deletion = 0"); - if($players && $players->rowCount() > 0) { - $players = $players->fetchAll(); - - $highestLevelId = 0; - $highestLevel = 0; - foreach ($players as $player) { - if ($player['level'] >= $highestLevel) { - $highestLevel = $player['level']; - $highestLevelId = $player['id']; - } - } + $players = Player::where('account_id', $account->id)->notDeleted()->selectRaw($columns)->get(); + if($players && $players->count()) { + $highestLevelId = $players->sortByDesc('experience')->first()->getKey(); foreach ($players as $player) { $characters[] = create_char($player, $highestLevelId); @@ -180,15 +176,10 @@ switch ($action) { if (fieldExist('premdays', 'accounts') && fieldExist('lastday', 'accounts')) { $save = false; $timeNow = time(); - $query = $db->query("select `premdays`, `lastday` from `accounts` where `id` = " . $account->getId()); - if ($query->rowCount() > 0) { - $query = $query->fetch(); - $premDays = (int)$query['premdays']; - $lastDay = (int)$query['lastday']; - $lastLogin = $lastDay; - } else { - sendError("Error while fetching your account data. Please contact admin."); - } + $premDays = $account->premdays; + $lastDay = $account->lastday; + $lastLogin = $lastDay; + if ($premDays != 0 && $premDays != PHP_INT_MAX) { if ($lastDay == 0) { $lastDay = $timeNow; @@ -213,7 +204,9 @@ switch ($action) { $save = true; } if ($save) { - $db->query("update `accounts` set `premdays` = " . $premDays . ", `lastday` = " . $lastDay . " where `id` = " . $account->getId()); + $account->premdays = $premDays; + $account->lastday = $lastDay; + $account->save(); } } @@ -235,13 +228,11 @@ switch ($action) { $sessionKey .= "\n".floor(time() / 30); } - //log_append('slaw.log', $sessionKey); - $session = [ 'sessionkey' => $sessionKey, 'lastlogintime' => 0, - 'ispremium' => $config['lua']['freePremium'] || $account->isPremium(), - 'premiumuntil' => ($account->getPremDays()) > 0 ? (time() + ($account->getPremDays() * 86400)) : 0, + 'ispremium' => $account->is_premium, + 'premiumuntil' => ($account->premium_days) > 0 ? (time() + ($account->premium_days * 86400)) : 0, 'status' => 'active', // active, frozen or suspended 'returnernotification' => false, 'showrewardnews' => true, @@ -259,24 +250,23 @@ switch ($action) { } function create_char($player, $highestLevelId) { - global $config; return [ 'worldid' => 0, - 'name' => $player['name'], - 'ismale' => intval($player['sex']) === 1, - 'tutorial' => isset($player['istutorial']) && $player['istutorial'], - 'level' => intval($player['level']), - 'vocation' => $config['vocations'][$player['vocation']], - 'outfitid' => intval($player['looktype']), - 'headcolor' => intval($player['lookhead']), - 'torsocolor' => intval($player['lookbody']), - 'legscolor' => intval($player['looklegs']), - 'detailcolor' => intval($player['lookfeet']), - 'addonsflags' => intval($player['lookaddons']), - 'ishidden' => isset($player['deletion']) && (int)$player['deletion'] === 1, + 'name' => $player->name, + 'ismale' => $player->sex === 1, + 'tutorial' => isset($player->istutorial) && $player->istutorial, + 'level' => $player->level, + 'vocation' => $player->vocation_name, + 'outfitid' => $player->looktype, + 'headcolor' => $player->lookhead, + 'torsocolor' => $player->lookbody, + 'legscolor' => $player->looklegs, + 'detailcolor' => $player->lookfeet, + 'addonsflags' => $player->lookaddons, + 'ishidden' => $player->is_deleted, 'istournamentparticipant' => false, - 'ismaincharacter' => $highestLevelId == $player['id'], - 'dailyrewardstate' => isset($player['isreward']) ? intval($player['isreward']) : 0, + 'ismaincharacter' => $highestLevelId === $player->getKey(), + 'dailyrewardstate' => $player->isreward ?? 0, 'remainingdailytournamentplaytime' => 0 ]; } diff --git a/system/compat/config.php b/system/compat/config.php index bf56f92a..b6cf29f7 100644 --- a/system/compat/config.php +++ b/system/compat/config.php @@ -71,6 +71,9 @@ $deprecatedConfig = [ 'account_login_by_email', 'account_login_by_email_fallback', 'account_mail_verify', + 'account_mail_unique', + 'account_premium_days', + 'account_premium_points', 'account_create_character_create', 'account_change_character_name', 'account_change_character_name_points' => 'account_change_character_name_price', diff --git a/system/database.php b/system/database.php index e50e8568..f20ca720 100644 --- a/system/database.php +++ b/system/database.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use Illuminate\Database\Capsule\Manager as Capsule; + defined('MYAAC') or die('Direct access not allowed!'); if (!isset($config['database_overwrite'])) { @@ -91,21 +94,34 @@ if(!isset($config['database_socket'])) { $config['database_socket'] = ''; } + try { $ots->connect(array( - 'host' => $config['database_host'], - 'user' => $config['database_user'], - 'password' => $config['database_password'], - 'database' => $config['database_name'], - 'log' => $config['database_log'], - 'socket' => @$config['database_socket'], - 'persistent' => @$config['database_persistent'] - ) - ); + 'host' => $config['database_host'], + 'user' => $config['database_user'], + 'password' => $config['database_password'], + 'database' => $config['database_name'], + 'log' => $config['database_log'], + 'socket' => @$config['database_socket'], + 'persistent' => @$config['database_persistent'] + )); $db = POT::getInstance()->getDBHandle(); -} -catch(PDOException $error) { + $capsule = new Capsule; + $capsule->addConnection([ + 'driver' => 'mysql', + 'database' => $config['database_name'], + ]); + + $capsule->getConnection()->setPdo($db); + $capsule->getConnection()->setReadPdo($db); + + $capsule->setAsGlobal(); + $capsule->bootEloquent(); + + $eloquentConnection = $capsule->getConnection(); + +} catch (Exception $e) { if(isset($cache) && $cache->enabled()) { $cache->delete('config_lua'); } @@ -119,5 +135,5 @@ catch(PDOException $error) { '
      ' . '
    • MySQL is not configured propertly in config.lua.
    • ' . '
    • MySQL server is not running.
    • ' . - '
    ' . $error->getMessage()); + '' . $e->getMessage()); } diff --git a/system/functions.php b/system/functions.php index 712cd36e..70a67f32 100644 --- a/system/functions.php +++ b/system/functions.php @@ -9,6 +9,11 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +use MyAAC\Models\Config; +use MyAAC\Models\Guild; +use MyAAC\Models\House; +use MyAAC\Models\Pages; +use MyAAC\Models\Player; use PHPMailer\PHPMailer\PHPMailer; use Twig\Loader\ArrayLoader as Twig_ArrayLoader; @@ -99,16 +104,15 @@ function getMonsterLink($name, $generate = true): string function getHouseLink($name, $generate = true): string { - global $db; - if(is_numeric($name)) { - $house = $db->query( - 'SELECT `name` FROM `houses` WHERE `id` = ' . (int)$name); - if($house->rowCount() > 0) - $name = $house->fetchColumn(); + $house = House::find(intval($name), ['name']); + if ($house) { + $name = $house->name; + } } + $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'houses/' . urlencode($name); if(!$generate) return $url; @@ -118,10 +122,8 @@ function getHouseLink($name, $generate = true): string function getGuildLink($name, $generate = true): string { if(is_numeric($name)) { - $name = getGuildNameById($name); - if ($name === false) { - $name = 'Unknown'; - } + $guild = Guild::find(intval($name), ['name']); + $name = $guild->name ?? 'Unknown'; } $url = BASE_URL . (setting('core.friendly_urls') ? '' : 'index.php/') . 'guilds/' . urlencode($name); @@ -272,13 +274,12 @@ function getForumBoards() */ function fetchDatabaseConfig($name, &$value) { - global $db; - - $query = $db->query('SELECT `value` FROM `' . TABLE_PREFIX . 'config` WHERE `name` = ' . $db->quote($name)); - if($query->rowCount() <= 0) + $config = Config::select('value')->where('name', '=', $name)->first(); + if (!$config) { return false; + } - $value = $query->fetchColumn(); + $value = $config->value; return true; } @@ -303,8 +304,7 @@ function getDatabaseConfig($name) */ function registerDatabaseConfig($name, $value) { - global $db; - $db->insert(TABLE_PREFIX . 'config', array('name' => $name, 'value' => $value)); + Config::create(compact('name', 'value')); } /** @@ -315,8 +315,9 @@ function registerDatabaseConfig($name, $value) */ function updateDatabaseConfig($name, $value) { - global $db; - $db->update(TABLE_PREFIX . 'config', array('value' => $value), array('name' => $name)); + Config::where('name', '=', $name)->update([ + 'value' => $value + ]); } /** @@ -343,47 +344,55 @@ function encrypt($str) //delete player with name function delete_player($name) { - global $db; - $player = new OTS_Player(); - $player->find($name); - if($player->isLoaded()) { - try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} - try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {} - $rank = $player->getRank(); - if($rank->isLoaded()) { - $guild = $rank->getGuild(); - if($guild->getOwner()->getId() == $player->getId()) { - $rank_list = $guild->getGuildRanksList(); - if(count($rank_list) > 0) { - $rank_list->orderBy('level'); - foreach($rank_list as $rank_in_guild) { - $players_with_rank = $rank_in_guild->getPlayersList(); - $players_with_rank->orderBy('name'); - $players_with_rank_number = count($players_with_rank); - if($players_with_rank_number > 0) { - foreach($players_with_rank as $player_in_guild) { - $player_in_guild->setRank(); - $player_in_guild->save(); - } - } - $rank_in_guild->delete(); - } - $guild->delete(); - } - } - } - $player->delete(); - return true; + // DB::beginTransaction(); + global $capsule; + $player = Player::where(compact('name'))->first(); + if (!$player) { + return false; } return false; + // global $db; + // $player = new OTS_Player(); + // $player->find($name); + // if($player->isLoaded()) { + // try { $db->exec("DELETE FROM player_skills WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM guild_invites WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_items WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_depotitems WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_spells WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_storage WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_viplist WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_deaths WHERE player_id = '".$player->getId()."';"); } catch(PDOException $error) {} + // try { $db->exec("DELETE FROM player_deaths WHERE killed_by = '".$player->getId()."';"); } catch(PDOException $error) {} + // $rank = $player->getRank(); + // if($rank->isLoaded()) { + // $guild = $rank->getGuild(); + // if($guild->getOwner()->getId() == $player->getId()) { + // $rank_list = $guild->getGuildRanksList(); + // if(count($rank_list) > 0) { + // $rank_list->orderBy('level'); + // foreach($rank_list as $rank_in_guild) { + // $players_with_rank = $rank_in_guild->getPlayersList(); + // $players_with_rank->orderBy('name'); + // $players_with_rank_number = count($players_with_rank); + // if($players_with_rank_number > 0) { + // foreach($players_with_rank as $player_in_guild) { + // $player_in_guild->setRank(); + // $player_in_guild->save(); + // } + // } + // $rank_in_guild->delete(); + // } + // $guild->delete(); + // } + // } + // } + // $player->delete(); + // return true; + // } + + // return false; } //delete guild with id @@ -1049,26 +1058,38 @@ function getTopPlayers($limit = 5) { } if (!isset($players)) { - $deleted = 'deleted'; - if($db->hasColumn('players', 'deletion')) - $deleted = 'deletion'; + $columns = [ + 'id', 'name', 'level', 'vocation', 'experience', + 'looktype', 'lookhead', 'lookbody', 'looklegs', 'lookfeet' + ]; - $is_tfs10 = $db->hasTable('players_online'); - $players = $db->query('SELECT `id`, `name`, `level`, `vocation`, `experience`, `looktype`' . ($db->hasColumn('players', 'lookaddons') ? ', `lookaddons`' : '') . ', `lookhead`, `lookbody`, `looklegs`, `lookfeet`' . ($is_tfs10 ? '' : ', `online`') . ' FROM `players` WHERE `group_id` < ' . setting('core.highscores_groups_hidden') . ' AND `id` NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND `' . $deleted . '` = 0 AND `account_id` != 1 ORDER BY `experience` DESC LIMIT ' . (int)$limit)->fetchAll(); - - if($is_tfs10) { - foreach($players as &$player) { - $query = $db->query('SELECT `player_id` FROM `players_online` WHERE `player_id` = ' . $player['id']); - $player['online'] = ($query->rowCount() > 0 ? 1 : 0); - } - unset($player); + if ($db->hasColumn('players', 'lookaddons')) { + $columns[] = 'lookaddons'; } - $i = 0; - foreach($players as &$player) { - $player['rank'] = ++$i; + if ($db->hasColumn('players', 'online')) { + $columns[] = 'online'; } - unset($player); + + $players = Player::query() + ->select($columns) + ->withOnlineStatus() + ->notDeleted() + ->where('group_id', '<', setting('core.highscores_groups_hidden')) + ->whereNotIn('id', setting('core.highscores_ids_hidden')) + ->where('account_id', '!=', 1) + ->orderByDesc('experience') + ->limit($limit) + ->get() + ->map(function ($e, $i) { + $row = $e->toArray(); + $row['online'] = $e->online_status; + $row['rank'] = $i + 1; + + unset($row['online_table']); + + return $row; + })->toArray(); if($cache->enabled()) { $cache->set('top_' . $limit . '_level', serialize($players), 120); @@ -1202,49 +1223,44 @@ function clearCache() return true; } -function getCustomPageInfo($page) +function getCustomPageInfo($name) { - global $db, $logged_access; - $query = - $db->query( - 'SELECT `id`, `title`, `body`, `php`, `hidden`' . - ' FROM `' . TABLE_PREFIX . 'pages`' . - ' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access)); - if($query->rowCount() > 0) // found page - { - return $query->fetch(PDO::FETCH_ASSOC); + global $logged_access; + $page = Pages::isPublic() + ->where('name', 'LIKE', $name) + ->where('access', '<=', $logged_access) + ->first(); + + if (!$page) { + return null; } - return null; + return $page->toArray(); } -function getCustomPage($page, &$success): string +function getCustomPage($name, &$success): string { - global $db, $twig, $title, $ignore, $logged_access; + global $twig, $title, $ignore; $success = false; $content = ''; - $query = - $db->query( - 'SELECT `id`, `title`, `body`, `php`, `hidden`' . - ' FROM `' . TABLE_PREFIX . 'pages`' . - ' WHERE `name` LIKE ' . $db->quote($page) . ' AND `hidden` != 1 AND `access` <= ' . $db->quote($logged_access)); - if($query->rowCount() > 0) // found page + $page = getCustomPageInfo($name); + + if($page) // found page { $success = $ignore = true; - $query = $query->fetch(); - $title = $query['title']; + $title = $page['title']; - if($query['php'] == '1') // execute it as php code + if($page['php'] == '1') // execute it as php code { - $tmp = substr($query['body'], 0, 10); + $tmp = substr($page['body'], 0, 10); if(($pos = strpos($tmp, 'getLoader(); $twig_loader_array = new Twig_ArrayLoader(array( - 'content.html' => $query['body'] + 'content.html' => $page['body'] )); $twig->setLoader($twig_loader_array); @@ -1390,22 +1406,17 @@ function getChangelogWhere($v) function getPlayerNameByAccountId($id) { - global $db; - if (!is_numeric($id)) { return ''; } - $account = new OTS_Account(); - $account->load($id); - if ($account->isLoaded()) { - $query = $db->query('SELECT `name` FROM `players` WHERE `account_id` = ' . $id . ' ORDER BY `lastlogin` DESC LIMIT 1;'); - - if (!$query || !$query->rowCount()) { + $account = \MyAAC\Models\Account::find(intval($id), ['id']); + if ($account) { + $player = \MyAAC\Models\Player::where('account_id', $account->id)->orderByDesc('lastlogin')->select('name')->first(); + if (!$player) { return ''; } - - return $query->fetch(PDO::FETCH_ASSOC)['name']; + return $player->name; } return ''; @@ -1425,10 +1436,9 @@ function getPlayerNameById($id) return ''; } - $player = new OTS_Player(); - $player->load($id); - if ($player->isLoaded()) { - return $player->getName(); + $player = \MyAAC\Models\Player::find((int)$id, ['name']); + if ($player) { + return $player->name; } return ''; @@ -1583,12 +1593,9 @@ function escapeHtml($html) { function getGuildNameById($id) { - global $db; - - $guild = $db->query('SELECT `name` FROM `guilds` WHERE `id` = ' . (int)$id); - - if($guild->rowCount() > 0) { - return $guild->fetchColumn(); + $guild = Guild::where('id', intval($id))->select('name')->first(); + if ($guild) { + return $guild->name; } return false; @@ -1596,15 +1603,11 @@ function getGuildNameById($id) function getGuildLogoById($id) { - global $db; - $logo = 'default.gif'; - $query = $db->query('SELECT `logo_name` FROM `guilds` WHERE `id` = ' . (int)$id); - if ($query->rowCount() == 1) { - - $query = $query->fetch(PDO::FETCH_ASSOC); - $guildLogo = $query['logo_name']; + $guild = Guild::where('id', intval($id))->select('logo_name')->first(); + if ($guild) { + $guildLogo = $query->logo_name; if (!empty($guildLogo) && file_exists(GUILD_IMAGES_DIR . $guildLogo)) { $logo = $guildLogo; diff --git a/system/init.php b/system/init.php index c941f4d4..bda1f85c 100644 --- a/system/init.php +++ b/system/init.php @@ -117,9 +117,11 @@ if(!isset($foundValue)) { $config['data_path'] = $foundValue; unset($foundValue); + // POT require_once SYSTEM . 'libs/pot/OTS.php'; $ots = POT::getInstance(); +$eloquentConnection = null; require_once SYSTEM . 'database.php'; // execute migrations diff --git a/system/libs/CreateCharacter.php b/system/libs/CreateCharacter.php index 8ec6993a..a4a1f87a 100644 --- a/system/libs/CreateCharacter.php +++ b/system/libs/CreateCharacter.php @@ -1,4 +1,7 @@ find($name); - if($player->isLoaded()) { + if(Player::where('name', '=', $name)->exists()) { $errors['name'] = 'Character with this name already exist.'; return false; } diff --git a/system/libs/Settings.php b/system/libs/Settings.php index 7e1d07f5..3ed320d2 100644 --- a/system/libs/Settings.php +++ b/system/libs/Settings.php @@ -1,4 +1,7 @@ query('SELECT * FROM `' . TABLE_PREFIX . 'settings`'); - - if($settings->rowCount() > 0) { - foreach ($settings->fetchAll(PDO::FETCH_ASSOC) as $setting) { - $this->settingsDatabase[$setting['name']][$setting['key']] = $setting['value']; - } + $settings = ModelsSettings::all(); + foreach ($settings as $setting) + { + $this->settingsDatabase[$setting->name][$setting->key] = $setting->value; } if ($cache->enabled()) { @@ -55,8 +55,6 @@ class Settings implements ArrayAccess } public function save($pluginName, $values) { - global $db; - if (!isset($this->settingsFile[$pluginName])) { throw new RuntimeException('Error on save settings: plugin does not exist'); } @@ -69,7 +67,7 @@ class Settings implements ArrayAccess } $this->errors = []; - $db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($pluginName) . ';'); + ModelsSettings::where('name', $pluginName)->delete(); foreach ($values as $key => $value) { $errorMessage = ''; if (isset($settings['settings'][$key]['callbacks']['beforeSave']) && !$settings['settings'][$key]['callbacks']['beforeSave']($key, $value, $errorMessage)) { @@ -78,7 +76,11 @@ class Settings implements ArrayAccess } try { - $db->insert(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key, 'value' => $value]); + ModelsSettings::create([ + 'name' => $pluginName, + 'key' => $key, + 'value' => $value + ]); } catch (PDOException $error) { $this->errors[] = 'Error while saving setting (' . $pluginName . ' - ' . $key . '): ' . $error->getMessage(); } @@ -94,36 +96,22 @@ class Settings implements ArrayAccess public function updateInDatabase($pluginName, $key, $value) { - global $db; - $db->update(TABLE_PREFIX . 'settings', ['value' => $value], ['name' => $pluginName, 'key' => $key]); + ModelsSettings::where(['name' => $pluginName, 'key' => $key])->update(['value' => $value]); } public function deleteFromDatabase($pluginName, $key = null) { - global $db; - if (!isset($key)) { - $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName], -1); + ModelsSettings::where('name', $pluginName)->delete(); } else { - $db->delete(TABLE_PREFIX . 'settings', ['name' => $pluginName, 'key' => $key]); + ModelsSettings::where('name', $pluginName)->where('key', $key)->delete(); } } public static function display($plugin, $settings): array { - global $db; - - $query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'settings` WHERE `name` = ' . $db->quote($plugin) . ';'; - $query = $db->query($query); - - $settingsDb = []; - if($query->rowCount() > 0) { - foreach($query->fetchAll(PDO::FETCH_ASSOC) as $value) { - $settingsDb[$value['key']] = $value['value']; - } - } - + $settingsDb = ModelsSettings::where('name', $plugin)->pluck('value', 'key')->toArray(); $config = []; require BASE . 'config.local.php'; diff --git a/system/libs/Towns.php b/system/libs/Towns.php index 01caa550..d528118a 100644 --- a/system/libs/Towns.php +++ b/system/libs/Towns.php @@ -23,6 +23,8 @@ * @link https://my-aac.org */ +use MyAAC\Models\Town; + /** * Class Towns */ @@ -124,15 +126,6 @@ class Towns */ public static function getFromDatabase() { - global $db; - - $query = $db->query('SELECT `id`, `name` FROM `towns`;')->fetchAll(PDO::FETCH_ASSOC); - - $towns = []; - foreach($query as $town) { - $towns[$town['id']] = $town['name']; - } - - return $towns; + return Town::pluck('name', 'id')->toArray(); } } diff --git a/system/libs/changelog.php b/system/libs/changelog.php index 89f78bfc..e612aa5b 100644 --- a/system/libs/changelog.php +++ b/system/libs/changelog.php @@ -1,5 +1,7 @@ insert(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'date' => $cdate, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0)); - self::clearCache(); - return true; + $row = new ModelsChangelog; + $row->body = $body; + $row->type = $type; + $row->date = $cdate; + $row->where = $where; + $row->player_id = $player_id ?? 0; + if ($row->save()) { + self::clearCache(); + return true; + } + + return false; } static public function get($id) { - global $db; - return $db->select(TABLE_PREFIX . 'changelog', array('id' => $id)); + return ModelsChangelog::find($id); } static public function update($id, $body, $type, $where, $player_id, $date, &$errors) { - global $db; if(!self::verify($body,$date, $errors)) return false; - $db->update(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0, 'date' => $date), array('id' => $id)); - self::clearCache(); - return true; + if (ModelsChangelog::where('id', '=', $id)->update([ + 'body' => $body, + 'type' => $type, + 'where' => $where, + 'player_id' => $player_id ?? 0, + 'date' => $date + ])) { + self::clearCache(); + return true; + } + + return false; } static public function delete($id, &$errors) { - global $db; if(isset($id)) { - if($db->select(TABLE_PREFIX . 'changelog', array('id' => $id)) !== false) - $db->delete(TABLE_PREFIX . 'changelog', array('id' => $id)); - else + $row = ModelsChangelog::find($id); + if ($row) { + if (!$row->delete()) { + $errors[] = 'Fail during delete Changelog.'; + } + } else { $errors[] = 'Changelog with id ' . $id . ' does not exist.'; - } - else + } + } else { $errors[] = 'Changelog id not set.'; + } if(count($errors)) { return false; @@ -67,17 +87,18 @@ class Changelog static public function toggleHidden($id, &$errors, &$status) { - global $db; if(isset($id)) { - $query = $db->select(TABLE_PREFIX . 'changelog', array('id' => $id)); - if($query !== false) - { - $db->update(TABLE_PREFIX . 'changelog', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - $status = $query['hidden']; - } - else + $row = ModelsChangelog::find($id); + if ($row) { + $row->hidden = $row->hidden == 1 ? 0 : 1; + if (!$row->save()) { + $errors[] = 'Fail during toggle hidden Changelog.'; + } + } else { $errors[] = 'Changelog with id ' . $id . ' does not exists.'; + } + } else $errors[] = 'Changelog id not set.'; diff --git a/system/libs/creatures.php b/system/libs/creatures.php index a9e76066..42be67ad 100644 --- a/system/libs/creatures.php +++ b/system/libs/creatures.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Monster; + defined('MYAAC') or die('Direct access not allowed!'); require_once LIBS . 'items.php'; @@ -19,9 +22,9 @@ class Creatures { private static $lastError = ''; public static function loadFromXML($show = false) { - global $db; - - try { $db->exec('DELETE FROM `' . TABLE_PREFIX . 'monsters`;'); } catch(PDOException $error) {} + try { + Monster::query()->delete(); + } catch(Exception $error) {} if($show) { echo '

    Reload monsters.

    '; @@ -93,9 +96,9 @@ class Creatures { $flags['convinceable'] = '0'; if(!isset($flags['pushable'])) - $flags['pushable'] = '0'; + $flags['pushable'] = '0'; if(!isset($flags['canpushitems'])) - $flags['canpushitems'] = '0'; + $flags['canpushitems'] = '0'; if(!isset($flags['canpushcreatures'])) $flags['canpushcreatures'] = '0'; if(!isset($flags['runonhealth'])) @@ -112,7 +115,7 @@ class Creatures { $flags['attackable'] = '0'; if(!isset($flags['rewardboss'])) $flags['rewardboss'] = '0'; - + $summons = $monster->getSummons(); $loot = $monster->getLoot(); foreach($loot as &$item) { @@ -124,7 +127,7 @@ class Creatures { } if(!in_array($name, $names_added)) { try { - $db->insert(TABLE_PREFIX . 'monsters', array( + Monster::create(array( 'name' => $name, 'mana' => empty($mana) ? 0 : $mana, 'exp' => $monster->getExperience(), @@ -132,7 +135,7 @@ class Creatures { 'speed_lvl' => $speed_lvl, 'use_haste' => $use_haste, 'voices' => json_encode($monster->getVoices()), - 'immunities' => json_encode($monster->getImmunities()), + 'immunities' => json_encode($monster->getImmunities()), 'elements' => json_encode($monster->getElements()), 'summonable' => $flags['summonable'] > 0 ? 1 : 0, 'convinceable' => $flags['convinceable'] > 0 ? 1 : 0, @@ -158,7 +161,7 @@ class Creatures { success('Added: ' . $name . '
    '); } } - catch(PDOException $error) { + catch(Exception $error) { if($show) { warning('Error while adding monster (' . $name . '): ' . $error->getMessage()); } diff --git a/system/libs/items.php b/system/libs/items.php index af663c1b..d90eff6b 100644 --- a/system/libs/items.php +++ b/system/libs/items.php @@ -78,8 +78,6 @@ class Items } public static function getDescription($id, $count = 1) { - global $db; - $item = self::get($id); $attr = $item['attributes']; @@ -112,17 +110,15 @@ class Items $s .= 'an item of type ' . $item['id']; if(isset($attr['type']) && strtolower($attr['type']) == 'rune') { - $query = $db->query('SELECT `level`, `maglevel`, `vocations` FROM `' . TABLE_PREFIX . 'spells` WHERE `item_id` = ' . $id); - if($query->rowCount() == 1) { - $query = $query->fetch(); - - if($query['level'] > 0 && $query['maglevel'] > 0) { + $item = Spells::where('item_id', $id)->first(); + if($item) { + if($item->level > 0 && $item->maglevel > 0) { $s .= '. ' . ($count > 1 ? "They" : "It") . ' can only be used by '; } $configVocations = config('vocations'); - if(!empty(trim($query['vocations']))) { - $vocations = json_decode($query['vocations']); + if(!empty(trim($item->vocations))) { + $vocations = json_decode($item->vocations); if(count($vocations) > 0) { foreach($vocations as $voc => $show) { $vocations[$configVocations[$voc]] = $show; diff --git a/system/libs/news.php b/system/libs/news.php index b0f17158..352b2a1e 100644 --- a/system/libs/news.php +++ b/system/libs/news.php @@ -1,5 +1,7 @@ insert(TABLE_PREFIX . 'news', array('title' => $title, 'body' => $body, 'type' => $type, 'date' => time(), 'category' => $category, 'player_id' => isset($player_id) ? $player_id : 0, 'comments' => $comments, 'article_text' => ($type == 3 ? $article_text : ''), 'article_image' => ($type == 3 ? $article_image : ''))); + ModelsNews::create([ + 'title' => $title, + 'body' => $body, + 'type' => $type, + 'date' => time(), + 'category' => $category, + 'player_id' => isset($player_id) ? $player_id : 0, + 'comments' => $comments, + 'article_text' => ($type == 3 ? $article_text : ''), + 'article_image' => ($type == 3 ? $article_image : '') + ]); self::clearCache(); return true; } static public function get($id) { - global $db; - return $db->select(TABLE_PREFIX . 'news', array('id' => $id)); + return ModelsNews::find($id)->toArray(); } static public function update($id, $title, $body, $type, $category, $player_id, $comments, $article_text, $article_image, &$errors) { - global $db; if(!self::verify($title, $body, $article_text, $article_image, $errors)) return false; - $db->update(TABLE_PREFIX . 'news', array('title' => $title, 'body' => $body, 'type' => $type, 'category' => $category, 'last_modified_by' => isset($player_id) ? $player_id : 0, 'last_modified_date' => time(), 'comments' => $comments, 'article_text' => $article_text, 'article_image' => $article_image), array('id' => $id)); + ModelsNews::where('id', $id)->update([ + 'title' => $title, + 'body' => $body, + 'type' => $type, + 'category' => $category, + 'last_modified_by' => isset($player_id) ? $player_id : 0, + 'last_modified_date' => time(), + 'comments' => $comments, + 'article_text' => $article_text, + 'article_image' => $article_image + ]); self::clearCache(); return true; } static public function delete($id, &$errors) { - global $db; if(isset($id)) { - if($db->select(TABLE_PREFIX . 'news', array('id' => $id)) !== false) - $db->delete(TABLE_PREFIX . 'news', array('id' => $id)); + $row = ModelsNews::find($id); + if($row) + if (!$row->delete()) { + $errors[] = 'Fail during delete News.'; + } else $errors[] = 'News with id ' . $id . ' does not exists.'; } @@ -77,14 +98,16 @@ class News static public function toggleHidden($id, &$errors, &$status) { - global $db; if(isset($id)) { - $query = $db->select(TABLE_PREFIX . 'news', array('id' => $id)); - if($query !== false) + $row = ModelsNews::find($id); + if($row) { - $db->update(TABLE_PREFIX . 'news', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - $status = $query['hidden']; + $row->hidden = $row->hidden == 1 ? 0 : 1; + if (!$row->save()) { + $errors[] = 'Fail during toggle hidden News.'; + } + $status = $row->hidden; } else $errors[] = 'News with id ' . $id . ' does not exists.'; diff --git a/system/libs/plugins.php b/system/libs/plugins.php index c2b8f594..d06ddf41 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -39,6 +39,7 @@ function is_sub_dir($path = NULL, $parent_folder = BASE) { } use Composer\Semver\Semver; +use MyAAC\Models\Menu; class Plugins { private static $warnings = []; @@ -649,11 +650,9 @@ class Plugins { */ public static function installMenus($templateName, $categories) { - global $db; - // check if menus already exist - $query = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($templateName) . ' LIMIT 1;'); - if ($query->rowCount() > 0) { + $menuInstalled = Menu::where('template', $templateName)->select('id')->first(); + if ($menuInstalled) { return; } @@ -687,7 +686,7 @@ class Plugins { 'color' => $color, ]; - $db->insert(TABLE_PREFIX . 'menu', $insert_array); + Menu::create($insert_array); } } } diff --git a/system/libs/spells.php b/system/libs/spells.php index 60ea182e..9a5d30d7 100644 --- a/system/libs/spells.php +++ b/system/libs/spells.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Spell; + defined('MYAAC') or die('Direct access not allowed!'); class Spells { @@ -31,9 +34,11 @@ class Spells { } public static function loadFromXML($show = false) { - global $config, $db; + global $config; - try { $db->exec('DELETE FROM `' . TABLE_PREFIX . 'spells`;'); } catch(PDOException $error) {} + try { + Spell::query()->delete(); + } catch(Exception $error) {} if($show) { echo '

    Reload spells.

    '; @@ -63,7 +68,7 @@ class Spells { continue; try { - $db->insert(TABLE_PREFIX . 'spells', array( + Spell::create(array( 'name' => $name, 'words' => $words, 'type' => 2, @@ -105,7 +110,7 @@ class Spells { continue; try { - $db->insert(TABLE_PREFIX . 'spells', array( + Spell::create(array( 'name' => $name, 'words' => $words, 'type' => 1, @@ -142,7 +147,7 @@ class Spells { $name = $spell->getName() . ' Rune'; try { - $db->insert(TABLE_PREFIX . 'spells', array( + Spell::create(array( 'name' => $name, 'words' => $spell->getWords(), 'type' => 3, @@ -178,4 +183,4 @@ class Spells { public static function getLastError() { return self::$lastError; } -} \ No newline at end of file +} diff --git a/system/libs/validator.php b/system/libs/validator.php index e7bffd6a..cc2002dd 100644 --- a/system/libs/validator.php +++ b/system/libs/validator.php @@ -7,6 +7,10 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Monster; +use MyAAC\Models\Spell; + defined('MYAAC') or die('Direct access not allowed!'); class Validator @@ -307,8 +311,7 @@ class Validator $monstersCheck = setting('core.create_character_name_monsters_check'); if ($monstersCheck) { - $monsters = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'monsters` WHERE `name` LIKE ' . $db->quote($name_lower)); - if ($monsters->rowCount() > 0) { + if (Monster::where('name', 'like', $name_lower)->exists()) { self::$lastError = 'Your name cannot contains monster name.'; return false; } @@ -316,14 +319,12 @@ class Validator $spellsCheck = setting('core.create_character_name_spells_check'); if ($spellsCheck) { - $spells_name = $db->query('SELECT `name` FROM `' . TABLE_PREFIX . 'spells` WHERE `name` LIKE ' . $db->quote($name_lower)); - if ($spells_name->rowCount() > 0) { + if (Spell::where('name', 'like', $name_lower)->exists()) { self::$lastError = 'Your name cannot contains spell name.'; return false; } - $spells_words = $db->query('SELECT `words` FROM `' . TABLE_PREFIX . 'spells` WHERE `words` = ' . $db->quote($name_lower)); - if ($spells_words->rowCount() > 0) { + if (Spell::where('words', $name_lower)->exists()) { self::$lastError = 'Your name cannot contains spell name.'; return false; } diff --git a/system/libs/visitors.php b/system/libs/visitors.php index 53cc5839..7afd47df 100644 --- a/system/libs/visitors.php +++ b/system/libs/visitors.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Visitor; + defined('MYAAC') or die('Direct access not allowed!'); class Visitors @@ -54,9 +57,7 @@ class Visitors return isset($this->data[$ip]); } - global $db; - $users = $db->query('SELECT COUNT(`ip`) as count FROM `' . TABLE_PREFIX . 'visitors' . '` WHERE ' . $db->fieldName('ip') . ' = ' . $db->quote($ip))->fetch(); - return ($users['count'] > 0); + return Visitor::where('ip', $ip)->exists(); } private function cleanVisitors() @@ -73,8 +74,7 @@ class Visitors return; } - global $db; - $db->exec('DELETE FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' WHERE ' . $db->fieldName('lastvisit') . ' < ' . (time() - $this->sessionTime * 60)); + Visitor::where('lastvisit', '<', (time() - $this->sessionTime * 60))->delete(); } private function updateVisitor($ip, $page, $userAgent) @@ -84,8 +84,7 @@ class Visitors return; } - global $db; - $db->update(TABLE_PREFIX . 'visitors', ['lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent], ['ip' => $ip]); + Visitor::where('ip', $ip)->update(['lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]); } private function addVisitor($ip, $page, $userAgent) @@ -95,8 +94,7 @@ class Visitors return; } - global $db; - $db->insert(TABLE_PREFIX . 'visitors', ['ip' => $ip, 'lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]); + Visitor::create(['ip' => $ip, 'lastvisit' => time(), 'page' => $page, 'user_agent' => $userAgent]); } public function getVisitors() @@ -108,8 +106,7 @@ class Visitors return $this->data; } - global $db; - return $db->query('SELECT ' . $db->fieldName('ip') . ', ' . $db->fieldName('lastvisit') . ', ' . $db->fieldName('page') . ', ' . $db->fieldName('user_agent') . ' FROM ' . $db->tableName(TABLE_PREFIX . 'visitors') . ' ORDER BY ' . $db->fieldName('lastvisit') . ' DESC')->fetchAll(); + return Visitor::orderByDesc('lastvisit')->get()->toArray(); } public function getAmountVisitors() @@ -118,9 +115,7 @@ class Visitors return count($this->data); } - global $db; - $users = $db->query('SELECT COUNT(`ip`) as count FROM `' . TABLE_PREFIX . 'visitors`')->fetch(); - return $users['count']; + return Visitor::count(); } public function show() { diff --git a/system/libs/weapons.php b/system/libs/weapons.php index 76657e60..83dca70b 100644 --- a/system/libs/weapons.php +++ b/system/libs/weapons.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Weapon; + defined('MYAAC') or die('Direct access not allowed!'); class Weapons { @@ -15,10 +18,10 @@ class Weapons { public static function loadFromXML($show = false) { - global $config, $db; + global $config; try { - $db->exec("DELETE FROM `myaac_weapons`;"); + Weapon::query()->delete(); } catch (PDOException $error) { } @@ -45,7 +48,7 @@ class Weapons { } public static function parseNode($node, $show = false) { - global $config, $db; + global $config; $id = (int)$node->getAttribute('id'); $vocations_ids = array_flip($config['vocations']); @@ -64,18 +67,19 @@ class Weapons { $vocations[$voc_id] = strlen($show) == 0 || $show != '0'; } - $exist = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'weapons` WHERE `id` = ' . $id); - if($exist->rowCount() > 0) { + if(Weapon::find($id)) { if($show) { warning('Duplicated weapon with id: ' . $id); } } else { - $db->insert(TABLE_PREFIX . 'weapons', array('id' => $id, 'level' => $level, 'maglevel' => $maglevel, 'vocations' => json_encode($vocations))); + Weapon::create([ + 'id' => $id, 'level' => $level, 'maglevel' => $maglevel, 'vocations' => json_encode($vocations) + ]); } } public static function getError() { return self::$error; } -} \ No newline at end of file +} diff --git a/system/migrations/1.php b/system/migrations/1.php index 538945df..6e4f3252 100644 --- a/system/migrations/1.php +++ b/system/migrations/1.php @@ -13,4 +13,4 @@ ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; "); -?> \ No newline at end of file +?> diff --git a/system/migrations/17.php b/system/migrations/17.php index 220bc90b..6ff83b84 100644 --- a/system/migrations/17.php +++ b/system/migrations/17.php @@ -15,74 +15,7 @@ CREATE TABLE `myaac_menu` ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8; "); - $db->query(" -/* MENU_CATEGORY_NEWS kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Latest News', 'news', 1, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'News Archive', 'news/archive', 1, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Changelog', 'changelog', 1, 2); -/* MENU_CATEGORY_ACCOUNT kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Account Management', 'account/manage', 2, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Create Account', 'account/create', 2, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Lost Account?', 'account/lost', 2, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Rules', 'rules', 2, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Downloads', 'downloads', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Report Bug', 'bugtracker', 2, 5); -/* MENU_CATEGORY_COMMUNITY kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Who is Online?', 'online', 3, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Characters', 'characters', 3, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Guilds', 'guilds', 3, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Highscores', 'highscores', 3, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Last Deaths', 'lastkills', 3, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Houses', 'houses', 3, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Bans', 'bans', 3, 6); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Forum', 'forum', 3, 7); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Team', 'team', 3, 8); -/* MENU_CATEGORY_LIBRARY kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Monsters', 'creatures', 5, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Spells', 'spells', 5, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Server Info', 'serverInfo', 5, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Commands', 'commands', 5, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Gallery', 'gallery', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Experience Table', 'experienceTable', 5, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'FAQ', 'faq', 5, 6); -/* MENU_CATEGORY_SHOP kathrine */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Buy Points', 'points', 6, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop Offer', 'gifts', 6, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('kathrine', 'Shop History', 'gifts/history', 6, 2); -/* MENU_CATEGORY_NEWS tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Latest News', 'news', 1, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'News Archive', 'news/archive', 1, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Changelog', 'changelog', 1, 2); -/* MENU_CATEGORY_ACCOUNT tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Account Management', 'account/manage', 2, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Create Account', 'account/create', 2, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Lost Account?', 'account/lost', 2, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Rules', 'rules', 2, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Downloads', 'downloads', 2, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Report Bug', 'bugtracker', 2, 5); -/* MENU_CATEGORY_COMMUNITY tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Characters', 'characters', 3, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Who Is Online?', 'online', 3, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Highscores', 'highscores', 3, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Last Kills', 'lastkills', 3, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Houses', 'houses', 3, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Guilds', 'guilds', 3, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Polls', 'polls', 3, 6); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Bans', 'bans', 3, 7); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Support List', 'team', 3, 8); -/* MENU_CATEGORY_FORUM tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Forum', 'forum', 4, 0); -/* MENU_CATEGORY_LIBRARY tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Creatures', 'creatures', 5, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Spells', 'spells', 5, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Commands', 'commands', 5, 2); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Exp Stages', 'experienceStages', 5, 3); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Gallery', 'gallery', 5, 4); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Server Info', 'serverInfo', 5, 5); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Experience Table', 'experienceTable', 5, 6); -/* MENU_CATEGORY_SHOP tibiacom */ -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Buy Points', 'points', 6, 0); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop Offer', 'gifts', 6, 1); -INSERT INTO `myaac_menu` (`template`, `name`, `link`, `category`, `ordering`) VALUES ('tibiacom', 'Shop History', 'gifts/history', 6, 2); - "); + require_once LIBS . 'plugins.php'; + Plugins::installMenus('kathrine', require TEMPLATES . 'kathrine/menus.php'); + Plugins::installMenus('tibiacom', require TEMPLATES . 'tibiacom/menus.php'); } diff --git a/system/pages/account/change_comment.php b/system/pages/account/change_comment.php index 21221426..868f38c6 100644 --- a/system/pages/account/change_comment.php +++ b/system/pages/account/change_comment.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Player; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Change Comment'; @@ -17,36 +20,36 @@ if(!$logged) { return; } +$player = null; $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; if($player_name != null) { if (Validator::characterName($player_name)) { - $player = new OTS_Player(); - $player->find($player_name); - if ($player->isLoaded()) { - $player_account = $player->getAccount(); - if ($account_logged->getId() == $player_account->getId()) { - if ($player->isDeleted()) { - $errors[] = 'This character is deleted.'; - $player = null; - } + $player = Player::query() + ->where('name', $player_name) + ->where('account_id', $account_logged->getId()) + ->first(); - if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) { - if(empty($errors)) { - $player->setCustomField("hidden", $new_hideacc); - $player->setCustomField("comment", $new_comment); - $account_logged->logAction('Changed comment for character ' . $player->getName() . '.'); - $twig->display('success.html.twig', array( - 'title' => 'Character Information Changed', - 'description' => 'The character information has been changed.' - )); - $show_form = false; - } + if ($player) { + if ($player->is_deleted) { + $errors[] = 'This character is deleted.'; + $player = null; + } + + if (isset($_POST['changecommentsave']) && $_POST['changecommentsave'] == 1) { + if(empty($errors)) { + $player->hidden = $new_hideacc; + $player->comment = $new_comment; + $player->save(); + $account_logged->logAction('Changed comment for character ' . $player->name . '.'); + $twig->display('success.html.twig', array( + 'title' => 'Character Information Changed', + 'description' => 'The character information has been changed.' + )); + $show_form = false; } - } else { - $errors[] = 'Error. Character ' . $player_name . ' is not on your account.'; } } else { $errors[] = "Error. Character with this name doesn't exist."; @@ -64,9 +67,9 @@ if($show_form) { $twig->display('error_box.html.twig', array('errors' => $errors)); } - if(isset($player) && $player->isLoaded()) { + if(isset($player) && $player) { $twig->display('account.change_comment.html.twig', array( - 'player' => $player + 'player' => $player->toArray() )); } } diff --git a/system/pages/account/change_info.php b/system/pages/account/change_info.php index 753f4ce5..8b61ea1c 100644 --- a/system/pages/account/change_info.php +++ b/system/pages/account/change_info.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Account; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Change Info'; @@ -20,6 +23,8 @@ if(!$logged) { if($config['account_country']) require SYSTEM . 'countries.conf.php'; +$account = Account::find($account_logged->getId()); + $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; @@ -30,9 +35,10 @@ if(isset($_POST['changeinfosave']) && $_POST['changeinfosave'] == 1) { if(empty($errors)) { //save data from form - $account_logged->setCustomField("rlname", $new_rlname); - $account_logged->setCustomField("location", $new_location); - $account_logged->setCustomField("country", $new_country); + $account->rlname = $new_rlname; + $account->location = $new_location; + $account->country = $new_country; + $account->save(); $account_logged->logAction('Changed Real Name to ' . $new_rlname . ', Location to ' . $new_location . ' and Country to ' . $config['countries'][$new_country] . '.'); $twig->display('success.html.twig', array( 'title' => 'Public Information Changed', @@ -47,10 +53,10 @@ if(isset($_POST['changeinfosave']) && $_POST['changeinfosave'] == 1) { //show form if($show_form) { - $account_rlname = $account_logged->getCustomField("rlname"); - $account_location = $account_logged->getCustomField("location"); + $account_rlname = $account->rlname; + $account_location = $account->location; if ($config['account_country']) { - $account_country = $account_logged->getCustomField("country"); + $account_country = $account->country; $countries = array(); foreach (array('pl', 'se', 'br', 'us', 'gb',) as $country) diff --git a/system/pages/account/confirm_email.php b/system/pages/account/confirm_email.php index 233c5533..925aef5e 100644 --- a/system/pages/account/confirm_email.php +++ b/system/pages/account/confirm_email.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Account; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Confirm Email'; @@ -17,14 +20,12 @@ if(empty($hash)) { return; } -$res = $db->query('SELECT `email_hash` FROM `accounts` WHERE `email_hash` = ' . $db->quote($hash)); -if(!$res->rowCount()) { +if(!Account::where('email_hash', $hash)->exists()) { note("Your email couldn't be verified. Please contact staff to do it manually."); } else { - $query = $db->query('SELECT id FROM accounts WHERE email_hash = ' . $db->quote($hash) . ' AND email_verified = 0'); - if ($query->rowCount() == 1) { + if (Account::where('email_hash', $hash)->where('email_verified', 0)->exists()) { $query = $query->fetch(PDO::FETCH_ASSOC); $account = new OTS_Account(); $account->load($query['id']); @@ -33,7 +34,7 @@ else } } - $db->update('accounts', array('email_verified' => '1'), array('email_hash' => $hash)); + Account::where('email_hash', $hash)->update('email_verified', 1); success('You have now verified your e-mail, this will increase the security of your account. Thank you for doing this.'); } ?> diff --git a/system/pages/bans.php b/system/pages/bans.php index f862183b..d2a69f47 100644 --- a/system/pages/bans.php +++ b/system/pages/bans.php @@ -11,8 +11,8 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Bans list'; -$configBansPerPage = config('bans_per_page'); -$_page = isset($_GET['page']) ? $_GET['page'] : 1; +$configBansPerPage = setting('core.bans_per_page'); +$_page = $_GET['page'] ?? 1; if(!is_numeric($_page) || $_page < 1 || $_page > PHP_INT_MAX) { $_page = 1; diff --git a/system/pages/bugtracker.php b/system/pages/bugtracker.php index ac37becd..790941cb 100644 --- a/system/pages/bugtracker.php +++ b/system/pages/bugtracker.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\BugTracker; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Bug tracker'; @@ -29,10 +32,10 @@ $showed = $post = $reply = false; if(admin() and isset($_REQUEST['control']) && $_REQUEST['control'] == "true") { if(empty($_REQUEST['id']) and empty($_REQUEST['acc']) or !is_numeric($_REQUEST['acc']) or !is_numeric($_REQUEST['id']) ) - $bug[1] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `type` = 1 order by `uid` desc'); + $bug[1] = BugTracker::where('type', 1)->orderByDesc('uid')->get()->toArray(); if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc'])) - $bug[2] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 1')->fetch(); + $bug[2] = BugTracker::where('type', 1)->where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->get()->toArray(); if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id']) and !empty($_REQUEST['acc']) and is_numeric($_REQUEST['acc'])) { @@ -67,7 +70,7 @@ $showed = $post = $reply = false; echo ''; echo '
    getName(); ?>getLevel(); ?>name; ?>level; ?>vocation_name; ?>
    '.nl2br($bug[2]['text']).'
    '; - $answers = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2 order by `reply`'); + $answers = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderBy('reply')->get()->toArray(); foreach($answers as $answer) { if($answer['who'] == 1) @@ -88,9 +91,9 @@ $showed = $post = $reply = false; { if($bug[2]['status'] != 3) { - $reply = $db->query('SELECT MAX(reply) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2')->fetch(); - $reply = $reply[0] + 1; - $iswho = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].' and `type` = 2 order by `reply` desc limit 1')->fetch(); + $reply = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->max('reply'); + $reply = $reply + 1; + $iswho = BugTracker::where('account', $_REQUEST['acc'])->where('id', $_REQUEST['id'])->where('type', 2)->orderByDesc('reply')->first()->toArray(); if(isset($_POST['finish'])) { @@ -109,8 +112,17 @@ $showed = $post = $reply = false; else { $type = 2; - $INSERT = $db->query('INSERT INTO `' . TABLE_PREFIX . 'bugtracker` (`account`,`id`,`text`,`reply`,`type`, `who`) VALUES ('.$db->quote($_REQUEST['acc']).','.$db->quote($_REQUEST['id']).','.$db->quote($_POST['text']).','.$db->quote($reply).','.$db->quote($type).','.$db->quote(1).')'); - $UPDATE = $db->query('UPDATE `' . TABLE_PREFIX . 'bugtracker` SET `status` = '.$_POST['status'].' where `account` = '.$_REQUEST['acc'].' and `id` = '.$_REQUEST['id'].''); + $INSERT = BugTracker::create([ + 'account' => $_REQUEST['aac'], + 'id' => $_REQUEST['id'], + 'text' => $_POST['text'], + 'reply' => $reply, + 'type' => $type, + 'who' => 1, + ]); + $UPDATE = Bugtracker::where('id', $_REQUEST['id'])->where('account', $_REQUEST['acc'])->update([ + 'status' => $_POST['status'] + ]); header('Location: ?subtopic=bugtracker&control=true&id='.$_REQUEST['id'].'&acc='.$_REQUEST['acc'].''); } } @@ -159,10 +171,10 @@ $showed = $post = $reply = false; $id = addslashes(htmlspecialchars(trim($_REQUEST['id']))); if(empty($_REQUEST['id'])) - $bug[1] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$account_logged->getId().' and `type` = 1 order by `id` desc'); + $bug[1] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->orderBy('id')->get()->toArray(); if(!empty($_REQUEST['id']) and is_numeric($_REQUEST['id'])) - $bug[2] = $db->query('SELECT * FROM '.$db->tableName(TABLE_PREFIX . 'bugtracker').' where `account` = '.$account_logged->getId().' and `id` = '.$id.' and `type` = 1')->fetch(); + $bug[2] = BugTracker::where('account', $account_logged->getId())->where('type', 1)->where('id', $id)->get()->toArray(); else $bug[2] = NULL; @@ -186,7 +198,7 @@ $showed = $post = $reply = false; echo ''.nl2br($bug[2]['text']).''; echo ''; - $answers = $db->query('SELECT * FROM '.$db->tableName('myaac_bugtracker').' where `account` = '.$account_logged->getId().' and `id` = '.$id.' and `type` = 2 order by `reply`'); + $answers = Bugtracker::where('account', $account_logged->getId())->where('id', $id)->where('type', 2)->orderBy('reply')->get()->toArray(); foreach($answers as $answer) { if($answer['who'] == 1) @@ -207,9 +219,9 @@ $showed = $post = $reply = false; { if($bug[2]['status'] != 3) { - $reply = $db->query('SELECT MAX(reply) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `id` = '.$id.' and `type` = 2')->fetch(); - $reply = $reply[0] + 1; - $iswho = $db->query('SELECT * FROM `myaac_bugtracker` where `account` = '.$acc.' and `id` = '.$id.' and `type` = 2 order by `reply` desc limit 1')->fetch(); + $reply = BugTracker::where('account', $aac)->where('id', $id)->where('type', 2)->max('reply'); + $reply = $reply + 1; + $iswho = BugTracker::where('account', $acc)->where('id', $id)->where('type', 2)->orderByDesc('reply')->first()->toArray(); if(isset($_POST['finish'])) { @@ -228,8 +240,16 @@ $showed = $post = $reply = false; else { $type = 2; - $INSERT = $db->query('INSERT INTO `myaac_bugtracker` (`account`,`id`,`text`,`reply`,`type`) VALUES ('.$db->quote($acc).','.$db->quote($id).','.$db->quote($_POST['text']).','.$db->quote($reply).','.$db->quote($type).')'); - $UPDATE = $db->query('UPDATE `myaac_bugtracker` SET `status` = 1 where `account` = '.$acc.' and `id` = '.$id.''); + $INSERT = BugTracker::create([ + 'account' => $acc, + 'id' => $id, + 'text' => $_POST['text'], + 'reply' => $reply, + 'type' => $type + ]); + $UPDATE = BugTracker::where('id', $id)->where('account', $acc)->update([ + 'status' => 1 + ]); header('Location: ?subtopic=bugtracker&id='.$id.''); } } @@ -289,9 +309,9 @@ $showed = $post = $reply = false; } elseif(isset($_REQUEST['add']) && $_REQUEST['add'] == TRUE) { - $thread = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `type` = 1 order by `id` desc')->fetch(); - $id_next = $db->query('SELECT MAX(id) FROM `' . TABLE_PREFIX . 'bugtracker` where `account` = '.$acc.' and `type` = 1')->fetch(); - $id_next = $id_next[0] + 1; + $thread = BugTracker::where('account', $acc)->where('type', 1)->orderByDesc('id')->get()->toArray(); + $id_next = BugTracker::where('account', $acc)->where('type', 1)->max('id'); + $id_next = $id_next + 1; if(empty($thread)) $thread['status'] = 3; @@ -318,7 +338,16 @@ $showed = $post = $reply = false; { $type = 1; $status = 1; - $INSERT = $db->query('INSERT INTO `' . TABLE_PREFIX . 'bugtracker` (`account`,`id`,`text`,`type`,`subject`, `reply`,`status`,`tag`) VALUES ('.$db->quote($acc).','.$db->quote($id_next).','.$db->quote($_POST['text']).','.$db->quote($type).','.$db->quote($_POST['subject']).', 0,'.$db->quote($status).','.$db->quote($_POST['tags']).')'); + $INSERT = BugTracker::create([ + 'account' => $acc, + 'id' => $id_next, + 'text' => $_POST['text'], + 'type' => $type, + 'subject' => $_POST['subject'], + 'reply' => 0, + 'status' => $status, + 'tag' => $_POST['tags'] + ]); header('Location: ?subtopic=bugtracker&id='.$id_next.''); } diff --git a/system/pages/changelog.php b/system/pages/changelog.php index bc65281b..9157dca0 100644 --- a/system/pages/changelog.php +++ b/system/pages/changelog.php @@ -10,6 +10,8 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Changelog'; +use MyAAC\Models\Changelog; + $_page = isset($_GET['page']) ? (int)$_GET['page'] : 0; $limit = 30; $offset = $_page * $limit; @@ -17,7 +19,7 @@ $next_page = false; $canEdit = hasFlag(FLAG_CONTENT_NEWS) || superAdmin(); -$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog` ' . ($canEdit ? '' : 'WHERE `hidden` = 0').' ORDER BY `id` DESC LIMIT ' . ($limit + 1) . ' OFFSET ' . $offset)->fetchAll(); +$changelogs = Changelog::isPublic()->orderByDesc('id')->limit($limit + 1)->offset($offset)->get()->toArray(); $i = 0; foreach($changelogs as $key => &$log) diff --git a/system/pages/creatures.php b/system/pages/creatures.php index 9e472738..1b0e0ae8 100644 --- a/system/pages/creatures.php +++ b/system/pages/creatures.php @@ -9,13 +9,18 @@ * @copyright 2020 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Monster; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Creatures'; if (empty($_REQUEST['name'])) { // display list of monsters $preview = config('monsters_images_preview'); - $creatures = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 '.(empty($_REQUEST['boss']) ? '': 'AND `rewardboss` = 1').' ORDER BY name asc')->fetchAll(); + $creatures = Monster::where('hidden', '!=', 1)->when(!empty($_REQUEST['boss']), function ($query) { + $query->where('rewardboss', 1); + })->get()->toArray(); if ($preview) { foreach($creatures as $key => &$creature) @@ -34,9 +39,7 @@ if (empty($_REQUEST['name'])) { // display monster $creature_name = urldecode(stripslashes(ucwords(strtolower($_REQUEST['name'])))); -$prep = $db->prepare('SELECT * FROM `' . TABLE_PREFIX . 'monsters` WHERE `hidden` != 1 AND `name` = ? LIMIT 1;'); -$prep->execute([$creature_name]); -$creature = $prep->fetch(); +$creature = Monster::where('hidden', '!=', 1)->where('name', $creature_name)->first()->toArray(); if (isset($creature['name'])) { function sort_by_chance($a, $b) diff --git a/system/pages/faq.php b/system/pages/faq.php index 5d71aa3c..f99a9fa8 100644 --- a/system/pages/faq.php +++ b/system/pages/faq.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\FAQ as ModelsFAQ; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Frequently Asked Questions'; @@ -68,21 +71,23 @@ if($canEdit) )); } -$faqs = - $db->query('SELECT `id`, `question`, `answer`' . - ($canEdit ? ', `hidden`, `ordering`' : '') . - ' FROM `' . TABLE_PREFIX . 'faq`' . - (!$canEdit ? ' WHERE `hidden` != 1' : '') . - ' ORDER BY `ordering`;'); +$faqs = ModelsFAQ::select('id', 'question', 'answer')->when(!$canEdit, function ($query) { + $query->where('hidden', '!=', 1); +})->orderBy('ordering'); -if(!$faqs->rowCount()) +if ($canEdit) { + $faqs->addSelect(['hidden', 'ordering']); +} + +$faqs = $faqs->get()->toArray(); +if(!count($faqs)) { ?> There are no questions added yet. rowCount(); +$last = count($faqs); $twig->display('faq.html.twig', array( 'faqs' => $faqs, 'last' => $last, @@ -93,26 +98,17 @@ class FAQ { static public function add($question, $answer, &$errors) { - global $db; if(isset($question[0]) && isset($answer[0])) { - $query = $db->select(TABLE_PREFIX . 'faq', array('question' => $question)); - - if($query === false) + $row = ModelsFAQ::where('question', $question)->first(); + if(!$row) { - $query = - $db->query( - 'SELECT ' . $db->fieldName('ordering') . - ' FROM ' . $db->tableName(TABLE_PREFIX . 'faq') . - ' ORDER BY ' . $db->fieldName('ordering') . ' DESC LIMIT 1' - ); - - $ordering = 0; - if($query->rowCount() > 0) { - $query = $query->fetch(); - $ordering = $query['ordering'] + 1; - } - $db->insert(TABLE_PREFIX . 'faq', array('question' => $question, 'answer' => $answer, 'ordering' => $ordering)); + $ordering = ModelsFAQ::max('ordering') ?? 0; + ModelsFAQ::create([ + 'question' => $question, + 'answer' => $answer, + 'ordering' => $ordering + ]); } else $errors[] = 'FAQ with this question already exists.'; @@ -124,22 +120,23 @@ class FAQ } static public function get($id) { - global $db; - return $db->select(TABLE_PREFIX . 'faq', array('id' => $id)); + return ModelsFAQ::find($id)->toArray(); } static public function update($id, $question, $answer) { - global $db; - $db->update(TABLE_PREFIX . 'faq', array('question' => $question, 'answer' => $answer), array('id' => $id)); + ModelsFAQ::where('id', $id)->update([ + 'question' => $question, + 'answer' => $answer + ]); } static public function delete($id, &$errors) { - global $db; if(isset($id)) { - if(self::get($id) !== false) - $db->delete(TABLE_PREFIX . 'faq', array('id' => $id)); + $row = ModelsFAQ::find($id); + if($row) + $row->delete(); else $errors[] = 'FAQ with id ' . $id . ' does not exists.'; } @@ -151,14 +148,15 @@ class FAQ static public function toggleHidden($id, &$errors) { - global $db; if(isset($id)) { - $query = self::get($id); - if($query !== false) - $db->update(TABLE_PREFIX . 'faq', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - else + $row = ModelsFAQ::find($id); + if ($row) { + $row->hidden = ($row->hidden == 1 ? 0 : 1); + $row->save(); + } else { $errors[] = 'FAQ with id ' . $id . ' does not exists.'; + } } else $errors[] = 'id not set'; @@ -169,15 +167,18 @@ class FAQ static public function move($id, $i, &$errors) { global $db; - $query = self::get($id); - if($query !== false) + $row = ModelsFAQ::find($id); + if($row) { - $ordering = $query['ordering'] + $i; - $old_record = $db->select(TABLE_PREFIX . 'faq', array('ordering' => $ordering)); - if($old_record !== false) - $db->update(TABLE_PREFIX . 'faq', array('ordering' => $query['ordering']), array('ordering' => $ordering)); + $ordering = $row->ordering + $i; + $old_record = ModelsFAQ::where('ordering', $ordering)->first(); + if($old_record) { + $old_record->ordering = $row->ordering; + $old_record->save(); + } - $db->update(TABLE_PREFIX . 'faq', array('ordering' => $ordering), array('id' => $id)); + $row->ordering = $ordering; + $row->save(); } else $errors[] = 'FAQ with id ' . $id . ' does not exists.'; diff --git a/system/pages/gallery.php b/system/pages/gallery.php index b6e2b07f..69ad2194 100644 --- a/system/pages/gallery.php +++ b/system/pages/gallery.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Gallery as ModelsGallery; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Gallery'; @@ -164,22 +167,19 @@ class Gallery } static public function get($id) { - global $db; - return $db->select(TABLE_PREFIX . 'gallery', array('id' => $id)); + return ModelsGallery::find($id)->toArray(); } static public function update($id, $comment, $image, $author) { - global $db; - $pathinfo = pathinfo($image); $extension = strtolower($pathinfo['extension']); $filename = GALLERY_DIR . $pathinfo['filename'] . '.' . $extension; - if($db->update(TABLE_PREFIX . 'gallery', array( + if(ModelsGallery::where('id', $id)->update([ 'comment' => $comment, - 'image' => $filename, 'author' => $author), - array('id' => $id) - )) { + 'image' => $filename, + 'author' => $author + ])) { if(self::generateThumb($id, $image, $errors)) self::resize($image, 650, 500, $filename, $errors); } @@ -187,11 +187,13 @@ class Gallery static public function delete($id, &$errors) { - global $db; if(isset($id)) { - if(self::get($id) !== false) - $db->delete(TABLE_PREFIX . 'gallery', array('id' => $id)); + $row = ModelsGallery::find($id); + if($row) + if (!$row->delete()) { + $errors[] = 'Fail during delete Gallery'; + } else $errors[] = 'Image with id ' . $id . ' does not exists.'; } @@ -203,13 +205,15 @@ class Gallery static public function toggleHidden($id, &$errors) { - global $db; if(isset($id)) { - $query = self::get($id); - if($query !== false) - $db->update(TABLE_PREFIX . 'gallery', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id)); - else + $row = ModelsGallery::find($id); + if($row) { + $row->hidden = $row->hidden == 1 ? 0 : 1; + if (!$row->save()) { + $errors[] = 'Fail during toggle hidden Gallery'; + } + } else $errors[] = 'Image with id ' . $id . ' does not exists.'; } else @@ -226,10 +230,15 @@ class Gallery { $ordering = $query['ordering'] + $i; $old_record = $db->select(TABLE_PREFIX . 'gallery', array('ordering' => $ordering)); - if($old_record !== false) - $db->update(TABLE_PREFIX . 'gallery', array('ordering' => $query['ordering']), array('ordering' => $ordering)); + if($old_record !== false) { + ModelsGallery::where('ordering', $ordering)->update([ + 'ordering' => $query['ordering'], + ]); + } - $db->update(TABLE_PREFIX . 'gallery', array('ordering' => $ordering), array('id' => $id)); + ModelsGallery::where('id', $id)->update([ + 'ordering' => $ordering, + ]); } else $errors[] = 'Image with id ' . $id . ' does not exists.'; @@ -297,13 +306,13 @@ class Gallery if(!self::resize($file, 170, 110, $thumb_filename, $errors)) return false; - global $db; if(isset($id)) { - $query = self::get($id); - if($query !== false) - $db->update(TABLE_PREFIX . 'gallery', array('thumb' => $thumb_filename), array('id' => $id)); - else + $row = ModelsGallery::find($id); + if($row) { + $row->thumb = $thumb_filename; + $row->save(); + } else $errors[] = 'Image with id ' . $id . ' does not exists.'; } else diff --git a/system/pages/highscores.php b/system/pages/highscores.php index fe8533c7..090da010 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -8,6 +8,11 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Player; +use MyAAC\Models\PlayerDeath; +use MyAAC\Models\PlayerKillers; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Highscores'; @@ -23,7 +28,7 @@ if(!is_numeric($page) || $page < 1 || $page > PHP_INT_MAX) { $page = 1; } -$add_sql = ''; +$query = Player::query(); $settingHighscoresVocationBox = setting('core.highscores_vocation_box'); $configVocations = config('vocations'); @@ -41,7 +46,7 @@ if($settingHighscoresVocationBox && $vocation !== 'all') $i += $configVocationsAmount; } - $add_sql = 'AND `vocation` IN (' . implode(', ', $add_vocs) . ')'; + $query->whereIn('players.vocation', $add_vocs); break; } } @@ -112,15 +117,7 @@ else $promotion = ''; if($db->hasColumn('players', 'promotion')) - $promotion = ',promotion'; - -$online = ''; -if($db->hasColumn('players', 'online')) - $online = ',online'; - -$deleted = 'deleted'; -if($db->hasColumn('players', 'deletion')) - $deleted = 'deletion'; + $promotion = ',players.promotion'; $outfit_addons = false; $outfit = ''; @@ -151,6 +148,16 @@ if ($cache->enabled()) { } $offset = ($page - 1) * $configHighscoresPerPage; +$query->join('accounts', 'accounts.id', '=', 'players.account_id') + ->withOnlineStatus() + ->whereNotIn('players.id', setting('core.highscores_ids_hidden')) + ->notDeleted() + ->where('players.group_id', '<', setting('core.highscores_groups_hidden')) + ->limit($limit) + ->offset($offset) + ->selectRaw('accounts.country, players.id, players.name, players.account_id, players.level, players.vocation' . $outfit . $promotion) + ->orderByDesc('value'); + if (!isset($highscores) || empty($highscores)) { if ($skill >= POT::SKILL_FIRST && $skill <= POT::SKILL_LAST) { // skills if ($db->hasColumn('players', 'skill_fist')) {// tfs 1.0 @@ -164,66 +171,51 @@ if (!isset($highscores) || empty($highscores)) { POT::SKILL_FISH => 'skill_fishing', ); - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,vocation' . $promotion . $outfit . ', ' . $skill_ids[$skill] . ' as value FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY ' . $skill_ids[$skill] . ' DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); - } else - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',value,level,vocation' . $promotion . $outfit . ' FROM accounts,players,player_skills WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_skills.player_id AND player_skills.skillid = ' . $skill . ' AND accounts.id = players.account_id ORDER BY value DESC, count DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query->addSelect($skill_ids[$skill] . ' as value'); + } else { + $query + ->join('player_skills', 'player_skills.player_id', '=', 'players.id') + ->where('skillid', $skill) + ->addSelect('player_skills.skillid as value'); + } } else if ($skill == SKILL_FRAGS) // frags { if ($db->hasTable('player_killers')) { - $highscores = $db->query('SELECT accounts.country, players.id, players.name' . $online . ',level, vocation' . $promotion . $outfit . ', COUNT(`player_killers`.`player_id`) as value' . - ' FROM `accounts`, `players`, `player_killers` ' . - ' WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND players.id = player_killers.player_id AND accounts.id = players.account_id' . - ' GROUP BY `player_id`' . - ' ORDER BY value DESC' . - ' LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query->addSelect(['value' => PlayerKillers::where('player_killers.player_id', 'players.id')->selectRaw('COUNT(*)')]); } else { - $db->query("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));"); - - $highscores = $db->query('SELECT `a`.country, `p`.id, `p`.name' . $online . ',`p`.level, vocation' . $promotion . $outfit . ', COUNT(`pd`.`killed_by`) as value - FROM `players` p - LEFT JOIN `accounts` a ON `a`.`id` = `p`.`account_id` - LEFT JOIN `player_deaths` pd ON `pd`.`killed_by` = `p`.`name` - WHERE `p`.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') - AND `p`.' . $deleted . ' = 0 - AND `p`.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' - AND `pd`.`unjustified` = 1 - GROUP BY `killed_by` - ORDER BY value DESC - LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query->addSelect(['value' => PlayerDeath::unjustified()->where('player_deaths.killed_by', 'players.name')->selectRaw('COUNT(*)')]); } } else if ($skill == SKILL_BALANCE) // balance { - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,balance as value,vocation' . $promotion . $outfit . ' FROM accounts,players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' ' . $add_sql . ' AND accounts.id = players.account_id ORDER BY value DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query + ->addSelect('players.balance as value'); } else { if ($skill == POT::SKILL__MAGLEVEL) { - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',maglevel,level,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY maglevel DESC, manaspent DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query + ->addSelect('players.maglevel as value', 'players.maglevel') + ->orderBy('manaspent'); } else { // level - $highscores = $db->query('SELECT accounts.country, players.id,players.name' . $online . ',level,experience,vocation' . $promotion . $outfit . ' FROM accounts, players WHERE players.id NOT IN (' . implode(', ', setting('core.highscores_ids_hidden')) . ') AND players.' . $deleted . ' = 0 ' . $add_sql . ' AND players.group_id < ' . setting('core.highscores_groups_hidden') . ' AND accounts.id = players.account_id ORDER BY level DESC, experience DESC LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll(); + $query + ->addSelect('players.level as value', 'players.experience') + ->orderBy('experience'); $list = 'experience'; } } } +$highscores = $query->get()->map(function($row) { + $tmp = $row->toArray(); + $tmp['online'] = $row->online_status; + $tmp['vocation'] = $row->vocation_name; + unset($tmp['online_table']); + + return $tmp; +})->toArray(); + if ($cache->enabled() && $needReCache) { $cache->set($cacheKey, serialize($highscores), setting('core.highscores_cache_ttl') * 60); } -$online_exist = false; -if($db->hasColumn('players', 'online')) - $online_exist = true; - -$players = array(); -foreach($highscores as $player) { - $players[] = $player['id']; -} - -if($db->hasTable('players_online') && count($players) > 0) { - $query = $db->query('SELECT `player_id`, 1 FROM `players_online` WHERE `player_id` IN (' . implode(', ', $players) . ')')->fetchAll(); - foreach($query as $t) { - $is_online[$t['player_id']] = true; - } -} - $show_link_to_next_page = false; $i = 0; @@ -231,14 +223,6 @@ $settingHighscoresVocation = setting('core.highscores_vocation'); foreach($highscores as $id => &$player) { - if(isset($is_online)) { - $player['online'] = (isset($is_online[$player['id']]) ? 1 : 0); - } else { - if(!isset($player['online'])) { - $player['online'] = 0; - } - } - if(++$i <= $configHighscoresPerPage) { if($skill == POT::SKILL__MAGIC) @@ -248,22 +232,10 @@ foreach($highscores as $id => &$player) $player['experience'] = number_format($player['experience']); } - if($settingHighscoresVocation) { - if(isset($player['promotion'])) { - if((int)$player['promotion'] > 0) { - $player['vocation'] += ($player['promotion'] * $configVocationsAmount); - } - } - - $tmp = 'Unknown'; - if(isset($configVocations[$player['vocation']])) { - $tmp = $configVocations[$player['vocation']]; - } - - $player['vocation'] = $tmp; + if(!$settingHighscoresVocation) { + unset($player['vocation']); } - $player['link'] = getPlayerLink($player['name'], false); $player['flag'] = getFlagImage($player['country']); if($settingHighscoresOutfit) { diff --git a/system/pages/online.php b/system/pages/online.php index 2d96a405..0ca74127 100644 --- a/system/pages/online.php +++ b/system/pages/online.php @@ -8,6 +8,10 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\ServerConfig; +use MyAAC\Models\ServerRecord; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Who is online?'; @@ -98,21 +102,19 @@ foreach($playersOnline as $player) { $record = ''; if($players > 0) { if($config['online_record']) { + $result = null; $timestamp = false; if($db->hasTable('server_record')) { - $query = - $db->query( - 'SELECT `record`, `timestamp` FROM `server_record` WHERE `world_id` = ' . (int)$config['lua']['worldId'] . - ' ORDER BY `record` DESC LIMIT 1'); $timestamp = true; + $result = ServerRecord::where('world_id', $config['lua']['worldId'])->orderByDesc('record')->first()->toArray(); } else if($db->hasTable('server_config')) { // tfs 1.0 - $query = $db->query('SELECT `value` as `record` FROM `server_config` WHERE `config` = ' . $db->quote('players_record')); - } else { - $query = NULL; + $row = ServerConfig::where('config', 'players_record')->first(); + if ($row) { + $result = ['record' => $row->value]; + } } - if(isset($query) && $query->rowCount() > 0) { - $result = $query->fetch(); + if($record) { $record = 'The maximum on this game world was ' . $result['record'] . ' players' . ($timestamp ? ' on ' . date("M d Y, H:i:s", $result['timestamp']) . '.' : '.'); } } diff --git a/system/pages/records.php b/system/pages/records.php index 9a000ef5..c4f38db3 100644 --- a/system/pages/records.php +++ b/system/pages/records.php @@ -8,10 +8,18 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\ServerRecord; + defined('MYAAC') or die('Direct access not allowed!'); $title = "Players Online Records"; +if(!$db->hasTable('server_record')) { + echo 'Record History is not supported in your distribution.'; + return; +} + echo '
    Players online records on '.$config['lua']['serverName'].'
    @@ -21,7 +29,7 @@ echo ' '; $i = 0; - $records_query = $db->query('SELECT * FROM `server_record` ORDER BY `record` DESC LIMIT 50;'); + $records_query = ServerRecord::limit(50)->orderByDesc('record')->get(); foreach($records_query as $data) { echo ' @@ -31,4 +39,4 @@ echo ' } echo '
    '; -?> \ No newline at end of file +?> diff --git a/system/pages/spells.php b/system/pages/spells.php index befed8d9..692df7cd 100644 --- a/system/pages/spells.php +++ b/system/pages/spells.php @@ -8,6 +8,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Spell; + defined('MYAAC') or die('Direct access not allowed!'); $title = 'Spells'; @@ -34,10 +37,10 @@ else { $order = 'name'; $spells = array(); -$spells_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'spells` WHERE `hidden` != 1 AND `type` < 4 ORDER BY ' . $order . ''); +$spells_db = Spell::where('hidden', '!=', 1)->where('type', '<', 4)->orderBy($order)->get(); if((string)$vocation_id != 'all') { - foreach($spells_db->fetchAll() as $spell) { + foreach($spells_db as $spell) { $spell_vocations = json_decode($spell['vocations'], true); if(in_array($vocation_id, $spell_vocations) || count($spell_vocations) == 0) { $spell['vocations'] = null; @@ -46,7 +49,7 @@ if((string)$vocation_id != 'all') { } } else { - foreach($spells_db->fetchAll() as $spell) { + foreach($spells_db as $spell) { $vocations = json_decode($spell['vocations'], true); foreach($vocations as &$tmp_vocation) { diff --git a/system/router.php b/system/router.php index 3f7abd25..a24a3b1b 100644 --- a/system/router.php +++ b/system/router.php @@ -7,6 +7,9 @@ * @copyright 2023 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Pages; + defined('MYAAC') or die('Direct access not allowed!'); if(!isset($content[0])) @@ -288,16 +291,13 @@ unset($page); function getDatabasePages($withHidden = false): array { - global $db, $logged_access; - $pages = $db->query('SELECT `name` FROM ' . TABLE_PREFIX . 'pages WHERE ' . ($withHidden ? '' : '`hidden` != 1 AND ') . '`access` <= ' . $db->quote($logged_access)); - $ret = []; + global $logged_access; + $pages = Pages::where('access', '<=', $logged_access)->when(!$withHidden, function ($q) { + $q->isPublic(); + })->get('name'); - if ($pages->rowCount() < 1) { - return $ret; - } - - foreach($pages->fetchAll() as $page) { - $ret [] = $page['name']; + foreach($pages as $page) { + $ret[] = $page->name; } return $ret; diff --git a/system/src/Models/Account.php b/system/src/Models/Account.php new file mode 100644 index 00000000..f26f9700 --- /dev/null +++ b/system/src/Models/Account.php @@ -0,0 +1,69 @@ + 'integer', + 'premdays' => 'integer', + 'premend' => 'integer', + 'premium_ends_at' => 'integer', + ]; + + public function players() + { + return $this->hasMany(Player::class); + } + + public function viplist() + { + return $this->hasMany(AccountVipList::class); + } + + public function getPremiumDaysAttribute() + { + if(isset($this->premium_ends_at) || isset($this->premend)) { + $col = isset($this->premium_ends_at) ? 'premium_ends_at' : 'premend'; + $ret = ceil(($this->{$col}- time()) / (24 * 60 * 60)); + return $ret > 0 ? $ret : 0; + } + + if($this->premdays == 0) { + return 0; + } + + global $config; + if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return -1; + + if($this->premdays == 65535){ + return 65535; + } + + $ret = ceil($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday))); + return $ret > 0 ? $ret : 0; + } + + public function getIsPremiumAttribute() + { + global $config; + if(isset($config['lua']['freePremium']) && getBoolean($config['lua']['freePremium'])) return true; + + if(isset($this->premium_ends_at)) { + return $this->premium_ends_at > time(); + } + + if(isset($this->premend)) { + return $this->premend > time(); + } + + return ($this->premdays - (date("z", time()) + (365 * (date("Y", time()) - date("Y", $this->lastday))) - date("z", $this->lastday)) > 0); + } + +} diff --git a/system/src/Models/AccountVipList.php b/system/src/Models/AccountVipList.php new file mode 100644 index 00000000..676ddc05 --- /dev/null +++ b/system/src/Models/AccountVipList.php @@ -0,0 +1,21 @@ +belongsTo(Account::class); + } + + public function player() + { + return $this->belongsTo(Player::class); + } +} diff --git a/system/src/Models/BoostedCreature.php b/system/src/Models/BoostedCreature.php new file mode 100644 index 00000000..77c6d399 --- /dev/null +++ b/system/src/Models/BoostedCreature.php @@ -0,0 +1,16 @@ + 'integer', + ]; + + public $timestamps = false; +} diff --git a/system/src/Models/BugTracker.php b/system/src/Models/BugTracker.php new file mode 100644 index 00000000..8c97ce4a --- /dev/null +++ b/system/src/Models/BugTracker.php @@ -0,0 +1,15 @@ +where('hidden', '!=', 1); + } +} diff --git a/system/src/Models/Config.php b/system/src/Models/Config.php new file mode 100644 index 00000000..72258dc3 --- /dev/null +++ b/system/src/Models/Config.php @@ -0,0 +1,14 @@ +hasColumn('guilds', 'owner_id')) { + $column = 'owner_id'; + } + + return $this->belongsTo(Player::class, $column); + } + + public function members() + { + return $this->belongsToMany(Player::class, 'guild_membership')->withPivot('rank_id', 'nick'); + } + + public function invites() + { + return $this->belongsToMany(Player::class, 'guild_invites'); + } + +} diff --git a/system/src/Models/GuildInvite.php b/system/src/Models/GuildInvite.php new file mode 100644 index 00000000..c95d629f --- /dev/null +++ b/system/src/Models/GuildInvite.php @@ -0,0 +1,22 @@ +belongsTo(Player::class); + } + + public function guild() + { + return $this->belongsTo(Guild::class); + } + +} diff --git a/system/src/Models/GuildMembership.php b/system/src/Models/GuildMembership.php new file mode 100644 index 00000000..81658e05 --- /dev/null +++ b/system/src/Models/GuildMembership.php @@ -0,0 +1,27 @@ +belongsTo(Player::class); + } + + public function guild() + { + return $this->belongsTo(Guild::class); + } + + public function rank() + { + return $this->belongsTo(GuildRank::class, 'rank_id'); + } + +} diff --git a/system/src/Models/GuildRank.php b/system/src/Models/GuildRank.php new file mode 100644 index 00000000..3abce8e8 --- /dev/null +++ b/system/src/Models/GuildRank.php @@ -0,0 +1,17 @@ +belongsTo(Guild::class); + } + +} diff --git a/system/src/Models/House.php b/system/src/Models/House.php new file mode 100644 index 00000000..53e7ab15 --- /dev/null +++ b/system/src/Models/House.php @@ -0,0 +1,16 @@ +belongsTo(Player::class, 'owner'); + } +} diff --git a/system/src/Models/Menu.php b/system/src/Models/Menu.php new file mode 100644 index 00000000..6e3b6d03 --- /dev/null +++ b/system/src/Models/Menu.php @@ -0,0 +1,14 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/Notepad.php b/system/src/Models/Notepad.php new file mode 100644 index 00000000..6f1d52f7 --- /dev/null +++ b/system/src/Models/Notepad.php @@ -0,0 +1,20 @@ +belongsTo(Account::class); + } +} diff --git a/system/src/Models/Pages.php b/system/src/Models/Pages.php new file mode 100644 index 00000000..44e6b0f6 --- /dev/null +++ b/system/src/Models/Pages.php @@ -0,0 +1,30 @@ + 'integer', + 'enable_tinymce' => 'integer', + 'access' => 'integer', + 'hidden' => 'integer', + ]; + + public function player() + { + return $this->belongsTo(Player::class); + } + + public function scopeIsPublic($query) { + $query->where('hidden', '!=', 1); + } + +} diff --git a/system/src/Models/Player.php b/system/src/Models/Player.php new file mode 100644 index 00000000..d140548c --- /dev/null +++ b/system/src/Models/Player.php @@ -0,0 +1,138 @@ + 'integer', + 'sex' => 'integer', + 'level' => 'integer', + 'vocation' => 'integer', + 'promotion' => 'integer', + 'looktype' => 'integer', + 'lookhead' => 'integer', + 'lookbody' => 'integer', + 'looklegs' => 'integer', + 'lookfeet' => 'integer', + 'lookaddons' => 'integer', + 'isreward' => 'integer', + ]; + + public function scopeOrderBySkill($query, $value) + { + global $db; + $query->when($db->hasColumn('players', 'skill_fist'), function ($query) { + + }); + } + + public function getVocationNameAttribute() + { + $vocation = $this->vocation; + if (isset($this->promotion)) { + $vocation *= $this->promotion; + } + + return config('vocations')[$vocation] ?? 'Unknown'; + } + + public function getIsDeletedAttribute() + { + if (isset($this->deleted)) { + return $this->deleted !== 0; + } + + if (isset($this->deletion)) { + return $this->deletion !== 0; + } + + return false; + } + + public function scopeNotDeleted($query) { + global $db; + + $column = 'deleted'; + if($db->hasColumn('players', 'deletion')) { + $column = 'deletion'; + } + + $query->where($column, 0); + } + + public function scopeWithOnlineStatus($query) { + global $db; + $query->when($db->hasTable('players_online'), function ($query) { + $query->with('onlineTable'); + }); + } + + public function getOnlineStatusAttribute() + { + global $db; + if ($db->hasColumn('players', 'online')) { + return $this->online; + } + + if ($db->hasTable('players_online')) { + return $this->onlineTable != null; + } + + return false; + } + + public function onlineTable() + { + return $this->belongsTo(PlayerOnline::class); + } + + public function account() + { + return $this->belongsTo(Account::class); + } + + public function storages() + { + return $this->hasMany(PlayerStorage::class); + } + + public function items() + { + return $this->hasMany(PlayerItem::class); + } + + public function kills() + { + return $this->hasMany(PlayerKillers::class); + } + + public function deaths() + { + return $this->hasMany(PlayerDeath::class); + } + + public function houses() + { + return $this->hasMany(House::class, 'owner'); + } + + public function skills() + { + return $this->hasMany(PlayerSkill::class); + } + + public function viplist() + { + return $this->hasMany(PlayerVipList::class); + } + + public function scopeOnline($query) { + $query->where('online', '>', 0); + } +} diff --git a/system/src/Models/PlayerDeath.php b/system/src/Models/PlayerDeath.php new file mode 100644 index 00000000..3009f20c --- /dev/null +++ b/system/src/Models/PlayerDeath.php @@ -0,0 +1,25 @@ +belongsTo(Player::class); + } + + public function killer() + { + return $this->belongsTo(Player::class, 'killed_by'); + } + + public function scopeUnjustified($query) { + $query->where('unjustified', 1); + } +} diff --git a/system/src/Models/PlayerDepotItem.php b/system/src/Models/PlayerDepotItem.php new file mode 100644 index 00000000..9149ea25 --- /dev/null +++ b/system/src/Models/PlayerDepotItem.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerKillers.php b/system/src/Models/PlayerKillers.php new file mode 100644 index 00000000..55abbfd8 --- /dev/null +++ b/system/src/Models/PlayerKillers.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerOnline.php b/system/src/Models/PlayerOnline.php new file mode 100644 index 00000000..e81b591e --- /dev/null +++ b/system/src/Models/PlayerOnline.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerSkill.php b/system/src/Models/PlayerSkill.php new file mode 100644 index 00000000..27ec5f84 --- /dev/null +++ b/system/src/Models/PlayerSkill.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerSpell.php b/system/src/Models/PlayerSpell.php new file mode 100644 index 00000000..030e014f --- /dev/null +++ b/system/src/Models/PlayerSpell.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerStorage.php b/system/src/Models/PlayerStorage.php new file mode 100644 index 00000000..43a05eda --- /dev/null +++ b/system/src/Models/PlayerStorage.php @@ -0,0 +1,16 @@ +belongsTo(Player::class); + } +} diff --git a/system/src/Models/PlayerVipList.php b/system/src/Models/PlayerVipList.php new file mode 100644 index 00000000..71067e45 --- /dev/null +++ b/system/src/Models/PlayerVipList.php @@ -0,0 +1,21 @@ +belongsTo(Player::class); + } + + public function vip() + { + return $this->belongsTo(Player::class, 'vip_id'); + } +} diff --git a/system/src/Models/Playeritem.php b/system/src/Models/Playeritem.php new file mode 100644 index 00000000..8e7ad5f0 --- /dev/null +++ b/system/src/Models/Playeritem.php @@ -0,0 +1,17 @@ +belongsTo(Player::class); + } + +} diff --git a/system/src/Models/ServerConfig.php b/system/src/Models/ServerConfig.php new file mode 100644 index 00000000..47c67b2e --- /dev/null +++ b/system/src/Models/ServerConfig.php @@ -0,0 +1,14 @@ +enabled()) if($fetch_from_db) { - // get info from db - /** - * @var OTS_DB_MySQL $db - */ - $status_query = $db->query('SELECT `name`, `value` FROM `' . TABLE_PREFIX . 'config` WHERE ' . $db->fieldName('name') . ' LIKE "%status%"'); - if($status_query->rowCount() <= 0) // empty, just insert it - { - foreach($status as $key => $value) + $status_query = Config::where('name', 'LIKE', '%status%')->get(); + if (!$status_query || !$status_query->count()) { + foreach($status as $key => $value) { registerDatabaseConfig('status_' . $key, $value); - } - else - { - foreach($status_query as $tmp) - $status[str_replace('status_', '', $tmp['name'])] = $tmp['value']; + } + } else { + foreach($status_query as $tmp) { + $status[str_replace('status_', '', $tmp->name)] = $tmp->value; + } } } @@ -128,19 +127,13 @@ function updateStatus() { // for status afk thing if($config['online_afk']) { + $status['playersTotal'] = 0; // get amount of players that are currently logged in-game, including disconnected clients (exited) if($db->hasTable('players_online')) { // tfs 1.x - $query = $db->query('SELECT COUNT(`player_id`) AS `playersTotal` FROM `players_online`;'); + $status['playersTotal'] = PlayerOnline::count(); } else { - $query = $db->query('SELECT COUNT(`id`) AS `playersTotal` FROM `players` WHERE `online` > 0'); - } - - $status['playersTotal'] = 0; - if($query->rowCount() > 0) - { - $query = $query->fetch(); - $status['playersTotal'] = $query['playersTotal']; + $status['playersTotal'] = Player::online()->count(); } } diff --git a/system/template.php b/system/template.php index a01939a4..0fbb0477 100644 --- a/system/template.php +++ b/system/template.php @@ -7,6 +7,9 @@ * @copyright 2019 MyAAC * @link https://my-aac.org */ + +use MyAAC\Models\Menu; + defined('MYAAC') or die('Direct access not allowed!'); // template @@ -126,7 +129,7 @@ if($twig_loader) { } function get_template_menus() { - global $db, $template_name; + global $template_name; $cache = Cache::getInstance(); if ($cache->enabled()) { @@ -137,11 +140,15 @@ function get_template_menus() { } if (!isset($result)) { - $query = $db->query('SELECT `name`, `link`, `blank`, `color`, `category` FROM `' . TABLE_PREFIX . 'menu` WHERE `template` = ' . $db->quote($template_name) . ' ORDER BY `category`, `ordering` ASC'); - $result = $query->fetchAll(); + + $result = Menu::select(['name', 'link', 'blank', 'color', 'category']) + ->where('template', $template_name) + ->orderBy('category') + ->orderBy('ordering') + ->get(); if ($cache->enabled()) { - $cache->set('template_menus', serialize($result), 600); + $cache->set('template_menus', serialize($result->toArray()), 600); } } diff --git a/system/templates/account.change_comment.html.twig b/system/templates/account.change_comment.html.twig index 15ac2208..c69e3f6b 100644 --- a/system/templates/account.change_comment.html.twig +++ b/system/templates/account.change_comment.html.twig @@ -30,15 +30,15 @@ If you do not want to specify a certain field, just leave it blank.

    - +
    Name:{{ player.getName() }}{{ player.name }}
    Hide Account: - + - {% if player.getCustomField('group_id') > 1 %} (you will be also hidden on the Team page!){% endif %} + {% if player.group_id > 1 %} (you will be also hidden on the Team page!){% endif %}
    @@ -62,7 +62,7 @@ If you do not want to specify a certain field, just leave it blank.

    - +
    Comment:
    [max. length: 2000 chars, 50 lines (ENTERs)]

    [max. length: 2000 chars, 50 lines (ENTERs)]
    @@ -88,7 +88,7 @@ If you do not want to specify a certain field, just leave it blank.

    @@ -108,4 +108,4 @@ If you do not want to specify a certain field, just leave it blank.

    - + {{ include('buttons.submit.html.twig') }}
    - \ No newline at end of file + diff --git a/system/templates/admin.notepad.html.twig b/system/templates/admin.notepad.html.twig index 3a3cb6b2..d3dc5000 100644 --- a/system/templates/admin.notepad.html.twig +++ b/system/templates/admin.notepad.html.twig @@ -7,7 +7,7 @@
    + onchange="notepad_onchange(this);">{{ content }}
    - getLookType() . ($hasLookAddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); ?> + getLookType() . ($hasLookAddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); ?>
    player outfit
    @@ -858,7 +858,7 @@ else if (isset($_REQUEST['search'])) { look_addons = '&addons=' + $('#look_addons').val(); - $("#player_outfit").attr("src", '?id=' + look_type + look_addons + '&head=' + look_head + '&body=' + look_body + '&legs=' + look_legs + '&feet=' + look_feet); + $("#player_outfit").attr("src", '?id=' + look_type + look_addons + '&head=' + look_head + '&body=' + look_body + '&legs=' + look_legs + '&feet=' + look_feet); } diff --git a/plugins/account-create-hint/hint.html.twig b/plugins/account-create-hint/hint.html.twig index 5c31dfb1..ffc85434 100644 --- a/plugins/account-create-hint/hint.html.twig +++ b/plugins/account-create-hint/hint.html.twig @@ -1,3 +1,3 @@ To play on {{ config.lua.serverName }} you need an account. -All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.account_country %}, country{% endif %} and your email address. +All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if setting('core.account_country') %}, country{% endif %} and your email address. Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.

    diff --git a/plugins/email-confirmed-reward/reward.php b/plugins/email-confirmed-reward/reward.php index 107ab8d7..11af5b34 100644 --- a/plugins/email-confirmed-reward/reward.php +++ b/plugins/email-confirmed-reward/reward.php @@ -1,33 +1,37 @@ hasColumn('accounts', 'coins'); -if ($reward['coins'] > 0 && $hasCoinsColumn) { - log_append('email_confirm_error.log', 'accounts.coins column does not exist.'); +$rewardCoins = setting('core.account_mail_confirmed_reward_coins'); +if ($rewardCoins > 0 && !$hasCoinsColumn) { + log_append('error.log', 'email_confirm: accounts.coins column does not exist.'); } if (!isset($account) || !$account->isLoaded()) { - log_append('email_confirm_error.log', 'Account not loaded.'); return; } -if ($reward['premium_points'] > 0) { - $account->setCustomField('premium_points', (int)$account->getCustomField('premium_points') + $reward['premium_points']); +$rewardMessage = 'You received %d %s for confirming your E-Mail address.'; - success(sprintf($reward['message'], $reward['premium_points'], 'premium points')); +$rewardPremiumPoints = setting('core.account_mail_confirmed_reward_premium_points'); +if ($rewardPremiumPoints > 0) { + $account->setCustomField('premium_points', (int)$account->getCustomField('premium_points') + $rewardPremiumPoints); + + success(sprintf($rewardMessage, $rewardPremiumPoints, 'premium points')); } -if ($reward['coins'] > 0 && $hasCoinsColumn) { - $account->setCustomField('coins', (int)$account->getCustomField('coins') + $reward['coins']); +if ($rewardCoins > 0 && $hasCoinsColumn) { + $account->setCustomField('coins', (int)$account->getCustomField('coins') + $rewardCoins); - success(sprintf($reward['message'], $reward['coins'], 'coins')); + success(sprintf($rewardMessage, $rewardCoins, 'coins')); } -if ($reward['premium_days'] > 0) { - $account->setPremDays($account->getPremDays() + $reward['premium_days']); +$rewardPremiumDays = setting('core.account_mail_confirmed_reward_premium_days'); +if ($rewardPremiumDays > 0) { + $account->setPremDays($account->getPremDays() + $rewardPremiumDays); $account->save(); - success(sprintf($reward['message'], $reward['premium_days'], 'premium days')); + success(sprintf($rewardMessage, $rewardPremiumDays, 'premium days')); } diff --git a/system/compat/config.php b/system/compat/config.php index b6cf29f7..9d58f4d6 100644 --- a/system/compat/config.php +++ b/system/compat/config.php @@ -68,10 +68,12 @@ $deprecatedConfig = [ 'status_ip', 'status_port', 'mail_enabled', + 'mail_address', 'account_login_by_email', 'account_login_by_email_fallback', 'account_mail_verify', 'account_mail_unique', + 'account_mail_change', 'account_premium_days', 'account_premium_points', 'account_create_character_create', diff --git a/system/functions.php b/system/functions.php index 70a67f32..5ea941cf 100644 --- a/system/functions.php +++ b/system/functions.php @@ -151,8 +151,7 @@ function getItemImage($id, $count = 1) if($count > 1) $file_name .= '-' . $count; - global $config; - return '' .$id . ''; + return '' .$id . ''; } function getItemRarity($chance) { @@ -490,8 +489,8 @@ function template_place_holder($type): string */ function template_header($is_admin = false): string { - global $title_full, $config, $twig; - $charset = $config['charset'] ?? 'utf-8'; + global $title_full, $twig; + $charset = setting('core.charset') ?? 'utf-8'; return $twig->render('templates.header.html.twig', [ @@ -1036,14 +1035,14 @@ function get_browser_real_ip() { return '0'; } function setSession($key, $data) { - $_SESSION[config('session_prefix') . $key] = $data; + $_SESSION[setting('core.session_prefix') . $key] = $data; } function getSession($key) { - $key = config('session_prefix') . $key; + $key = setting('core.session_prefix') . $key; return isset($_SESSION[$key]) ? $_SESSION[$key] : false; } function unsetSession($key) { - unset($_SESSION[config('session_prefix') . $key]); + unset($_SESSION[setting('core.session_prefix') . $key]); } function getTopPlayers($limit = 5) { @@ -1270,7 +1269,7 @@ function getCustomPage($name, &$success): string set_error_handler('error_handler'); global $config; - if($config['backward_support']) { + if(setting('core.backward_support')) { global $SQL, $main_content, $subtopic; } @@ -1527,8 +1526,8 @@ function right($str, $length) { } function getCreatureImgPath($creature){ - $creature_path = config('monsters_images_url'); - $creature_gfx_name = trim(strtolower($creature)) . config('monsters_images_extension'); + $creature_path = setting('core.monsters_images_url'); + $creature_gfx_name = trim(strtolower($creature)) . setting('core.monsters_images_extension'); if (!file_exists($creature_path . $creature_gfx_name)) { $creature_gfx_name = str_replace(" ", "", $creature_gfx_name); if (file_exists($creature_path . $creature_gfx_name)) { diff --git a/system/init.php b/system/init.php index bda1f85c..cf4b3f9b 100644 --- a/system/init.php +++ b/system/init.php @@ -137,7 +137,12 @@ require_once SYSTEM . 'compat/config.php'; date_default_timezone_set(setting('core.date_timezone')); -$config['account_create_character_create'] = config('account_create_character_create') && (!setting('core.mail_enabled') || !config('account_mail_verify')); +setting( + [ + 'core.account_create_character_create', + setting('core.account_create_character_create') && (!setting('core.mail_enabled') || !setting('core.account_mail_verify')) + ] +); $settingsItemImagesURL = setting('core.item_images_url'); if($settingsItemImagesURL[strlen($settingsItemImagesURL) - 1] !== '/') { diff --git a/system/libs/CreateCharacter.php b/system/libs/CreateCharacter.php index a4a1f87a..994c4a61 100644 --- a/system/libs/CreateCharacter.php +++ b/system/libs/CreateCharacter.php @@ -140,8 +140,8 @@ class CreateCharacter if(empty($errors)) { $number_of_players_on_account = $account->getPlayersList(true)->count(); - if($number_of_players_on_account >= config('characters_per_account')) - $errors[] = 'You have too many characters on your account ('.$number_of_players_on_account.'/'.config('characters_per_account').')!'; + if($number_of_players_on_account >= setting('core.characters_per_account')) + $errors[] = 'You have too many characters on your account ('.$number_of_players_on_account . '/' . setting('core.characters_per_account') . ')!'; } if(empty($errors)) diff --git a/system/libs/forum.php b/system/libs/forum.php index c7f303f7..3f80c927 100644 --- a/system/libs/forum.php +++ b/system/libs/forum.php @@ -10,13 +10,13 @@ */ defined('MYAAC') or die('Direct access not allowed!'); -$configForumTablePrefix = setting('core.forum_table_prefix'); -if(null !== $configForumTablePrefix && !empty(trim($configForumTablePrefix))) { - if(!in_array($configForumTablePrefix, array('myaac_', 'z_'))) { +$settingForumTablePrefix = setting('core.forum_table_prefix'); +if(null !== $settingForumTablePrefix && !empty(trim($settingForumTablePrefix))) { + if(!in_array($settingForumTablePrefix, array('myaac_', 'z_'))) { throw new RuntimeException('Invalid value for forum_table_prefix in config.php. Can be only: "myaac_" or "z_".'); } - define('FORUM_TABLE_PREFIX', $configForumTablePrefix); + define('FORUM_TABLE_PREFIX', $settingForumTablePrefix); } else { if($db->hasTable('z_forum')) { diff --git a/system/libs/usage_statistics.php b/system/libs/usage_statistics.php index 0002c1c7..29afc51b 100644 --- a/system/libs/usage_statistics.php +++ b/system/libs/usage_statistics.php @@ -106,8 +106,8 @@ WHERE TABLE_SCHEMA = "' . $config['database_name'] . '";'); } $ret['templates'] = get_templates(); - $ret['date_timezone'] = $config['date_timezone']; - $ret['backward_support'] = $config['backward_support']; + $ret['date_timezone'] = setting('core.date_timezone'); + $ret['backward_support'] = setting('core.backward_support'); $cache_engine = strtolower($config['cache_engine']); if($cache_engine == 'auto') { @@ -117,4 +117,4 @@ WHERE TABLE_SCHEMA = "' . $config['database_name'] . '";'); $ret['cache_engine'] = $cache_engine; return $ret; } -} \ No newline at end of file +} diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 3bc8edd7..95ce48fc 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -43,7 +43,7 @@ if($email_new_time < 10) { } if(empty($errors)) { - $email_new_time = time() + $config['account_mail_change'] * 24 * 3600; + $email_new_time = time() + setting('account_mail_change') * 24 * 3600; $account_logged->setCustomField("email_new", $email_new); $account_logged->setCustomField("email_new_time", $email_new_time); $twig->display('success.html.twig', array( diff --git a/system/pages/account/change_info.php b/system/pages/account/change_info.php index 8b61ea1c..2a8d4a07 100644 --- a/system/pages/account/change_info.php +++ b/system/pages/account/change_info.php @@ -20,7 +20,7 @@ if(!$logged) { return; } -if($config['account_country']) +if(setting('core.account_country')) require SYSTEM . 'countries.conf.php'; $account = Account::find($account_logged->getId()); @@ -55,7 +55,7 @@ if(isset($_POST['changeinfosave']) && $_POST['changeinfosave'] == 1) { if($show_form) { $account_rlname = $account->rlname; $account_location = $account->location; - if ($config['account_country']) { + if (setting('core.account_country')) { $account_country = $account->country; $countries = array(); diff --git a/system/pages/account/create.php b/system/pages/account/create.php index 2aa7c544..aff92145 100644 --- a/system/pages/account/create.php +++ b/system/pages/account/create.php @@ -11,7 +11,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Create Account'; -if($config['account_country']) +if (setting('core.account_country')) require SYSTEM . 'countries.conf.php'; if($logged) @@ -20,7 +20,7 @@ if($logged) return; } -if(config('account_create_character_create')) { +if(setting('core.account_create_character_create')) { require_once LIBS . 'CreateCharacter.php'; $createCharacter = new CreateCharacter(); } @@ -68,7 +68,7 @@ if($save) // country $country = ''; - if($config['account_country']) + if (setting('core.account_country')) { $country = $_POST['country']; if(!isset($country)) @@ -93,7 +93,7 @@ if($save) $errors['password'] = 'Password may not be the same as account name.'; } - if($config['account_mail_unique']) + if(setting('core.account_mail_unique')) { $test_email_account = new OTS_Account(); $test_email_account->findByEMail($email); @@ -115,7 +115,7 @@ if($save) } if($account_db->isLoaded()) { - if (config('account_login_by_email') && !config('account_mail_unique')) { + if (config('account_login_by_email') && !setting('core.account_mail_unique')) { $errors['account'] = 'Account with this email already exist.'; } else if (!config('account_login_by_email')) { @@ -150,7 +150,7 @@ if($save) return; } - if(config('account_create_character_create')) { + if(setting('core.account_create_character_create')) { $character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null; $character_sex = isset($_POST['sex']) ? (int)$_POST['sex'] : null; $character_vocation = isset($_POST['vocation']) ? (int)$_POST['vocation'] : null; @@ -191,27 +191,28 @@ if($save) $new_account->setCustomField('created', time()); $new_account->logAction('Account created.'); - if($config['account_country']) { + if(setting('core.account_country')) { $new_account->setCustomField('country', $country); } - if($config['account_premium_days'] && $config['account_premium_days'] > 0) { + $settingAccountPremiumDays = setting('core.account_premium_days'); + if($settingAccountPremiumDays && $settingAccountPremiumDays > 0) { if($db->hasColumn('accounts', 'premend')) { // othire - $new_account->setCustomField('premend', time() + $config['account_premium_days'] * 86400); + $new_account->setCustomField('premend', time() + $settingAccountPremiumDays * 86400); } else { // rest if ($db->hasColumn('accounts', 'premium_ends_at')) { // TFS 1.4+ - $new_account->setCustomField('premium_ends_at', time() + $config['account_premium_days'] * (60 * 60 * 24)); + $new_account->setCustomField('premium_ends_at', time() + $settingAccountPremiumDays * (60 * 60 * 24)); } else { - $new_account->setCustomField('premdays', $config['account_premium_days']); + $new_account->setCustomField('premdays', $settingAccountPremiumDays); $new_account->setCustomField('lastday', time()); } } } - if($config['account_premium_points']) { - $new_account->setCustomField('premium_points', $config['account_premium_points']); + if(setting('account_premium_points') && setting('account_premium_points') > 0) { + $new_account->setCustomField('premium_points', setting('account_premium_points')); } $tmp_account = $email; @@ -219,7 +220,7 @@ if($save) $tmp_account = (USE_ACCOUNT_NAME ? $account_name : $account_id); } - if(setting('core.mail_enabled') && $config['account_mail_verify']) + if(setting('core.mail_enabled') && setting('core.account_mail_verify')) { $hash = md5(generateRandomString(16, true, true) . $email); $new_account->setCustomField('email_hash', $hash); @@ -238,7 +239,7 @@ if($save) 'description' => 'Your account ' . $account_type . ' is ' . $tmp_account . '
    You will need the account ' . $account_type . ' and your password to play on ' . configLua('serverName') . '. Please keep your account ' . $account_type . ' and password in a safe place and never give your account ' . $account_type . ' or password to anybody.', - 'custom_buttons' => config('account_create_character_create') ? '' : null + 'custom_buttons' => setting('core.account_create_character_create') ? '' : null )); } else @@ -249,7 +250,7 @@ if($save) } else { - if(config('account_create_character_create')) { + if(setting('core.account_create_character_create')) { // character creation $character_created = $createCharacter->doCreate($character_name, $character_sex, $character_vocation, $character_town, $new_account, $errors); if (!$character_created) { @@ -258,7 +259,7 @@ if($save) } } - if(config('account_create_auto_login')) { + if(setting('core.account_create_auto_login')) { if ($hasBeenCreatedByEMail) { $_POST['account_login'] = $email; } @@ -273,7 +274,7 @@ if($save) } echo 'Your account'; - if(config('account_create_character_create')) { + if(setting('core.account_create_character_create')) { echo ' and character have'; } else { @@ -281,7 +282,7 @@ if($save) } echo ' been created.'; - if(!config('account_create_character_create')) { + if(!setting('core.account_create_character_create')) { echo ' Now you can login and create your first character.'; } @@ -291,10 +292,10 @@ if($save) 'description' => 'Your account ' . $account_type . ' is ' . $tmp_account . '
    You will need the account ' . $account_type . ' and your password to play on ' . configLua('serverName') . '. Please keep your account ' . $account_type . ' and password in a safe place and never give your account ' . $account_type . ' or password to anybody.', - 'custom_buttons' => config('account_create_character_create') ? '' : null + 'custom_buttons' => setting('core.account_create_character_create') ? '' : null )); - if(setting('core.mail_enabled') && $config['account_welcome_mail']) + if(setting('core.mail_enabled') && setting('account_welcome_mail')) { $mailBody = $twig->render('account.welcome_mail.html.twig', array( 'account' => $tmp_account @@ -330,7 +331,7 @@ if(setting('core.account_country_recognize')) { if(!empty($errors)) $twig->display('error_box.html.twig', array('errors' => $errors)); -if($config['account_country']) { +if (setting('core.account_country')) { $countries = array(); foreach (array('pl', 'se', 'br', 'us', 'gb') as $c) $countries[$c] = $config['countries'][$c]; @@ -353,7 +354,7 @@ $params = array( 'save' => $save ); -if($save && config('account_create_character_create')) { +if($save && setting('core.account_create_character_create')) { $params = array_merge($params, array( 'name' => $character_name, 'sex' => $character_sex, diff --git a/system/pages/characters.php b/system/pages/characters.php index 3411c043..2cb5e084 100644 --- a/system/pages/characters.php +++ b/system/pages/characters.php @@ -77,10 +77,10 @@ if($player->isLoaded() && !$player->isDeleted()) $rows = 0; if($config['characters']['outfit']) - $outfit = $config['outfit_images_url'] . '?id=' . $player->getLookType() . ($db->hasColumn('players', 'lookaddons') ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); + $outfit = setting('core.outfit_images_url') . '?id=' . $player->getLookType() . ($db->hasColumn('players', 'lookaddons') ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); $flag = ''; - if($config['account_country']) { + if(setting('core.account_country')) { $flag = getFlagImage($account->getCountry()); } @@ -423,7 +423,7 @@ WHERE killers.death_id = '".$death['id']."' ORDER BY killers.final_hit DESC, kil if($db->hasColumn('players', 'deletion')) $deleted = 'deletion'; - $query = $db->query('SELECT `name`, `level`, `vocation`' . $promotion . ' FROM `players` WHERE `name` LIKE ' . $db->quote('%' . $name . '%') . ' AND ' . $deleted . ' != 1 LIMIT ' . (int)config('characters_search_limit') . ';'); + $query = $db->query('SELECT `name`, `level`, `vocation`' . $promotion . ' FROM `players` WHERE `name` LIKE ' . $db->quote('%' . $name . '%') . ' AND ' . $deleted . ' != 1 LIMIT ' . (int)setting('core.characters_search_limit') . ';'); if($query->rowCount() > 0) { echo 'Did you mean:
      '; foreach($query as $player) { diff --git a/system/pages/creatures.php b/system/pages/creatures.php index 1b0e0ae8..672ea1a8 100644 --- a/system/pages/creatures.php +++ b/system/pages/creatures.php @@ -17,7 +17,7 @@ $title = 'Creatures'; if (empty($_REQUEST['name'])) { // display list of monsters - $preview = config('monsters_images_preview'); + $preview = setting('core.monsters_images_preview'); $creatures = Monster::where('hidden', '!=', 1)->when(!empty($_REQUEST['boss']), function ($query) { $query->where('rewardboss', 1); })->get()->toArray(); @@ -65,7 +65,7 @@ if (isset($creature['name'])) { $item['name'] = getItemNameById($item['id']); $item['rarity_chance'] = round($item['chance'] / 1000, 2); $item['rarity'] = getItemRarity($item['chance']); - $item['tooltip'] = ucfirst($item['name']) . '
      Chance: ' . $item['rarity'] . (config('monsters_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
      Max count: ' . $item['count']; + $item['tooltip'] = ucfirst($item['name']) . '
      Chance: ' . $item['rarity'] . (setting('core.monsters_loot_percentage') ? ' ('. $item['rarity_chance'] .'%)' : '') . '
      Max count: ' . $item['count']; } $creature['loot'] = isset($loot) ? $loot : null; diff --git a/system/pages/forum/show_thread.php b/system/pages/forum/show_thread.php index 263683ee..124928bc 100644 --- a/system/pages/forum/show_thread.php +++ b/system/pages/forum/show_thread.php @@ -57,7 +57,7 @@ foreach($posts as &$post) { } if($config['characters']['outfit']) { - $post['outfit'] = $config['outfit_images_url'] . '?id=' . $player->getLookType() . ($lookaddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); + $post['outfit'] = setting('core.outfit_images_url') . '?id=' . $player->getLookType() . ($lookaddons ? '&addons=' . $player->getLookAddons() : '') . '&head=' . $player->getLookHead() . '&body=' . $player->getLookBody() . '&legs=' . $player->getLookLegs() . '&feet=' . $player->getLookFeet(); } $groupName = ''; diff --git a/system/pages/guilds/change_description.php b/system/pages/guilds/change_description.php index 9f6fc0dc..a1e7b1d7 100644 --- a/system/pages/guilds/change_description.php +++ b/system/pages/guilds/change_description.php @@ -43,7 +43,7 @@ if(empty($errors)) { $saved = false; if($guild_leader) { if(isset($_REQUEST['todo']) && $_REQUEST['todo'] == 'save') { - $description = htmlspecialchars(stripslashes(substr(trim($_REQUEST['description']),0,$config['guild_description_chars_limit']))); + $description = htmlspecialchars(stripslashes(substr(trim($_REQUEST['description']),0, setting('core.guild_description_chars_limit')))); $guild->setCustomField('description', $description); $saved = true; } diff --git a/system/pages/guilds/change_logo.php b/system/pages/guilds/change_logo.php index fea3005f..eee33582 100644 --- a/system/pages/guilds/change_logo.php +++ b/system/pages/guilds/change_logo.php @@ -42,7 +42,7 @@ if(empty($errors)) { if($guild_leader) { - $max_image_size_b = $config['guild_image_size_kb'] * 1024; + $max_image_size_b = setting('core.guild_image_size_kb') * 1024; $allowed_ext = array('image/gif', 'image/jpg', 'image/pjpeg', 'image/jpeg', 'image/bmp', 'image/png', 'image/x-png'); $ext_name = array('image/gif' => 'gif', 'image/jpg' => 'jpg', 'image/jpeg' => 'jpg', 'image/pjpeg' => 'jpg', 'image/bmp' => 'bmp', 'image/png' => 'png', 'image/x-png' => 'png'); $save_file_name = str_replace(' ', '_', strtolower($guild->getName())); @@ -62,7 +62,7 @@ if(empty($errors)) { } } else { - $upload_errors[] = 'You didn\'t send file or file is too big. Limit: '.$config['guild_image_size_kb'].' KB.'; + $upload_errors[] = 'You didn\'t send file or file is too big. Limit: '.setting('core.guild_image_size_kb').' KB.'; } if(empty($upload_errors)) { diff --git a/system/pages/guilds/change_motd.php b/system/pages/guilds/change_motd.php index 84581485..7d546670 100644 --- a/system/pages/guilds/change_motd.php +++ b/system/pages/guilds/change_motd.php @@ -46,7 +46,7 @@ if(empty($errors)) { $saved = false; if($guild_leader) { if(isset($_REQUEST['todo']) && $_REQUEST['todo'] == 'save') { - $motd = htmlspecialchars(stripslashes(substr($_REQUEST['motd'],0, $config['guild_motd_chars_limit']))); + $motd = htmlspecialchars(stripslashes(substr($_REQUEST['motd'],0, setting('core.guild_motd_chars_limit')))); $guild->setCustomField('motd', $motd); $saved = true; } diff --git a/system/pages/guilds/create.php b/system/pages/guilds/create.php index d7319fce..dcecf988 100644 --- a/system/pages/guilds/create.php +++ b/system/pages/guilds/create.php @@ -28,8 +28,8 @@ if(empty($guild_errors)) $player_rank = $player->getRank(); if(!$player_rank->isLoaded()) { - if($player->getLevel() >= $config['guild_need_level']) { - if(!$config['guild_need_premium'] || $account_logged->isPremium()) { + if($player->getLevel() >= setting('core.guild_need_level')) { + if(!setting('core.guild_need_premium') || $account_logged->isPremium()) { $array_of_player_nig[] = $player->getName(); } } @@ -39,7 +39,7 @@ if(empty($guild_errors)) if(empty($todo)) { if(count($array_of_player_nig) == 0) { - $guild_errors[] = 'On your account all characters are in guilds, have too low level to create new guild' . ($config['guild_need_premium'] ? ' or you don\' have a premium account' : '') . '.'; + $guild_errors[] = 'On your account all characters are in guilds, have too low level to create new guild' . (setting('core.guild_need_premium') ? ' or you don\' have a premium account' : '') . '.'; } } @@ -91,10 +91,10 @@ if($todo == 'save') } if(empty($guild_errors)) { - if($player->getLevel() < $config['guild_need_level']) { - $guild_errors[] = 'Character '.$name.' has too low level. To create guild you need character with level '.$config['guild_need_level'].'.'; + if($player->getLevel() < setting('core.guild_need_level')) { + $guild_errors[] = 'Character '.$name.' has too low level. To create guild you need character with level ' . setting('core.guild_need_level') . '.'; } - if($config['guild_need_premium'] && !$account_logged->isPremium()) { + if(setting('core.guild_need_premium') && !$account_logged->isPremium()) { $guild_errors[] = 'Character '.$name.' is on FREE account. To create guild you need PREMIUM account.'; } } @@ -112,7 +112,7 @@ if(isset($todo) && $todo == 'save') $new_guild->setName($guild_name); $new_guild->setOwner($player); $new_guild->save(); - $new_guild->setCustomField('description', config('guild_description_default')); + $new_guild->setCustomField('description', setting('core.guild_description_default')); //$new_guild->setCustomField('creationdata', time()); $ranks = $new_guild->getGuildRanksList(); $ranks->orderBy('level', POT::ORDER_DESC); diff --git a/system/pages/guilds/list.php b/system/pages/guilds/list.php index e91b644d..e8425dc4 100644 --- a/system/pages/guilds/list.php +++ b/system/pages/guilds/list.php @@ -26,7 +26,7 @@ if(count($guilds_list) > 0) $description = $guild->getCustomField('description'); $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
      ', $description, $count); - if ($count < $config['guild_description_lines_limit']) + if ($count < setting('core.guild_description_lines_limit')) $description = nl2br($description); $guildName = $guild->getName(); diff --git a/system/pages/guilds/show.php b/system/pages/guilds/show.php index 8a519c61..58a4b45f 100644 --- a/system/pages/guilds/show.php +++ b/system/pages/guilds/show.php @@ -85,7 +85,7 @@ if(empty($guild_logo) || !file_exists(GUILD_IMAGES_DIR . $guild_logo)) $description = $guild->getCustomField('description'); $description_with_lines = str_replace(array("\r\n", "\n", "\r"), '
      ', $description, $count); -if($count < $config['guild_description_lines_limit']) +if($count < setting('core.guild_description_lines_limit')) $description = nl2br($description); //$description = $description_with_lines; diff --git a/system/pages/highscores.php b/system/pages/highscores.php index 090da010..e3b64e3c 100644 --- a/system/pages/highscores.php +++ b/system/pages/highscores.php @@ -239,7 +239,7 @@ foreach($highscores as $id => &$player) $player['link'] = getPlayerLink($player['name'], false); $player['flag'] = getFlagImage($player['country']); if($settingHighscoresOutfit) { - $player['outfit'] = ''; + $player['outfit'] = ''; } $player['rank'] = $offset + $i; } diff --git a/system/pages/lastkills.php b/system/pages/lastkills.php index b325f506..798d91c3 100644 --- a/system/pages/lastkills.php +++ b/system/pages/lastkills.php @@ -21,7 +21,7 @@ if($cache->enabled() && $cache->fetch('last_kills', $tmp)) { else { if($db->hasTable('player_killers')) // tfs 0.3 { - $players_deaths = $db->query('SELECT `player_deaths`.`id`, `player_deaths`.`date`, `player_deaths`.`level`, `players`.`name`' . ($db->hasColumn('players', 'world_id') ? ', `players`.`world_id`' : '') . ' FROM `player_deaths` LEFT JOIN `players` ON `player_deaths`.`player_id` = `players`.`id` ORDER BY `date` DESC LIMIT 0, ' . $config['last_kills_limit']); + $players_deaths = $db->query('SELECT `player_deaths`.`id`, `player_deaths`.`date`, `player_deaths`.`level`, `players`.`name`' . ($db->hasColumn('players', 'world_id') ? ', `players`.`world_id`' : '') . ' FROM `player_deaths` LEFT JOIN `players` ON `player_deaths`.`player_id` = `players`.`id` ORDER BY `date` DESC LIMIT 0, ' . setting('core.last_kills_limit')); if(!empty($players_deaths)) { foreach($players_deaths as $death) { @@ -82,9 +82,9 @@ else { } } } else { - //$players_deaths = $db->query("SELECT `p`.`name` AS `victim`, `player_deaths`.`killed_by` as `killed_by`, `player_deaths`.`time` as `time`, `player_deaths`.`is_player` as `is_player`, `player_deaths`.`level` as `level` FROM `player_deaths`, `players` as `d` INNER JOIN `players` as `p` ON player_deaths.player_id = p.id WHERE player_deaths.`is_player`='1' ORDER BY `time` DESC LIMIT " . $config['last_kills_limit'] . ";"); + //$players_deaths = $db->query("SELECT `p`.`name` AS `victim`, `player_deaths`.`killed_by` as `killed_by`, `player_deaths`.`time` as `time`, `player_deaths`.`is_player` as `is_player`, `player_deaths`.`level` as `level` FROM `player_deaths`, `players` as `d` INNER JOIN `players` as `p` ON player_deaths.player_id = p.id WHERE player_deaths.`is_player`='1' ORDER BY `time` DESC LIMIT " . setting('core.last_kills_limit') . ";"); - $players_deaths = $db->query("SELECT `p`.`name` AS `victim`, `d`.`killed_by` as `killed_by`, `d`.`time` as `time`, `d`.`level`, `d`.`is_player` FROM `player_deaths` as `d` INNER JOIN `players` as `p` ON d.player_id = p.id ORDER BY `time` DESC LIMIT " . $config['last_kills_limit'] . ";"); + $players_deaths = $db->query("SELECT `p`.`name` AS `victim`, `d`.`killed_by` as `killed_by`, `d`.`time` as `time`, `d`.`level`, `d`.`is_player` FROM `player_deaths` as `d` INNER JOIN `players` as `p` ON d.player_id = p.id ORDER BY `time` DESC LIMIT " . setting('core.last_kills_limit') . ";"); if(!empty($players_deaths)) { foreach($players_deaths as $death) { $players_deaths_count++; @@ -114,4 +114,4 @@ else { $twig->display('lastkills.html.twig', array( 'lastkills' => $last_kills -)); \ No newline at end of file +)); diff --git a/system/pages/news.php b/system/pages/news.php index db04092d..5f30454f 100644 --- a/system/pages/news.php +++ b/system/pages/news.php @@ -62,7 +62,7 @@ if(isset($_GET['archive'])) 'content' => $content_, 'date' => $news['date'], 'icon' => $categories[$news['category']]['icon_id'], - 'author' => $config['news_author'] ? $author : '', + 'author' => setting('core.news_author') ? $author : '', 'comments' => $news['comments'] != 0 ? getForumThreadLink($news['comments']) : null, )); } @@ -116,7 +116,7 @@ if(!$news_cached) ); } - $tickers_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . TICKER .($canEdit ? '' : ' AND `hidden` != 1') .' ORDER BY `date` DESC LIMIT ' . $config['news_ticker_limit']); + $tickers_db = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'news` WHERE `type` = ' . TICKER .($canEdit ? '' : ' AND `hidden` != 1') .' ORDER BY `date` DESC LIMIT ' . setting('core.news_ticker_limit')); $tickers_content = ''; if($tickers_db->rowCount() > 0) { @@ -167,7 +167,7 @@ else { if(!$news_cached) { ob_start(); - $newses = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news') . ' WHERE type = ' . NEWS . ($canEdit ? '' : ' AND hidden != 1') . ' ORDER BY date' . ' DESC LIMIT ' . $config['news_limit']); + $newses = $db->query('SELECT * FROM ' . $db->tableName(TABLE_PREFIX . 'news') . ' WHERE type = ' . NEWS . ($canEdit ? '' : ' AND hidden != 1') . ' ORDER BY date' . ' DESC LIMIT ' . setting('core.news_limit')); if($newses->rowCount() > 0) { foreach($newses as $news) @@ -211,7 +211,7 @@ if(!$news_cached) 'content' => $content_ . $admin_options, 'date' => $news['date'], 'icon' => $categories[$news['category']]['icon_id'], - 'author' => $config['news_author'] ? $author : '', + 'author' => setting('core.news_author') ? $author : '', 'comments' => $news['comments'] != 0 ? getForumThreadLink($news['comments']) : null, 'hidden'=> $news['hidden'] )); diff --git a/system/pages/online.php b/system/pages/online.php index 0ca74127..77f01a2a 100644 --- a/system/pages/online.php +++ b/system/pages/online.php @@ -15,7 +15,7 @@ use MyAAC\Models\ServerRecord; defined('MYAAC') or die('Direct access not allowed!'); $title = 'Who is online?'; -if($config['account_country']) +if (setting('core.account_country')) require SYSTEM . 'countries.conf.php'; $promotion = ''; @@ -42,7 +42,7 @@ if($db->hasColumn('players', 'skull_time')) { $outfit_addons = false; $outfit = ''; -if($config['online_outfit']) { +if (setting('core.online_outfit')) { $outfit = ', lookbody, lookfeet, lookhead, looklegs, looktype'; if($db->hasColumn('players', 'lookaddons')) { $outfit .= ', lookaddons'; @@ -50,7 +50,7 @@ if($config['online_outfit']) { } } -if($config['online_vocations']) { +if (setting('core.online_vocations')) { $vocs = array(); foreach($config['vocations'] as $id => $name) { $vocs[$id] = 0; @@ -67,7 +67,7 @@ $players = 0; $data = ''; foreach($playersOnline as $player) { $skull = ''; - if($config['online_skulls']) + if (setting('core.online_skulls')) { if($player['skulltime'] > 0) { @@ -90,18 +90,18 @@ foreach($playersOnline as $player) { 'player' => $player, 'level' => $player['level'], 'vocation' => $config['vocations'][$player['vocation']], - 'country_image' => $config['account_country'] ? getFlagImage($player['country']) : null, - 'outfit' => $config['online_outfit'] ? $config['outfit_images_url'] . '?id=' . $player['looktype'] . ($outfit_addons ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet'] : null + 'country_image' => setting('core.account_country') ? getFlagImage($player['country']) : null, + 'outfit' => setting('core.online_outfit') ? setting('core.outfit_images_url') . '?id=' . $player['looktype'] . ($outfit_addons ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet'] : null ); - if($config['online_vocations']) { + if (setting('core.online_vocations')) { $vocs[($player['vocation'] > $config['vocations_amount'] ? $player['vocation'] - $config['vocations_amount'] : $player['vocation'])]++; } } $record = ''; if($players > 0) { - if($config['online_record']) { + if( setting('core.online_record')) { $result = null; $timestamp = false; if($db->hasTable('server_record')) { diff --git a/system/pages/spells.php b/system/pages/spells.php index 692df7cd..28bcbb23 100644 --- a/system/pages/spells.php +++ b/system/pages/spells.php @@ -71,7 +71,7 @@ $twig->display('spells.html.twig', array( 'post_vocation_id' => $vocation_id, 'post_vocation' => $vocation, 'spells' => $spells, - 'item_path' => $config['item_images_url'], + 'item_path' => setting('core.item_images_url'), )); ?> diff --git a/system/pages/team.php b/system/pages/team.php index b1fd15dc..ae0c9d93 100644 --- a/system/pages/team.php +++ b/system/pages/team.php @@ -11,7 +11,7 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Support in game'; -if($config['account_country']) +if(setting('core.account_country')) require SYSTEM . 'countries.conf.php'; $groups = new OTS_Groups_List(); diff --git a/system/router.php b/system/router.php index a24a3b1b..d45889f9 100644 --- a/system/router.php +++ b/system/router.php @@ -170,7 +170,7 @@ if(!empty($page) && preg_match('/^[A-z0-9\-]+$/', $page)) { $_REQUEST['subtopic'] = $_REQUEST['p']; } - if (config('backward_support')) { + if (setting('core.backward_support')) { require SYSTEM . 'compat/pages.php'; } @@ -271,7 +271,7 @@ if($hooks->trigger(HOOK_BEFORE_PAGE)) { unset($file); -if(config('backward_support') && isset($main_content[0])) +if(setting('core.backward_support') && isset($main_content[0])) $content .= $main_content; $content .= ob_get_contents(); @@ -282,7 +282,7 @@ if(!isset($title)) { $title = ucfirst($page); } -if(config('backward_support')) { +if(setting('core.backward_support')) { $main_content = $content; $topic = $title; } diff --git a/system/settings.php b/system/settings.php index bbd72e2f..d62dda9e 100644 --- a/system/settings.php +++ b/system/settings.php @@ -1047,12 +1047,12 @@ Sent by MyAAC,
      'desc' => 'Show player outfit?', 'default' => true, ], - 'highscores_country_box' => [ // not implemented yet + /*'highscores_country_box' => [ // not implemented yet 'name' => 'Display Country Box', 'type' => 'hidden', 'desc' => 'Show player outfit?', 'default' => false, - ], + ],*/ 'highscores_groups_hidden' => [ 'name' => 'Hidden Groups', 'type' => 'number', @@ -1225,9 +1225,9 @@ Sent by MyAAC,
      'team_style' => [ 'name' => 'Style', 'type' => 'options', - 'desc' => '', - 'options' => ['normal table', 'in boxes, grouped by group id'], - 'default' => 1, + 'desc' => 'How to show groups', + 'options' => [1 => 'normal table', 2 => 'in boxes, grouped by group id'], + 'default' => 2, ], 'team_status' => [ 'name' => 'Display Online Status', diff --git a/system/status.php b/system/status.php index 88a48917..d55f68e1 100644 --- a/system/status.php +++ b/system/status.php @@ -125,7 +125,7 @@ function updateStatus() { $status['playersMax'] = $serverStatus->getMaxPlayers(); // for status afk thing - if($config['online_afk']) + if (setting('core.online_afk')) { $status['playersTotal'] = 0; // get amount of players that are currently logged in-game, including disconnected clients (exited) diff --git a/system/template.php b/system/template.php index 0fbb0477..0a8775b0 100644 --- a/system/template.php +++ b/system/template.php @@ -54,7 +54,7 @@ if(file_exists(BASE . $template_path . '/index.php')) { elseif(file_exists(BASE . $template_path . '/template.php')) { $template_index = 'template.php'; } -elseif($config['backward_support'] && file_exists(BASE . $template_path . '/layout.php')) { +elseif(setting('core.backward_support') && file_exists(BASE . $template_path . '/layout.php')) { $template_index = 'layout.php'; } else { @@ -77,7 +77,7 @@ if ($cache->enabled() && $cache->fetch('template_ini_' . $template_name, $tmp)) else { $file = BASE . $template_path . '/config.ini'; $exists = file_exists($file); - if ($exists || ($config['backward_support'] && file_exists(BASE . $template_path . '/layout_config.ini'))) { + if ($exists || (setting('core.backward_support') && file_exists(BASE . $template_path . '/layout_config.ini'))) { if (!$exists) { $file = BASE . $template_path . '/layout_config.ini'; } diff --git a/system/templates/account.change_info.html.twig b/system/templates/account.change_info.html.twig index 80be0bd2..fb503e8e 100644 --- a/system/templates/account.change_info.html.twig +++ b/system/templates/account.change_info.html.twig @@ -31,7 +31,7 @@ Here you can tell other players about yourself. This information will be display - {% if config.account_country %} + {% if setting('core.account_country') %} Country: @@ -97,4 +97,4 @@ Here you can tell other players about yourself. This information will be display - \ No newline at end of file + diff --git a/system/templates/account.change_mail.html.twig b/system/templates/account.change_mail.html.twig index 1c0d1c12..35d64854 100644 --- a/system/templates/account.change_mail.html.twig +++ b/system/templates/account.change_mail.html.twig @@ -1,4 +1,4 @@ -Please enter your password and the new email address. Make sure that you enter a valid email address which you have access to.
      For security reasons, the actual change will be finalised after a waiting period of {{ config.account_mail_change }} days.

      +Please enter your password and the new email address. Make sure that you enter a valid email address which you have access to.
      For security reasons, the actual change will be finalised after a waiting period of {{ setting('core.account_mail_change') }} days.

      @@ -67,4 +67,4 @@ Please enter your password and the new email address. Make sure that you enter a
      - \ No newline at end of file + diff --git a/system/templates/account.create.html.twig b/system/templates/account.create.html.twig index a43d6e7d..290809c3 100644 --- a/system/templates/account.create.html.twig +++ b/system/templates/account.create.html.twig @@ -59,13 +59,13 @@ {% if errors.email is defined %}{{ errors.email }}{% endif %} - {% if setting('core.mail_enabled') and config.account_mail_verify %} + {% if setting('core.mail_enabled') and setting('account_mail_verify') %} Please use real address!
      We will send a link to validate your Email.
      {% endif %} {{ hook('HOOK_ACCOUNT_CREATE_AFTER_EMAIL') }} - {% if config.account_country %} + {% if setting('core.account_country') %} Country: @@ -122,7 +122,7 @@ {{ hook('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1') }} - {% if (not setting('core.mail_enabled') or not config.account_mail_verify) and config.account_create_character_create %} + {% if (not setting('core.mail_enabled') or not setting('core.account_mail_verify')) and setting('account_create_character_create') %}
      diff --git a/system/templates/account.create_character.html.twig b/system/templates/account.create_character.html.twig index acb57f5c..c116cec2 100644 --- a/system/templates/account.create_character.html.twig +++ b/system/templates/account.create_character.html.twig @@ -2,7 +2,7 @@ Please choose a name{% if config.character_samples|length > 1 %}, vocation{% end {% if config.character_towns|length > 1 %}, town{% endif %} and sex for your character.
      In any case the name must not violate the naming conventions stated in the {{ config.lua.serverName }} Rules, or your character might get deleted or name locked. -{% if account_logged.getPlayersList(true)|length >= config.characters_per_account %} +{% if account_logged.getPlayersList(true)|length >= setting('core.characters_per_account') %} You have maximum number of characters per account on your account. Delete one before you make new. {% endif %}

      diff --git a/system/templates/admin.news.html.twig b/system/templates/admin.news.html.twig index 4436c262..0eb16d3f 100644 --- a/system/templates/admin.news.html.twig +++ b/system/templates/admin.news.html.twig @@ -21,7 +21,7 @@ {{ news.id|raw }} {{ news.title }} - {{ news.date|date(config.news_date_format) }} + {{ news.date|date(setting('core.news_date_format')) }} {{ news.player_name }}
      @@ -66,7 +66,7 @@ {{ ticker.id|raw }} {{ ticker.title }} - {{ ticker.date|date(config.news_date_format) }} + {{ ticker.date|date(setting('core.news_date_format')) }} {{ ticker.player_name }}
      @@ -110,7 +110,7 @@ {{ article.id|raw }} {{ article.title }} - {{ article.date|date(config.news_date_format) }} + {{ article.date|date(setting('core.news_date_format')) }} {{ article.player_name }}
      diff --git a/system/templates/characters.html.twig b/system/templates/characters.html.twig index 9553d20c..865c39ca 100644 --- a/system/templates/characters.html.twig +++ b/system/templates/characters.html.twig @@ -17,7 +17,7 @@ {% endif %} {% if config.characters.outfit %} -
      player outfit
      +
      player outfit
      {% endif %} diff --git a/system/templates/creature.html.twig b/system/templates/creature.html.twig index 46e2e508..18828e0c 100644 --- a/system/templates/creature.html.twig +++ b/system/templates/creature.html.twig @@ -155,7 +155,7 @@ {% if (item.count > 1) %} {{ item.count }} {% endif %} - + {% endfor %} diff --git a/system/templates/forum.show_thread.html.twig b/system/templates/forum.show_thread.html.twig index 80985d43..ddcb3be5 100644 --- a/system/templates/forum.show_thread.html.twig +++ b/system/templates/forum.show_thread.html.twig @@ -24,7 +24,7 @@ Page: {{ links_to_pages|raw }}
      {% set i = i + 1 %} - {% if setting('core.mail_enabled') and setting('account_mail_verify') %} + {% if setting('core.mail_enabled') and setting('core.account_mail_verify') %} {% endif %} @@ -122,7 +122,7 @@ {{ hook('HOOK_ACCOUNT_CREATE_BETWEEN_BOXES_1') }} - {% if (not setting('core.mail_enabled') or not setting('core.account_mail_verify')) and setting('account_create_character_create') %} + {% if (not setting('core.mail_enabled') or not setting('core.account_mail_verify')) and setting('core.account_create_character_create') %}
      {{ post.player_link|raw }}
      {% if post.outfit is defined %} - player outfit + player outfit
      {% endif %} diff --git a/system/templates/guilds.change_description.html.twig b/system/templates/guilds.change_description.html.twig index b6d43dd0..97cb866c 100644 --- a/system/templates/guilds.change_description.html.twig +++ b/system/templates/guilds.change_description.html.twig @@ -2,8 +2,8 @@ Here you can change description of your guild.
      -
      - (max. {{ config.guild_description_lines_limit }} lines, max. {{ config.guild_description_chars_limit }} chars)
      +
      + (max. {{ setting('core.guild_description_lines_limit') }} lines, max. {{ setting('core.guild_description_chars_limit') }} chars)

      diff --git a/system/templates/guilds.change_logo.html.twig b/system/templates/guilds.change_logo.html.twig index f8aa002e..3194858f 100644 --- a/system/templates/guilds.change_logo.html.twig +++ b/system/templates/guilds.change_logo.html.twig @@ -6,7 +6,7 @@ Here you can change logo of your guild.
      Actuall logo:
      -Only jpg, gif, png, bmp pictures. Max. size: {{ config.guild_image_size_kb }} KB
      +Only jpg, gif, png, bmp pictures. Max. size: {{ setting('core.guild_image_size_kb') }} KB

      @@ -16,7 +16,7 @@ Only jpg, gif, png, bmp pictures. Max. size: {{ config.guild_image_siz diff --git a/templates/kathrine/menu.js.html.twig b/templates/kathrine/menu.js.html.twig index 7cd25c59..adf7ceb0 100644 --- a/templates/kathrine/menu.js.html.twig +++ b/templates/kathrine/menu.js.html.twig @@ -1,7 +1,7 @@ var list = new Array(); {% set i = 0 %} {% for cat in categories %} - {% if cat.id != 'shops' or config.gifts_system %} + {% if cat.id != 'shops' or setting('core.gifts_system') %} list[{{ i }}] = '{{ cat.id }}'; {% endif %} {% set i = i + 1 %} diff --git a/templates/tibiacom/boxes/highscores.php b/templates/tibiacom/boxes/highscores.php index 808bb237..a2f371fa 100644 --- a/templates/tibiacom/boxes/highscores.php +++ b/templates/tibiacom/boxes/highscores.php @@ -3,8 +3,8 @@ $topPlayers = getTopPlayers(5); foreach($topPlayers as &$player) { $outfit_url = ''; - if($config['online_outfit']) { - $outfit_url = $config['outfit_images_url'] . '?id=' . $player['looktype'] . (!empty + if (setting('core.online_outfit')) { + $outfit_url = setting('core.outfit_images_url') . '?id=' . $player['looktype'] . (!empty ($player['lookaddons']) ? '&addons=' . $player['lookaddons'] : '') . '&head=' . $player['lookhead'] . '&body=' . $player['lookbody'] . '&legs=' . $player['looklegs'] . '&feet=' . $player['lookfeet']; $player['outfit'] = $outfit_url; diff --git a/templates/tibiacom/boxes/templates/highscores.html.twig b/templates/tibiacom/boxes/templates/highscores.html.twig index 0cac1f0a..c5eb5516 100644 --- a/templates/tibiacom/boxes/templates/highscores.html.twig +++ b/templates/tibiacom/boxes/templates/highscores.html.twig @@ -45,8 +45,8 @@
      {% for player in topPlayers %}
      - {% if config.online_outfit %} - player outfit + {% if setting('core.online_outfit') %} + player outfit {% endif %} {{ player['rank'] }} - {{ player['name'] }} diff --git a/templates/tibiacom/index.php b/templates/tibiacom/index.php index 6bb5f445..95c73c33 100644 --- a/templates/tibiacom/index.php +++ b/templates/tibiacom/index.php @@ -124,7 +124,7 @@ if(isset($config['boxes'])) document.getElementById("ActiveSubmenuItemIcon_"+activeSubmenuItem).style.visibility = "visible"; menus = localStorage.getItem('menus'); if(menus.lastIndexOf("&") === -1) { - menus = "news=1&account=0&community=0&library=0&forum=0&"; + menus = "news=1&account=0&community=0&library=0&forum=0&"; } FillMenuArray(); InitializeMenu(); @@ -329,7 +329,7 @@ if(isset($config['boxes'])) $menus = get_template_menus(); foreach($config['menu_categories'] as $id => $cat) { - if(!isset($menus[$id]) || ($id == MENU_CATEGORY_SHOP && !$config['gifts_system'])) { + if(!isset($menus[$id]) || ($id == MENU_CATEGORY_SHOP && !setting('core.gifts_system'))) { continue; } ?> @@ -368,7 +368,7 @@ foreach($config['menu_categories'] as $id => $cat) { ?>
      $_GET['body'], 'date' => time(), 'icon' => $categories[$_GET['category']]['icon_id'], - 'author' => $config['news_author'] ? $author : '', + 'author' => setting('core.news_author') ? $author : '', 'comments' => null, - 'news_date_format' => $config['news_date_format'], + 'news_date_format' => setting('core.news_date_format'), 'hidden'=> 0 ))); } diff --git a/tools/validate.php b/tools/validate.php index ff9176e6..43c965d0 100644 --- a/tools/validate.php +++ b/tools/validate.php @@ -46,7 +46,7 @@ else if(isset($_GET['email'])) if(!Validator::email($email)) error_(Validator::getLastError()); - if($config['account_mail_unique']) + if(setting('core.account_mail_unique')) { if(Account::where('email', '=', $email)->exists()) error_('Account with this e-mail already exist.'); From 9e2a87f448b508cbb7076144c0df7ddd0229631c Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 25 Aug 2023 17:09:31 +0200 Subject: [PATCH 231/232] Add forgotten prefix for some settings --- system/pages/account/change_email.php | 2 +- system/pages/account/create.php | 6 +++--- system/templates/account.create.html.twig | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/system/pages/account/change_email.php b/system/pages/account/change_email.php index 95ce48fc..4168131c 100644 --- a/system/pages/account/change_email.php +++ b/system/pages/account/change_email.php @@ -43,7 +43,7 @@ if($email_new_time < 10) { } if(empty($errors)) { - $email_new_time = time() + setting('account_mail_change') * 24 * 3600; + $email_new_time = time() + setting('core.account_mail_change') * 24 * 3600; $account_logged->setCustomField("email_new", $email_new); $account_logged->setCustomField("email_new_time", $email_new_time); $twig->display('success.html.twig', array( diff --git a/system/pages/account/create.php b/system/pages/account/create.php index aff92145..5775855f 100644 --- a/system/pages/account/create.php +++ b/system/pages/account/create.php @@ -211,8 +211,8 @@ if($save) } } - if(setting('account_premium_points') && setting('account_premium_points') > 0) { - $new_account->setCustomField('premium_points', setting('account_premium_points')); + if(setting('core.account_premium_points') && setting('core.account_premium_points') > 0) { + $new_account->setCustomField('premium_points', setting('core.account_premium_points')); } $tmp_account = $email; @@ -295,7 +295,7 @@ if($save) 'custom_buttons' => setting('core.account_create_character_create') ? '' : null )); - if(setting('core.mail_enabled') && setting('account_welcome_mail')) + if(setting('core.mail_enabled') && setting('core.account_welcome_mail')) { $mailBody = $twig->render('account.welcome_mail.html.twig', array( 'account' => $tmp_account diff --git a/system/templates/account.create.html.twig b/system/templates/account.create.html.twig index 290809c3..5f9ea910 100644 --- a/system/templates/account.create.html.twig +++ b/system/templates/account.create.html.twig @@ -59,7 +59,7 @@
      {% if errors.email is defined %}{{ errors.email }}{% endif %}
      Please use real address!
      We will send a link to validate your Email.
      From 8a3986932d4ed6433e04508ca93a2d04770052fb Mon Sep 17 00:00:00 2001 From: slawkens Date: Fri, 25 Aug 2023 17:13:21 +0200 Subject: [PATCH 232/232] My fault was commenting this --- system/settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/settings.php b/system/settings.php index d62dda9e..e12514cd 100644 --- a/system/settings.php +++ b/system/settings.php @@ -1047,12 +1047,12 @@ Sent by MyAAC,
      'desc' => 'Show player outfit?', 'default' => true, ], - /*'highscores_country_box' => [ // not implemented yet + 'highscores_country_box' => [ // not implemented yet 'name' => 'Display Country Box', 'type' => 'hidden', 'desc' => 'Show player outfit?', 'default' => false, - ],*/ + ], 'highscores_groups_hidden' => [ 'name' => 'Hidden Groups', 'type' => 'number',