Merge branch 'main' into feature/refactor-account-lost

This commit is contained in:
slawkens
2025-09-28 19:14:24 +02:00
9 changed files with 106 additions and 36 deletions

View File

@@ -1,5 +1,21 @@
# Changelog
## [1.8.2 - 26.09.2025]
### Added
* Routes: Possibility to override routes with plugins pages, like characters.php - No need to define routes in plugin.json anymore (https://github.com/slawkens/myaac/commit/3f24f961b1cdeff5c60387e837ae454448bc5e1b)
### Changed
* Style: Better look for myaac-table (https://github.com/slawkens/myaac/commit/a6032093b21e5bb3f0e75d2704da87d6dea6469d, https://github.com/slawkens/myaac/commit/5aa9bbf1c8e580d973ec82ac012489f8e7bc437e)
### Fixed
* Install: Fix when config.local.php cannot be saved (https://github.com/slawkens/myaac/commit/4eab805d26d8c5562b29ed699769919d77dabced)
* Create Account: Fix an exception when email cannot be sent (https://github.com/slawkens/myaac/commit/d0112d1a67e8b854b65ad131f0375b79305df8d3)
* Login Page: Add missing csrf() - fix create account button (https://github.com/slawkens/myaac/commit/3c0cb53e17dd0b85394cfa0fdc9cf9ad8d4551df)
* tibiacom template: Fix account lost menu (https://github.com/slawkens/myaac/commit/ed9beaf2b6ca069e304e569c52e5b9188b58f05c)
* tibiacom template: Fix Menu div wrong tag/closing (#329) (https://github.com/slawkens/myaac/commit/85e7005fd3f0be51466151a3c122b96085fdfe68)
* tibiacom template: Replace firstChild with firstElementChild (Thanks to @un000000) (https://github.com/slawkens/myaac/commit/df7b6e29fb8875da97f431468c81ee99116271d9)
## [1.8.1 - 05.09.2025]
### Added

View File

@@ -26,7 +26,7 @@
if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is required.');
const MYAAC = true;
const MYAAC_VERSION = '1.8.2-dev';
const MYAAC_VERSION = '1.8.3-dev';
const DATABASE_VERSION = 45;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));

View File

@@ -26,10 +26,11 @@ use MyAAC\Cache\Cache;
*/
class OTS_DB_MySQL extends OTS_Base_DB
{
private $has_table_cache = array();
private $has_column_cache = array();
private array $has_table_cache = [];
private array $has_column_cache = [];
private array $get_column_info_cache = [];
private $clearCacheAfter = false;
private bool $clearCacheAfter = false;
/**
* Creates database connection.
*
@@ -209,7 +210,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $sql;
}
public function hasTable($name) {
public function hasTable($name): bool
{
if(isset($this->has_table_cache[$name])) {
return $this->has_table_cache[$name];
}
@@ -217,12 +219,13 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $this->hasTableInternal($name);
}
private function hasTableInternal($name) {
global $config;
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote($config['database_name']) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
private function hasTableInternal($name): bool
{
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
}
public function hasColumn($table, $column) {
public function hasColumn($table, $column): bool
{
if(isset($this->has_column_cache[$table . '.' . $column])) {
return $this->has_column_cache[$table . '.' . $column];
}
@@ -230,8 +233,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $this->hasColumnInternal($table, $column);
}
private function hasColumnInternal($table, $column) {
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE '" . $column . "'")->fetchAll()) > 0);
private function hasColumnInternal($table, $column): bool {
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0);
}
public function hasTableAndColumns(string $table, array $columns = []): bool
@@ -247,6 +250,51 @@ class OTS_DB_MySQL extends OTS_Base_DB
return true;
}
public function getColumnInfo(string $table, string $column): bool|array
{
if(isset($this->get_column_info_cache[$table . '.' . $column])) {
return $this->get_column_info_cache[$table . '.' . $column];
}
return $this->getColumnInfoInternal($table, $column);
}
private function getColumnInfoInternal(string $table, string $column): bool|array
{
if (!$this->hasTable($table) || !$this->hasColumn($table, $column)) {
return false;
}
$formatResult = function ($result) {
return [
'field' => $result['Field'],
'type' => $result['Type'],
'null' => strtolower($result['Null']),
'default' => $result['Default'],
'extra' => $result['Extra'],
];
};
$query = $this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column));
$rowCount = $query->rowCount();
if ($rowCount > 1) {
$tmp = [];
$results = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $result) {
$tmp[] = $formatResult($result);
}
return ($this->get_column_info_cache[$table . '.' . $column] = $tmp);
}
else if ($rowCount == 1) {
$result = $query->fetch(PDO::FETCH_ASSOC);
return ($this->get_column_info_cache[$table . '.' . $column] = $formatResult($result));
}
return [];
}
public function revalidateCache() {
foreach($this->has_table_cache as $key => $value) {
$this->hasTableInternal($key);

View File

@@ -268,8 +268,10 @@ if($save)
}
else
{
error('An error occorred while sending email! Account not created. Try again. For Admin: More info can be found in system/logs/mailer-error.log');
error('An error occurred while sending email! Account not created. Try again. For Admin: More info can be found in system/logs/mailer-error.log');
$new_account->delete();
return;
}
}
else

View File

@@ -9,7 +9,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr>
<td><img src="{{ template_path }}/images/general/blank.gif" width="10" height="1" border="0"></td>
<td>
{{ hook(constant('HOOK_CHARACTERS_BEFORE_INFORMATIONS')) }}
{{ hook('HOOK_CHARACTERS_BEFORE_INFORMATIONS') }}
{% if canEdit %}
<a href="{{ constant('ADMIN_URL') }}?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
<img src="images/edit.png"/>Edit
@@ -153,11 +153,11 @@
<td>{% if account.isPremium() %}Premium Account{% else %}Free Account{% endif %}</td>
</tr>
</table>
{{ hook(constant('HOOK_CHARACTERS_AFTER_INFORMATIONS')) }}
{{ hook('HOOK_CHARACTERS_AFTER_INFORMATIONS') }}
<br/>
<table border="0" width="100%">
<tr>
{{ hook(constant('HOOK_CHARACTERS_BEFORE_SKILLS')) }}
{{ hook('HOOK_CHARACTERS_BEFORE_SKILLS') }}
{% if config.characters.skills %}
<!-- SKILLS -->
@@ -179,7 +179,7 @@
<!-- SKILLS_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_AFTER_SKILLS')) }}
{{ hook('HOOK_CHARACTERS_AFTER_SKILLS') }}
{% if quests_enabled %}
<!-- QUESTS -->
@@ -201,7 +201,7 @@
<!-- QUESTS_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_AFTER_QUESTS')) }}
{{ hook('HOOK_CHARACTERS_AFTER_QUESTS') }}
{% if config.characters.equipment %}
<!-- EQUIPMENT -->
@@ -239,11 +239,11 @@
<!-- EQUIPMENT_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_AFTER_EQUIPMENT')) }}
{{ hook('HOOK_CHARACTERS_AFTER_EQUIPMENT') }}
</tr>
</table>
{{ hook(constant('HOOK_CHARACTERS_BEFORE_DEATHS')) }}
{{ hook('HOOK_CHARACTERS_BEFORE_DEATHS') }}
{% if deaths|length > 0 %}
<!-- DEATHS -->
@@ -283,7 +283,7 @@
<!-- FRAGS_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_BEFORE_SIGNATURE')) }}
{{ hook('HOOK_CHARACTERS_BEFORE_SIGNATURE') }}
{% if setting('core.signature_enabled') %}
<!-- SIGNATURE -->
@@ -327,7 +327,7 @@
</table>
<!-- SIGNATURE_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_AFTER_SIGNATURE')) }}
{{ hook('HOOK_CHARACTERS_AFTER_SIGNATURE') }}
{% if not player.isHidden() %}
{% set rows = 0 %}
<!-- ACCOUNT_INFORMATION -->
@@ -377,7 +377,7 @@
</tr>
</table>
<!-- ACCOUNT_INFORMATION_END -->
{{ hook(constant('HOOK_CHARACTERS_AFTER_ACCOUNT')) }}
{{ hook('HOOK_CHARACTERS_AFTER_ACCOUNT') }}
<!-- CHARACTERS_LIST -->
<br/><br/>
<table border="0" cellspacing="1" cellpadding="4" width="100%">
@@ -421,7 +421,7 @@
</table>
<!-- CHARACTERS_LIST_END -->
{% endif %}
{{ hook(constant('HOOK_CHARACTERS_AFTER_CHARACTERS')) }}
{{ hook('HOOK_CHARACTERS_AFTER_CHARACTERS') }}
{% if canEdit %}
<a href="{{ constant('ADMIN_URL') }}?p=players&id={{ player.getId() }}" title="Edit in Admin Panel" target="_blank">
<img src="images/edit.png"/>Edit

View File

@@ -101,6 +101,8 @@ $twig->addFunction($function);
$function = new TwigFunction('hook', function ($context, $hook, array $params = []) {
global $hooks;
//note($hook);
if(is_string($hook)) {
if (defined($hook)) {
$hook = constant($hook);

View File

@@ -130,6 +130,7 @@
<div style="float: right; margin-top: 20px;" >
{% apply spaceless %}
<form class="MediumButtonForm" action="{{ getLink('account/create') }}" method="post" >
{{ csrf() }}
<div class="MediumButtonBackground" style="background-image:url({{ template_path }}/images/global/buttons/mediumbutton.gif)" onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);">
<div class="MediumButtonOver" style="background-image:url({{ template_path }}/images/global/buttons/mediumbutton-over.gif)" onMouseOver="MouseOverBigButton(this);" onMouseOut="MouseOutBigButton(this);"></div>
<input class="MediumButtonText" type="image" name="Create Account" alt="Create Account" src="{{ template_path }}/images/global/buttons/mediumbutton_createaccount.png" />

View File

@@ -92,24 +92,24 @@ if(isset($config['boxes']))
// mouse-over and click events of the loginbox
function MouseOverLoginBoxText(source)
{
source.lastChild.style.visibility = "visible";
source.firstChild.style.visibility = "hidden";
source.lastElementChild.style.visibility = "visible";
source.firstElementChild.style.visibility = "hidden";
}
function MouseOutLoginBoxText(source)
{
source.firstChild.style.visibility = "visible";
source.lastChild.style.visibility = "hidden";
source.firstElementChild.style.visibility = "visible";
source.lastElementChild.style.visibility = "hidden";
}
function LoginButtonAction()
{
if(loginStatus == "false") {
if(loginStatus === "false") {
window.location = "<?php echo getLink('account/manage'); ?>";
} else {
window.location = "<?php echo getLink('account/manage'); ?>";
}
}
function LoginstatusTextAction(source) {
if(loginStatus == "false") {
if(loginStatus === "false") {
window.location = "<?php echo getLink('account/create'); ?>";
} else {
window.location = "<?php echo getLink('account/logout'); ?>";
@@ -228,11 +228,11 @@ if(isset($config['boxes']))
// mouse-over effects of menubuttons and submenuitems
function MouseOverMenuItem(source)
{
source.firstChild.style.visibility = "visible";
source.firstElementChild.style.visibility = "visible";
}
function MouseOutMenuItem(source)
{
source.firstChild.style.visibility = "hidden";
source.firstElementChild.style.visibility = "hidden";
}
function MouseOverSubmenuItem(source)
{
@@ -338,7 +338,7 @@ if(isset($config['boxes']))
<div id="LoginBottom" class="Loginstatus" style="background-image:url(<?php echo $template_path; ?>/images/general/box-bottom.gif)" ></div>
</div>
<div-- id='Menu'>
<div id='Menu'>
<div id='MenuTop' style='background-image:url(<?php echo $template_path; ?>/images/general/box-top.gif);'></div>
<?php
@@ -403,6 +403,7 @@ foreach($config['menu_categories'] as $id => $cat) {
<?php
}
?>
</div>
<script type="text/javascript">
InitializePage();
</script>

View File

@@ -1,11 +1,11 @@
function MouseOverBigButton(source) {
if (source?.firstChild?.style) {
source.firstChild.style.visibility = "visible";
if (source?.firstElementChild?.style) {
source.firstElementChild.style.visibility = "visible";
}
}
function MouseOutBigButton(source) {
if (source?.firstChild?.style) {
source.firstChild.style.visibility = "hidden";
if (source?.firstElementChild?.style) {
source.firstElementChild.style.visibility = "hidden";
}
}
function BigButtonAction(path) {