diff --git a/config.php b/config.php
index c00cbe16..2f721088 100644
--- a/config.php
+++ b/config.php
@@ -31,38 +31,8 @@ $config = array(
*/
'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)
@@ -84,10 +54,6 @@ $config = array(
//'2' => 'Your Second World Name'
),
- // images
- 'outfit_images_url' => 'http://outfit-images.ots.me/outfit.php', // set to animoutfit.php for animated outfit
- 'item_images_url' => 'http://item-images.ots.me/1092/', // set to images/items if you host your own items in images folder
-
// account
'account_management' => true, // disable if you're using other method to manage users (fe. tfs account manager)
'account_create_auto_login' => false, // auto login after creating account?
diff --git a/system/compat_config.php b/system/compat_config.php
new file mode 100644
index 00000000..01c2aa00
--- /dev/null
+++ b/system/compat_config.php
@@ -0,0 +1,25 @@
+getName();
}
- $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'characters/' . urlencode($name);
+ $settings = Settings::getInstance();
+ $url = BASE_URL . ($settings['core.friendly_urls']['value'] ? '' : '?') . 'characters/' . urlencode($name);
if(!$generate) return $url;
return generateLink($url, $name);
@@ -114,7 +113,7 @@ function getPlayerLink($name, $generate = true)
function getHouseLink($name, $generate = true)
{
- global $db, $config;
+ global $db;
if(is_numeric($name))
{
@@ -124,7 +123,8 @@ function getHouseLink($name, $generate = true)
$name = $house->fetchColumn();
}
- $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'houses/' . urlencode($name);
+ $settings = Settings::getInstance();
+ $url = BASE_URL . ($settings['core.friendly_urls']['value'] ? '' : '?') . 'houses/' . urlencode($name);
if(!$generate) return $url;
return generateLink($url, $name);
@@ -132,7 +132,7 @@ function getHouseLink($name, $generate = true)
function getGuildLink($name, $generate = true)
{
- global $db, $config;
+ global $db;
if(is_numeric($name))
{
@@ -142,7 +142,8 @@ function getGuildLink($name, $generate = true)
$name = $guild->fetchColumn();
}
- $url = BASE_URL . ($config['friendly_urls'] ? '' : '?') . 'guilds/' . urlencode($name);
+ $settings = Settings::getInstance();
+ $url = BASE_URL . ($settings['core.friendly_urls']['value'] ? '' : '?') . 'guilds/' . urlencode($name);
if(!$generate) return $url;
return generateLink($url, $name);
@@ -472,12 +473,12 @@ function template_place_holder($type)
*/
function template_header($is_admin = false)
{
- global $title_full, $config;
- $charset = isset($config['charset']) ? $config['charset'] : 'utf-8';
+ global $title_full;
+ $charset = config('charset') ? config('charset') : 'utf-8';
$ret = '
-
+
';
if(!$is_admin)
$ret .= '
@@ -485,8 +486,8 @@ function template_header($is_admin = false)
' . $title_full . '';
$ret .= '
-
-
+
+
@@ -496,7 +497,7 @@ function template_header($is_admin = false)
';
- if($config['recaptcha_enabled'])
+ if(config('recaptcha_enabled'))
$ret .= "";
return $ret;
}
@@ -1081,6 +1082,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];
}
diff --git a/system/init.php b/system/init.php
index 25d28f26..516f61d0 100644
--- a/system/init.php
+++ b/system/init.php
@@ -88,9 +88,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])) {
@@ -124,6 +121,20 @@ require_once SYSTEM . 'libs/pot/OTS.php';
$ots = POT::getInstance();
require_once SYSTEM . 'database.php';
+// settings
+require_once LIBS . 'Settings.php';
+$settings = Settings::getInstance();
+$settings->load();
+
+// deprecated config values
+require_once __DIR__ . '/compat_config.php';
+
+$settingsItemImagesURL = $settings['core.item_images_url'];
+if($settingsItemImagesURL['value'][strlen($settingsItemImagesURL['value']) - 1] !== '/') {
+ $settingsItemImagesURL['value'] .= '/';
+ $settings['core.item_images_url'] = $settingsItemImagesURL;
+}
+
define('USE_ACCOUNT_NAME', $db->hasColumn('accounts', 'name'));
// load vocation names
$tmp = '';
@@ -207,4 +218,4 @@ else {
config(['towns', $towns]);
//////////////////////////////////////////////
// END - load towns from database (TFS 1.3) //
-//////////////////////////////////////////////
+//////////////////////////////////////////////
\ No newline at end of file
diff --git a/system/libs/Settings.php b/system/libs/Settings.php
index 51e1098f..fd3644cf 100644
--- a/system/libs/Settings.php
+++ b/system/libs/Settings.php
@@ -10,35 +10,172 @@
class Settings implements ArrayAccess
{
- private $container = array();
+ static private $instance;
+ private $plugins = [];
+ private $settings = [];
+ private $cache = [];
- public function offsetSet($offset, $value) {
- if (is_null($offset)) {
- $this->container[] = $value;
- } else {
- $this->container[$offset] = $value;
+ /**
+ * @return Settings
+ */
+ public static function getInstance()
+ {
+ 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->settings = 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->settings[$setting['plugin_name']][$setting['key']] = $setting['value'];
+ }
+ }
+
+ if ($cache->enabled()) {
+ $cache->set('settings', serialize($this->settings), 600);
+ }
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ throw new \RuntimeException("Settings: You cannot set empty offset with value: $value!");
+ }
+
+ $pluginName = $offset;
+ if (strpos($offset, '.')) {
+ $explode = explode('.', $offset, 2);
+
+ $pluginName = $explode[0];
+ $key = $explode[1];
+ }
+
+ $this->loadPlugin($pluginName);
+
+ // remove whole plugin settings
+ if (!isset($key)) {
+ $this->plugins[$pluginName] = [];
+
+ // remove from settings
+ if (isset($this->settings[$pluginName])) {
+ unset($this->settings[$pluginName]);
+ }
+
+ // remove from cache
+ if (isset($this->cache[$pluginName])) {
+ unset($this->cache[$pluginName]);
+ }
+ /*foreach ($this->cache as $_key => $value) {
+ if (strpos($_key, $pluginName) !== false) {
+ unset($this->cache[$_key]);
+ }
+ }*/
+ }
+
+ $this->settings[$pluginName][$key] = $value['value'];
}
public function offsetExists($offset) {
- return isset($this->container[$offset]);
+ return isset($this->settings[$offset]);
}
public function offsetUnset($offset) {
- unset($this->container[$offset]);
+ unset($this->settings[$offset]);
}
+ /**
+ * Get settings
+ * Usage: $setting['plugin_name.key']
+ * Example: $settings['shop_system.paypal_email']
+ *
+ * @param mixed $offset
+ * @return array|mixed
+ */
public function offsetGet($offset)
{
- if (!isset($this->container[$offset])) {
- $file = PLUGINS . $offset . '/settings.php';
- if(!file_exists($file)) {
- throw new \RuntimeException('Failed to load settings file for plugin: ' . $offset);
- }
-
- $this->container[$offset] = require $file;
+ // try cache hit
+ if(isset($this->cache[$offset])) {
+ return $this->cache[$offset];
}
- return $this->container[$offset];
+ $pluginName = $offset;
+ if (strpos($offset, '.')) {
+ $explode = explode('.', $offset, 2);
+
+ $pluginName = $explode[0];
+ $key = $explode[1];
+ }
+
+ $this->loadPlugin($pluginName);
+
+ // return specified plugin settings (all)
+ if(!isset($key)) {
+ return $this->plugins[$pluginName];
+ }
+
+ $ret = [];
+ if(isset($this->plugins[$pluginName][$key])) {
+ $ret = $this->plugins[$pluginName][$key];
+ }
+
+ if(isset($this->settings[$pluginName][$key])) {
+ $value = $this->settings[$pluginName][$key];
+
+ $ret['value'] = $value;
+ }
+ else {
+ $ret['value'] = $this->plugins[$pluginName][$key]['default'];
+ }
+
+ if(isset($ret['type'])) {
+ switch($ret['type']) {
+ case 'boolean':
+ $ret['value'] = $ret['value'] === 'true';
+ break;
+
+ case 'number':
+ $ret['value'] = (int)$ret['value'];
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ $this->cache[$offset] = $ret;
+ return $ret;
+ }
+
+ private function loadPlugin($pluginName)
+ {
+ if (!isset($this->plugins[$pluginName])) {
+ if ($pluginName === 'core') {
+ $file = SYSTEM . 'settings.php';
+ } else {
+ $file = PLUGINS . $pluginName . '/settings.php';
+ }
+
+ if (!file_exists($file)) {
+ throw new \RuntimeException('Failed to load settings file for plugin: ' . $pluginName);
+ }
+
+ $this->plugins[$pluginName] = require $file;
+ }
}
}
\ No newline at end of file
diff --git a/system/libs/plugins.php b/system/libs/plugins.php
index 410f1639..77af4259 100644
--- a/system/libs/plugins.php
+++ b/system/libs/plugins.php
@@ -44,6 +44,32 @@ class Plugins {
private static $warnings = array();
private static $error = null;
private static $plugin_json = array();
+ private static $plugins = [];
+
+ public static function load()
+ {
+ $cache = Cache::getInstance();
+ if ($cache->enabled()) {
+ $tmp = '';
+ if ($cache->fetch('plugins', $tmp)) {
+ self::$plugins = unserialize($tmp);
+ return;
+ }
+ }
+
+ foreach (get_plugins() as $filename) {
+ $plugin_json = self::getPluginJson($filename);
+ if (!$plugin_json) {
+ continue;
+ }
+
+ self::$plugins[$filename] = $plugin_json;
+ }
+
+ if ($cache->enabled()) {
+ $cache->set('hooks', serialize(self::$plugins), 600);
+ }
+ }
public static function getHooks()
{
@@ -56,12 +82,7 @@ class Plugins {
}
$hooks = [];
- foreach (get_plugins() as $filename) {
- $plugin_json = self::getPluginJson($filename);
- if (!$plugin_json) {
- continue;
- }
-
+ foreach (self::$plugins as $filename => $plugin_json) {
if (isset($plugin_json['hooks'])) {
foreach ($plugin_json['hooks'] as $_name => $info) {
if (defined('HOOK_'. $info['type'])) {
@@ -81,18 +102,18 @@ class Plugins {
return $hooks;
}
- public static function getPluginOptions($pluginName)
+ public static function getPluginSettings($pluginName)
{
$plugin_json = self::getPluginJson($pluginName);
if (!$plugin_json) {
return false;
}
- if (!isset($plugin_json['options']) || !file_exists(BASE . $plugin_json['options'])) {
+ if (!isset($plugin_json['settings']) || !file_exists(BASE . $plugin_json['settings'])) {
return false;
}
- return $plugin_json['options'];
+ return $plugin_json['settings'];
}
public static function getPluginJson($name = null)
diff --git a/system/pages/admin/config.php b/system/pages/admin/config.php
deleted file mode 100644
index 8fabdd8b..00000000
--- a/system/pages/admin/config.php
+++ /dev/null
@@ -1,309 +0,0 @@
-
- * @copyright 2019 MyAAC
- * @link https://my-aac.org
- */
-defined('MYAAC') or die('Direct access not allowed!');
-$title = 'Config Editor';
-
-require_once SYSTEM . 'clients.conf.php';
-
-$message = '';
-$config_options = array(
- 'server_path' => array(
- 'name' => 'Server Path',
- 'type' => 'text',
- 'desc' => 'path to the server directory (same directory where config file is located)'
- ),
- 'env' => array(
- 'name' => 'Environment',
- 'type' => 'options',
- 'options' => array('prod' => 'Production', 'dev' => 'Development'),
- 'desc' => 'if you use this script on your live server - set to 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 !!!
-Recommended: Production cause of speed (page load time is better)'
- ),
- 'template' => array(
- 'name' => 'Template Name',
- 'type' => 'options',
- 'options' => '$templates',
- 'desc' => 'Name of the template used by website'
- ),
- 'template_allow_change' => array(
- 'name' => 'Template Allow Change',
- 'type' => 'boolean',
- 'desc' => 'Allow changing template of the website by showing a special select in the part of website'
- ),
- 'vocations_amount' => array(
- 'name' => 'Amount of Vocations',
- 'type' => 'number',
- 'desc' => 'how much basic vocations your server got (without promotion)'
- ),
- 'client' => array(
- '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'
- ),
- 'session_prefix' => array(
- 'name' => 'Session Prefix',
- 'type' => 'text',
- 'desc' => 'must be unique for every site on your server',
- ),
- 'friendly_urls' => array(
- 'name' => 'Friendly URLs',
- 'type' => 'boolean',
- 'desc' => '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' => array(
- 'name' => 'GZIP Output',
- 'type' => 'boolean',
- 'desc' => 'gzip page content before sending it to the browser, uses less bandwidth but more cpu cycles'
- ),
- 'backward_support' => array(
- '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'
- ),
- 'meta_description' => array(
- 'name' => 'Meta Description',
- 'type' => 'textarea',
- 'desc' => 'description of the site in '
- ),
- 'meta_keywords' => array(
- 'name' => 'Meta Keywords',
- 'type' => 'textarea',
- 'desc' => 'keywords list separated by commas'
- ),
- 'title_separator' => array(
- 'name' => 'Title Separator',
- 'type' => 'text',
- 'desc' => 'Separator used in the title of the website'
- ),
- 'footer' => array(
- 'name' => 'Footer',
- 'type' => 'textarea',
- 'desc' => 'For example: "
Your Server © 2016. All rights reserved."'
- ),
- 'language' => array(
- 'name' => 'Language',
- 'type' => 'options',
- 'options' => array('en' => 'English'),
- 'desc' => 'default language (currently only English available)'
- ),
- 'visitors_counter' => array(
- 'name' => 'Visitors Counter',
- 'type' => 'boolean',
- 'desc' => 'Enable Visitors Counter? It will show list of online members on the website in Admin Panel'
- ),
- 'visitors_counter_ttl' => array(
- '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'
- ),
- 'views_counter' => array(
- 'name' => 'Views Counter',
- 'type' => 'boolean',
- 'desc' => 'Enable Views Counter? It will show how many times the website has been viewed by users'
- ),
- 'cache_engine' => array(
- 'name' => 'Cache Engine',
- 'type' => 'text',
- 'desc' => 'cache system. by default file cache is used.
-Other available options: apc, apcu, eaccelerator, xcache, file, auto, or blank to disable'
- ),
- 'cache_prefix' => array(
- 'name' => 'Cache Prefix',
- 'type' => 'text',
- 'desc' => 'have to be unique if running more MyAAC instances on the same server (except file system cache)'
- ),
- 'database_log' => array(
- 'name' => 'Database Log',
- 'type' => 'boolean',
- 'desc' => 'Should database queries be logged and displayed in the page source? They will be included at the end of the .html source of the page, only for Super Admin'
- ),
- 'database_socket' => array(
- 'name' => 'Database Socket',
- 'type' => 'text',
- 'desc' => 'Set if you want to connect to database through socket (example: /var/run/mysqld/mysqld.sock)'
- ),
- 'database_persistent' => array(
- 'name' => 'Database Persistent',
- 'type' => 'boolean',
- 'desc' => 'Use database permanent connection (like server), may speed up your site'
- ),
- 'outfit_images_url' => array(
- 'name' => 'Outfit Images URL',
- 'type' => 'text',
- 'desc' => 'Set to animoutfit.php for animated outfit'
- ),
- 'item_images_url' => array(
- 'name' => 'Item Images URL',
- 'type' => 'text',
- 'desc' => 'Set to images/items if you host your own items in images folder'
- ),
-);
-
-if (isset($_POST['save'])) {
- $content = ' $_config) {
- $content .= PHP_EOL . "\$config['$key'] = ";
- if (in_array($_config['type'], array('boolean', 'number'))) {
- $content .= $_POST[$key];
- }
-
- else if (in_array($_config['type'], array('text', 'textarea'))) {
- $content .= "'" . $_POST[$key] . "'";
- }
-
- else if($_config['type'] === 'options') {
- if(is_numeric($_POST[$key])) {
- $content .= $_POST[$key];
- }
- else {
- $content .= "'" . $_POST[$key] . "'";
- }
- }
-
- $content .= ';';
- }
-
- //$saved = file_put_contents(BASE . 'config.local.php', $content);
- $saved = false;
- ob_start();
- if($saved) {
- ?>
-
- Config has been successfully saved.
-
-
-
- = BASE ?>config.local.php couldn't be opened. Please copy this content and paste there:
-
-
-
-
-
-
\ No newline at end of file
diff --git a/system/pages/admin/settings.php b/system/pages/admin/settings.php
index d6d8ac69..c370c90a 100644
--- a/system/pages/admin/settings.php
+++ b/system/pages/admin/settings.php
@@ -8,71 +8,76 @@
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
-$title = 'Options';
+$title = 'Settings';
-$plugin = $_GET['plugin'];
-if (!isset($plugin) || empty($plugin)) {
+require_once SYSTEM . 'clients.conf.php';
+if (!isset($_GET['plugin']) || empty($_GET['plugin'])) {
error('Please select plugin name from left Panel.');
return;
}
-$pluginOptions = Plugins::getPluginOptions($plugin);
-if (!$pluginOptions) {
- error('This plugin does not exist or does not have options defined.');
- return;
-}
+$plugin = $_GET['plugin'];
-$message = '';
-$optionsFile = require BASE . $pluginOptions;
-if (!is_array($optionsFile)) {
- return;
-}
-
-$name = $optionsFile['name'];
-$options = $optionsFile['options'];
-
-if (isset($_POST['save'])) {
- foreach ($options as $key => $_config) {
- // TODO:
- // Save functionality
- // Check if exist, then INSERT or UPDATE
-
- /*$query = $db->query(
- sprintf('SELECT `value` FROM `%s` WHERE `name` = %s AND `key` = %s',
- TABLE_PREFIX . 'options_' . $table,
- $name,
- $key)
- );*/
+if($plugin != 'core') {
+ $pluginSettings = Plugins::getPluginSettings($plugin);
+ if (!$pluginSettings) {
+ error('This plugin does not exist or does not have options defined.');
+ return;
}
}
-$optionsValues = [];
-$optionsTypes = ['bool', 'double', 'int', 'text', 'varchar'];
-foreach($optionsTypes as $type) {
- $query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'options_' . $type . '` WHERE `name` = ' . $db->quote($name) . ';';
- $query = $db->query($query);
-
- $optionsValues = $optionsValues + $query->fetchAll();
+if($plugin === 'core') {
+ $settingsFile = require SYSTEM . 'settings.php';
+}
+else {
+ $settingsFile = require BASE . $pluginSettings;
+}
+
+if (!is_array($settingsFile)) {
+ return;
+}
+
+if (isset($_POST['save'])) {
+ $db->query('DELETE FROM `' . TABLE_PREFIX . 'settings` WHERE `plugin_name` = ' . $db->quote($plugin) . ';');
+ foreach ($_POST['settings'] as $key => $value) {
+ try {
+ $db->insert(TABLE_PREFIX . 'settings', ['plugin_name' => $plugin, 'key' => $key, 'value' => $value]);
+ } catch (PDOException $error) {
+ warning('Error while saving setting (' . $plugin . ' - ' . $key . '): ' . $error->getMessage());
+ }
+ }
+
+ $cache = Cache::getInstance();
+ if ($cache->enabled()) {
+ $cache->delete('settings');
+ }
+ success('Saved at ' . date('H:i'));
+}
+
+$title = ($plugin == 'core' ? 'MyAAC Settings' : 'Plugin Settings - ' . $plugin);
+
+$query = 'SELECT `key`, `value` FROM `' . TABLE_PREFIX . 'settings` WHERE `plugin_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'];
+ }
}
-//var_dump($optionsValues);
?>