From 4320fb796ae2ac0eca652dd2e2056070f9aba3f1 Mon Sep 17 00:00:00 2001 From: Luca Libralato Date: Mon, 5 Sep 2011 19:18:37 +0200 Subject: [PATCH] Fixed a bug in Mobile Style and added a switch. Improved some plugins functions. Ported UMIL to Icy Phoenix to be able to easily deal with permissions and modules. --- adm/admin_plugins.php | 13 + includes/class_auth_admin.php | 11 +- includes/class_plugins.php | 38 + includes/class_umil.php | 2392 +++++++++++++++++ includes/constants.php | 2 +- includes/db/db_tools.php | 1359 +--------- includes/functions.php | 74 +- includes/sessions.php | 1 + includes/settings/settings_seo.php | 10 + install/schemas/db_update_054.sql | 27 +- install/schemas/mysql_basic.sql | 20 +- install/schemas/sql_update_ip.php | 23 +- install/schemas/versions.php | 2 +- .../lang_english/lang_extend_icy_phoenix.php | 3 + language/lang_english/lang_main.php | 3 + language/lang_english/lang_umil.php | 127 + templates/common/common_colors.css | 2 +- templates/default/default.cfg | 1 + templates/default/login_body.tpl | 41 +- templates/mobile/overall_footer.tpl | 8 +- 20 files changed, 2858 insertions(+), 1299 deletions(-) create mode 100644 includes/class_umil.php create mode 100644 language/lang_english/lang_umil.php diff --git a/adm/admin_plugins.php b/adm/admin_plugins.php index c4ae8f86..4489e2fb 100644 --- a/adm/admin_plugins.php +++ b/adm/admin_plugins.php @@ -23,6 +23,19 @@ define('THIS_PAGE', 'admin_plugins.' . PHP_EXT); +// NEW AUTH - BEGIN +// To be removed when auth integration has been completed! +if (!class_exists('auth')) +{ + @include(IP_ROOT_PATH . 'includes/class_auth.' . PHP_EXT); +} +if (empty($auth)) +{ + $auth = new auth(); + $auth->acl($user->data); +} +// NEW AUTH - END + // FORM CLASS - BEGIN include(IP_ROOT_PATH . 'includes/class_form.' . PHP_EXT); $class_form = new class_form(); diff --git a/includes/class_auth_admin.php b/includes/class_auth_admin.php index 13773bbd..7fc20cb7 100644 --- a/includes/class_auth_admin.php +++ b/includes/class_auth_admin.php @@ -144,7 +144,6 @@ function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth2 = &$auth; } - $hold_ary[$userdata['user_id']] = array(); foreach ($forum_ids as $f_id) { @@ -266,7 +265,7 @@ function get_role_mask($role_id) */ function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true) { - global $template, $user, $db; + global $db, $template, $user, $lang; // Define names for template loops, might be able to be set $tpl_pmask = 'p_mask'; @@ -458,7 +457,8 @@ function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', 'S_VIEW' => ($mode == 'view') ? true : false, 'S_NUM_OBJECTS' => sizeof($content_array), 'S_USER_MODE' => ($user_mode == 'user') ? true : false, - 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) + 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false + ) ); @reset($content_array); @@ -544,7 +544,8 @@ function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', 'S_VIEW' => ($mode == 'view') ? true : false, 'S_NUM_OBJECTS' => sizeof($content_array), 'S_USER_MODE' => ($user_mode == 'user') ? true : false, - 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) + 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false + ) ); @reset($content_array); @@ -610,7 +611,7 @@ function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', */ function display_role_mask(&$hold_ary) { - global $db, $template, $user, $phpbb_admin_path; + global $db, $template, $user, $lang, $phpbb_admin_path; if (!sizeof($hold_ary)) { diff --git a/includes/class_plugins.php b/includes/class_plugins.php index 9a420253..df8b5658 100644 --- a/includes/class_plugins.php +++ b/includes/class_plugins.php @@ -47,6 +47,13 @@ function install($plugin_data, $clear_cache = true) { global $db, $config, $table_prefix; + // Include install functions file... if any! + $plugin_functions_install_file = $this->plugins_path . $plugin_data['dir'] . '/includes/functions_install.' . PHP_EXT; + if (file_exists($plugin_functions_install_file)) + { + @include($plugin_functions_install_file); + } + $sql_results = array(); $plugin_info = $this->get_plugin_info($plugin_data['dir']); $plugin_install_data = $this->get_plugin_install_data($plugin_data['dir']); @@ -113,6 +120,13 @@ function update($plugin_data, $clear_cache = true) { global $db, $config, $table_prefix; + // Include install functions file... if any! + $plugin_functions_install_file = $this->plugins_path . $plugin_data['dir'] . '/includes/functions_install.' . PHP_EXT; + if (file_exists($plugin_functions_install_file)) + { + @include($plugin_functions_install_file); + } + $sql_results = array(); $plugin_info = $this->get_plugin_info($plugin_data['dir']); $plugin_install_data = $this->get_plugin_install_data($plugin_data['dir']); @@ -173,6 +187,13 @@ function uninstall($plugin_data, $clear_cache = true) { global $db, $config, $table_prefix; + // Include install functions file... if any! + $plugin_functions_install_file = $this->plugins_path . $plugin_data['dir'] . '/includes/functions_install.' . PHP_EXT; + if (file_exists($plugin_functions_install_file)) + { + @include($plugin_functions_install_file); + } + $sql_results = array(); $plugin_info = $this->get_plugin_info($plugin_data['dir']); $plugin_uninstall_data = $this->get_plugin_uninstall_data($plugin_data['dir']); @@ -237,6 +258,23 @@ function get_plugin_info($plugin_dir) return $plugin_info; } + /* + * Get plugin auth data + */ + function get_plugin_auth_data($plugin_dir) + { + global $config, $table_prefix; + + $auth_data = array(); + $plugin_install_file = $this->plugins_path . $plugin_dir . '/install/install.' . PHP_EXT; + if (file_exists($plugin_install_file)) + { + @include($plugin_install_file); + } + + return $auth_data; + } + /* * Get plugin install data */ diff --git a/includes/class_umil.php b/includes/class_umil.php new file mode 100644 index 00000000..1ec92aaa --- /dev/null +++ b/includes/class_umil.php @@ -0,0 +1,2392 @@ +config_add(array( +* array('config_name', 'config_value'), +* array('config_name1', 'config_value1'), +* array('config_name2', 'config_value2', true), +* array('config_name3', 'config_value3', true), +* ); +*/ + +/** +* UMIL - Unified MOD Installation Library class +* +* Cache Functions +* cache_purge($type = '', $style_id = 0) +* +* Config Functions: +* config_exists($config_name, $return_result = false) +* config_add($config_name, $config_value = '', $is_dynamic = false) +* config_update($config_name, $config_value, $is_dynamic = false) +* config_remove($config_name) +* +* Module Functions +* module_exists($class, $parent, $module) +* module_add($class, $parent = 0, $data = array()) +* module_remove($class, $parent = 0, $module = '') +* +* Permissions/Auth Functions +* permission_exists($auth_option, $global = true) +* permission_add($auth_option, $global = true) +* permission_remove($auth_option, $global = true) +* permission_set($name, $auth_option = array(), $type = 'role', $global = true, $has_permission = true) +* permission_unset($name, $auth_option = array(), $type = 'role', $global = true) +* +* Table Functions +* table_exists($table_name) +* table_add($table_name, $table_data = array()) +* table_remove($table_name) +* +* Table Column Functions +* table_column_exists($table_name, $column_name) +* table_column_add($table_name, $column_name = '', $column_data = array()) +* table_column_update($table_name, $column_name = '', $column_data = array()) +* table_column_remove($table_name, $column_name = '') +* +* Table Key/Index Functions +* table_index_exists($table_name, $index_name) +* table_index_add($table_name, $index_name = '', $column = array()) +* table_index_remove($table_name, $index_name = '') +* +* Table Row Functions (note that these actions are not reversed automatically during uninstallation) +* table_row_insert($table_name, $data = array()) +* table_row_remove($table_name, $data = array()) +* table_row_update($table_name, $data = array(), $new_data = array()) +* +* Version Check Function +* version_check($url, $path, $file) +*/ +class umil +{ + /** + * This will hold the text output for the inputted command (if the mod author would like to display the command that was ran) + * + * @var string + */ + var $command = ''; + + /** + * This will hold the text output for the result of the command. $lang['SUCCESS'] if everything worked. + * + * @var string + */ + var $result = ''; + + /** + * Auto run $this->display_results after running a command + */ + var $auto_display_results = false; + + /** + * Stand Alone option (this makes it possible to just use the single umil file and not worry about any language stuff + */ + var $stand_alone = false; + + /** + * Were any new permissions added (used in umil_frontend)? + */ + var $permissions_added = false; + + /** + * Database Object + */ + var $db = false; + + /** + * Database Tools Object + */ + var $db_tools = false; + + /** + * Do we want a custom prefix besides the phpBB table prefix? You *probably* should not change this... + */ + var $table_prefix = false; + + /** + * Constructor + */ + function umil($stand_alone = false, $db = false) + { + // Setup $this->db + if ($db !== false) + { + if (!is_object($db) || !method_exists($db, 'sql_query')) + { + trigger_error('Invalid $db Object'); + } + + $this->db = $db; + } + else + { + global $db; + $this->db = $db; + } + + // Setup $this->db_tools + if (!class_exists('phpbb_db_tools')) + { + include(IP_ROOT_PATH . 'includes/db/db_tools.' . PHP_EXT); + } + $this->db_tools = new phpbb_db_tools($this->db); + + $this->stand_alone = $stand_alone; + + if (!$stand_alone) + { + global $config, $user; + setup_extra_lang(array('lang_umil', 'lang_admin')); + } + } + + /** + * umil_start + * + * A function which runs (almost) every time a function here is ran + */ + function umil_start() + { + global $user; + + // Set up the command. This will get the arguments sent to the function. + $args = func_get_args(); + $this->command = call_user_func_array(array($this, 'get_output_text'), $args); + + $this->result = (isset($lang['SUCCESS'])) ? $lang['SUCCESS'] : 'SUCCESS'; + $this->db->sql_return_on_error(true); + + //$this->db->sql_transaction('begin'); + } + + /** + * umil_end + * + * A function which runs (almost) every time a function here is ran + */ + function umil_end() + { + global $user, $lang; + + // Set up the result. This will get the arguments sent to the function. + $args = func_get_args(); + $result = call_user_func_array(array($this, 'get_output_text'), $args); + $this->result = ($result) ? $result : $this->result; + + if ($this->db->sql_error_triggered) + { + if ($this->result == ((isset($lang['SUCCESS'])) ? $lang['SUCCESS'] : 'SUCCESS')) + { + $this->result = 'SQL ERROR ' . $this->db->sql_error_returned['message']; + } + else + { + $this->result .= '

SQL ERROR ' . $this->db->sql_error_returned['message']; + } + + //$this->db->sql_transaction('rollback'); + } + else + { + //$this->db->sql_transaction('commit'); + } + + $this->db->sql_return_on_error(false); + + // Auto output if requested. + if ($this->auto_display_results && method_exists($this, 'display_results')) + { + $this->display_results(); + } + + return '' . $this->command . '
' . $this->result; + } + + /** + * Get text for output + * + * Takes the given arguments and prepares them for the UI + * + * First argument sent is used as the language key + * Further arguments (if send) are used on the language key through vsprintf() + * + * @return string Returns the prepared string for output + */ + function get_output_text() + { + global $user, $lang; + + // Set up the command. This will get the arguments sent to the function. + $args = func_get_args(); + if (sizeof($args)) + { + $lang_key = array_shift($args); + + if (sizeof($args)) + { + $lang_args = array(); + foreach ($args as $arg) + { + $lang_args[] = (isset($lang[$arg])) ? $lang[$arg] : $arg; + } + + return @vsprintf(((isset($lang[$lang_key])) ? $lang[$lang_key] : $lang_key), $lang_args); + } + else + { + return ((isset($lang[$lang_key])) ? $lang[$lang_key] : $lang_key); + } + } + + return ''; + } + + /** + * Run Actions + * + * Do-It-All function that can do everything required for installing/updating/uninstalling a mod based on an array of actions and the versions. + * + * @param string $action The action. install|update|uninstall + * @param array $versions The array of versions and the actions for each + * @param string $version_config_name The name of the config setting which holds/will hold the currently installed version + * @param string $version_select Added for the UMIL Auto system to allow you to select the version you want to install/update/uninstall to. + */ + function run_actions($action, $versions, $version_config_name, $version_select = '') + { + // We will sort the actions to prevent issues from mod authors incorrectly listing the version numbers + uksort($versions, 'version_compare'); + + // Find the current version to install + $current_version = '0.0.0'; + foreach ($versions as $version => $actions) + { + $current_version = $version; + } + + $db_version = ''; + if ($this->config_exists($version_config_name)) + { + global $config; + $db_version = $config[$version_config_name]; + } + + // Set the action to install from update if nothing is currently installed + if (($action == 'update') && !$db_version) + { + $action = 'install'; + } + + if (($action == 'install') || ($action == 'update')) + { + $version_installed = $db_version; + foreach ($versions as $version => $version_actions) + { + // If we are updating + if ($db_version && version_compare($version, $db_version, '<=')) + { + continue; + } + + if ($version_select && version_compare($version, $version_select, '>')) + { + break; + } + + foreach ($version_actions as $method => $params) + { + if ($method == 'custom') + { + $this->_call_custom_function($params, $action, $version); + } + else + { + if (method_exists($this, $method)) + { + call_user_func(array($this, $method), $params); + } + } + } + + $version_installed = $version; + } + + // update the version number or add it + if ($this->config_exists($version_config_name)) + { + $this->config_update($version_config_name, $version_installed); + } + else + { + $this->config_add($version_config_name, $version_installed); + } + } + elseif ($action == 'uninstall' && $db_version) + { + // reverse version list + $versions = array_reverse($versions); + + foreach ($versions as $version => $version_actions) + { + // Uninstalling and this listed version is newer than installed + if (version_compare($version, $db_version, '>')) + { + continue; + } + + // Version selection stuff + if ($version_select && version_compare($version, $version_select, '<=')) + { + // update the version number + $this->config_update($version_config_name, $version); + break; + } + + $cache_purge = false; + $version_actions = array_reverse($version_actions); + foreach ($version_actions as $method => $params) + { + if ($method == 'custom') + { + $this->_call_custom_function($params, $action, $version); + } + else + { + // This way we always run the cache purge at the end of the version (done for the uninstall because the instructions are reversed, which would cause the cache purge to be run at the beginning if it was meant to run at the end). + if ($method == 'cache_purge') + { + $cache_purge = $params; + continue; + } + + // A few things are not possible for uninstallations update actions and table_row actions + if (strpos($method, 'update') !== false || strpos($method, 'table_insert') !== false || strpos($method, 'table_row_') !== false) + { + continue; + } + + // reverse function call + $method = str_replace(array('add', 'remove', 'temp'), array('temp', 'add', 'remove'), $method); + $method = str_replace(array('set', 'unset', 'temp'), array('temp', 'set', 'unset'), $method); + + if (method_exists($this, $method)) + { + call_user_func(array($this, $method), ((is_array($params) ? array_reverse($params) : $params))); + } + } + } + + if ($cache_purge !== false) + { + $this->cache_purge($cache_purge); + } + } + + if (!$version_select) + { + // Unset the version number + $this->config_remove($version_config_name); + } + } + } + + /** + * Call custom function helper + */ + function _call_custom_function($functions, $action, $version) + { + if (!is_array($functions)) + { + $functions = array($functions); + } + + $return = ''; + + foreach ($functions as $function) + { + if (function_exists($function)) + { + // Must reset before calling the function + $this->umil_start(); + + $returned = call_user_func($function, $action, $version); + if (is_string($returned)) + { + $this->command = $this->get_output_text($returned); + } + elseif (is_array($returned) && isset($returned['command'])) + { + if (is_array($returned['command'])) + { + $this->command = call_user_func_array(array($this, 'get_output_text'), $returned['command']); + } + else + { + $this->command = $this->get_output_text($returned['command']); + } + + if (isset($returned['result'])) + { + $this->result = $this->get_output_text($returned['result']); + } + } + else + { + $this->command = $this->get_output_text('UNKNOWN'); + } + + $return .= $this->umil_end() . '
'; + } + } + + return $return; + } + + /** + * Multicall Helper + * + * @param mixed $function Function name to call + * @param mixed $params The parameters array + * + * @return bool True if we have done a multicall ($params is an array), false if not ($params is not an array) + */ + function multicall($function, $params) + { + if (is_array($params) && !empty($params)) + { + foreach ($params as $param) + { + if (!is_array($param)) + { + call_user_func(array($this, $function), $param); + } + else + { + call_user_func_array(array($this, $function), $param); + } + } + return true; + } + + return false; + } + + /** + * Cache Purge + * + * This function is for purging either phpBB3's data cache, authorization cache, or the styles cache. + * + * @param string $type The type of cache you want purged. Available types: auth, imageset, template, theme. Anything else sent will purge the forum's cache. + * @param int $style_id The id of the item you want purged (if the type selected is imageset/template/theme, 0 for all items in that section) + */ + function cache_purge($type = '', $style_id = 0) + { + global $auth, $cache, $user, $lang; + + // Multicall + if ($this->multicall(__FUNCTION__, $type)) + { + return; + } + + $style_id = (int) $style_id; + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'auth': + $this->umil_start('AUTH_CACHE_PURGE'); + $cache->destroy('_acl_options'); + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + break; + + case 'imageset': + case 'template': + case 'theme': + break; + + default: + $this->umil_start('CACHE_PURGE'); + $cache->purge(); + + return $this->umil_end(); + break; + } + } + + /** + * Config Exists + * + * This function is to check to see if a config variable exists or if it does not. + * + * @param string $config_name The name of the config setting you wish to check for. + * @param bool $return_result - return the config value/default if true : default false. + * + * @return bool true/false if config exists + */ + function config_exists($config_name, $return_result = false) + { + global $config, $cache; + + $sql = 'SELECT * + FROM ' . CONFIG_TABLE . " + WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + if (!isset($config[$config_name])) + { + $config[$config_name] = $row['config_value']; + $cache->destroy('config'); + } + + return ($return_result) ? $row : true; + } + + // this should never happen, but if it does, we need to remove the config from the array + if (isset($config[$config_name])) + { + unset($config[$config_name]); + $cache->destroy('config'); + } + + return false; + } + + /** + * Config Add + * + * This function allows you to add a config setting. + * + * @param string $config_name The name of the config setting you would like to add + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_add($config_name, $config_value = '', $clear_cache = true) + { + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_ADD', $config_name); + + if ($this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_ALREADY_EXISTS', $config_name); + } + + set_config($config_name, $config_value, $clear_cache); + + return $this->umil_end(); + } + + /** + * Config Update + * + * This function allows you to update an existing config setting. + * + * @param string $config_name The name of the config setting you would like to update + * @param mixed $config_value The value of the config setting + * @param bool $is_dynamic True if it is dynamic (changes very often) and should not be stored in the cache, false if not. + * + * @return result + */ + function config_update($config_name, $config_value = '', $clear_cache = true) + { + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_UPDATE', $config_name); + + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + set_config($config_name, $config_value, $clear_cache); + + return $this->umil_end(); + } + + /** + * Config Remove + * + * This function allows you to remove an existing config setting. + * + * @param string $config_name The name of the config setting you would like to remove + * + * @return result + */ + function config_remove($config_name) + { + global $cache, $config; + + // Multicall + if ($this->multicall(__FUNCTION__, $config_name)) + { + return; + } + + $this->umil_start('CONFIG_REMOVE', $config_name); + + if (!$this->config_exists($config_name)) + { + return $this->umil_end('CONFIG_NOT_EXIST', $config_name); + } + + $sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = '" . $this->db->sql_escape($config_name) . "'"; + $this->db->sql_query($sql); + + unset($config[$config_name]); + $cache->destroy('config'); + + return $this->umil_end(); + } + + /** + * Module Exists + * + * Check if a module exists + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. + * @param int|string $module The module_id|module_langname you would like to check for to see if it exists + */ + function module_exists($class, $parent, $module) + { + // the main root directory should return true + if (!$module) + { + return true; + } + + $class = $this->db->sql_escape($class); + $module = $this->db->sql_escape($module); + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + return false; + } + + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_class = '$class' + $parent_sql + AND " . ((is_numeric($module)) ? 'module_id = ' . (int) $module : "module_langname = '$module'"); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Module Add + * + * Add a new module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string $parent The parent module_id|module_langname (0 for no parent) + * @param array $data an array of the data on the new module. This can be setup in two different ways. + * 1. The "manual" way. For inserting a category or one at a time. It will be merged with the base array shown a bit below, + * but at the least requires 'module_langname' to be sent, and, if you want to create a module (instead of just a category) you must send module_basename and module_mode. + * array( + * 'module_enabled' => 1, + * 'module_display' => 1, + * 'module_basename' => '', + * 'module_class' => $class, + * 'parent_id' => (int) $parent, + * 'module_langname' => '', + * 'module_mode' => '', + * 'module_auth' => '', + * ) + * 2. The "automatic" way. For inserting multiple at a time based on the specs in the info file for the module(s). For this to work the modules must be correctly setup in the info file. + * An example follows (this would insert the settings, log, and flag modes from the includes/acp/info/acp_asacp.php file): + * array( + * 'module_basename' => 'asacp', + * 'modes' => array('settings', 'log', 'flag'), + * ) + * Optionally you may not send 'modes' and it will insert all of the modules in that info file. + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + function module_add($class, $parent = 0, $data = array(), $include_path = false) + { + global $cache, $user, $lang; + + // Multicall + if ($this->multicall(__FUNCTION__, $class)) + { + return; + } + + // Prevent stupid things like trying to add a module with no name or any data on it + if (empty($data)) + { + $this->umil_start('MODULE_ADD', $class, 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + // allow sending the name as a string in $data to create a category + if (!is_array($data)) + { + $data = array('module_langname' => $data); + } + + if (!isset($data['module_langname'])) + { + // The "automatic" way + $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; + $basename = str_replace(array('/', '\\'), '', $basename); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename." . PHP_EXT; + + // The manual and automatic ways both failed... + if (!file_exists((($include_path === false) ? (IP_ROOT_PATH . 'includes/') : $include_path) . $info_file)) + { + $this->umil_start('MODULE_ADD', $class, $info_file); + return $this->umil_end('FAIL'); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? (IP_ROOT_PATH . 'includes/') : $include_path) . $info_file); + } + + $info = new $classname; + $module = $info->module(); + unset($info); + + $result = ''; + foreach ($module['modes'] as $mode => $module_info) + { + if (!isset($data['modes']) || in_array($mode, $data['modes'])) + { + $new_module = array( + 'module_basename' => $basename, + 'module_langname' => $module_info['title'], + 'module_mode' => $mode, + 'module_auth' => $module_info['auth'], + 'module_display' => (isset($module_info['display'])) ? $module_info['display'] : true, + 'before' => (isset($module_info['before'])) ? $module_info['before'] : false, + 'after' => (isset($module_info['after'])) ? $module_info['after'] : false, + ); + + // Run the "manual" way with the data we've collected. + $result .= ((isset($data['spacer'])) ? $data['spacer'] : '
') . $this->module_add($class, $parent, $new_module); + } + } + + return $result; + } + + // The "manual" way + $this->umil_start('MODULE_ADD', $class, ((isset($lang[$data['module_langname']])) ? $lang[$data['module_langname']] : $data['module_langname'])); + add_log('admin', 'LOG_MODULE_ADD', ((isset($lang[$data['module_langname']])) ? $lang[$data['module_langname']] : $data['module_langname'])); + + $class = $this->db->sql_escape($class); + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + return $this->umil_end('PARENT_NOT_EXIST'); + } + + $parent = $data['parent_id'] = $row['module_id']; + } + elseif (!$this->module_exists($class, false, $parent)) + { + return $this->umil_end('PARENT_NOT_EXIST'); + } + + if ($this->module_exists($class, $parent, $data['module_langname'])) + { + return $this->umil_end('MODULE_ALREADY_EXIST'); + } + + if (!class_exists('acp_modules')) + { + include(IP_ROOT_PATH . 'includes/acp/acp_modules.' . PHP_EXT); + $user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + + $module_data = array( + 'module_enabled' => (isset($data['module_enabled'])) ? $data['module_enabled'] : 1, + 'module_display' => (isset($data['module_display'])) ? $data['module_display'] : 1, + 'module_basename' => (isset($data['module_basename'])) ? $data['module_basename'] : '', + 'module_class' => $class, + 'parent_id' => (int) $parent, + 'module_langname' => (isset($data['module_langname'])) ? $data['module_langname'] : '', + 'module_mode' => (isset($data['module_mode'])) ? $data['module_mode'] : '', + 'module_auth' => (isset($data['module_auth'])) ? $data['module_auth'] : '', + ); + $result = $acp_modules->update_module_data($module_data, true); + + // update_module_data can either return a string or an empty array... + if (is_string($result)) + { + // Error + $this->result = $this->get_output_text($result); + } + else + { + // Success + + // Move the module if requested above/below an existing one + if (isset($data['before']) && $data['before']) + { + $sql = 'SELECT left_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['before']) . '\''; + $this->db->sql_query($sql); + $to_left = $this->db->sql_fetchfield('left_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_left + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = $to_left, right_id = " . ($to_left + 1) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + elseif (isset($data['after']) && $data['after']) + { + $sql = 'SELECT right_id FROM ' . MODULES_TABLE . ' + WHERE module_class = \'' . $class . '\' + AND parent_id = ' . (int) $parent . ' + AND module_langname = \'' . $this->db->sql_escape($data['after']) . '\''; + $this->db->sql_query($sql); + $to_right = $this->db->sql_fetchfield('right_id'); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 + WHERE module_class = '$class' + AND left_id >= $to_right + AND left_id < {$module_data['left_id']}"; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . MODULES_TABLE . ' SET left_id = ' . ($to_right + 1) . ', right_id = ' . ($to_right + 2) . " + WHERE module_class = '$class' + AND module_id = {$module_data['module_id']}"; + $this->db->sql_query($sql); + } + } + + // Clear the Modules Cache + $cache->destroy("_modules_$class"); + + return $this->umil_end(); + } + + /** + * Module Remove + * + * Remove a module + * + * @param string $class The module class(acp|mcp|ucp) + * @param int|string|bool $parent The parent module_id|module_langname (0 for no parent). Use false to ignore the parent check and check class wide. + * @param int|string $module The module id|module_langname + * @param string|bool $include_path If you would like to use a custom include path, specify that here + */ + function module_remove($class, $parent = 0, $module = '', $include_path = false) + { + global $cache, $user, $lang; + + // Multicall + if ($this->multicall(__FUNCTION__, $class)) + { + return; + } + + // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto + if (is_array($module)) + { + if (isset($module['module_langname'])) + { + // Manual Method + return $this->module_remove($class, $parent, $module['module_langname'], $include_path); + } + + // Failed. + if (!isset($module['module_basename'])) + { + $this->umil_start('MODULE_REMOVE', $class, 'UNKNOWN'); + return $this->umil_end('FAIL'); + } + + // Automatic method + $basename = str_replace(array('/', '\\'), '', $module['module_basename']); + $class = str_replace(array('/', '\\'), '', $class); + $info_file = "$class/info/{$class}_$basename." . PHP_EXT; + + if (!file_exists((($include_path === false) ? (IP_ROOT_PATH . 'includes/') : $include_path) . $info_file)) + { + $this->umil_start('MODULE_REMOVE', $class, $info_file); + return $this->umil_end('FAIL'); + } + + $classname = "{$class}_{$basename}_info"; + + if (!class_exists($classname)) + { + include((($include_path === false) ? (IP_ROOT_PATH . 'includes/') : $include_path) . $info_file); + } + + $info = new $classname; + $module_info = $info->module(); + unset($info); + + $result = ''; + foreach ($module_info['modes'] as $mode => $info) + { + if (!isset($module['modes']) || in_array($mode, $module['modes'])) + { + $result .= $this->module_remove($class, $parent, $info['title']) . '
'; + } + } + return $result; + } + else + { + $class = $this->db->sql_escape($class); + + if (!$this->module_exists($class, $parent, $module)) + { + $this->umil_start('MODULE_REMOVE', $class, ((isset($lang[$module])) ? $lang[$module] : $module)); + return $this->umil_end('MODULE_NOT_EXIST'); + } + + $parent_sql = ''; + if ($parent !== false) + { + // Allows '' to be sent as 0 + $parent = (!$parent) ? 0 : $parent; + + if (!is_numeric($parent)) + { + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($parent) . "' + AND module_class = '$class'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + // we know it exists from the module_exists check + $parent_sql = 'AND parent_id = ' . (int) $row['module_id']; + } + else + { + $parent_sql = 'AND parent_id = ' . (int) $parent; + } + } + + $module_ids = array(); + if (!is_numeric($module)) + { + $module = $this->db->sql_escape($module); + $sql = 'SELECT module_id FROM ' . MODULES_TABLE . " + WHERE module_langname = '$module' + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $module_ids[] = (int) $row['module_id']; + } + $this->db->sql_freeresult($result); + + $module_name = $module; + } + else + { + $module = (int) $module; + $sql = 'SELECT module_langname FROM ' . MODULES_TABLE . " + WHERE module_id = $module + AND module_class = '$class' + $parent_sql"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $module_name = $row['module_langname']; + $module_ids[] = $module; + } + + $this->umil_start('MODULE_REMOVE', $class, ((isset($lang[$module_name])) ? $lang[$module_name] : $module_name)); + add_log('admin', 'LOG_MODULE_REMOVED', ((isset($lang[$module_name])) ? $lang[$module_name] : $module_name)); + + if (!class_exists('acp_modules')) + { + include(IP_ROOT_PATH . 'includes/acp/acp_modules.' . PHP_EXT); + $user->add_lang('acp/modules'); + } + $acp_modules = new acp_modules(); + $acp_modules->module_class = $class; + + foreach ($module_ids as $module_id) + { + $result = $acp_modules->delete_module($module_id); + if (!empty($result)) + { + if ($this->result == ((isset($lang['SUCCESS'])) ? $lang['SUCCESS'] : 'SUCCESS')) + { + $this->result = implode('
', $result); + } + else + { + $this->result .= '
' . implode('
', $result); + } + } + } + + $cache->destroy("_modules_$class"); + + return $this->umil_end(); + } + } + + /** + * Permission Exists + * + * Check if a permission (auth) setting exists + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return bool true if it exists, false if not + */ + function permission_exists($auth_option, $global = true) + { + if ($global) + { + $type_sql = ' AND is_global = 1'; + } + else + { + $type_sql = ' AND is_local = 1'; + } + + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" + . $type_sql; + $result = $this->db->sql_query($sql); + + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + return true; + } + + return false; + } + + /** + * Permission Add + * + * Add a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + function permission_add($auth_option, $global = true) + { + // Multicall + if ($this->multicall(__FUNCTION__, $auth_option)) + { + return; + } + + $this->umil_start('PERMISSION_ADD', $auth_option); + + if ($this->permission_exists($auth_option, $global)) + { + return $this->umil_end('PERMISSION_ALREADY_EXISTS', $auth_option); + } + + // We've added permissions, so set to true to notify the user. + $this->permissions_added = true; + + if (!class_exists('auth')) + { + include(IP_ROOT_PATH . 'includes/class_auth.' . PHP_EXT); + } + if (!class_exists('auth_admin')) + { + include(IP_ROOT_PATH . 'includes/class_auth_admin.' . PHP_EXT); + } + $auth_admin = new auth_admin(); + + // We have to add a check to see if the !$global (if global, local, and if local, global) permission already exists. If it does, acl_add_option currently has a bug which would break the ACL system, so we are having a work-around here. + if ($this->permission_exists($auth_option, !$global)) + { + $sql_ary = array( + 'is_global' => 1, + 'is_local' => 1, + ); + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE auth_option = \'' . $this->db->sql_escape($auth_option) . "'"; + $this->db->sql_query($sql); + } + else + { + if ($global) + { + $auth_admin->acl_add_option(array('global' => array($auth_option))); + } + else + { + $auth_admin->acl_add_option(array('local' => array($auth_option))); + } + } + + return $this->umil_end(); + } + + /** + * Permission Remove + * + * Remove a permission (auth) option + * + * @param string $auth_option The name of the permission (auth) option + * @param bool $global True for checking a global permission setting, False for a local permission setting + * + * @return result + */ + function permission_remove($auth_option, $global = true) + { + global $auth, $cache; + + // Multicall + if ($this->multicall(__FUNCTION__, $auth_option)) + { + return; + } + + $this->umil_start('PERMISSION_REMOVE', $auth_option); + + if (!$this->permission_exists($auth_option, $global)) + { + return $this->umil_end('PERMISSION_NOT_EXIST', $auth_option); + } + + if ($global) + { + $type_sql = ' AND is_global = 1'; + } + else + { + $type_sql = ' AND is_local = 1'; + } + $sql = 'SELECT auth_option_id, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . + $type_sql; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $id = $row['auth_option_id']; + + // If it is a local and global permission, do not remove the row! :P + if ($row['is_global'] && $row['is_local']) + { + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET ' . (($global) ? 'is_global = 0' : 'is_local = 0') . ' + WHERE auth_option_id = ' . $id; + $this->db->sql_query($sql); + } + else + { + // Delete time + $this->db->sql_query('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $id); + $this->db->sql_query('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $id); + } + + // Purge the auth cache + $cache->destroy('_acl_options'); + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Add a new permission role + * + * @param string $role_name The new role name + * @param sting $role_type The type (u_, m_, a_) + */ + function permission_role_add($role_name, $role_type = '', $role_description = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_ADD', $role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if ($role_id) + { + return $this->umil_end('ROLE_ALREADY_EXISTS', $old_role_name); + } + + $sql = 'SELECT MAX(role_order) AS max FROM ' . ACL_ROLES_TABLE . ' + WHERE role_type = \'' . $this->db->sql_escape($role_type) . '\''; + $this->db->sql_query($sql); + $role_order = $this->db->sql_fetchfield('max'); + $role_order = (!$role_order) ? 1 : $role_order + 1; + + $sql_ary = array( + 'role_name' => $role_name, + 'role_description' => $role_description, + 'role_type' => $role_type, + 'role_order' => $role_order, + ); + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Update the name on a permission role + * + * @param string $old_role_name The old role name + * @param string $new_role_name The new role name + */ + function permission_role_update($old_role_name, $new_role_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_UPDATE', $old_role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST', $old_role_name); + } + + $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' + SET role_name = \'' . $this->db->sql_escape($new_role_name) . '\' + WHERE role_name = \'' . $this->db->sql_escape($old_role_name) . '\''; + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Remove a permission role + * + * @param string $role_name The role name to remove + */ + function permission_role_remove($role_name) + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $role_name)) + { + return; + } + + $this->umil_start('PERMISSION_ROLE_REMOVE', $role_name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($role_name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST', $role_name); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Permission Set + * + * Allows you to set permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + * @param bool $has_permission True if you want to give them permission, false if you want to deny them permission + */ + function permission_set($name, $auth_option = array(), $type = 'role', $has_permission = true) + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $name)) + { + return; + } + + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $new_auth = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $new_auth[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($new_auth)) + { + return false; + } + + $current_auth = array(); + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role': + $this->umil_start('PERMISSION_SET_ROLE', $name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST'); + } + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE role_id = ' . $role_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + + case 'group': + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + $this->umil_start('PERMISSION_SET_GROUP', $name); + return $this->umil_end('GROUP_NOT_EXIST'); + } + + // If the group has a role set for them we will add the requested permissions to that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0 + AND forum_id = 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->permission_set($role_name, $auth_option, 'role', $has_permission); + } + + $this->umil_start('PERMISSION_SET_GROUP', $name); + + $sql = 'SELECT auth_option_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $current_auth[$row['auth_option_id']] = $row['auth_setting']; + } + $this->db->sql_freeresult($result); + break; + } + + $sql_ary = array(); + switch ($type) + { + case 'role': + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'role_id' => $role_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); + break; + + case 'group': + foreach ($new_auth as $auth_option_id) + { + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = array( + 'group_id' => $group_id, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => $has_permission, + ); + } + } + + $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); + break; + } + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Permission Unset + * + * Allows you to unset (remove) permissions for a certain group/role + * + * @param string $name The name of the role/group + * @param string|array $auth_option The auth_option or array of auth_options you would like to set + * @param string $type The type (role|group) + */ + function permission_unset($name, $auth_option = array(), $type = 'role') + { + global $auth; + + // Multicall + if ($this->multicall(__FUNCTION__, $name)) + { + return; + } + + if (!is_array($auth_option)) + { + $auth_option = array($auth_option); + } + + $to_remove = array(); + $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $to_remove[] = $row['auth_option_id']; + } + $this->db->sql_freeresult($result); + + if (!sizeof($to_remove)) + { + return false; + } + + $type = (string) $type; // Prevent PHP bug. + + switch ($type) + { + case 'role': + $this->umil_start('PERMISSION_UNSET_ROLE', $name); + + $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . ' + WHERE role_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('role_id'); + + if (!$role_id) + { + return $this->umil_end('ROLE_NOT_EXIST'); + } + + $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + + case 'group': + $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_name = \'' . $this->db->sql_escape($name) . '\''; + $this->db->sql_query($sql); + $group_id = $this->db->sql_fetchfield('group_id'); + + if (!$group_id) + { + $this->umil_start('PERMISSION_UNSET_GROUP', $name); + return $this->umil_end('GROUP_NOT_EXIST'); + } + + // If the group has a role set for them we will remove the requested permissions from that role. + $sql = 'SELECT auth_role_id FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id <> 0'; + $this->db->sql_query($sql); + $role_id = $this->db->sql_fetchfield('auth_role_id'); + if ($role_id) + { + $sql = 'SELECT role_name FROM ' . ACL_ROLES_TABLE . ' + WHERE role_id = ' . $role_id; + $this->db->sql_query($sql); + $role_name = $this->db->sql_fetchfield('role_name'); + + return $this->permission_unset($role_name, $auth_option, 'role'); + } + + $this->umil_start('PERMISSION_UNSET_GROUP', $name); + + $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); + $this->db->sql_query($sql); + break; + } + + $auth->acl_clear_prefetch(); + + return $this->umil_end(); + } + + /** + * Table Exists + * + * Check if a table exists in the DB or not + * + * @param string $table_name The table name to check for + * + * @return bool true if the table exists, false if not + */ + function table_exists($table_name) + { + $this->get_table_name($table_name); + + // Use sql_table_exists if available + if (method_exists($this->db_tools, 'sql_table_exists')) + { + $roe = $this->db->return_on_error; + $result = $this->db_tools->sql_table_exists($table_name); + + // db_tools::sql_table_exists resets the return_on_error to false always after completing, so we must make sure we set it to true again if it was before + if ($roe) + { + $this->db->sql_return_on_error(true); + } + + return $result; + } + + if (!function_exists('get_tables')) + { + include(IP_ROOT_PATH . 'includes/functions_install.' . PHP_EXT); + } + + $tables = get_tables($this->db); + + if (in_array($table_name, $tables)) + { + return true; + } + else + { + return false; + } + } + + /** + * Table Add + * + * This only supports input from the array format of db_tools or create_schema_files. + */ + function table_add($table_name, $table_data = array()) + { + global $dbms, $user; + + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + /** + * $table_data can be empty when uninstalling a mod and table_remove was used, but no 2rd argument was given. + * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 2rd argument) and skip this to prevent an error + */ + if (empty($table_data)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ADD', $table_name); + + if ($this->table_exists($table_name)) + { + return $this->umil_end('TABLE_ALREADY_EXISTS', $table_name); + } + + if (!is_array($table_data)) + { + return $this->umil_end('NO_TABLE_DATA'); + } + + if (!function_exists('get_available_dbms')) + { + include(IP_ROOT_PATH . "includes/functions_install." . PHP_EXT); + } + + /* + * This function has had numerous problems and is currently broken, so until phpBB uses it I will not be anymore + if (method_exists($this->db_tools, 'sql_create_table')) + { + // Added in 3.0.5 + $this->db_tools->sql_create_table($table_name, $table_data); + } + else + {*/ + $available_dbms = get_available_dbms($dbms); + + $sql_query = $this->create_table_sql($table_name, $table_data); + $sql_query = split_sql_file($sql_query, $available_dbms[$dbms]['DELIM']); + + foreach ($sql_query as $sql) + { + $this->db->sql_query($sql); + } + //} + + return $this->umil_end(); + } + + /** + * Table Remove + * + * Delete/Drop a DB table + */ + function table_remove($table_name) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_REMOVE', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + if (method_exists($this->db_tools, 'sql_table_drop')) + { + // Added in 3.0.5 + $this->db_tools->sql_table_drop($table_name); + } + else + { + $this->db->sql_query('DROP TABLE ' . $table_name); + } + + return $this->umil_end(); + } + + /** + * Table Column Exists + * + * Check to see if a column exists in a table + */ + function table_column_exists($table_name, $column_name) + { + $this->get_table_name($table_name); + + return $this->db_tools->sql_column_exists($table_name, $column_name); + } + + /** + * Table Column Add + * + * Add a new column to a table. + */ + function table_column_add($table_name, $column_name = '', $column_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + /** + * $column_data can be empty when uninstalling a mod and table_column_remove was used, but no 3rd argument was given. + * In that case we'll assume that it was a column previously added by the mod (if not the author should specify a 3rd argument) and skip this to prevent an error + */ + if (empty($column_data)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_ADD', $table_name, $column_name); + + if ($this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_ALREADY_EXISTS', $table_name, $column_name); + } + + $this->db_tools->sql_column_add($table_name, $column_name, $column_data); + + return $this->umil_end(); + } + + /** + * Table Column Update + * + * Alter/Update a column in a table. You can not change a column name with this. + */ + function table_column_update($table_name, $column_name = '', $column_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_UPDATE', $table_name, $column_name); + + if (!$this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); + } + + $this->db_tools->sql_column_change($table_name, $column_name, $column_data); + + return $this->umil_end(); + } + + /** + * Table Column Remove + * + * Remove a column from a table + */ + function table_column_remove($table_name, $column_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_COLUMN_REMOVE', $table_name, $column_name); + + if (!$this->table_column_exists($table_name, $column_name)) + { + return $this->umil_end('TABLE_COLUMN_NOT_EXIST', $table_name, $column_name); + } + + $this->db_tools->sql_column_remove($table_name, $column_name); + + return $this->umil_end(); + } + + /** + * Table Index Exists + * + * Check if a table key/index exists on a table (can not check primary or unique) + */ + function table_index_exists($table_name, $index_name) + { + $this->get_table_name($table_name); + + $indexes = $this->db_tools->sql_list_index($table_name); + + if (in_array($index_name, $indexes)) + { + return true; + } + + return false; + } + + /** + * Table Index Add + * + * Add a new key/index to a table + */ + function table_index_add($table_name, $index_name = '', $column = array()) + { + global $config; + + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + // Let them skip the column field and just use the index name in that case as the column as well + if (empty($column)) + { + $column = array($index_name); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_KEY_ADD', $table_name, $index_name); + + if ($this->table_index_exists($table_name, $index_name)) + { + return $this->umil_end('TABLE_KEY_ALREADY_EXIST', $table_name, $index_name); + } + + if (!is_array($column)) + { + $column = array($column); + } + + // MIGHTY GORGON - BEGIN + // Mighty Gorgon: To be checked! + // remove index length if we are before 3.0.8 the feature (required for some types when using MySQL4) was added in that release (ticket PHPBB3-8944) + /* + if (version_compare($config['version'], '3.0.7-pl1', '<=')) + { + $column = preg_replace('#:.*$#', '', $column); + } + */ + $column = preg_replace('#:.*$#', '', $column); + // MIGHTY GORGON - END + + $this->db_tools->sql_create_index($table_name, $index_name, $column); + + return $this->umil_end(); + } + + /** + * Table Index Remove + * + * Remove a key/index from a table + */ + function table_index_remove($table_name, $index_name = '') + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_KEY_REMOVE', $table_name, $index_name); + + if (!$this->table_index_exists($table_name, $index_name)) + { + return $this->umil_end('TABLE_KEY_NOT_EXIST', $table_name, $index_name); + } + + $this->db_tools->sql_index_drop($table_name, $index_name); + + return $this->umil_end(); + } + + // Ignore, function was renamed to table_row_insert and keeping for backwards compatibility + function table_insert($table_name, $data = array()) { $this->table_row_insert($table_name, $data); } + + /** + * Table Insert + * + * Insert data into a table + */ + function table_row_insert($table_name, $data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_INSERT_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $this->db->sql_multi_insert($table_name, $data); + + return $this->umil_end(); + } + + /** + * Table Row Update + * + * Update a row in a table + * + * $data should be an array with the column names as keys and values as the items to check for each column. Example: + * array('user_id' => 123, 'user_name' => 'test user') would become: + * WHERE user_id = 123 AND user_name = 'test user' + * + * $new_data is the new data it will be updated to (same format as you'd enter into $db->sql_build_array('UPDATE' ). + */ + function table_row_update($table_name, $data = array(), $new_data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + if (!sizeof($data)) + { + return $this->umil_end('FAIL'); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_UPDATE_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $sql = 'UPDATE ' . $table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', $new_data) . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Table Row Remove + * + * Remove a row from a table + * + * $data should be an array with the column names as keys and values as the items to check for each column. Example: + * array('user_id' => 123, 'user_name' => 'test user') would become: + * WHERE user_id = 123 AND user_name = 'test user' + */ + function table_row_remove($table_name, $data = array()) + { + // Multicall + if ($this->multicall(__FUNCTION__, $table_name)) + { + return; + } + + if (!sizeof($data)) + { + return $this->umil_end('FAIL'); + } + + $this->get_table_name($table_name); + + $this->umil_start('TABLE_ROW_REMOVE_DATA', $table_name); + + if (!$this->table_exists($table_name)) + { + return $this->umil_end('TABLE_NOT_EXIST', $table_name); + } + + $sql = 'DELETE FROM ' . $table_name . ' WHERE ' . $this->db->sql_build_array('SELECT', $data); + $this->db->sql_query($sql); + + return $this->umil_end(); + } + + /** + * Version Checker + * + * Format the file like the following: + * http://www.phpbb.com/updatecheck/30x.txt + * + * @param string $url The url to access (ex: www.phpbb.com) + * @param string $path The path to access (ex: /updatecheck) + * @param string $file The name of the file to access (ex: 30x.txt) + * + * @return array|string Error Message if there was any error, or an array (each line in the file as a value) + */ + function version_check($url, $path, $file, $timeout = 10, $port = 80) + { + if (!function_exists('get_remote_file')) + { + include(IP_ROOT_PATH . 'includes/functions_admin.' . PHP_EXT); + } + + $errstr = $errno = ''; + + $info = get_remote_file($url, $path, $file, $errstr, $errno, $port, $timeout); + + if ($info === false) + { + return $errstr . ' [ ' . $errno . ' ]'; + } + + $info = str_replace("\r\n", "\n", $info); + $info = explode("\n", $info); + + return $info; + } + + /** + * Create table SQL + * + * Create the SQL query for the specified DBMS on the fly from a create_schema_files type of table array + * + * @param string $table_name The name of the table + * @param array $table_data The table data (formatted in the array format used by create_schema_files) + * @param string $dbms The dbms this will be built for (for testing only, leave blank to use the current DBMS) + * + * @return The sql query to run for the submitted dbms to insert the table + */ + function create_table_sql($table_name, $table_data, $dbms = '') + { + // To allow testing + $dbms = ($dbms) ? $dbms : $this->db_tools->sql_layer; + + // A list of types being unsigned for better reference in some db's + $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + $supported_dbms = array('mysql_40', 'mysql_41'); + + $sql = ''; + + // Create Table statement + $generator = $textimage = false; + + $sql .= "CREATE TABLE {$table_name} (\n"; + + // Table specific so we don't get overlap + $modded_array = array(); + + // Write columns one by one... + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // Get type + if (strpos($column_data[0], ':') !== false) + { + list($orig_column_type, $column_length) = explode(':', $column_data[0]); + if (!is_array($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'])) + { + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'], $column_length); + } + else + { + if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'])) + { + switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0]) + { + case 'div': + $column_length /= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1]; + $column_length = ceil($column_length); + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); + break; + } + } + + if (isset($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'])) + { + switch ($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0]) + { + case 'mult': + $column_length *= $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1]; + if ($column_length > $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2]) + { + $column_type = $this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3]; + $modded_array[$column_name] = $column_type; + } + else + { + $column_type = sprintf($this->db_tools->dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); + } + break; + } + } + } + $orig_column_type .= ':'; + } + else + { + $orig_column_type = $column_data[0]; + $column_type = $this->db_tools->dbms_type_map[$dbms][$column_data[0]]; + if ($column_type == 'text' || $column_type == 'blob') + { + $modded_array[$column_name] = $column_type; + } + } + + // Adjust default value if db-dependant specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; + } + + $sql .= "\t{$column_name} {$column_type} "; + + // For hexadecimal values do not use single quotes + if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') + { + $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; + } + $sql .= 'NOT NULL'; + + if (isset($column_data[2])) + { + if ($column_data[2] == 'auto_increment') + { + $sql .= ' auto_increment'; + } + elseif ($dbms === 'mysql_41' && $column_data[2] == 'true_sort') + { + $sql .= ' COLLATE utf8_unicode_ci'; + } + } + + $sql .= ",\n"; + } + + // Write primary key + if (isset($table_data['PRIMARY_KEY'])) + { + if (!is_array($table_data['PRIMARY_KEY'])) + { + $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); + } + + $sql .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; + } + + // Write Keys + if (isset($table_data['KEYS'])) + { + foreach ($table_data['KEYS'] as $key_name => $key_data) + { + if (!is_array($key_data[1])) + { + $key_data[1] = array($key_data[1]); + } + + $sql .= ($key_data[0] == 'INDEX') ? "\tKEY" : ''; + $sql .= ($key_data[0] == 'UNIQUE') ? "\tUNIQUE" : ''; + foreach ($key_data[1] as $key => $col_name) + { + if (isset($modded_array[$col_name])) + { + switch ($modded_array[$col_name]) + { + case 'text': + case 'blob': + $key_data[1][$key] = $col_name . '(255)'; + break; + } + } + } + $sql .= ' ' . $key_name . ' (' . implode(', ', $key_data[1]) . "),\n"; + } + } + + switch ($dbms) + { + case 'mysql_40': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n);\n\n"; + break; + + case 'mysql_41': + // Remove last line delimiter... + $sql = substr($sql, 0, -2); + $sql .= "\n) CHARACTER SET utf8 COLLATE utf8_bin;\n\n"; + break; + + } + + return $sql; + } + + /** + * Get the real table name + * By A_Jelly_Doughnut + * + * @param string $table_name The table name to get the real table name from + */ + function get_table_name(&$table_name) + { + // Use the global table prefix if a custom one is not specified + if ($this->table_prefix === false) + { + global $table_prefix; + } + else + { + $table_prefix = $this->table_prefix; + } + + static $constants = NULL; + + if (is_null($constants)) + { + $constants = get_defined_constants(); + } + + /** + * only do the replace if the table prefix is not already present + * this is required since UMIL supports specifying a table via phpbb_foo + * (where a replace would be needed) + * or by FOO_TABLE (where a replace is already done at constant-define time) + */ + if (!preg_match('#^' . preg_quote($table_prefix, '#') . '#', $table_name) || !in_array($table_name, $constants, true)) + { + $table_name = preg_replace('#^phpbb_#i', $table_prefix, $table_name); + } + } +} + +?> \ No newline at end of file diff --git a/includes/constants.php b/includes/constants.php index ef5f026f..da4aa4b7 100644 --- a/includes/constants.php +++ b/includes/constants.php @@ -20,7 +20,7 @@ die('Hacking attempt'); } -define('ICYPHOENIX_VERSION', '1.3.19.72'); +define('ICYPHOENIX_VERSION', '1.3.20.73'); // FOUNDER ID, this is the ID of the main admin of the site, only this user canc access special features of the site and this ID is also used to send Welcome and Birthday PM define('FOUNDER_ID', '2'); diff --git a/includes/db/db_tools.php b/includes/db/db_tools.php index c7e4339e..7cb740a9 100644 --- a/includes/db/db_tools.php +++ b/includes/db/db_tools.php @@ -47,215 +47,66 @@ class phpbb_db_tools * @var array */ var $dbms_type_map = array( - 'mysql_41' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT' => 'text', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT' => 'text', - 'TEXT_UNI' => 'text', - 'MTEXT' => 'mediumtext', - 'MTEXT_UNI' => 'mediumtext', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'varbinary(255)', + 'mysql_41' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'text', + 'XSTEXT_UNI' => 'varchar(100)', + 'STEXT' => 'text', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT' => 'text', + 'TEXT_UNI' => 'text', + 'MTEXT' => 'mediumtext', + 'MTEXT_UNI' => 'mediumtext', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:' => 'varchar(%d)', + 'VCHAR_CI' => 'varchar(255)', + 'VARBINARY' => 'varbinary(255)', ), - 'mysql_40' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varbinary(255)', - 'VCHAR:' => 'varbinary(%d)', - 'CHAR:' => 'binary(%d)', - 'XSTEXT' => 'blob', - 'XSTEXT_UNI'=> 'blob', - 'STEXT' => 'blob', - 'STEXT_UNI' => 'blob', - 'TEXT' => 'blob', - 'TEXT_UNI' => 'blob', - 'MTEXT' => 'mediumblob', - 'MTEXT_UNI' => 'mediumblob', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'blob', - 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), - 'VCHAR_CI' => 'blob', - 'VARBINARY' => 'varbinary(255)', + 'mysql_40' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varbinary(255)', + 'VCHAR:' => 'varbinary(%d)', + 'CHAR:' => 'binary(%d)', + 'XSTEXT' => 'blob', + 'XSTEXT_UNI' => 'blob', + 'STEXT' => 'blob', + 'STEXT_UNI' => 'blob', + 'TEXT' => 'blob', + 'TEXT_UNI' => 'blob', + 'MTEXT' => 'mediumblob', + 'MTEXT_UNI' => 'mediumblob', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'blob', + 'VCHAR_UNI:' => array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), + 'VCHAR_CI' => 'blob', + 'VARBINARY' => 'varbinary(255)', ), - 'firebird' => array( - 'INT:' => 'INTEGER', - 'BINT' => 'DOUBLE PRECISION', - 'UINT' => 'INTEGER', - 'UINT:' => 'INTEGER', - 'TINT:' => 'INTEGER', - 'USINT' => 'INTEGER', - 'BOOL' => 'INTEGER', - 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE', - 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE', - 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE', - 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8', - 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'TIMESTAMP' => 'INTEGER', - 'DECIMAL' => 'DOUBLE PRECISION', - 'DECIMAL:' => 'DOUBLE PRECISION', - 'PDECIMAL' => 'DOUBLE PRECISION', - 'PDECIMAL:' => 'DOUBLE PRECISION', - 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8', - 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE', - ), - - 'mssql' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'oracle' => array( - 'INT:' => 'number(%d)', - 'BINT' => 'number(20)', - 'UINT' => 'number(8)', - 'UINT:' => 'number(%d)', - 'TINT:' => 'number(%d)', - 'USINT' => 'number(4)', - 'BOOL' => 'number(1)', - 'VCHAR' => 'varchar2(255)', - 'VCHAR:' => 'varchar2(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar2(1000)', - 'STEXT' => 'varchar2(3000)', - 'TEXT' => 'clob', - 'MTEXT' => 'clob', - 'XSTEXT_UNI'=> 'varchar2(300)', - 'STEXT_UNI' => 'varchar2(765)', - 'TEXT_UNI' => 'clob', - 'MTEXT_UNI' => 'clob', - 'TIMESTAMP' => 'number(11)', - 'DECIMAL' => 'number(5, 2)', - 'DECIMAL:' => 'number(%d, 2)', - 'PDECIMAL' => 'number(6, 3)', - 'PDECIMAL:' => 'number(%d, 3)', - 'VCHAR_UNI' => 'varchar2(765)', - 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), - 'VCHAR_CI' => 'varchar2(255)', - 'VARBINARY' => 'raw(255)', - ), - - 'sqlite' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text(65535)', - 'STEXT' => 'text(65535)', - 'TEXT' => 'text(65535)', - 'MTEXT' => 'mediumtext(16777215)', - 'XSTEXT_UNI'=> 'text(65535)', - 'STEXT_UNI' => 'text(65535)', - 'TEXT_UNI' => 'text(65535)', - 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'blob', - ), - - 'postgres' => array( - 'INT:' => 'INT4', - 'BINT' => 'INT8', - 'UINT' => 'INT4', // unsigned - 'UINT:' => 'INT4', // unsigned - 'USINT' => 'INT2', // unsigned - 'BOOL' => 'INT2', // unsigned - 'TINT:' => 'INT2', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar(1000)', - 'STEXT' => 'varchar(3000)', - 'TEXT' => 'varchar(8000)', - 'MTEXT' => 'TEXT', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT_UNI' => 'varchar(4000)', - 'MTEXT_UNI' => 'TEXT', - 'TIMESTAMP' => 'INT4', // unsigned - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar_ci', - 'VARBINARY' => 'bytea', - ), ); /** @@ -268,7 +119,7 @@ class phpbb_db_tools * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. * @var array */ - var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); + var $supported_dbms = array('mysql_40', 'mysql_41'); /** * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). @@ -309,11 +160,6 @@ function phpbb_db_tools(&$db, $return_statements = false) $this->sql_layer = 'mysql_41'; break; - case 'mssql': - case 'mssql_odbc': - $this->sql_layer = 'mssql'; - break; - default: $this->sql_layer = $this->db->sql_layer; break; @@ -374,10 +220,6 @@ function sql_create_table($table_name, $table_data) // Begin table sql statement switch ($this->sql_layer) { - case 'mssql': - $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; - break; - default: $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; break; @@ -392,10 +234,6 @@ function sql_create_table($table_name, $table_data) // here we add the definition of the new column to the list of columns switch ($this->sql_layer) { - case 'mssql': - $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; - break; - default: $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; break; @@ -423,20 +261,6 @@ function sql_create_table($table_name, $table_data) // this makes up all the columns in the create table statement $table_sql .= implode(",\n", $columns); - // Close the table for two DBMS and add to the statements - switch ($this->sql_layer) - { - case 'firebird': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - - case 'mssql': - $table_sql .= "\n) ON [PRIMARY]" . (($create_textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : ''); - $statements[] = $table_sql; - break; - } - // we have yet to create a primary key for this table, // this means that we can add the one we really wanted instead if (!$primary_key_gen) @@ -449,34 +273,7 @@ function sql_create_table($table_name, $table_data) $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); } - switch ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - case 'postgres': - case 'sqlite': - $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; - break; - - case 'firebird': - case 'mssql': - // We need the data here - $old_return_statements = $this->return_statements; - $this->return_statements = true; - - $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); - foreach ($primary_key_stmts as $pk_stmt) - { - $statements[] = $pk_stmt; - } - - $this->return_statements = $old_return_statements; - break; - - case 'oracle': - $table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; - break; - } + $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; } } @@ -490,54 +287,10 @@ function sql_create_table($table_name, $table_data) break; case 'mysql_40': - case 'sqlite': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - - case 'postgres': - // do we need to add a sequence for auto incrementing columns? - if ($create_sequence) - { - $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; - } - - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - - case 'oracle': $table_sql .= "\n);"; $statements[] = $table_sql; - - // do we need to add a sequence and a tigger for auto incrementing columns? - if ($create_sequence) - { - // create the actual sequence - $statements[] = "CREATE SEQUENCE {$table_name}_seq"; - - // the trigger is the mechanism by which we increment the counter - $trigger = "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; - $trigger .= "BEFORE INSERT ON {$table_name}\n"; - $trigger .= "FOR EACH ROW WHEN (\n"; - $trigger .= "\tnew.{$create_sequence} IS NULL OR new.{$create_sequence} = 0\n"; - $trigger .= ")\n"; - $trigger .= "BEGIN\n"; - $trigger .= "\tSELECT {$table_name}_seq.nextval\n"; - $trigger .= "\tINTO :new.{$create_sequence}\n"; - $trigger .= "\tFROM dual\n"; - $trigger .= "END;"; - - $statements[] = $trigger; - } break; - case 'firebird': - if ($create_sequence) - { - $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; - } - break; } // Write Keys @@ -635,7 +388,7 @@ function perform_schema_changes($schema_changes) $sqlite_data[$table]['add_columns'][] = $result; } } - else if ($this->return_statements) + elseif ($this->return_statements) { $statements = array_merge($statements, $result); } @@ -671,7 +424,7 @@ function perform_schema_changes($schema_changes) $sqlite_data[$table]['add_columns'][] = $result; } } - else if ($this->return_statements) + elseif ($this->return_statements) { $statements = array_merge($statements, $result); } @@ -707,15 +460,7 @@ function perform_schema_changes($schema_changes) if ($this->sql_column_exists($table, $column)) { $result = $this->sql_column_remove($table, $column, true); - - if ($sqlite) - { - $sqlite_data[$table]['drop_columns'][] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } + $statements = array_merge($statements, $result); } } } @@ -727,15 +472,7 @@ function perform_schema_changes($schema_changes) foreach ($schema_changes['add_primary_keys'] as $table => $columns) { $result = $this->sql_create_primary_key($table, $columns, true); - - if ($sqlite) - { - $sqlite_data[$table]['primary_key'] = $result; - } - else if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } + $statements = array_merge($statements, $result); } } @@ -898,7 +635,7 @@ function perform_schema_changes($schema_changes) $new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')'; } // Add a new one or the old primary key - else if ($primary_key !== false) + elseif ($primary_key !== false) { $new_table_cols[] = $primary_key; } @@ -930,144 +667,20 @@ function perform_schema_changes($schema_changes) */ function sql_column_exists($table, $column_name) { - switch ($this->sql_layer) - { - case 'mysql_40': - case 'mysql_41': - - $sql = "SHOW COLUMNS FROM $table"; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['Field']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - // PostgreSQL has a way of doing this in a much simpler way but would - // not allow us to support all versions of PostgreSQL - case 'postgres': - $sql = "SELECT a.attname - FROM pg_class c, pg_attribute a - WHERE c.relname = '{$table}' - AND a.attnum > 0 - AND a.attrelid = c.oid"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['attname']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - - return false; - break; - - // same deal with PostgreSQL, we must perform more complex operations than - // we technically could - case 'mssql': - $sql = "SELECT c.name - FROM syscolumns c - LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '{$table}'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['name']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - case 'oracle': - $sql = "SELECT column_name - FROM user_tab_columns - WHERE LOWER(table_name) = '" . strtolower($table) . "'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['column_name']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - case 'firebird': - $sql = "SELECT RDB\$FIELD_NAME as FNAME - FROM RDB\$RELATION_FIELDS - WHERE RDB\$RELATION_NAME = '" . strtoupper($table) . "'"; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // lower case just in case - if (strtolower($row['fname']) == $column_name) - { - $this->db->sql_freeresult($result); - return true; - } - } - $this->db->sql_freeresult($result); - return false; - break; - - // ugh, SQLite - case 'sqlite': - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table}'"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - return false; - } + $sql = "SHOW COLUMNS FROM $table"; + $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); + while ($row = $this->db->sql_fetchrow($result)) + { + // lower case just in case + if (strtolower($row['Field']) == $column_name) + { $this->db->sql_freeresult($result); - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $cols = trim($matches[1]); - $col_array = preg_split('/,(?![\s\w]+\))/m', $cols); - - foreach ($col_array as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - - if (strtolower($entities[0]) == $column_name) - { - return true; - } - } - return false; - break; + return true; + } } + $this->db->sql_freeresult($result); + return false; } /** @@ -1088,7 +701,7 @@ function _sql_run_sql($statements) { $this->db->sql_transaction('begin'); } - else if ($sql === 'commit') + elseif ($sql === 'commit') { $this->db->sql_transaction('commit'); } @@ -1165,161 +778,25 @@ function sql_prepare_column_data($table_name, $column_name, $column_data) $return_array = array(); - switch ($this->sql_layer) - { - case 'firebird': - $sql .= " {$column_type} "; - $return_array['column_type_sql_type'] = " {$column_type} "; - - if (!is_null($column_data[1])) - { - $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - $return_array['column_type_sql_default'] = ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - } - - $sql .= 'NOT NULL'; - - // This is a UNICODE column and thus should be given it's fair share - if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) - { - $sql .= ' COLLATE UNICODE'; - } - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $return_array['auto_increment'] = true; - } - - break; - - case 'mssql': - $sql .= " {$column_type} "; - $sql_default = " {$column_type} "; - - // For adding columns we need the default definition - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $return_array['default'] = 'DEFAULT (' . $column_data[1] . ') '; - $sql_default .= $return_array['default']; - } - else - { - $return_array['default'] = 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - $sql_default .= $return_array['default']; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { -// $sql .= 'IDENTITY (1, 1) '; - $sql_default .= 'IDENTITY (1, 1) '; - } - - $return_array['textimage'] = $column_type === '[text]'; - - $sql .= 'NOT NULL'; - $sql_default .= 'NOT NULL'; - - $return_array['column_type_sql_default'] = $sql_default; - - break; - - case 'mysql_40': - case 'mysql_41': - $sql .= " {$column_type} "; - - // For hexadecimal values do not use single quotes - if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') - { - $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; - } - $sql .= 'NOT NULL'; - - if (isset($column_data[2])) - { - if ($column_data[2] == 'auto_increment') - { - $sql .= ' auto_increment'; - } - else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') - { - $sql .= ' COLLATE utf8_unicode_ci'; - } - } - - break; - - case 'oracle': - $sql .= " {$column_type} "; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - - // In Oracle empty strings ('') are treated as NULL. - // Therefore in oracle we allow NULL's for all DEFAULT '' entries - // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) - if (!preg_match('/number/i', $column_type)) - { - $sql .= ($column_data[1] === '') ? '' : 'NOT NULL'; - } - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $return_array['auto_increment'] = true; - } - - break; - - case 'postgres': - $return_array['column_type'] = $column_type; - - $sql .= " {$column_type} "; - - $return_array['auto_increment'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $default_val = "nextval('{$table_name}_seq')"; - $return_array['auto_increment'] = true; - } - else if (!is_null($column_data[1])) - { - $default_val = "'" . $column_data[1] . "'"; - $return_array['null'] = 'NOT NULL'; - $sql .= 'NOT NULL '; - } - - $return_array['default'] = $default_val; - - $sql .= "DEFAULT {$default_val}"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $this->unsigned_types)) - { - $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; - $sql .= " CHECK ({$column_name} >= 0)"; - } - - break; - - case 'sqlite': - $return_array['primary_key_set'] = false; - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $sql .= ' INTEGER PRIMARY KEY'; - $return_array['primary_key_set'] = true; - } - else - { - $sql .= ' ' . $column_type; - } + $sql .= " {$column_type} "; - $sql .= ' NOT NULL '; - $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; + // For hexadecimal values do not use single quotes + if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') + { + $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; + } + $sql .= 'NOT NULL'; - break; + if (isset($column_data[2])) + { + if ($column_data[2] == 'auto_increment') + { + $sql .= ' auto_increment'; + } + elseif ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort') + { + $sql .= ' COLLATE utf8_unicode_ci'; + } } $return_array['column_type_sql'] = $sql; @@ -1335,288 +812,46 @@ function sql_column_add($table_name, $column_name, $column_data, $inline = false $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); $statements = array(); - switch ($this->sql_layer) - { - case 'firebird': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql']; - break; + $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql']; + return $this->_sql_run_sql($statements); + } - case 'mssql': - $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default']; - break; + /** + * Drop column + */ + function sql_column_remove($table_name, $column_name, $inline = false) + { + $statements = array(); - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql']; - break; + $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; + return $this->_sql_run_sql($statements); + } - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; - break; + /** + * Drop Index + */ + function sql_index_drop($table_name, $index_name) + { + $statements = array(); - case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; - break; + $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; + return $this->_sql_run_sql($statements); + } - case 'sqlite': + /** + * Drop Table + */ + function sql_table_drop($table_name) + { + $statements = array(); - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - if (version_compare(sqlite_libversion(), '3.0') == -1) - { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - else - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']'; - } - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Drop column - */ - function sql_column_remove($table_name, $column_name, $inline = false) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'firebird': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"'; - break; - - case 'mssql': - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`'; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name; - break; - - case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"'; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column_name; - } - - if (version_compare(sqlite_libversion(), '3.0') == -1) - { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - } - else - { - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; - } - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Drop Index - */ - function sql_index_drop($table_name, $index_name) - { - $statements = array(); - - switch ($this->sql_layer) - { - case 'mssql': - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; - break; - - case 'firebird': - case 'oracle': - case 'postgres': - case 'sqlite': - $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; - break; - } - - return $this->_sql_run_sql($statements); - } - - /** - * Drop Table - */ - function sql_table_drop($table_name) - { - $statements = array(); - - if (!$this->sql_table_exists($table_name)) - { - return $this->_sql_run_sql($statements); - } + if (!$this->sql_table_exists($table_name)) + { + return $this->_sql_run_sql($statements); + } // the most basic operation, get rid of the table $statements[] = 'DROP TABLE ' . $table_name; - - switch ($this->sql_layer) - { - case 'firebird': - $sql = 'SELECT RDB$GENERATOR_NAME as gen - FROM RDB$GENERATORS - WHERE RDB$SYSTEM_FLAG = 0 - AND RDB$GENERATOR_NAME = \'' . strtoupper($table_name) . "_GEN'"; - $result = $this->db->sql_query($sql); - - // does a generator exist? - if ($row = $this->db->sql_fetchrow($result)) - { - $statements[] = "DROP GENERATOR {$row['gen']};"; - } - $this->db->sql_freeresult($result); - break; - - case 'oracle': - $sql = 'SELECT A.REFERENCED_NAME - FROM USER_DEPENDENCIES A, USER_TRIGGERS B - WHERE A.REFERENCED_TYPE = \'SEQUENCE\' - AND A.NAME = B.TRIGGER_NAME - AND B.TABLE_NAME = \'' . strtoupper($table_name) . "'"; - $result = $this->db->sql_query($sql); - - // any sequences ref'd to this table's triggers? - while ($row = $this->db->sql_fetchrow($result)) - { - $statements[] = "DROP SEQUENCE {$row['referenced_name']}"; - } - $this->db->sql_freeresult($result); - - case 'postgres': - // PGSQL does not "tightly" bind sequences and tables, we must guess... - $sql = "SELECT relname - FROM pg_class - WHERE relkind = 'S' - AND relname = '{$table_name}_seq'"; - $result = $this->db->sql_query($sql); - - // We don't even care about storing the results. We already know the answer if we get rows back. - if ($this->db->sql_fetchrow($result)) - { - $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; - } - $this->db->sql_freeresult($result); - break; - } - return $this->_sql_run_sql($statements); } @@ -1627,84 +862,7 @@ function sql_create_primary_key($table_name, $column, $inline = false) { $statements = array(); - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'mssql': - $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; - $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; - $sql .= '[' . implode("],\n\t\t[", $column) . ']'; - $sql .= ') ON [PRIMARY]'; - - $statements[] = $sql; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column; - } - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - break; - } - + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; return $this->_sql_run_sql($statements); } @@ -1715,25 +873,7 @@ function sql_create_unique_index($table_name, $index_name, $column) { $statements = array(); - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'oracle': - case 'sqlite': - $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; - break; - } - + $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; return $this->_sql_run_sql($statements); } @@ -1744,25 +884,7 @@ function sql_create_index($table_name, $index_name, $column) { $statements = array(); - switch ($this->sql_layer) - { - case 'firebird': - case 'postgres': - case 'oracle': - case 'sqlite': - $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; - break; - - case 'mssql': - $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; - break; - } - + $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; return $this->_sql_run_sql($statements); } @@ -1791,68 +913,17 @@ function sql_list_index($table_name) } else { - switch ($this->sql_layer) - { - case 'firebird': - $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name - FROM RDB\$INDICES - WHERE RDB\$RELATION_NAME = '" . strtoupper($table_name) . "' - AND RDB\$UNIQUE_FLAG IS NULL - AND RDB\$FOREIGN_KEY IS NULL"; - $col = 'index_name'; - break; - - case 'postgres': - $sql = "SELECT ic.relname as index_name - FROM pg_class bc, pg_class ic, pg_index i - WHERE (bc.oid = i.indrelid) - AND (ic.oid = i.indexrelid) - AND (bc.relname = '" . $table_name . "') - AND (i.indisunique != 't') - AND (i.indisprimary != 't')"; - $col = 'index_name'; - break; - - case 'mysql_40': - case 'mysql_41': - $sql = 'SHOW KEYS - FROM ' . $table_name; - $col = 'Key_name'; - break; - - case 'oracle': - $sql = "SELECT index_name - FROM user_indexes - WHERE table_name = '" . strtoupper($table_name) . "' - AND generated = 'N' - AND uniqueness = 'NONUNIQUE'"; - $col = 'index_name'; - break; - - case 'sqlite': - $sql = "PRAGMA index_info('" . $table_name . "');"; - $col = 'name'; - break; - } + $sql = 'SHOW KEYS + FROM ' . $table_name; + $col = 'Key_name'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique']) + if (!$row['Non_unique']) { continue; } - - switch ($this->sql_layer) - { - case 'firebird': - case 'oracle': - case 'postgres': - case 'sqlite': - $row[$col] = substr($row[$col], strlen($table_name) + 1); - break; - } - $index_array[] = $row[$col]; } $this->db->sql_freeresult($result); @@ -1869,175 +940,7 @@ function sql_column_change($table_name, $column_name, $column_data, $inline = fa $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); $statements = array(); - switch ($this->sql_layer) - { - case 'firebird': - // Change type... - if (!empty($column_data['column_type_sql_default'])) - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" SET DEFAULT ' . ' ' . $column_data['column_type_sql_default']; - } - else - { - $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql_type']; - } - break; - - case 'mssql': - $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - - if (!empty($column_data['default'])) - { - // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END - SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' - EXEC(@cmd)"; - } - break; - - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; - break; - - case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; - break; - - case 'postgres': - $sql = 'ALTER TABLE ' . $table_name . ' '; - - $sql_array = array(); - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type']; - - if (isset($column_data['null'])) - { - if ($column_data['null'] == 'NOT NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL'; - } - else if ($column_data['null'] == 'NULL') - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL'; - } - } - - if (isset($column_data['default'])) - { - $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; - } - - // we don't want to double up on constraints if we change different number data types - if (isset($column_data['constraint'])) - { - $constraint_sql = "SELECT consrc as constraint_data - FROM pg_constraint, pg_class bc - WHERE conrelid = bc.oid - AND bc.relname = '{$table_name}' - AND NOT EXISTS ( - SELECT * - FROM pg_constraint as c, pg_inherits as i - WHERE i.inhrelid = pg_constraint.conrelid - AND c.conname = pg_constraint.conname - AND c.consrc = pg_constraint.consrc - AND c.conrelid = i.inhparent - )"; - - $constraint_exists = false; - - $result = $this->db->sql_query($constraint_sql); - while ($row = $this->db->sql_fetchrow($result)) - { - if (trim($row['constraint_data']) == trim($column_data['constraint'])) - { - $constraint_exists = true; - break; - } - } - $this->db->sql_freeresult($result); - - if (!$constraint_exists) - { - $sql_array[] = 'ADD ' . $column_data['constraint']; - } - } - - $sql .= implode(', ', $sql_array); - - $statements[] = $sql; - break; - - case 'sqlite': - - if ($inline && $this->return_statements) - { - return $column_name . ' ' . $column_data['column_type_sql']; - } - - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } - - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $statements[] = 'begin'; - - // Create a temp table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; - - preg_match('#\((.*)\)#s', $row['sql'], $matches); - - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); - - foreach ($old_table_cols as $key => $declaration) - { - $entities = preg_split('#\s+#', trim($declaration)); - $column_list[] = $entities[0]; - if ($entities[0] == $column_name) - { - $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql']; - } - } - - $columns = implode(',', $column_list); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; - - $statements[] = 'commit'; - - break; - } - + $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql']; return $this->_sql_run_sql($statements); } } diff --git a/includes/functions.php b/includes/functions.php index aaf851c2..d19e9475 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1294,6 +1294,9 @@ function ip_clean_string($text, $charset = false, $extra_chars = false, $is_file { $charset = empty($charset) ? 'utf-8' : $charset; + // Function needed to convert some of the cyrillic characters into latin correspondent characters + $text = utf_cyr_to_latin($text, false); + // Remove all HTML tags and convert to lowercase $text = strtolower(strip_tags($text)); @@ -1386,6 +1389,53 @@ function ip_clean_string($text, $charset = false, $extra_chars = false, $is_file return $text; } +/** +* Cyrillic to Latin chars conversion +*/ +function utf_cyr_to_latin($string, $reverse = false) +{ + $cyr = array( + 'а', 'б', 'в', 'г', 'д', + 'e', 'ж', 'з', 'и', 'й', + 'к', 'л', 'м', 'н', 'о', + 'п', 'р', 'с', 'т', 'у', + 'ф', 'х', 'ц', 'ч', 'ш', + 'щ', 'ъ', 'ь', 'ю', 'я', + 'А', 'Б', 'В', 'Г', 'Д', + 'Е', 'Ж', 'З', 'И', 'Й', + 'К', 'Л', 'М', 'Н', 'О', + 'П', 'Р', 'С', 'Т', 'У', + 'Ф', 'Х', 'Ц', 'Ч', 'Ш', + 'Щ', 'Ъ', 'Ь', 'Ю', 'Я' + ); + + $lat = array( + 'a', 'b', 'v', 'g', 'd', + 'e', 'zh', 'z', 'i', 'y', + 'k', 'l', 'm', 'n', 'o', + 'p', 'r', 's', 't', 'u', + 'f', 'h', 'ts', 'ch', 'sh', + 'sht', 'a', 'y', 'yu', 'ya', + 'A', 'B', 'V', 'G', 'D', + 'E', 'Zh', 'Z', 'I', 'Y', + 'K', 'L', 'M', 'N', 'O', + 'P', 'R', 'S', 'T', 'U', + 'F', 'H', 'Ts', 'Ch', 'Sh', + 'Sht', 'A', 'Y', 'Yu', 'Ya' + ); + + if (!empty($reverse)) + { + $string = str_replace($lat, $cyr, $string); + } + else + { + $string = str_replace($cyr, $lat, $string); + } + + return $string; +} + /* * jumpbox() : replace the original phpBB make_jumpbox() */ @@ -3061,23 +3111,23 @@ function is_mobile() { global $user; - if (!empty($user) && !empty($user->is_mobile)) + if (!empty($user) && !empty($user->data['is_mobile'])) { return true; } if (!empty($user) && !empty($user->data['is_bot'])) { - $user->is_mobile = false; + $user->data['is_mobile'] = false; return false; } - if (!empty($user)) $user->is_mobile = false; + if (!empty($user)) $user->data['is_mobile'] = false; $browser = (!empty($user) && !empty($user->browser)) ? $user->browser : (!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''); $browser_lc = strtolower($browser); - if (strpos(strtolower($browser), 'windows') !== false) + if (strpos($browser_lc, 'windows') !== false) { return false; } @@ -3085,13 +3135,13 @@ function is_mobile() // Just a quick check on most common browsers... if(preg_match('/(android|blackberry|fennec|htc_|iphone|ipod|mobile|midp|mmp|phone|symbian|smartphone|up.browser|up.link|wap)/i', $browser_lc)) { - if (!empty($user)) $user->is_mobile = true; + if (!empty($user)) $user->data['is_mobile'] = true; return true; } if((strpos(strtolower($_SERVER['HTTP_ACCEPT']), 'application/vnd.wap.xhtml+xml') !== false) || ((isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])))) { - if (!empty($user)) $user->is_mobile = true; + if (!empty($user)) $user->data['is_mobile'] = true; return true; } @@ -3110,13 +3160,13 @@ function is_mobile() if(in_array($mobile_ua, $mobile_agents)) { - if (!empty($user)) $user->is_mobile = true; + if (!empty($user)) $user->data['is_mobile'] = true; return true; } if (strpos(strtolower($_SERVER['ALL_HTTP']), 'OperaMini') !== false) { - if (!empty($user)) $user->is_mobile = true; + if (!empty($user)) $user->data['is_mobile'] = true; return true; } @@ -3129,7 +3179,7 @@ function is_mobile() /* if(preg_match('/android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|htc_|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mobile|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $browser) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i', substr($browser, 0, 4))) { - if (!empty($user)) $user->is_mobile = true; + if (!empty($user)) $user->data['is_mobile'] = true; return true; } */ @@ -4983,11 +5033,13 @@ function page_footer($exit = true, $template_to_parse = 'body', $parse_template //Begin Lo-Fi Mod $path_parts = pathinfo($_SERVER['SCRIPT_NAME']); - $lofi = '' . (empty($_COOKIE['lofi']) ? ($lang['Lofi']) : ($lang['Full_Version'])) . ''; + $lofi = '' . (empty($_COOKIE['lofi']) ? ($lang['Lofi']) : ($lang['Full_Version'])) . ''; + $mobile_style = '' . (!empty($_COOKIE['mob']) ? ($lang['MOBILE_STYLE_DISABLE']) : ($lang['MOBILE_STYLE_ENABLE'])) . ''; $template->assign_vars(array( 'L_LOFI' => $lang['Lofi'], 'L_FULL_VERSION' => $lang['Full_Version'], - 'LOFI' => $lofi + 'LOFI' => $lofi . ($user->data['is_mobile'] ? (' • ' . $mobile_style) : ''), + 'MOBILE_STYLE' => $mobile_style ) ); //End Lo-Fi Mod diff --git a/includes/sessions.php b/includes/sessions.php index 01a99a2b..e67886c1 100644 --- a/includes/sessions.php +++ b/includes/sessions.php @@ -1546,6 +1546,7 @@ function setup($lang_set = false, $style = false) if (empty($disable_mobile_style) && !empty($this->data['is_mobile']) && !defined('IN_CMS') && !defined('IN_ADMIN')) { $this->data['mobile_style'] = true; + @setcookie('mob', 1, time() + 31536000); $theme = setup_mobile_style(); } else diff --git a/includes/settings/settings_seo.php b/includes/settings/settings_seo.php index bab37356..3aab4da0 100644 --- a/includes/settings/settings_seo.php +++ b/includes/settings/settings_seo.php @@ -60,6 +60,16 @@ 'values' => $this->list_yes_no, ), + /* + 'seo_cyrillic' => array( + 'lang_key' => 'IP_seo_cyrillic', + 'explain' => 'IP_seo_cyrillic_explain', + 'type' => 'LIST_RADIO', + 'default' => 0, + 'values' => $this->list_yes_no, + ), + */ + 'adsense_code' => array( 'lang_key' => 'IP_adsense_code', 'explain' => 'IP_adsense_code_explain', diff --git a/install/schemas/db_update_054.sql b/install/schemas/db_update_054.sql index d487d4e2..5f880ca9 100644 --- a/install/schemas/db_update_054.sql +++ b/install/schemas/db_update_054.sql @@ -774,15 +774,15 @@ TRUNCATE TABLE `phpbb_acl_roles_data`; TRUNCATE TABLE `phpbb_acl_users`; # -- CMS related auth options -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 0, 1, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 1, 0, 0); # -- Admin related auth options INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_', 1); @@ -939,12 +939,19 @@ ALTER TABLE `phpbb_posts` CHANGE `post_text_compiled` `post_text_compiled` MEDIU +######################################## +## BUILD 073 ## +######################################## +UPDATE phpbb_acl_options SET is_global = 1, is_local = 0 WHERE auth_option LIKE 'cms_%'; + + + ##################### ##UPDATE phpbb_config SET config_value = '2' WHERE config_name = 'main_admin_id'; #-- DB CHANGES FOR VERSIONING -UPDATE phpbb_config SET config_value = '1.3.19.72' WHERE config_name = 'ip_version'; +UPDATE phpbb_config SET config_value = '1.3.20.73' WHERE config_name = 'ip_version'; UPDATE phpbb_config SET config_value = '.0.23' WHERE config_name = 'version'; UPDATE phpbb_config SET config_value = '2.0.0' WHERE config_name = 'cms_version'; UPDATE phpbb_album_config SET config_value = '1.5.0' WHERE config_name = 'fap_version'; diff --git a/install/schemas/mysql_basic.sql b/install/schemas/mysql_basic.sql index 85d9ac2b..0be06471 100644 --- a/install/schemas/mysql_basic.sql +++ b/install/schemas/mysql_basic.sql @@ -1,7 +1,7 @@ ## Better leaving these input at the beginning... so they will be inserted as first values into tables ## Roll on version INSERT INTO `phpbb_config` (`config_name`, `config_value`) VALUES ('version', '.0.23'); -INSERT INTO `phpbb_config` (`config_name`, `config_value`) VALUES ('ip_version', '1.3.19.72'); +INSERT INTO `phpbb_config` (`config_name`, `config_value`) VALUES ('ip_version', '1.3.20.73'); INSERT INTO `phpbb_config` (`config_name`, `config_value`) VALUES ('cms_version', '2.0.0'); INSERT INTO `phpbb_album_config` (`config_name`, `config_value`) VALUES ('fap_version', '1.5.0'); ## INSERT INTO phpbb_link_config (config_name, config_value) VALUES ('site_logo', 'http://www.mightygorgon.com/images/banners/banner_mightygorgon.gif'); @@ -1815,15 +1815,15 @@ INSERT INTO phpbb_dl_ext_blacklist (extention) VALUES ## AUTH SYSTEM - BEGIN # -- CMS related auth options -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 0, 1, 0); -INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 0, 1, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 1, 0, 0); +INSERT INTO phpbb_acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 1, 0, 0); # -- Admin related auth options INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_', 1); diff --git a/install/schemas/sql_update_ip.php b/install/schemas/sql_update_ip.php index 5eeb3926..e24fcab2 100644 --- a/install/schemas/sql_update_ip.php +++ b/install/schemas/sql_update_ip.php @@ -74,6 +74,7 @@ case '131770': $current_ip_version = '1.3.17.70'; break; case '131871': $current_ip_version = '1.3.18.71'; break; case '131972': $current_ip_version = '1.3.19.72'; break; + case '132073': $current_ip_version = '1.3.20.73'; break; } // We need to force this because in MySQL 5.5.5 the new default DB Engine is InnoDB, not MyISAM any more @@ -4199,15 +4200,15 @@ $sql[] = "TRUNCATE TABLE `" . $table_prefix . "acl_users`"; // CMS related auth options - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 0, 1, 0)"; - $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 0, 1, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (1, 'cms_', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (2, 'cms_view', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (3, 'cms_edit', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (4, 'cms_l_add', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (5, 'cms_l_edit', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (6, 'cms_l_delete', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (7, 'cms_b_add', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (8, 'cms_b_edit', 1, 0, 0)"; + $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option_id, auth_option, is_global, is_local, founder_only) VALUES (9, 'cms_b_delete', 1, 0, 0)"; // Admin related auth options $sql[] = "INSERT INTO " . $table_prefix . "acl_options (auth_option, is_global) VALUES ('a_', 1)"; @@ -4358,6 +4359,10 @@ /* Updating from IP 1.3.19.72 */ case '1.3.19.72': + $sql[] = "UPDATE `" . $table_prefix . "acl_options` SET is_global = 1, is_local = 0 WHERE auth_option LIKE 'cms_%'"; + + /* Updating from IP 1.3.20.73 */ + case '1.3.20.73': } diff --git a/install/schemas/versions.php b/install/schemas/versions.php index 570508c7..87d583c4 100644 --- a/install/schemas/versions.php +++ b/install/schemas/versions.php @@ -23,7 +23,7 @@ // Versioning $fap_version = '1.5.0'; $phpbb_version = '.0.23'; -$ip_version = '1.3.18.71'; +$ip_version = '1.3.20.73'; // CHMOD $chmod_777 = array(); diff --git a/language/lang_english/lang_extend_icy_phoenix.php b/language/lang_english/lang_extend_icy_phoenix.php index c0cadb92..822ff455 100644 --- a/language/lang_english/lang_extend_icy_phoenix.php +++ b/language/lang_english/lang_extend_icy_phoenix.php @@ -374,6 +374,9 @@ 'IP_lofi_bots' => 'LoFi For Bots', 'IP_lofi_bots_explain' => 'By enabling this option LoFi will be enabled for bots.', + 'IP_seo_cyrillic' => 'Cyrillic Chars Conversion', + 'IP_seo_cyrillic_explain' => 'By enabling this option some cyrillic characters will be converted to latin characters (not in posts, but in keywords, tags and where the clean strings function is used).', + 'IP_adsense_code' => 'Google AdSense Publisher Code', 'IP_adsense_code_explain' => 'Insert here your Google AdSense Publisher Code and it will be inserted in the Google Search page. If you don\'t want to use it, just leave this field blank.', diff --git a/language/lang_english/lang_main.php b/language/lang_english/lang_main.php index 1fa2fffc..4657ee21 100644 --- a/language/lang_english/lang_main.php +++ b/language/lang_english/lang_main.php @@ -2412,6 +2412,9 @@ 'LINKEDIN' => 'LinkedIn', 'YOUTUBE' => 'YouTube', + 'MOBILE_STYLE_ENABLE' => 'Enable Mobile Friendly Style', + 'MOBILE_STYLE_DISABLE' => 'Disable Mobile Friendly Style', + ) ); diff --git a/language/lang_english/lang_umil.php b/language/lang_english/lang_umil.php new file mode 100644 index 00000000..63184a30 --- /dev/null +++ b/language/lang_english/lang_umil.php @@ -0,0 +1,127 @@ + 'Action', + 'ADVANCED' => 'Advanced', + 'AUTH_CACHE_PURGE' => 'Purging the Auth Cache', + + 'CACHE_PURGE' => 'Purging your forum’s cache', + 'CONFIGURE' => 'Configure', + 'CONFIG_ADD' => 'Adding new config variable: %s', + 'CONFIG_ALREADY_EXISTS' => 'ERROR: Config variable %s already exists.', + 'CONFIG_NOT_EXIST' => 'ERROR: Config variable %s does not exist.', + 'CONFIG_REMOVE' => 'Removing config variable: %s', + 'CONFIG_UPDATE' => 'Updating config variable: %s', + + 'DISPLAY_RESULTS' => 'Display Full Results', + 'DISPLAY_RESULTS_EXPLAIN' => 'Select yes to display all of the actions and results during the requested action.', + + 'ERROR_NOTICE' => 'One or more errors occured during the requested action. Please download this file with the errors listed in it and ask the mod author for assistance.

If you have any problem downloading that file you may access it directly with an FTP browser at the following location: %2$s', + 'ERROR_NOTICE_NO_FILE' => 'One or more errors occured during the requested action. Please make a full record of any errors and ask the mod author for assistance.', + + 'FAIL' => 'Fail', + 'FILE_COULD_NOT_READ' => 'ERROR: Could not open the file %s for reading.', + 'FOUNDERS_ONLY' => 'You must be a board founder to access this page.', + + 'GROUP_NOT_EXIST' => 'Group does not exist', + + 'IGNORE' => 'Ignore', + 'IMAGESET_CACHE_PURGE' => 'Refreshing the %s imageset', + 'INSTALL' => 'Install', + 'INSTALL_MOD' => 'Install %s', + 'INSTALL_MOD_CONFIRM' => 'Are you ready to install %s?', + + 'MODULE_ADD' => 'Adding %1$s module: %2$s', + 'MODULE_ALREADY_EXIST' => 'ERROR: Module already exists.', + 'MODULE_NOT_EXIST' => 'ERROR: Module does not exist.', + 'MODULE_REMOVE' => 'Removing %1$s module: %2$s', + + 'NONE' => 'None', + 'NO_TABLE_DATA' => 'ERROR: No table data was specified', + + 'PARENT_NOT_EXIST' => 'ERROR: The parent category specified for this module does not exist.', + 'PERMISSIONS_WARNING' => 'New permission settings have been added. Be sure to check your permission settings and see that they are as you would like them.', + 'PERMISSION_ADD' => 'Adding new permission option: %s', + 'PERMISSION_ALREADY_EXISTS' => 'ERROR: Permission option %s already exists.', + 'PERMISSION_NOT_EXIST' => 'ERROR: Permission option %s does not exist.', + 'PERMISSION_REMOVE' => 'Removing permission option: %s', + 'PERMISSION_ROLE_ADD' => 'Adding new permission role: %s', + 'PERMISSION_ROLE_UPDATE' => 'Updating permission role: %s', + 'PERMISSION_ROLE_REMOVE' => 'Removing permission role: %s', + 'PERMISSION_SET_GROUP' => 'Setting permissions for the %s group.', + 'PERMISSION_SET_ROLE' => 'Setting permissions for the %s role.', + 'PERMISSION_UNSET_GROUP' => 'Unsetting permissions for the %s group.', + 'PERMISSION_UNSET_ROLE' => 'Unsetting permissions for the %s role.', + + 'ROLE_ALREADY_EXISTS' => 'Permission role already exists.', + 'ROLE_NOT_EXIST' => 'Permission role does not exist', + + 'SUCCESS' => 'Success', + + 'TABLE_ADD' => 'Adding a new database table: %s', + 'TABLE_ALREADY_EXISTS' => 'ERROR: Database table %s already exists.', + 'TABLE_COLUMN_ADD' => 'Adding a new column named %2$s to table %1$s', + 'TABLE_COLUMN_ALREADY_EXISTS' => 'ERROR: The column %2$s already exists on table %1$s.', + 'TABLE_COLUMN_NOT_EXIST' => 'ERROR: The column %2$s does not exist on table %1$s.', + 'TABLE_COLUMN_REMOVE' => 'Removing the column named %2$s from table %1$s', + 'TABLE_COLUMN_UPDATE' => 'Updating a column named %2$s from table %1$s', + 'TABLE_KEY_ADD' => 'Adding a key named %2$s to table %1$s', + 'TABLE_KEY_ALREADY_EXIST' => 'ERROR: The index %2$s already exists on table %1$s.', + 'TABLE_KEY_NOT_EXIST' => 'ERROR: The index %2$s does not exist on table %1$s.', + 'TABLE_KEY_REMOVE' => 'Removing a key named %2$s from table %1$s', + 'TABLE_NOT_EXIST' => 'ERROR: Database table %s does not exist.', + 'TABLE_REMOVE' => 'Removing database table: %s', + 'TABLE_ROW_INSERT_DATA' => 'Inserting data in the %s database table.', + 'TABLE_ROW_REMOVE_DATA' => 'Removing a row from the %s database table', + 'TABLE_ROW_UPDATE_DATA' => 'Updating a row in the %s database table.', + 'TEMPLATE_CACHE_PURGE' => 'Refreshing the %s template', + 'THEME_CACHE_PURGE' => 'Refreshing the %s theme', + + 'UNINSTALL' => 'Uninstall', + 'UNINSTALL_MOD' => 'Uninstall %s', + 'UNINSTALL_MOD_CONFIRM' => 'Are you ready to uninstall %s? All settings and data saved by this mod will be removed!', + 'UNKNOWN' => 'Unknown', + 'UPDATE_MOD' => 'Update %s', + 'UPDATE_MOD_CONFIRM' => 'Are you ready to update %s?', + 'UPDATE_UMIL' => 'This version of UMIL is outdated.

Please download the latest UMIL (Unified MOD Install Library) from: %1$s', + + 'VERSIONS' => 'Mod Version: %1$s
Currently Installed: %2$s', + 'VERSION_SELECT' => 'Version Select', + 'VERSION_SELECT_EXPLAIN' => 'Do not change from “Ignore” unless you know what you are doing or were told to.', + ) +); + +?> \ No newline at end of file diff --git a/templates/common/common_colors.css b/templates/common/common_colors.css index fe720aba..2f43255d 100644 --- a/templates/common/common_colors.css +++ b/templates/common/common_colors.css @@ -9,7 +9,7 @@ div.rmb-gray { background-color: #eeeeee; border-color: #999999; } div.rmb-green { background-color: #e8ffee; border-color: #00cc00; } div.rmb-orange { background-color: #ffaa55; border-color: #ff5500; } div.rmb-red { background-color: #ffeee8; border-color: #cc0000; } -div.rmb-yellow { background-color: #ffffdd; border-color: #e8dd55; } +div.rmb-yellow { background-color: #ffffdd; border-color: #ffdd22; } /* ROUNDED MSG BOX - END */ /* TEXT BOX - BEGIN */ diff --git a/templates/default/default.cfg b/templates/default/default.cfg index 6d41a714..df3e2952 100644 --- a/templates/default/default.cfg +++ b/templates/default/default.cfg @@ -721,6 +721,7 @@ $template->assign_vars(array( 'S_MOD' => (($user->data['user_level'] == MOD) ? 1 : 0), 'S_ADMIN_MOD' => ((($user->data['user_level'] == ADMIN) || ($user->data['user_level'] == MOD)) ? 1 : 0), 'S_BOT' => ($user->data['is_bot'] ? 1 : 0), + 'S_MOBILE' => ($user->data['is_mobile'] ? 1 : 0), 'S_LOFI' => ((!empty($_COOKIE['lofi'])) || $lofi_bots_parsing) ? true : false, 'S_LOFI_BOTS' => ($user->data['is_bot'] && $config['lofi_bots']) ? true : false, 'S_NIFTY' => (isset($nifty_corners) ? $nifty_corners : true), diff --git a/templates/default/login_body.tpl b/templates/default/login_body.tpl index 8b0b038f..642716e1 100644 --- a/templates/default/login_body.tpl +++ b/templates/default/login_body.tpl @@ -4,28 +4,20 @@ {IMG_THL}{IMG_THC}{L_ENTER_PASSWORD}{IMG_THR} - - + -
+ - - + + - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + +
{L_USERNAME}:{L_USERNAME}:
{L_PASSWORD}:{L_PASSWORD}:
{L_AUTOLOGIN}: 
{L_STATUS}:  {L_DEFAULT}   {L_HIDDEN}   {L_VISIBLE}  

{S_HIDDEN_FIELDS}
+   {L_REGISTER} • {L_SEND_PASSWORD} @@ -34,9 +26,24 @@
 {L_STATUS}:   {L_DEFAULT}     {L_HIDDEN}     {L_VISIBLE}  

   {L_AUTOLOGIN}
 {S_HIDDEN_FIELDS}
{IMG_TFL}{IMG_TFC}{IMG_TFR} diff --git a/templates/mobile/overall_footer.tpl b/templates/mobile/overall_footer.tpl index 2f1fbb3f..7cf78beb 100644 --- a/templates/mobile/overall_footer.tpl +++ b/templates/mobile/overall_footer.tpl @@ -9,12 +9,8 @@