diff options
| author | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:37 +0100 |
|---|---|---|
| committer | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:37 +0100 |
| commit | 54f94e0d428c5963ecca86a40247105e51288432 (patch) | |
| tree | 275c5ec85c31595d0341d6ad630565b7a6a4cdcc /phpBB/includes | |
| parent | 1a09d0e238666a386a76878d6395986947b11c1e (diff) | |
| parent | b5535db081dca0187caae84cf7ffd8d6045dccba (diff) | |
| download | forums-54f94e0d428c5963ecca86a40247105e51288432.tar forums-54f94e0d428c5963ecca86a40247105e51288432.tar.gz forums-54f94e0d428c5963ecca86a40247105e51288432.tar.bz2 forums-54f94e0d428c5963ecca86a40247105e51288432.tar.xz forums-54f94e0d428c5963ecca86a40247105e51288432.zip | |
Merge commit 'release-3.0-RC6'
Diffstat (limited to 'phpBB/includes')
151 files changed, 6174 insertions, 2732 deletions
diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php index a1734c1c55..2b9eca6c88 100644 --- a/phpBB/includes/acm/acm_file.php +++ b/phpBB/includes/acm/acm_file.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acm * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ACM File Based Caching * @package acm */ @@ -64,7 +72,7 @@ class acm /** * Save modified objects */ - function save() + function save() { if (!$this->is_modified) { diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 95a2b0e322..4ab47ec9d6 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_attachments @@ -27,6 +35,14 @@ class acp_attachments $submit = (isset($_POST['submit'])) ? true : false; $action = request_var('action', ''); + $form_key = 'acp_attach'; + add_form_key($form_key); + + if ($submit && !check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + switch ($mode) { case 'attach': @@ -288,7 +304,7 @@ class acp_attachments { if ($row['group_id'] != $extensions[$row['extension_id']]['group_id']) { - $sql = 'UPDATE ' . EXTENSIONS_TABLE . ' + $sql = 'UPDATE ' . EXTENSIONS_TABLE . ' SET group_id = ' . (int) $extensions[$row['extension_id']]['group_id'] . ' WHERE extension_id = ' . $row['extension_id']; $db->sql_query($sql); @@ -303,7 +319,7 @@ class acp_attachments if (sizeof($extension_id_list)) { - $sql = 'SELECT extension + $sql = 'SELECT extension FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $result = $db->sql_query($sql); @@ -315,7 +331,7 @@ class acp_attachments } $db->sql_freeresult($result); - $sql = 'DELETE + $sql = 'DELETE FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $db->sql_query($sql); @@ -371,8 +387,8 @@ class acp_attachments 'GROUP_SELECT_OPTIONS' => (isset($_POST['add_extension_check'])) ? $this->group_select('add_group_select', $add_extension_group, 'extension_group') : $this->group_select('add_group_select', false, 'extension_group')) ); - $sql = 'SELECT * - FROM ' . EXTENSIONS_TABLE . ' + $sql = 'SELECT * + FROM ' . EXTENSIONS_TABLE . ' ORDER BY group_id, extension'; $result = $db->sql_query($sql); @@ -452,7 +468,7 @@ class acp_attachments // Check New Group Name if ($new_group_name) { - $sql = 'SELECT group_id + $sql = 'SELECT group_id FROM ' . EXTENSION_GROUPS_TABLE . " WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($new_group_name)) . "'"; $result = $db->sql_query($sql); @@ -527,7 +543,7 @@ class acp_attachments if (sizeof($extension_list)) { - $sql = 'UPDATE ' . EXTENSIONS_TABLE . " + $sql = 'UPDATE ' . EXTENSIONS_TABLE . " SET group_id = $group_id WHERE " . $db->sql_in_set('extension_id', $extension_list); $db->sql_query($sql); @@ -559,15 +575,15 @@ class acp_attachments if (confirm_box(true)) { - $sql = 'SELECT group_name + $sql = 'SELECT group_name FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $group_name = (string) $db->sql_fetchfield('group_name'); $db->sql_freeresult($result); - $sql = 'DELETE - FROM ' . EXTENSION_GROUPS_TABLE . " + $sql = 'DELETE + FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $db->sql_query($sql); @@ -983,7 +999,7 @@ class acp_attachments 'PHYSICAL_FILENAME' => basename($row['physical_filename']), 'ATTACH_ID' => $row['attach_id'], 'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? $post_ids[$row['attach_id']] : '', - 'U_FILE' => append_sid($phpbb_root_path . 'download.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) + 'U_FILE' => append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) ); } $db->sql_freeresult($result); diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php index 206f332c36..77fb44dda9 100644 --- a/phpBB/includes/acp/acp_ban.php +++ b/phpBB/includes/acp/acp_ban.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_ban @@ -23,11 +31,18 @@ class acp_ban include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $bansubmit = (isset($_POST['bansubmit'])) ? true : false; - $unbansubmit= (isset($_POST['unbansubmit'])) ? true : false; + $unbansubmit = (isset($_POST['unbansubmit'])) ? true : false; $current_time = time(); $user->add_lang(array('acp/ban', 'acp/users')); $this->tpl_name = 'acp_ban'; + $form_key = 'acp_ban'; + add_form_key($form_key); + + if (($bansubmit || $unbansubmit) && !check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } // Ban submitted? if ($bansubmit) @@ -97,9 +112,8 @@ class acp_ban 'S_USERNAME_BAN' => ($mode == 'user') ? true : false, 'U_ACTION' => $this->u_action, - 'U_FIND_USER' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_ban&field=ban'), - ) - ); + 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_ban&field=ban'), + )); } /** @@ -179,10 +193,10 @@ class acp_ban foreach ($ban_length as $ban_id => $length) { $template->assign_block_vars('ban_length', array( - 'BAN_ID' => $ban_id, + 'BAN_ID' => (int) $ban_id, 'LENGTH' => $length, - 'A_LENGTH' => addslashes($length)) - ); + 'A_LENGTH' => addslashes($length), + )); } } @@ -193,8 +207,8 @@ class acp_ban $template->assign_block_vars('ban_reason', array( 'BAN_ID' => $ban_id, 'REASON' => $reason, - 'A_REASON' => addslashes(htmlspecialchars_decode($reason))) - ); + 'A_REASON' => addslashes(htmlspecialchars_decode($reason)), + )); } } @@ -205,8 +219,8 @@ class acp_ban $template->assign_block_vars('ban_give_reason', array( 'BAN_ID' => $ban_id, 'REASON' => $reason, - 'A_REASON' => addslashes(htmlspecialchars_decode($reason))) - ); + 'A_REASON' => addslashes(htmlspecialchars_decode($reason)), + )); } } diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index 235028fc3c..21370036ee 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_bbcodes @@ -28,6 +36,9 @@ class acp_bbcodes $this->tpl_name = 'acp_bbcodes'; $this->page_title = 'ACP_BBCODES'; + $form_key = 'acp_bbcodes'; + + add_form_key($form_key); // Set up mode-specific vars switch ($action) @@ -320,6 +331,17 @@ class acp_bbcodes ) ); + $sp_tokens = array( + 'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)', + 'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)', + 'EMAIL' => '([a-zA-Z0-9]+[a-zA-Z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-zA-Z0-9]+[a-zA-Z0-9\-\._]*\.[a-zA-Z]+))', + 'TEXT' => '(.*?)', + 'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)', + 'IDENTIFIER' => '([a-zA-Z0-9-_]+)', + 'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)', + 'NUMBER' => '([0-9]+)', + ); + $pad = 0; $modifiers = 'i'; @@ -365,7 +387,7 @@ class acp_bbcodes $fp_match = str_replace(preg_quote($token, '!'), $regex, $fp_match); $fp_replace = str_replace($token, $replace, $fp_replace); - $sp_match = str_replace(preg_quote($token, '!'), '(.*?)', $sp_match); + $sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match); $sp_replace = str_replace($token, '${' . ($n + 1) . '}', $sp_replace); } diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 463087e106..4d467b6895 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -10,6 +10,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_board @@ -27,6 +35,9 @@ class acp_board $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; + $form_key = 'acp_board'; + add_form_key($form_key); + /** * Validation types are: * string, int, bool, @@ -212,6 +223,8 @@ class acp_board 'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true), 'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true), + 'min_time_reg' => array('lang' => 'MIN_TIME_REG', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), + 'min_time_terms' => array('lang' => 'MIN_TIME_TERMS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'legend3' => 'COPPA', 'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), @@ -314,6 +327,10 @@ class acp_board 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true), 'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), + 'form_token_mintime' => array('lang' => 'FORM_TIME_MIN', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), + 'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + ) ); break; @@ -360,6 +377,10 @@ class acp_board // We validate the complete config if whished validate_config_vars($display_vars['vars'], $cfg_array, $error); + if ($submit && !check_form_key($form_key)) + { + $error[] = $user->lang['FORM_INVALID']; + } // Do not write values if there is an error if (sizeof($error)) { @@ -407,7 +428,7 @@ class acp_board { if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file)) { - $auth_plugins[] = preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file); + $auth_plugins[] = basename(preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file)); } } closedir($dp); @@ -459,7 +480,7 @@ class acp_board if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings)) { - $method = $cfg_array['auth_method']; + $method = basename($cfg_array['auth_method']); if ($method && in_array($method, $auth_plugins)) { include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx); @@ -476,7 +497,7 @@ class acp_board trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } } - set_config('auth_method', $cfg_array['auth_method']); + set_config('auth_method', basename($cfg_array['auth_method'])); } else { @@ -784,7 +805,7 @@ class acp_board $user->timezone = $old_tz; $user->dst = $old_dst; - return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('$key').value = '$value'; } else { document.getElementById('$key').value = this.value; }\">$dateformat_options</select> + return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('" . addslashes($key) . "').value = '" . addslashes($value) . "'; } else { document.getElementById('" . addslashes($key) . "').value = this.value; }\">$dateformat_options</select> <input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"30\" />"; } } diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php index 93108c7fec..d08cabb062 100644 --- a/phpBB/includes/acp/acp_bots.php +++ b/phpBB/includes/acp/acp_bots.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_bots @@ -35,6 +43,13 @@ class acp_bots $user->add_lang('acp/bots'); $this->tpl_name = 'acp_bots'; $this->page_title = 'ACP_BOTS'; + $form_key = 'acp_bots'; + add_form_key($form_key); + + if ($submit && !check_form_key($form_key)) + { + $error[] = $user->lang['FORM_INVALID']; + } // User wants to do something, how inconsiderate of them! switch ($action) @@ -44,7 +59,7 @@ class acp_bots { $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; - $sql = 'UPDATE ' . BOTS_TABLE . " + $sql = 'UPDATE ' . BOTS_TABLE . " SET bot_active = 1 WHERE bot_id $sql_id"; $db->sql_query($sql); @@ -58,7 +73,7 @@ class acp_bots { $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; - $sql = 'UPDATE ' . BOTS_TABLE . " + $sql = 'UPDATE ' . BOTS_TABLE . " SET bot_active = 0 WHERE bot_id $sql_id"; $db->sql_query($sql); @@ -75,8 +90,8 @@ class acp_bots // We need to delete the relevant user, usergroup and bot entries ... $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; - $sql = 'SELECT bot_name, user_id - FROM ' . BOTS_TABLE . " + $sql = 'SELECT bot_name, user_id + FROM ' . BOTS_TABLE . " WHERE bot_id $sql_id"; $result = $db->sql_query($sql); @@ -90,7 +105,7 @@ class acp_bots $db->sql_transaction('begin'); - $sql = 'DELETE FROM ' . BOTS_TABLE . " + $sql = 'DELETE FROM ' . BOTS_TABLE . " WHERE bot_id $sql_id"; $db->sql_query($sql); @@ -193,9 +208,9 @@ class acp_bots // New bot? Create a new user and group entry if ($action == 'add') { - $sql = 'SELECT group_id, group_colour - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'BOTS' + $sql = 'SELECT group_id, group_colour + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS' AND group_type = " . GROUP_SPECIAL; $result = $db->sql_query($sql); $group_row = $db->sql_fetchrow($result); @@ -208,22 +223,22 @@ class acp_bots $user_id = user_add(array( - 'user_type' => (int) USER_IGNORE, - 'group_id' => (int) $group_row['group_id'], - 'username' => (string) $bot_row['bot_name'], + 'user_type' => (int) USER_IGNORE, + 'group_id' => (int) $group_row['group_id'], + 'username' => (string) $bot_row['bot_name'], 'user_regdate' => time(), 'user_password' => '', 'user_colour' => (string) $group_row['group_colour'], 'user_email' => '', - 'user_lang' => (string) $bot_row['bot_lang'], + 'user_lang' => (string) $bot_row['bot_lang'], 'user_style' => (int) $bot_row['bot_style'], 'user_allow_massemail' => 0, )); $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( 'user_id' => (int) $user_id, - 'bot_name' => (string) $bot_row['bot_name'], - 'bot_active' => (int) $bot_row['bot_active'], + 'bot_name' => (string) $bot_row['bot_name'], + 'bot_active' => (int) $bot_row['bot_active'], 'bot_agent' => (string) $bot_row['bot_agent'], 'bot_ip' => (string) $bot_row['bot_ip']) ); @@ -233,8 +248,8 @@ class acp_bots } else if ($bot_id) { - $sql = 'SELECT user_id, bot_name - FROM ' . BOTS_TABLE . " + $sql = 'SELECT user_id, bot_name + FROM ' . BOTS_TABLE . " WHERE bot_id = $bot_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); @@ -260,8 +275,8 @@ class acp_bots $db->sql_query($sql); $sql = 'UPDATE ' . BOTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array( - 'bot_name' => (string) $bot_row['bot_name'], - 'bot_active' => (int) $bot_row['bot_active'], + 'bot_name' => (string) $bot_row['bot_name'], + 'bot_active' => (int) $bot_row['bot_active'], 'bot_agent' => (string) $bot_row['bot_agent'], 'bot_ip' => (string) $bot_row['bot_ip']) ) . " WHERE bot_id = $bot_id"; @@ -285,7 +300,7 @@ class acp_bots } else if ($bot_id) { - $sql = 'SELECT b.*, u.user_lang, u.user_style + $sql = 'SELECT b.*, u.user_lang, u.user_style FROM ' . BOTS_TABLE . ' b, ' . USERS_TABLE . " u WHERE b.bot_id = $bot_id AND u.user_id = b.user_id"; @@ -351,7 +366,7 @@ class acp_bots 'S_BOT_OPTIONS' => $s_options) ); - $sql = 'SELECT b.bot_id, b.bot_name, b.bot_active, u.user_lastvisit + $sql = 'SELECT b.bot_id, b.bot_name, b.bot_active, u.user_lastvisit FROM ' . BOTS_TABLE . ' b, ' . USERS_TABLE . ' u WHERE u.user_id = b.user_id ORDER BY u.user_lastvisit DESC, b.bot_name ASC'; diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index 7386c378a3..0d653c22d1 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -1,11 +1,19 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +*/ + +/** +* @ignore */ +if (!defined('IN_PHPBB')) +{ + exit; +} /** * @package acp @@ -46,7 +54,7 @@ class acp_captcha } $captcha = new captcha(); $captcha->execute(gen_rand_string(mt_rand(5, 8)), time()); - exit; + exit_handler(); } $config_vars = array( @@ -57,9 +65,12 @@ class acp_captcha $this->tpl_name = 'acp_captcha'; $this->page_title = 'ACP_VC_SETTINGS'; + $form_key = 'acp_captcha'; + add_form_key($form_key); + $submit = request_var('submit', ''); - - if ($submit) + + if ($submit && check_form_key($form_key)) { $config_vars = array_keys($config_vars); foreach ($config_vars as $config_var) @@ -73,6 +84,10 @@ class acp_captcha } trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } + else if ($submit) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action)); + } else { diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index d8d4b8a306..62331fbca2 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_database @@ -713,7 +721,7 @@ class mysql_extractor extends base_extractor // Get field information $field = array(); - for ($i = 0; $i < $fields_cnt; $i++) + for ($i = 0; $i < $fields_cnt; $i++) { $field[] = mysql_fetch_field($result, $i); } @@ -915,8 +923,8 @@ class sqlite_extractor extends base_extractor $sql_data .= "DROP TABLE $table_name;\n"; $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' + FROM sqlite_master + WHERE type = 'table' AND name = '" . $db->sql_escape($table_name) . "' ORDER BY type DESC, name;"; $result = $db->sql_query($sql); @@ -974,8 +982,8 @@ class sqlite_extractor extends base_extractor else { $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' + FROM sqlite_master + WHERE type = 'table' AND name = '" . $table_name . "'"; $table_data = sqlite_single_query($db->db_connect_id, $sql); $table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data); diff --git a/phpBB/includes/acp/acp_disallow.php b/phpBB/includes/acp/acp_disallow.php index 4be61ad778..9549955cc8 100644 --- a/phpBB/includes/acp/acp_disallow.php +++ b/phpBB/includes/acp/acp_disallow.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_disallow @@ -28,9 +36,17 @@ class acp_disallow $this->tpl_name = 'acp_disallow'; $this->page_title = 'ACP_DISALLOW_USERNAMES'; + $form_key = 'acp_disallow'; + add_form_key($form_key); + $disallow = (isset($_POST['disallow'])) ? true : false; $allow = (isset($_POST['allow'])) ? true : false; + if (($allow || $disallow) && !check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if ($disallow) { $disallowed_user = str_replace('*', '%', utf8_normalize_nfc(request_var('disallowed_user', '', true))); diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php index 50f3d2a4c8..125908c296 100644 --- a/phpBB/includes/acp/acp_email.php +++ b/phpBB/includes/acp/acp_email.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_email @@ -24,6 +32,9 @@ class acp_email $this->tpl_name = 'acp_email'; $this->page_title = 'ACP_MASS_EMAIL'; + $form_key = 'acp_email'; + add_form_key($form_key); + // Set some vars $submit = (isset($_POST['submit'])) ? true : false; $error = array(); @@ -36,11 +47,16 @@ class acp_email // Do the job ... if ($submit) { - // Error checking needs to go here ... if no subject and/or no message then skip + // Error checking needs to go here ... if no subject and/or no message then skip // over the send and return to the form $use_queue = (isset($_POST['send_immediately'])) ? false : true; $priority = request_var('mail_priority_flag', MAIL_NORMAL_PRIORITY); + if (!check_form_key($form_key)) + { + $error[] = $user->lang['FORM_INVALID']; + } + if (!$subject) { $error[] = $user->lang['NO_EMAIL_SUBJECT']; @@ -56,7 +72,7 @@ class acp_email if ($usernames) { // If giving usernames the admin is able to email inactive users too... - $sql = 'SELECT username, user_email, user_jabber, user_notify_type, user_lang + $sql = 'SELECT username, user_email, user_jabber, user_notify_type, user_lang FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', explode("\n", $usernames))) . ' AND user_allow_massemail = 1 @@ -66,18 +82,18 @@ class acp_email { if ($group_id) { - $sql = 'SELECT u.user_email, u.username, u.username_clean, u.user_lang, u.user_jabber, u.user_notify_type - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug + $sql = 'SELECT u.user_email, u.username, u.username_clean, u.user_lang, u.user_jabber, u.user_notify_type + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug WHERE ug.group_id = ' . $group_id . ' AND ug.user_pending = 0 - AND u.user_id = ug.user_id + AND u.user_id = ug.user_id AND u.user_allow_massemail = 1 AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') ORDER BY u.user_lang, u.user_notify_type'; } else { - $sql = 'SELECT username, username_clean, user_email, user_jabber, user_notify_type, user_lang + $sql = 'SELECT username, username_clean, user_email, user_jabber, user_notify_type, user_lang FROM ' . USERS_TABLE . ' WHERE user_allow_massemail = 1 AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') @@ -235,7 +251,6 @@ class acp_email 'S_GROUP_OPTIONS' => $select_list, 'USERNAMES' => $usernames, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_email&field=usernames'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_email&field=usernames', false), 'SUBJECT' => $subject, 'MESSAGE' => $message, 'S_PRIORITY_OPTIONS' => $s_priority_options) diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index fd2602d329..50b67d0346 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_forums @@ -25,13 +33,20 @@ class acp_forums $this->tpl_name = 'acp_forums'; $this->page_title = 'ACP_MANAGE_FORUMS'; + $form_key = 'acp_forums'; + add_form_key($form_key); + $action = request_var('action', ''); $update = (isset($_POST['update'])) ? true : false; $forum_id = request_var('f', 0); $this->parent_id = request_var('parent_id', 0); - $forum_data = $errors = array(); + if ($update && !check_form_key($form_key)) + { + $update = false; + $error[] = $user->lang['FORM_INVALID']; + } // Check additional permissions switch ($action) @@ -41,7 +56,7 @@ class acp_forums $total = request_var('total', 0); $this->display_progress_bar($start, $total); - exit; + exit_handler(); break; case 'delete': @@ -118,8 +133,8 @@ class acp_forums 'forum_image' => request_var('forum_image', ''), 'forum_style' => request_var('forum_style', 0), 'display_on_index' => request_var('display_on_index', false), - 'forum_topics_per_page' => request_var('topics_per_page', 0), - 'enable_indexing' => request_var('enable_indexing', true), + 'forum_topics_per_page' => request_var('topics_per_page', 0), + 'enable_indexing' => request_var('enable_indexing', true), 'enable_icons' => request_var('enable_icons', false), 'enable_prune' => request_var('enable_prune', false), 'enable_post_review' => request_var('enable_post_review', true), @@ -131,6 +146,7 @@ class acp_forums 'prune_sticky' => request_var('prune_sticky', false), 'forum_password' => request_var('forum_password', '', true), 'forum_password_confirm'=> request_var('forum_password_confirm', '', true), + 'forum_password_unset' => request_var('forum_password_unset', false), ); // Use link_display_on_index setting if forum type is link @@ -163,7 +179,8 @@ class acp_forums $forum_perm_from = request_var('forum_perm_from', 0); // Copy permissions? - if ($forum_perm_from && !empty($forum_perm_from) && $forum_perm_from != $forum_data['forum_id']) + if ($forum_perm_from && !empty($forum_perm_from) && $forum_perm_from != $forum_data['forum_id'] && + (($action != 'edit') || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')))) { // if we edit a forum delete current permissions first if ($action == 'edit') @@ -343,7 +360,7 @@ class acp_forums $template->assign_vars(array( 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$topics_done&total={$row['forum_topics_real']}", - 'UA_PROGRESS_BAR' => str_replace('&', '&', $this->u_action) . "&action=progress_bar&start=$topics_done&total={$row['forum_topics_real']}", + 'UA_PROGRESS_BAR' => addslashes($this->u_action . "&action=progress_bar&start=$topics_done&total={$row['forum_topics_real']}"), 'S_CONTINUE_SYNC' => true, 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['forum_topics_real'])) ); @@ -357,7 +374,7 @@ class acp_forums $template->assign_vars(array( 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar', - 'UA_PROGRESS_BAR' => str_replace('&', '&', $this->u_action) . '&action=progress_bar', + 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'), 'S_CONTINUE_SYNC' => true, 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], 0, $row['forum_topics_real'])) ); @@ -454,8 +471,8 @@ class acp_forums 'forum_image' => '', 'forum_style' => 0, 'display_on_index' => false, - 'forum_topics_per_page' => 0, - 'enable_indexing' => true, + 'forum_topics_per_page' => 0, + 'enable_indexing' => true, 'enable_icons' => false, 'enable_prune' => false, 'prune_days' => 7, @@ -593,6 +610,11 @@ class acp_forums } } } + + if (strlen($forum_data['forum_password']) == 32) + { + $errors[] = 'FORUM_PASSWORD_OLD'; + } $template->assign_vars(array( 'S_EDIT_FORUM' => true, @@ -619,8 +641,6 @@ class acp_forums 'PRUNE_DAYS' => $forum_data['prune_days'], 'PRUNE_VIEWED' => $forum_data['prune_viewed'], 'TOPICS_PER_PAGE' => $forum_data['forum_topics_per_page'], - 'FORUM_PASSWORD' => $forum_data['forum_password'], - 'FORUM_PASSWORD_CONFIRM' => $forum_data['forum_password_confirm'], 'FORUM_RULES_LINK' => $forum_data['forum_rules_link'], 'FORUM_RULES' => $forum_data['forum_rules'], 'FORUM_RULES_PREVIEW' => $forum_rules_preview, @@ -628,6 +648,7 @@ class acp_forums 'S_BBCODE_CHECKED' => ($forum_rules_data['allow_bbcode']) ? true : false, 'S_SMILIES_CHECKED' => ($forum_rules_data['allow_smilies']) ? true : false, 'S_URLS_CHECKED' => ($forum_rules_data['allow_urls']) ? true : false, + 'S_FORUM_PASSWORD_SET' => (empty($forum_data['forum_password'])) ? false : true, 'FORUM_DESC' => $forum_desc_data['text'], 'S_DESC_BBCODE_CHECKED' => ($forum_desc_data['allow_bbcode']) ? true : false, @@ -656,8 +677,8 @@ class acp_forums 'S_PRUNE_STICKY' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_STICKY) ? true : false, 'S_DISPLAY_ACTIVE_TOPICS' => ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) ? true : false, 'S_ENABLE_POST_REVIEW' => ($forum_data['forum_flags'] & FORUM_FLAG_POST_REVIEW) ? true : false, - ) - ); + 'S_CAN_COPY_PERMISSIONS' => ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))) ? true : false, + )); return; @@ -829,8 +850,8 @@ class acp_forums 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar', - 'UA_PROGRESS_BAR' => str_replace('&', '&', $this->u_action) . '&action=progress_bar') - ); + 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'), + )); } /** @@ -927,7 +948,22 @@ class acp_forums { return $errors; } - + + // As we don't know the old password, it's kinda tricky to detect changes + if ($forum_data_sql['forum_password_unset']) + { + $forum_data_sql['forum_password'] = ''; + } + else if (empty($forum_data_sql['forum_password'])) + { + unset($forum_data_sql['forum_password']); + } + else + { + $forum_data_sql['forum_password'] = phpbb_hash($forum_data_sql['forum_password']); + } + unset($forum_data_sql['forum_password_unset']); + if (!isset($forum_data_sql['forum_id'])) { // no forum_id means we're creating a new forum @@ -1069,7 +1105,7 @@ class acp_forums $db->sql_query($sql); // Delete forum ids from extension groups table - $sql = 'SELECT group_id, allowed_forums + $sql = 'SELECT group_id, allowed_forums FROM ' . EXTENSION_GROUPS_TABLE; $result = $db->sql_query($sql); @@ -1083,7 +1119,7 @@ class acp_forums $allowed_forums = unserialize(trim($_row['allowed_forums'])); $allowed_forums = array_diff($allowed_forums, $forum_ids); - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " SET allowed_forums = '" . ((sizeof($allowed_forums)) ? serialize($allowed_forums) : '') . "' WHERE group_id = {$_row['group_id']}"; $db->sql_query($sql); @@ -1100,7 +1136,7 @@ class acp_forums return array($user->lang['NO_DESTINATION_FORUM']); } - $sql = 'SELECT forum_name + $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $subforums_to_id; $result = $db->sql_query($sql); @@ -1355,7 +1391,7 @@ class acp_forums { $log_action_posts = 'MOVE_POSTS'; - $sql = 'SELECT forum_name + $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $posts_to_id; $result = $db->sql_query($sql); @@ -1419,7 +1455,7 @@ class acp_forums { $log_action_forums = 'MOVE_FORUMS'; - $sql = 'SELECT forum_name + $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $subforums_to_id; $result = $db->sql_query($sql); @@ -1501,7 +1537,7 @@ class acp_forums $db->sql_query($sql); // Delete forum ids from extension groups table - $sql = 'SELECT group_id, allowed_forums + $sql = 'SELECT group_id, allowed_forums FROM ' . EXTENSION_GROUPS_TABLE; $result = $db->sql_query($sql); @@ -1515,7 +1551,7 @@ class acp_forums $allowed_forums = unserialize(trim($row['allowed_forums'])); $allowed_forums = array_diff($allowed_forums, $forum_ids); - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " SET allowed_forums = '" . ((sizeof($allowed_forums)) ? serialize($allowed_forums) : '') . "' WHERE group_id = {$row['group_id']}"; $db->sql_query($sql); @@ -1718,12 +1754,12 @@ class acp_forums { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0 - WHERE user_id = ' . $poster_id . ' + WHERE user_id = ' . $poster_id . ' AND user_posts < ' . $substract; $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - ' . $substract . ' - WHERE user_id = ' . $poster_id . ' + WHERE user_id = ' . $poster_id . ' AND user_posts >= ' . $substract; $db->sql_query($sql); } @@ -1732,7 +1768,7 @@ class acp_forums $db->sql_transaction('commit'); // Make sure the overall post/topic count is correct... - $sql = 'SELECT COUNT(post_id) AS stat + $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' WHERE post_approved = 1'; $result = $db->sql_query($sql); @@ -1842,7 +1878,7 @@ class acp_forums ELSE {$diff_down} END, forum_parents = '' - WHERE + WHERE left_id BETWEEN {$left_id} AND {$right_id} AND right_id BETWEEN {$left_id} AND {$right_id}"; $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 35499b132f..eb785ced23 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_groups @@ -24,6 +32,9 @@ class acp_groups $this->tpl_name = 'acp_groups'; $this->page_title = 'ACP_GROUPS_MANAGE'; + $form_key = 'acp_groups'; + add_form_key($form_key); + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); // Check and set some common vars @@ -36,6 +47,7 @@ class acp_groups $start = request_var('start', 0); $update = (isset($_POST['update'])) ? true : false; + // Clear some vars $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false; $group_row = array(); @@ -43,8 +55,8 @@ class acp_groups // Grab basic data for group, if group_id is set and exists if ($group_id) { - $sql = 'SELECT * - FROM ' . GROUPS_TABLE . " + $sql = 'SELECT * + FROM ' . GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $group_row = $db->sql_fetchrow($result); @@ -111,9 +123,9 @@ class acp_groups do { - $sql = 'SELECT user_id + $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . " - WHERE group_id = $group_id + WHERE group_id = $group_id ORDER BY user_id"; $result = $db->sql_query_limit($sql, 200, $start); @@ -251,13 +263,18 @@ class acp_groups $error = array(); $user->add_lang('ucp'); - + $avatar_select = basename(request_var('avatar_select', '')); $category = basename(request_var('category', '')); // Did we submit? if ($update) { + if (!check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + $group_name = utf8_normalize_nfc(request_var('group_name', '', true)); $group_desc = utf8_normalize_nfc(request_var('group_desc', '', true)); $group_type = request_var('group_type', GROUP_FREE); @@ -290,10 +307,10 @@ class acp_groups { // Avatar stuff $var_ary = array( - 'uploadurl' => array('string', true, 5, 255), - 'remotelink' => array('string', true, 5, 255), - 'width' => array('string', true, 1, 3), - 'height' => array('string', true, 1, 3), + 'uploadurl' => array('string', true, 5, 255), + 'remotelink' => array('string', true, 5, 255), + 'width' => array('string', true, 1, 3), + 'height' => array('string', true, 1, 3), ); if (!($error = validate_data($data, $var_ary))) @@ -366,7 +383,7 @@ class acp_groups if (!sizeof($error)) { // Only set the rank, colour, etc. if it's changed or if we're adding a new - // group. This prevents existing group members being updated if no changes + // group. This prevents existing group members being updated if no changes // were made. $group_attributes = array(); @@ -468,7 +485,7 @@ class acp_groups $group_rank = $group_row['group_rank']; } - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . RANKS_TABLE . ' WHERE rank_special = 1 ORDER BY rank_title'; @@ -558,7 +575,6 @@ class acp_groups 'U_BACK' => $u_back, 'U_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=settings&name=group_colour'), - 'UA_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=settings&name=group_colour', false), 'U_ACTION' => "{$this->u_action}&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], round($config['avatar_filesize'] / 1024)), ) @@ -577,9 +593,9 @@ class acp_groups $this->page_title = 'GROUP_MEMBERS'; // Grab the leaders - always, on every page... - $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug - WHERE ug.group_id = $group_id + $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug + WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 1 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; @@ -600,9 +616,9 @@ class acp_groups $db->sql_freeresult($result); // Total number of group members (non-leaders) - $sql = 'SELECT COUNT(user_id) AS total_members - FROM ' . USER_GROUP_TABLE . " - WHERE group_id = $group_id + $sql = 'SELECT COUNT(user_id) AS total_members + FROM ' . USER_GROUP_TABLE . " + WHERE group_id = $group_id AND group_leader = 0"; $result = $db->sql_query($sql); $total_members = (int) $db->sql_fetchfield('total_members'); @@ -628,14 +644,13 @@ class acp_groups 'U_ACTION' => $this->u_action . "&g=$group_id", 'U_BACK' => $this->u_action, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=list&field=usernames'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=list&field=usernames', false), - 'U_DEFAULT_ALL' => "{$this->u_action}&action=default&g=$group_id") - ); + 'U_DEFAULT_ALL' => "{$this->u_action}&action=default&g=$group_id", + )); // Grab the members - $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug - WHERE ug.group_id = $group_id + $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug + WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 0 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index 56a660ced2..97864d0e27 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @todo [smilies] check regular expressions for special char replacements (stored specialchared in db) * @package acp */ @@ -30,6 +38,8 @@ class acp_icons $action = (isset($_POST['import'])) ? 'import' : $action; $icon_id = request_var('id', 0); + $mode = ($mode == 'smilies') ? 'smilies' : 'icons'; + $this->tpl_name = 'acp_icons'; // What are we working on? @@ -106,7 +116,7 @@ class acp_icons if ($action == 'add' && $mode == 'smilies') { - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY smiley_order'; $result = $db->sql_query($sql); @@ -145,8 +155,8 @@ class acp_icons } } - $sql = "SELECT * - FROM $table + $sql = "SELECT * + FROM $table ORDER BY {$fields}_order " . (($icon_id || $action == 'add') ? 'DESC' : 'ASC'); $result = $db->sql_query($sql); @@ -200,13 +210,13 @@ class acp_icons $db->sql_freeresult($result); $order_list = '<option value="1"' . ((!isset($after)) ? ' selected="selected"' : '') . '>' . $user->lang['FIRST'] . '</option>'; - $add_order_list = '<option value="1">' . $user->lang['FIRST'] . '</option>'; - + $add_order_list = '<option value="1">' . $user->lang['FIRST'] . '</option>'; + if ($action == 'add') { $data = $_images; } - + $colspan = (($mode == 'smilies') ? '7' : '5'); $colspan += ($icon_id) ? 1 : 0; $colspan += ($action == 'add') ? 2 : 0; @@ -241,6 +251,7 @@ class acp_icons { $template->assign_block_vars('items', array( 'IMG' => $img, + 'A_IMG' => addslashes($img), 'IMG_SRC' => $phpbb_root_path . $img_path . '/' . $img, 'CODE' => ($mode == 'smilies' && isset($img_row['code'])) ? $img_row['code'] : '', @@ -385,7 +396,7 @@ class acp_icons if ($action == 'modify' && !empty($image_id[$image])) { $sql = "UPDATE $table - SET " . $db->sql_build_array('UPDATE', $img_sql) . " + SET " . $db->sql_build_array('UPDATE', $img_sql) . " WHERE {$fields}_id = " . $image_id[$image]; $db->sql_query($sql); $icons_updated++; @@ -448,7 +459,7 @@ class acp_icons { if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data)) { - if ((sizeof($data[1]) != 4 && $mode == 'icons') || + if ((sizeof($data[1]) != 4 && $mode == 'icons') || (sizeof($data[1]) != 6 && $mode == 'smilies')) { trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); @@ -488,7 +499,7 @@ class acp_icons break; } } - else + else { $cur_img = array(); @@ -511,7 +522,7 @@ class acp_icons $data = array(); if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data)) { - if ((sizeof($data[1]) != 4 && $mode == 'icons') || + if ((sizeof($data[1]) != 4 && $mode == 'icons') || (sizeof($data[1]) != 6 && $mode == 'smilies')) { trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); @@ -529,8 +540,8 @@ class acp_icons $code = stripslashes($data[1][5]); } - if ($current == 'replace' && - (($mode == 'smilies' && !empty($cur_img[$code])) || + if ($current == 'replace' && + (($mode == 'smilies' && !empty($cur_img[$code])) || ($mode == 'icons' && !empty($cur_img[$img])))) { $replace_sql = ($mode == 'smilies') ? $code : $img; @@ -548,7 +559,7 @@ class acp_icons )); } - $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql) . " + $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql) . " WHERE $field_sql = '" . $db->sql_escape($replace_sql) . "'"; $db->sql_query($sql); } @@ -627,7 +638,7 @@ class acp_icons case 'send': - $sql = "SELECT * + $sql = "SELECT * FROM $table ORDER BY {$fields}_order"; $result = $db->sql_query($sql); @@ -657,8 +668,8 @@ class acp_icons header('Pragma: public'); // Send out the Headers - header('Content-Type: text/x-delimtext; name="' . $fields . '.pak"'); - header('Content-Disposition: inline; filename="' . $fields . '.pak"'); + header('Content-Type: text/x-delimtext; name="' . $mode . '.pak"'); + header('Content-Disposition: inline; filename="' . $mode . '.pak"'); echo $pak; flush(); @@ -686,12 +697,12 @@ class acp_icons case 'icons': // Reset appropriate icon_ids - $db->sql_query('UPDATE ' . TOPICS_TABLE . " - SET icon_id = 0 + $db->sql_query('UPDATE ' . TOPICS_TABLE . " + SET icon_id = 0 WHERE icon_id = $icon_id"); - $db->sql_query('UPDATE ' . POSTS_TABLE . " - SET icon_id = 0 + $db->sql_query('UPDATE ' . POSTS_TABLE . " + SET icon_id = 0 WHERE icon_id = $icon_id"); break; } @@ -733,7 +744,7 @@ class acp_icons // on move_up, switch position with previous order_id... $switch_order_id = ($action == 'move_down') ? $current_order + 1 : $current_order - 1; - // + // $sql = "UPDATE $table SET {$fields}_order = $current_order WHERE {$fields}_order = $switch_order_id @@ -801,7 +812,7 @@ class acp_icons $spacer = false; - $sql = "SELECT * + $sql = "SELECT * FROM $table ORDER BY {$fields}_order ASC"; $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index a3eefdfaba..73872c9b72 100755 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_inactive @@ -33,20 +41,29 @@ class acp_inactive $action = request_var('action', ''); $mark = (isset($_REQUEST['mark'])) ? request_var('mark', array(0)) : array(); $start = request_var('start', 0); + $submit = isset($_POST['submit']); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 'i'); $sort_dir = request_var('sd', 'd'); - if (sizeof($mark)) + $form_key = 'acp_inactive'; + add_form_key($form_key); + + if ($submit && sizeof($mark)) { + if ($action !== 'delete' && !check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + switch ($action) { case 'activate': case 'delete': - $sql = 'SELECT user_id, username + $sql = 'SELECT user_id, username FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $mark); $result = $db->sql_query($sql); @@ -107,14 +124,27 @@ class acp_inactive } else if ($action == 'delete') { - if (!$auth->acl_get('a_userdel')) + if (confirm_box(true)) { - trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); - } + if (!$auth->acl_get('a_userdel')) + { + trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); + } - foreach ($mark as $user_id) + foreach ($mark as $user_id) + { + user_delete('retain', $user_id, $user_affected[$user_id]); + } + } + else { - user_delete('retain', $user_id, $user_affected[$user_id]); + $s_hidden_fields = array( + 'mode' => $mode, + 'action' => $action, + 'mark' => $mark, + 'submit' => 1, + ); + confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields)); } } @@ -128,8 +158,8 @@ class acp_inactive trigger_error($user->lang['EMAIL_DISABLED'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type, user_regdate, user_actkey - FROM ' . USERS_TABLE . ' + $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type, user_regdate, user_actkey + FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $mark); $result = $db->sql_query($sql); @@ -150,7 +180,7 @@ class acp_inactive $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username']), - 'REGISTER_DATE' => $user->format_date($row['user_regdate']), + 'REGISTER_DATE' => $user->format_date($row['user_regdate']), 'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u=" . $row['user_id'] . '&k=' . $row['user_actkey']) ); diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php index 9f02530b27..3862ee1ee8 100644 --- a/phpBB/includes/acp/acp_jabber.php +++ b/phpBB/includes/acp/acp_jabber.php @@ -10,6 +10,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_jabber @@ -44,8 +52,16 @@ class acp_jabber $jab_package_size = request_var('jab_package_size', $config['jab_package_size']); $jab_use_ssl = request_var('jab_use_ssl', $config['jab_use_ssl']); + $form_name = 'acp_jabber'; + add_form_key($form_name); + if ($submit) { + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } + $error = array(); $message = $user->lang['JAB_SETTINGS_CHANGED']; @@ -93,6 +109,7 @@ class acp_jabber 'JAB_PACKAGE_SIZE' => $jab_package_size, 'JAB_USE_SSL' => $jab_use_ssl, 'S_CAN_USE_SSL' => jabber::can_use_ssl(), + 'S_GTALK_NOTE' => (!@function_exists('dns_get_record')) ? true : false, )); } } diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php index b59729c873..f68b3ea287 100644 --- a/phpBB/includes/acp/acp_language.php +++ b/phpBB/includes/acp/acp_language.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_language @@ -32,14 +40,19 @@ class acp_language $this->default_variables(); // Check and set some common vars - $action = request_var('action', ''); - $action = (isset($_POST['update_details'])) ? 'update_details' : $action; - $action = (isset($_POST['download_file'])) ? 'download_file' : $action; - $action = (isset($_POST['upload_file'])) ? 'upload_file' : $action; - $action = (isset($_POST['upload_data'])) ? 'upload_data' : $action; - $action = (isset($_POST['submit_file'])) ? 'submit_file' : $action; - $action = (isset($_POST['remove_store'])) ? 'details' : $action; + $action = (isset($_POST['update_details'])) ? 'update_details' : ''; + $action = (isset($_POST['download_file'])) ? 'download_file' : ''; + $action = (isset($_POST['upload_file'])) ? 'upload_file' : ''; + $action = (isset($_POST['upload_data'])) ? 'upload_data' : ''; + $action = (isset($_POST['submit_file'])) ? 'submit_file' : ''; + $action = (isset($_POST['remove_store'])) ? 'details' : ''; + + $submit = (empty($action)) ? false : true; + $action = (empty($action)) ? request_var('action', '') : $action; + + $form_name = 'acp_lang'; + add_form_key('acp_lang'); $lang_id = request_var('id', 0); if (isset($_POST['missing_file'])) @@ -59,7 +72,7 @@ class acp_language $this->tpl_name = 'acp_language'; $this->page_title = 'ACP_LANGUAGE_PACKS'; - if ($action == 'upload_data' && request_var('test_connection', '')) + if ($submit && $action == 'upload_data' && request_var('test_connection', '')) { $test_connection = false; $action = 'upload_file'; @@ -89,6 +102,7 @@ class acp_language switch ($action) { case 'upload_file': + include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx); $method = request_var('method', ''); @@ -132,6 +146,11 @@ class acp_language case 'update_details': + if (!$submit || !check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } + if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); @@ -150,7 +169,7 @@ class acp_language 'lang_author' => utf8_normalize_nfc(request_var('lang_author', $row['lang_author'], true)), ); - $db->sql_query('UPDATE ' . LANG_TABLE . ' + $db->sql_query('UPDATE ' . LANG_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE lang_id = ' . $lang_id); @@ -162,8 +181,18 @@ class acp_language case 'submit_file': case 'download_file': case 'upload_data': + + if (!$submit || !check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } - if (!$lang_id || empty($_POST['entry']) || !is_array($_POST['entry'])) + if (!$lang_id || empty($_POST['entry'])) + { + trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + + if ($this->language_directory != 'email' && !is_array($_POST['entry'])) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -180,6 +209,55 @@ class acp_language $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); + if (!$row) + { + trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + + // Before we attempt to write anything let's check if the admin really chose a correct filename + switch ($this->language_directory) + { + case 'email': + // Get email templates + $email_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt'); + $email_files = $email_files['email/']; + + if (!in_array($this->language_file, $email_files)) + { + trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); + } + break; + + case 'acp': + // Get acp files + $acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx); + $acp_files = $acp_files['acp/']; + + if (!in_array($this->language_file, $acp_files)) + { + trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); + } + break; + + case 'mods': + // Get mod files + $mods_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx); + $mods_files = (isset($mods_files['mods/'])) ? $mods_files['mods/'] : array(); + + if (!in_array($this->language_file, $mods_files)) + { + trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); + } + break; + + default: + if (!in_array($this->language_file, $this->main_files)) + { + trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING); + } + break; + } + if (!$safe_mode) { $mkdir_ary = array('language', 'language/' . $row['lang_iso']); @@ -690,7 +768,7 @@ class acp_language $db->sql_query('DELETE FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id); - $sql = 'UPDATE ' . USERS_TABLE . " + $sql = 'UPDATE ' . USERS_TABLE . " SET user_lang = '" . $db->sql_escape($config['default_lang']) . "' WHERE user_lang = '" . $db->sql_escape($row['lang_iso']) . "'"; $db->sql_query($sql); @@ -869,7 +947,7 @@ class acp_language trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); @@ -985,7 +1063,7 @@ class acp_language } $sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count - FROM ' . USERS_TABLE . ' + FROM ' . USERS_TABLE . ' GROUP BY user_lang'; $result = $db->sql_query($sql); @@ -996,7 +1074,7 @@ class acp_language } $db->sql_freeresult($result); - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . LANG_TABLE . ' ORDER BY lang_english_name'; $result = $db->sql_query($sql); @@ -1078,15 +1156,15 @@ class acp_language global $phpEx; $this->language_file_header = '<?php -/** +/** * * {FILENAME} [{LANG_NAME}] * * @package language * @version $' . 'Id: ' . '$ -* @copyright (c) ' . date('Y') . ' phpBB Group +* @copyright (c) ' . date('Y') . ' phpBB Group * @author {CHANGED} - {AUTHOR} -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 402209e66c..12953173f1 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_logs diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 84ea8cdfbd..06385fd97b 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_main @@ -117,7 +125,7 @@ class acp_main trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = 'SELECT COUNT(post_id) AS stat + $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' WHERE post_approved = 1'; $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 8077bfa2b4..f3540941df 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * - Able to check for new module versions (modes changed/adjusted/added/removed) * Icons for: * - module enabled and displayed (common) @@ -124,7 +132,7 @@ class acp_modules trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } - $sql = 'UPDATE ' . MODULES_TABLE . ' + $sql = 'UPDATE ' . MODULES_TABLE . ' SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; @@ -310,7 +318,7 @@ class acp_modules // Name options $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $this->module_class . '_' . $option . ']</option>'; - $template->assign_block_vars('m_names', array('NAME' => $option)); + $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option))); // Build module modes foreach ($values['modes'] as $m_mode => $m_values) @@ -346,7 +354,7 @@ class acp_modules 'ACTION' => $action, 'MODULE_ID' => $module_id, - ), + ), array_change_key_case($module_data, CASE_UPPER)) ); @@ -730,7 +738,7 @@ class acp_modules /** * Update/Add module - * + * * @param bool $run_inline if set to true errors will be returned and no logs being written */ function update_module_data(&$module_data, $run_inline = false) diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php index 57fd4c1ea5..03ea5a39dd 100644 --- a/phpBB/includes/acp/acp_permission_roles.php +++ b/phpBB/includes/acp/acp_permission_roles.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_permission_roles @@ -35,6 +43,9 @@ class acp_permission_roles $action = request_var('action', ''); $action = (isset($_POST['add'])) ? 'add' : $action; + $form_name = 'acp_permissions'; + add_form_key($form_name); + switch ($mode) { case 'admin_roles': @@ -134,6 +145,11 @@ class acp_permission_roles case 'add': + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } + $role_name = utf8_normalize_nfc(request_var('role_name', '', true)); $role_description = utf8_normalize_nfc(request_var('role_description', '', true)); $auth_settings = request_var('setting', array('' => 0)); @@ -171,8 +187,8 @@ class acp_permission_roles if ($action == 'edit') { - $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE role_id = ' . $role_id; $db->sql_query($sql); } diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index 008e5f5494..1b2b19d4ab 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_permissions @@ -46,7 +54,6 @@ class acp_permissions $this->permission_trace($user_id, $forum_id, $permission); return; } - trigger_error('NO_MODE', E_USER_ERROR); } @@ -66,6 +73,9 @@ class acp_permissions $group_id = request_var('group_id', array(0)); $select_all_groups = request_var('select_all_groups', 0); + $form_name = 'acp_permissions'; + add_form_key($form_name); + // If select all groups is set, we pre-build the group id array (this option is used for other screens to link to the permission settings screen) if ($select_all_groups) { @@ -214,6 +224,11 @@ class acp_permissions switch ($action) { case 'delete': + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } // All users/groups selected? $all_users = (isset($_POST['all_users'])) ? true : false; $all_groups = (isset($_POST['all_groups'])) ? true : false; @@ -247,6 +262,10 @@ class acp_permissions { trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } $this->set_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id); break; @@ -256,6 +275,10 @@ class acp_permissions { trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } $this->set_all_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id); break; @@ -332,8 +355,7 @@ class acp_permissions $template->assign_vars(array( 'S_SELECT_USER' => true, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_victim&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_victim&field=username&select_single=true', false)) - ); + )); break; @@ -395,8 +417,7 @@ class acp_permissions 'S_DEFINED_GROUP_OPTIONS' => $items['group_ids_options'], 'S_ADD_GROUP_OPTIONS' => group_select_options(false, $items['group_ids'], (($user->data['user_type'] == USER_FOUNDER) ? false : 0)), 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=add_user&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=add_user&field=username&select_single=true', false)) - ); + )); break; } @@ -588,7 +609,7 @@ class acp_permissions } } - /** + /** * Apply permissions */ function set_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) @@ -612,6 +633,14 @@ class acp_permissions list($ug_id, ) = each($psubmit); list($forum_id, ) = each($psubmit[$ug_id]); + if (empty($_POST['setting']) || empty($_POST['setting'][$ug_id]) || empty($_POST['setting'][$ug_id][$forum_id]) || !is_array($_POST['setting'][$ug_id][$forum_id])) + { + trigger_error('WRONG_PERMISSION_SETTING_FORMAT', E_USER_WARNING); + } + + // We obtain and check $_POST['setting'][$ug_id][$forum_id] directly and not using request_var() because request_var() + // currently does not support the amount of dimensions required. ;) + // $auth_settings = request_var('setting', array(0 => array(0 => array('' => 0)))); $auth_settings = array_map('intval', $_POST['setting'][$ug_id][$forum_id]); // Do we have a role we want to set? @@ -669,7 +698,7 @@ class acp_permissions trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); } - /** + /** * Apply all permissions */ function set_all_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) @@ -841,7 +870,7 @@ class acp_permissions else { // Grab the forum details if non-zero forum_id - $sql = 'SELECT forum_name + $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_php_info.php b/phpBB/includes/acp/acp_php_info.php index 3b4873bdc8..9935c0466e 100644 --- a/phpBB/includes/acp/acp_php_info.php +++ b/phpBB/includes/acp/acp_php_info.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_php_info @@ -28,16 +36,16 @@ class acp_php_info $this->tpl_name = 'acp_php_info'; $this->page_title = 'ACP_PHP_INFO'; - ob_start(); - @phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES | INFO_VARIABLES); - $phpinfo = ob_get_clean(); + ob_start(); + @phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES | INFO_VARIABLES); + $phpinfo = ob_get_clean(); $phpinfo = trim($phpinfo); // Here we play around a little with the PHP Info HTML to try and stylise // it along phpBB's lines ... hopefully without breaking anything. The idea // for this was nabbed from the PHP annotated manual - preg_match_all('#<body[^>]*>(.*)</body>#si', $phpinfo, $output); + preg_match_all('#<body[^>]*>(.*)</body>#si', $phpinfo, $output); if (empty($phpinfo) || empty($output)) { @@ -66,7 +74,7 @@ class acp_php_info $orig_output = $output; - preg_match_all('#<div class="center">(.*)</div>#siU', $output, $output); + preg_match_all('#<div class="center">(.*)</div>#siU', $output, $output); $output = (!empty($output[1][0])) ? $output[1][0] : $orig_output; $template->assign_var('PHPINFO', $output); diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index c2fde25eb5..9acfbe41c1 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_profile @@ -99,8 +107,8 @@ class acp_profile if (confirm_box(true)) { - $sql = 'SELECT field_ident - FROM ' . PROFILE_FIELDS_TABLE . " + $sql = 'SELECT field_ident + FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); @@ -116,8 +124,8 @@ class acp_profile { case 'sqlite': $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' + FROM sqlite_master + WHERE type = 'table' AND name = '" . PROFILE_FIELDS_DATA_TABLE . "' ORDER BY type DESC, name;"; $result = $db->sql_query($sql); @@ -138,6 +146,12 @@ class acp_profile foreach ($old_table_cols as $declaration) { $entities = preg_split('#\s+#', trim($declaration)); + + if ($entities[0] == 'PRIMARY') + { + continue; + } + if ($entities[0] !== 'pf_' . $field_ident) { $column_list[] = $entities[0]; @@ -170,8 +184,8 @@ class acp_profile $order++; if ($row['field_order'] != $order) { - $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " - SET field_order = $order + $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " + SET field_order = $order WHERE field_id = {$row['field_id']}"; $db->sql_query($sql); } @@ -203,8 +217,8 @@ class acp_profile trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = 'SELECT lang_id - FROM ' . LANG_TABLE . " + $sql = 'SELECT lang_id + FROM ' . LANG_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql); $default_lang_id = (int) $db->sql_fetchfield('lang_id'); @@ -215,13 +229,13 @@ class acp_profile trigger_error($user->lang['DEFAULT_LANGUAGE_NOT_FILLED'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " - SET field_active = 1 + $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " + SET field_active = 1 WHERE field_id = $field_id"; $db->sql_query($sql); - $sql = 'SELECT field_ident - FROM ' . PROFILE_FIELDS_TABLE . " + $sql = 'SELECT field_ident + FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); @@ -241,12 +255,12 @@ class acp_profile } $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " - SET field_active = 0 + SET field_active = 0 WHERE field_id = $field_id"; $db->sql_query($sql); - $sql = 'SELECT field_ident - FROM ' . PROFILE_FIELDS_TABLE . " + $sql = 'SELECT field_ident + FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); @@ -290,7 +304,7 @@ class acp_profile } $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id = ' . $this->edit_lang_id . " AND f.field_id = $field_id AND l.field_id = f.field_id"; @@ -302,7 +316,7 @@ class acp_profile { // Some admin changed the default language? $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id <> ' . $this->edit_lang_id . " AND f.field_id = $field_id AND l.field_id = f.field_id"; @@ -321,7 +335,7 @@ class acp_profile // Get language entries $sql = 'SELECT * - FROM ' . PROFILE_FIELDS_LANG_TABLE . ' + FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY option_id ASC"; @@ -491,7 +505,7 @@ class acp_profile list($cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']) = explode('-', $var); } } - } + } /* else if ($field_type == FIELD_BOOL && $key == 'field_default_value') { // Get the number of options if this key is 'field_maxlen' @@ -506,7 +520,7 @@ class acp_profile { // Get language entries $sql = 'SELECT * - FROM ' . PROFILE_FIELDS_LANG_TABLE . ' + FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id <> ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY option_id ASC"; @@ -521,7 +535,7 @@ class acp_profile $sql = 'SELECT lang_id, lang_name, lang_explain, lang_default_value - FROM ' . PROFILE_LANG_TABLE . ' + FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id <> ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY lang_id ASC"; @@ -596,8 +610,8 @@ class acp_profile // Check for already existing field ident if ($action != 'edit') { - $sql = 'SELECT field_ident - FROM ' . PROFILE_FIELDS_TABLE . " + $sql = 'SELECT field_ident + FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_ident = '" . $db->sql_escape($cp->vars['field_ident']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); @@ -704,7 +718,7 @@ class acp_profile switch ($step) { // Create basic options - only small differences between field types - case 1: + case 1: // Build common create options $template->assign_vars(array( @@ -783,7 +797,7 @@ class acp_profile break; // Define remaining language variables - case 3: + case 3: $template->assign_var('S_STEP_THREE', true); $options = $this->build_language_options($cp, $field_type, $action); @@ -879,7 +893,7 @@ class acp_profile $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']]; - $sql = 'SELECT lang_id, lang_iso + $sql = 'SELECT lang_id, lang_iso FROM ' . LANG_TABLE . ' WHERE lang_id <> ' . (int) $default_lang_id . ' ORDER BY lang_english_name'; @@ -1102,7 +1116,7 @@ class acp_profile foreach ($empty_lang as $lang_id => $NULL) { - $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . " + $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); @@ -1136,7 +1150,7 @@ class acp_profile if ($action != 'create') { - $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " + $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $default_lang_id; $db->sql_query($sql); @@ -1188,7 +1202,7 @@ class acp_profile { if ($action != 'create') { - $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " + $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); @@ -1209,7 +1223,7 @@ class acp_profile foreach ($empty_lang as $lang_id => $NULL) { - $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " + $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); @@ -1246,7 +1260,7 @@ class acp_profile unset($sql['lang_id'], $sql['field_id'], $sql['option_id']); $this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql, array( - 'lang_id' => $lang_id, + 'lang_id' => $lang_id, 'field_id' => $field_id, 'option_id' => $option_id) ); @@ -1300,7 +1314,7 @@ class acp_profile return; } - $sql = "SELECT $check_key + $sql = "SELECT $check_key FROM $table WHERE " . implode(' AND ', $where_sql); $result = $db->sql_query($sql); @@ -1320,7 +1334,7 @@ class acp_profile { if (sizeof($sql_ary)) { - $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql_ary) . ' + $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE ' . implode(' AND ', $where_sql); $db->sql_query($sql); } @@ -1409,8 +1423,8 @@ class acp_profile if (version_compare(sqlite_libversion(), '3.0') == -1) { $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' + FROM sqlite_master + WHERE type = 'table' AND name = '" . PROFILE_FIELDS_DATA_TABLE . "' ORDER BY type DESC, name;"; $result = $db->sql_query($sql); @@ -1431,7 +1445,7 @@ class acp_profile foreach ($old_table_cols as $declaration) { $entities = preg_split('#\s+#', trim($declaration)); - if ($entities == 'PRIMARY') + if ($entities[0] == 'PRIMARY') { continue; } diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index 34f43e2426..308f83387c 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_prune @@ -89,10 +97,10 @@ class acp_prune $sql_forum = (sizeof($forum_id)) ? ' AND ' . $db->sql_in_set('forum_id', $forum_id) : ''; // Get a list of forum's or the data for the forum that we are pruning. - $sql = 'SELECT forum_id, forum_name + $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " - $sql_forum + $sql_forum ORDER BY left_id ASC"; $result = $db->sql_query($sql); @@ -181,8 +189,8 @@ class acp_prune } else { - $sql = 'SELECT forum_id, forum_name - FROM ' . FORUMS_TABLE . ' + $sql = 'SELECT forum_id, forum_name + FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); @@ -350,8 +358,8 @@ class acp_prune 'S_JOINED_OPTIONS' => $s_find_join_time, 'S_ACTIVE_OPTIONS' => $s_find_active_time, 'S_COUNT_OPTIONS' => $s_find_count, - 'U_FIND_USER' => append_sid($phpbb_root_path . "memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users')) - ); + 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'), + )); } /** @@ -407,7 +415,7 @@ class acp_prune } // Get bot ids - $sql = 'SELECT user_id + $sql = 'SELECT user_id FROM ' . BOTS_TABLE; $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php index 950a645487..51561e03f1 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_ranks @@ -31,10 +39,17 @@ class acp_ranks $this->tpl_name = 'acp_ranks'; $this->page_title = 'ACP_MANAGE_RANKS'; + $form_name = 'acp_prune'; + add_form_key($form_name); + switch ($action) { case 'save': - + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } $rank_title = utf8_normalize_nfc(request_var('title', '', true)); $special_rank = request_var('special_rank', 0); $min_posts = ($special_rank) ? 0 : request_var('min_posts', 0); @@ -124,10 +139,15 @@ class acp_ranks case 'edit': case 'add': + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } + $data = $ranks = $existing_imgs = array(); - $sql = 'SELECT * - FROM ' . RANKS_TABLE . ' + $sql = 'SELECT * + FROM ' . RANKS_TABLE . ' ORDER BY rank_min ASC, rank_special ASC'; $result = $db->sql_query($sql); @@ -151,7 +171,7 @@ class acp_ranks foreach ($img_ary as $img) { - $img = $path . $img; + $img = $path . $img; if (!in_array($img, $existing_imgs) || $action == 'edit') { diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php index ca9fbcb806..8d7bc88769 100644 --- a/phpBB/includes/acp/acp_reasons.php +++ b/phpBB/includes/acp/acp_reasons.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_reasons @@ -30,6 +38,9 @@ class acp_reasons $this->tpl_name = 'acp_reasons'; $this->page_title = 'ACP_REASONS'; + $form_name = 'acp_reason'; + add_form_key('acp_reason'); + $error = array(); switch ($action) @@ -44,6 +55,10 @@ class acp_reasons if ($submit) { + if (!check_form_key($form_name)) + { + $error[] = $user->lang['FORM_INVALID']; + } // Reason specified? if (!$reason_row['reason_title'] || !$reason_row['reason_description']) { @@ -308,7 +323,7 @@ class acp_reasons // Reason count $sql = 'SELECT reason_id, COUNT(reason_id) AS reason_count - FROM ' . REPORTS_TABLE . ' + FROM ' . REPORTS_TABLE . ' GROUP BY reason_id'; $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php index f8d4f1f80d..65634ebb25 100644 --- a/phpBB/includes/acp/acp_search.php +++ b/phpBB/includes/acp/acp_search.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_search @@ -473,8 +481,8 @@ class acp_search 'S_INDEX' => true, 'U_ACTION' => $this->u_action, 'U_PROGRESS_BAR' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=progress_bar"), - 'UA_PROGRESS_BAR' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=progress_bar", false)) - ); + 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=progress_bar")), + )); if (isset($this->state[1])) { diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 300e795f3b..9e04ede90b 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_styles @@ -61,10 +69,10 @@ class acp_styles # For on/off options the valid values are on, off, 1, 0, true and false # # Values get trimmed, if you want to add a space in front or at the end of -# the value, then enclose the value with single or double quotes. +# the value, then enclose the value with single or double quotes. # Single and double quotes do not need to be escaped. # -# +# # General Information about this {MODE} name = {NAME} @@ -76,7 +84,7 @@ version = {VERSION} # Some configuration options # -# You have to turn this option on if you want to use the +# You have to turn this option on if you want to use the # path template variables ({T_IMAGESET_PATH} for example) within # your css file. # This is mostly the case if you want to use language specific @@ -321,7 +329,7 @@ parse_css_file = {PARSE_CSS_FILE} { // Save CSS contents $sql_ary = array( - 'theme_mtime' => @filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"), + 'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/{$theme_row['theme_path']}/theme/stylesheet.css"), 'theme_data' => $this->db_theme_data($theme_row) ); @@ -978,7 +986,7 @@ parse_css_file = {PARSE_CSS_FILE} { $file = str_replace('/', '.', $file); - // perform some dirty guessing to get the path right. + // perform some dirty guessing to get the path right. // We assume that three dots in a row were '../' $tpl_file = str_replace('.', '/', $file); $tpl_file = str_replace('///', '../', $tpl_file); @@ -987,7 +995,6 @@ parse_css_file = {PARSE_CSS_FILE} $template->assign_block_vars('file', array( 'U_VIEWSOURCE' => $this->u_action . "&action=cache&id=$template_id&source=$file", - 'UA_VIEWSOURCE' => str_replace('&', '&', $this->u_action) . "&action=cache&id=$template_id&source=$file", 'CACHED' => $user->format_date(filemtime("{$phpbb_root_path}cache/$filename")), 'FILENAME' => $file, @@ -1287,7 +1294,7 @@ parse_css_file = {PARSE_CSS_FILE} } $imgwidth = ($imgname != 'poll_center') ? (int) $imgwidth : 0; $imgheight = (int) $imgheight; - } + } if (strpos($imgpath, '/') !== false) @@ -1300,10 +1307,10 @@ parse_css_file = {PARSE_CSS_FILE} } $sql_ary = array( - 'image_filename' => $imgfilename, - 'image_width' => $imgwidth, - 'image_height' => $imgheight, - 'image_lang' => $imglang, + 'image_filename' => (string) $imgfilename, + 'image_width' => (int) $imgwidth, + 'image_height' => (int) $imgheight, + 'image_lang' => (string) $imglang, ); // already exists @@ -1318,7 +1325,7 @@ parse_css_file = {PARSE_CSS_FILE} else if (!$imageset_data_row) { $sql_ary['image_name'] = $imgname; - $sql_ary['imageset_id'] = $imageset_id; + $sql_ary['imageset_id'] = (int) $imageset_id; $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); } @@ -1454,6 +1461,7 @@ parse_css_file = {PARSE_CSS_FILE} 'U_ACTION' => $this->u_action . "&action=edit&id=$imageset_id", 'U_BACK' => $this->u_action, 'NAME' => $imageset_name, + 'A_NAME' => addslashes($imageset_name), 'ERROR' => !$valid_name, 'IMG_SRC' => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png', 'IMAGE_SELECT' => $image_found @@ -1511,8 +1519,8 @@ parse_css_file = {PARSE_CSS_FILE} $sql = "SELECT {$mode}_id, {$mode}_name FROM $sql_from - WHERE {$mode}_id <> $style_id - $sql_where + WHERE {$mode}_id <> $style_id + $sql_where ORDER BY {$mode}_name ASC"; $result = $db->sql_query($sql); @@ -2101,7 +2109,7 @@ parse_css_file = {PARSE_CSS_FILE} { $cfg = parse_cfg_file("{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . "/theme/theme.cfg"); - if (isset($cfg['parse_css_file']) && $cfg['parse_css_file']) + if (isset($cfg['parse_css_file']) && $cfg['parse_css_file'] && !$store_db) { $error[] = $user->lang['EDIT_THEME_STORE_PARSED']; $store_db = 1; @@ -2150,10 +2158,10 @@ parse_css_file = {PARSE_CSS_FILE} case 'style': $sql_ary += array( - 'template_id' => $template_id, - 'theme_id' => $theme_id, - 'imageset_id' => $imageset_id, - 'style_active' => $style_active, + 'template_id' => (int) $template_id, + 'theme_id' => (int) $theme_id, + 'imageset_id' => (int) $imageset_id, + 'style_active' => (int) $style_active, ); break; @@ -2430,11 +2438,11 @@ parse_css_file = {PARSE_CSS_FILE} // We could do this using extended inserts ... but that could be one // heck of a lot of data ... $sql_ary = array( - 'template_id' => $style_id, + 'template_id' => (int) $style_id, 'template_filename' => "$pathfile$file", 'template_included' => (isset($includes[$file])) ? implode(':', $includes[$file]) . ':' : '', - 'template_mtime' => filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"), - 'template_data' => file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"), + 'template_mtime' => (int) filemtime("{$phpbb_root_path}styles/$template_path$pathfile$file"), + 'template_data' => (string) file_get_contents("{$phpbb_root_path}styles/$template_path$pathfile$file"), ); if ($mode == 'insert') @@ -2976,10 +2984,10 @@ parse_css_file = {PARSE_CSS_FILE} $sql_ary = array( 'style_name' => $name, 'style_copyright' => $copyright, - 'style_active' => $active, - 'template_id' => $style_row['template_id'], - 'theme_id' => $style_row['theme_id'], - 'imageset_id' => $style_row['imageset_id'], + 'style_active' => (int) $active, + 'template_id' => (int) $style_row['template_id'], + 'theme_id' => (int) $style_row['theme_id'], + 'imageset_id' => (int) $style_row['imageset_id'], ); $sql = 'INSERT INTO ' . STYLES_TABLE . ' @@ -3107,7 +3115,7 @@ parse_css_file = {PARSE_CSS_FILE} $sql_ary += array( 'theme_storedb' => $store_db, 'theme_data' => ($store_db) ? $this->db_theme_data($sql_ary, false, $root_path) : '', - 'theme_mtime' => filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css") + 'theme_mtime' => (int) filemtime("{$phpbb_root_path}styles/$path/theme/stylesheet.css") ); break; @@ -3159,7 +3167,7 @@ parse_css_file = {PARSE_CSS_FILE} $image_height = $image_width = 0; } - if (strpos($key, 'img_') === 0&& $image_filename) + if (strpos($key, 'img_') === 0 && $image_filename) { $key = substr($key, 4); if (in_array($key, $imageset_definitions)) @@ -3167,9 +3175,9 @@ parse_css_file = {PARSE_CSS_FILE} $sql_ary = array( 'image_name' => $key, 'image_filename' => str_replace('{PATH}', "styles/$path/imageset/", trim($image_filename)), - 'image_height' => $image_height, - 'image_width' => $image_width, - 'imageset_id' => $id, + 'image_height' => (int) $image_height, + 'image_width' => (int) $image_width, + 'imageset_id' => (int) $id, 'image_lang' => '', ); $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); @@ -3215,9 +3223,9 @@ parse_css_file = {PARSE_CSS_FILE} $sql_ary = array( 'image_name' => $image_name, 'image_filename' => $image_filename, - 'image_height' => $image_height, - 'image_width' => $image_width, - 'imageset_id' => $id, + 'image_height' => (int) $image_height, + 'image_width' => (int) $image_width, + 'imageset_id' => (int) $id, 'image_lang' => $row['lang_dir'], ); $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php index 03f2db7d15..1ab4726e8b 100644 --- a/phpBB/includes/acp/acp_update.php +++ b/phpBB/includes/acp/acp_update.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_update diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index cab16af7b6..344df3169d 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package acp */ class acp_users @@ -37,6 +45,9 @@ class acp_users $submit = (isset($_POST['update'])) ? true : false; + $form_name = 'acp_users'; + add_form_key($form_name); + // Whois (special case) if ($action == 'whois') { @@ -47,13 +58,7 @@ class acp_users $user_ip = request_var('user_ip', ''); $domain = gethostbyaddr($user_ip); - $ipwhois = ''; - - if ($ipwhois = user_ipwhois($user_ip)) - { - $ipwhois = preg_replace('#(\s)([\w\-\._\+]+@[\w\-\.]+)(\s)#', '\1<a href="mailto:\2">\2</a>\3', $ipwhois); - $ipwhois = preg_replace('#(\s)(http:/{2}[^\s]*)(\s)#', '\1<a href="\2">\2</a>\3', $ipwhois); - } + $ipwhois = user_ipwhois($user_ip); $template->assign_vars(array( 'MESSAGE_TITLE' => sprintf($user->lang['IP_WHOIS_FOR'], $domain), @@ -74,9 +79,7 @@ class acp_users 'S_SELECT_USER' => true, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_user&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_user&field=username&select_single=true', false), - ) - ); + )); return; } @@ -226,6 +229,11 @@ class acp_users trigger_error($user->lang['CANNOT_BAN_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $ban = array(); switch ($action) @@ -278,6 +286,11 @@ class acp_users trigger_error($user->lang['CANNOT_FORCE_REACT_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_FORCE_REACT_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); @@ -345,6 +358,11 @@ class acp_users trigger_error($user->lang['CANNOT_DEACTIVATE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_DEACTIVATE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); @@ -369,6 +387,11 @@ class acp_users case 'delsig': + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $sql_ary = array( 'user_sig' => '', 'user_sig_bbcode_uid' => '', @@ -387,7 +410,12 @@ class acp_users break; case 'delavatar': - + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $sql_ary = array( 'user_avatar' => '', 'user_avatar_type' => 0, @@ -459,6 +487,11 @@ class acp_users case 'moveposts': + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $user->add_lang('acp/forums'); $new_forum_id = request_var('new_f', 0); @@ -662,9 +695,14 @@ class acp_users $error[] = 'NEW_EMAIL_ERROR'; } + if (!check_form_key($form_name)) + { + $error[] = 'FORM_INVALID'; + } + // Which updates do we need to do? $update_username = ($user_row['username'] != $data['username']) ? $data['username'] : false; - $update_password = ($data['new_password'] && $user_row['user_password'] != md5($data['new_password'])) ? true : false; + $update_password = ($data['new_password'] && !phpbb_check_hash($user_row['user_password'], $data['new_password'])) ? true : false; $update_email = ($data['email'] != $user_row['user_email']) ? $data['email'] : false; if (!sizeof($error)) @@ -736,7 +774,7 @@ class acp_users if ($update_password) { $sql_ary += array( - 'user_password' => md5($data['new_password']), + 'user_password' => phpbb_hash($data['new_password']), 'user_passchg' => time(), ); @@ -890,6 +928,11 @@ class acp_users // Delete entries if requested and able if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs')) { + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $where_sql = ''; if ($deletemark && $marked) { @@ -915,6 +958,11 @@ class acp_users if ($submit && $message) { + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + add_log('admin', 'LOG_USER_FEEDBACK', $user_row['username']); add_log('mod', 0, 0, 'LOG_USER_FEEDBACK', $user_row['username']); add_log('user', $user_id, 'LOG_USER_GENERAL', $message); @@ -1035,6 +1083,10 @@ class acp_users { $error = array_merge($error, $cp_error); } + if (!check_form_key($form_name)) + { + $error[] = 'FORM_INVALID'; + } if (!sizeof($error)) { @@ -1192,7 +1244,7 @@ class acp_users 'view_smilies' => request_var('view_smilies', $this->optionget($user_row, 'viewsmilies')), 'view_sigs' => request_var('view_sigs', $this->optionget($user_row, 'viewsigs')), 'view_avatars' => request_var('view_avatars', $this->optionget($user_row, 'viewavatars')), - 'view_wordcensor' => request_var('view_wordcensore', $this->optionget($user_row, 'viewcensors')), + 'view_wordcensor' => request_var('view_wordcensor', $this->optionget($user_row, 'viewcensors')), 'bbcode' => request_var('bbcode', $this->optionget($user_row, 'bbcode')), 'smilies' => request_var('smilies', $this->optionget($user_row, 'smilies')), @@ -1213,6 +1265,11 @@ class acp_users 'post_sd' => array('string', false, 1, 1), )); + if (!check_form_key($form_name)) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error)) { $this->optionset($user_row, 'popuppm', $data['popuppm']); @@ -1376,6 +1433,12 @@ class acp_users if ($submit) { + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + if (avatar_process_user($error, $user_row)) { trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_row['user_id'])); @@ -1418,6 +1481,11 @@ class acp_users if ($submit) { + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + $rank_id = request_var('user_rank', 0); $sql = 'UPDATE ' . USERS_TABLE . " @@ -1428,7 +1496,7 @@ class acp_users trigger_error($user->lang['USER_RANK_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . RANKS_TABLE . ' WHERE rank_special = 1 ORDER BY rank_title'; @@ -1475,17 +1543,22 @@ class acp_users { $error[] = implode('<br />', $message_parser->warn_msg); } - + + if (!check_form_key($form_name)) + { + $error = 'FORM_INVALID'; + } + if (!sizeof($error) && $submit) { $sql_ary = array( - 'user_sig' => (string) $message_parser->message, - 'user_sig_bbcode_uid' => (string) $message_parser->bbcode_uid, + 'user_sig' => (string) $message_parser->message, + 'user_sig_bbcode_uid' => (string) $message_parser->bbcode_uid, 'user_sig_bbcode_bitfield' => (string) $message_parser->bbcode_bitfield ); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $user_id; $db->sql_query($sql); @@ -1525,7 +1598,7 @@ class acp_users 'L_SIGNATURE_EXPLAIN' => sprintf($user->lang['SIGNATURE_EXPLAIN'], $config['max_sig_chars']), - 'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'], + 'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'], 'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'], 'S_BBCODE_IMG' => ($config['allow_sig_img']) ? true : false, 'S_BBCODE_FLASH' => ($config['allow_sig_flash']) ? true : false, @@ -1549,6 +1622,23 @@ class acp_users if ($deletemark && sizeof($marked)) { + $sql = 'SELECT attach_id + FROM ' . ATTACHMENTS_TABLE . ' + WHERE poster_id = ' . $user_id . ' + AND is_orphan = 0 + AND ' . $db->sql_in_set('attach_id', $marked); + $result = $db->sql_query($sql); + + $marked = array(); + while ($row = $db->sql_fetchrow($result)) + { + $marked[] = $row['attach_id']; + } + $db->sql_freeresult($result); + } + + if ($deletemark && sizeof($marked)) + { if (confirm_box(true)) { $sql = 'SELECT real_filename @@ -1611,18 +1701,20 @@ class acp_users $sql = 'SELECT COUNT(attach_id) as num_attachments FROM ' . ATTACHMENTS_TABLE . " - WHERE poster_id = $user_id"; + WHERE poster_id = $user_id + AND is_orphan = 0"; $result = $db->sql_query_limit($sql, 1); $num_attachments = (int) $db->sql_fetchfield('num_attachments'); $db->sql_freeresult($result); $sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title - FROM ' . ATTACHMENTS_TABLE . ' a + FROM ' . ATTACHMENTS_TABLE . ' a LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0) LEFT JOIN ' . PRIVMSGS_TABLE . ' p ON (a.post_msg_id = p.msg_id AND a.in_message = 1) WHERE a.poster_id = ' . $user_id . " + AND a.is_orphan = 0 ORDER BY $order_by"; $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start); @@ -1652,7 +1744,7 @@ class acp_users 'S_IN_MESSAGE' => $row['in_message'], - 'U_DOWNLOAD' => append_sid("{$phpbb_root_path}download.$phpEx", 'mode=view&id=' . $row['attach_id']), + 'U_DOWNLOAD' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&id=' . $row['attach_id']), 'U_VIEW_TOPIC' => $view_topic) ); } @@ -1722,6 +1814,12 @@ class acp_users // Add user to group? if ($submit) { + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); diff --git a/phpBB/includes/acp/acp_words.php b/phpBB/includes/acp/acp_words.php index 7e971d8e0f..596c2fc743 100644 --- a/phpBB/includes/acp/acp_words.php +++ b/phpBB/includes/acp/acp_words.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @todo [words] check regular expressions for special char replacements (stored specialchared in db) * @package acp */ @@ -33,6 +41,9 @@ class acp_words $this->tpl_name = 'acp_words'; $this->page_title = 'ACP_WORDS'; + $form_name = 'acp_words'; + add_form_key($form_name); + switch ($action) { case 'edit': @@ -68,6 +79,11 @@ class acp_words break; case 'save': + + if (!check_form_key($form_name)) + { + trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); + } $word_id = request_var('id', 0); $word = utf8_normalize_nfc(request_var('word', '', true)); $replacement = utf8_normalize_nfc(request_var('replacement', '', true)); diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php index e3514833b5..b4ea0e46d0 100644 --- a/phpBB/includes/acp/auth.php +++ b/phpBB/includes/acp/auth.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package phpBB3 -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @version $Id$ +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -119,7 +120,7 @@ class auth_admin extends auth // If forum_ids is false and the scope is local we actually want to have all forums within the array if ($scope == 'local' && !sizeof($forum_ids)) { - $sql = 'SELECT forum_id + $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql, 120); @@ -206,10 +207,10 @@ class auth_admin extends auth // Do not include the global auth_option unset($options[$auth_option]); - // Not a "fine" solution, but at all it's a 1-dimensional + // Not a "fine" solution, but at all it's a 1-dimensional // array_diff_key function filling the resulting array values with zeros // The differences get merged into $hold_ary (all permissions having $acl_fill set) - $hold_ary[$ug_id][$id] = array_merge($options, + $hold_ary[$ug_id][$id] = array_merge($options, array_map($return_acl_fill, array_flip( @@ -253,7 +254,7 @@ class auth_admin extends auth } $db->sql_freeresult($result); - // Now grab groups... + // Now grab groups... $sql = 'SELECT group_id, forum_id FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_role_id = ' . $role_id . ' @@ -382,7 +383,7 @@ class auth_admin extends auth continue; } - $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . $row['auth_option'] . '\'] = ' . $row['auth_setting'] . '; '; + $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; '; } $db->sql_freeresult($result); @@ -428,7 +429,7 @@ class auth_admin extends auth unset($memberships, $groups); } - // If we only have one forum id to display or being in local mode and more than one user/group to display, + // If we only have one forum id to display or being in local mode and more than one user/group to display, // we switch the complete interface to group by user/usergroup instead of grouping by forum // To achieve this, we need to switch the array a bit if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1)) @@ -628,7 +629,7 @@ class auth_admin extends auth // Get forum names $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . ' - WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . ' + WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . ' ORDER BY left_id'; $result = $db->sql_query($sql); @@ -639,7 +640,7 @@ class auth_admin extends auth $forum_names[$row['forum_id']] = $row['forum_name']; } $db->sql_freeresult($result); - + foreach ($forum_names as $forum_id => $forum_name) { $auth_ary = $hold_ary[$forum_id]; @@ -1224,7 +1225,7 @@ class auth_admin extends auth /** * Use permissions from another user. This transferes a permission set from one user to another. * The other user is always able to revert back to his permission set. - * This function does not check for lower/higher permissions, it is possible for the user to gain + * This function does not check for lower/higher permissions, it is possible for the user to gain * "more" permissions by this. * Admin permissions will not be copied. */ diff --git a/phpBB/includes/acp/info/acp_attachments.php b/phpBB/includes/acp/info/acp_attachments.php index 9ca76e284d..b77785801f 100644 --- a/phpBB/includes/acp/info/acp_attachments.php +++ b/phpBB/includes/acp/info/acp_attachments.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_ban.php b/phpBB/includes/acp/info/acp_ban.php index 11c60abcd9..df51011ec6 100644 --- a/phpBB/includes/acp/info/acp_ban.php +++ b/phpBB/includes/acp/info/acp_ban.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_bbcodes.php b/phpBB/includes/acp/info/acp_bbcodes.php index 89a7c117e7..c0206432d6 100644 --- a/phpBB/includes/acp/info/acp_bbcodes.php +++ b/phpBB/includes/acp/info/acp_bbcodes.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_board.php b/phpBB/includes/acp/info/acp_board.php index e6a2372088..72d86676a6 100644 --- a/phpBB/includes/acp/info/acp_board.php +++ b/phpBB/includes/acp/info/acp_board.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_bots.php b/phpBB/includes/acp/info/acp_bots.php index c63648f141..45087f9225 100644 --- a/phpBB/includes/acp/info/acp_bots.php +++ b/phpBB/includes/acp/info/acp_bots.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_captcha.php b/phpBB/includes/acp/info/acp_captcha.php index 82fbf997f4..b2541c252c 100644 --- a/phpBB/includes/acp/info/acp_captcha.php +++ b/phpBB/includes/acp/info/acp_captcha.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_database.php b/phpBB/includes/acp/info/acp_database.php index 5eafe67c34..85c3c8b21c 100644 --- a/phpBB/includes/acp/info/acp_database.php +++ b/phpBB/includes/acp/info/acp_database.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_disallow.php b/phpBB/includes/acp/info/acp_disallow.php index fa23b27cdf..41315eb716 100644 --- a/phpBB/includes/acp/info/acp_disallow.php +++ b/phpBB/includes/acp/info/acp_disallow.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_email.php b/phpBB/includes/acp/info/acp_email.php index 2174a43249..f2270892e0 100644 --- a/phpBB/includes/acp/info/acp_email.php +++ b/phpBB/includes/acp/info/acp_email.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_forums.php b/phpBB/includes/acp/info/acp_forums.php index 5e5f4d7bb2..8d82eaf42d 100644 --- a/phpBB/includes/acp/info/acp_forums.php +++ b/phpBB/includes/acp/info/acp_forums.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_groups.php b/phpBB/includes/acp/info/acp_groups.php index 4ea14f237d..3910c24e6b 100644 --- a/phpBB/includes/acp/info/acp_groups.php +++ b/phpBB/includes/acp/info/acp_groups.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_icons.php b/phpBB/includes/acp/info/acp_icons.php index 897ad50af9..16bf753940 100644 --- a/phpBB/includes/acp/info/acp_icons.php +++ b/phpBB/includes/acp/info/acp_icons.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_inactive.php b/phpBB/includes/acp/info/acp_inactive.php index bee9d977d4..e17fbda9dd 100755 --- a/phpBB/includes/acp/info/acp_inactive.php +++ b/phpBB/includes/acp/info/acp_inactive.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_jabber.php b/phpBB/includes/acp/info/acp_jabber.php index 379e0ff56e..7bcf7744e1 100644 --- a/phpBB/includes/acp/info/acp_jabber.php +++ b/phpBB/includes/acp/info/acp_jabber.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_language.php b/phpBB/includes/acp/info/acp_language.php index 90598f102e..f7606631fe 100644 --- a/phpBB/includes/acp/info/acp_language.php +++ b/phpBB/includes/acp/info/acp_language.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_logs.php b/phpBB/includes/acp/info/acp_logs.php index d4f8424b73..f119e10b83 100644 --- a/phpBB/includes/acp/info/acp_logs.php +++ b/phpBB/includes/acp/info/acp_logs.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_main.php b/phpBB/includes/acp/info/acp_main.php index acad8e113b..5574cc40d1 100644 --- a/phpBB/includes/acp/info/acp_main.php +++ b/phpBB/includes/acp/info/acp_main.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_modules.php b/phpBB/includes/acp/info/acp_modules.php index 2c21ce494e..886f17d628 100644 --- a/phpBB/includes/acp/info/acp_modules.php +++ b/phpBB/includes/acp/info/acp_modules.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_permission_roles.php b/phpBB/includes/acp/info/acp_permission_roles.php index 114d23f018..3ab2fecd53 100644 --- a/phpBB/includes/acp/info/acp_permission_roles.php +++ b/phpBB/includes/acp/info/acp_permission_roles.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_permissions.php b/phpBB/includes/acp/info/acp_permissions.php index bb921b9976..22de666af3 100644 --- a/phpBB/includes/acp/info/acp_permissions.php +++ b/phpBB/includes/acp/info/acp_permissions.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_php_info.php b/phpBB/includes/acp/info/acp_php_info.php index 740cbd442f..7d716b0f83 100644 --- a/phpBB/includes/acp/info/acp_php_info.php +++ b/phpBB/includes/acp/info/acp_php_info.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_profile.php b/phpBB/includes/acp/info/acp_profile.php index f9ebcb4751..8590226038 100644 --- a/phpBB/includes/acp/info/acp_profile.php +++ b/phpBB/includes/acp/info/acp_profile.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_prune.php b/phpBB/includes/acp/info/acp_prune.php index cf29aaee81..46565c4f16 100644 --- a/phpBB/includes/acp/info/acp_prune.php +++ b/phpBB/includes/acp/info/acp_prune.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_ranks.php b/phpBB/includes/acp/info/acp_ranks.php index 88d667e47a..06b9c6d284 100644 --- a/phpBB/includes/acp/info/acp_ranks.php +++ b/phpBB/includes/acp/info/acp_ranks.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_reasons.php b/phpBB/includes/acp/info/acp_reasons.php index 11d374d72a..65d805ee18 100644 --- a/phpBB/includes/acp/info/acp_reasons.php +++ b/phpBB/includes/acp/info/acp_reasons.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_search.php b/phpBB/includes/acp/info/acp_search.php index d38bae99ba..4afd6c6994 100644 --- a/phpBB/includes/acp/info/acp_search.php +++ b/phpBB/includes/acp/info/acp_search.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_styles.php b/phpBB/includes/acp/info/acp_styles.php index 3df02828b3..db67167e39 100644 --- a/phpBB/includes/acp/info/acp_styles.php +++ b/phpBB/includes/acp/info/acp_styles.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_update.php b/phpBB/includes/acp/info/acp_update.php index 0355c583f3..886cdc94d5 100644 --- a/phpBB/includes/acp/info/acp_update.php +++ b/phpBB/includes/acp/info/acp_update.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_users.php b/phpBB/includes/acp/info/acp_users.php index a6e4abe6d3..0cd5f7ae97 100644 --- a/phpBB/includes/acp/info/acp_users.php +++ b/phpBB/includes/acp/info/acp_users.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/acp/info/acp_words.php b/phpBB/includes/acp/info/acp_words.php index 1f47ce870c..a2417f8a7f 100644 --- a/phpBB/includes/acp/info/acp_words.php +++ b/phpBB/includes/acp/info/acp_words.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/auth.php b/phpBB/includes/auth.php index de9cc9bac7..c965149018 100644 --- a/phpBB/includes/auth.php +++ b/phpBB/includes/auth.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Permission/Auth class * @package phpBB3 */ @@ -156,7 +164,7 @@ class auth { global $db; - $sql = 'SELECT forum_id + $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE; if (sizeof($this->acl)) @@ -578,7 +586,7 @@ class auth ) ), - 'WHERE' => 'ao.auth_option_id = a.auth_option_id + 'WHERE' => 'ao.auth_option_id = a.auth_option_id AND a.group_id = ug.group_id AND ug.user_pending = 0 ' . (($sql_user) ? 'AND ug.' . $sql_user : '') . " @@ -725,7 +733,7 @@ class auth $hold_ary = array(); - // Grab group settings... + // Grab group settings... $sql = $db->sql_build_query('SELECT', array( 'SELECT' => 'a.group_id, ao.auth_option, a.forum_id, a.auth_setting, a.auth_role_id, r.auth_setting as role_auth_setting', diff --git a/phpBB/includes/auth/auth_apache.php b/phpBB/includes/auth/auth_apache.php index 4c8293c707..ed3951dd7b 100644 --- a/phpBB/includes/auth/auth_apache.php +++ b/phpBB/includes/auth/auth_apache.php @@ -6,12 +6,20 @@ * * @package login * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Checks whether the user is identified to apache * Only allow changing authentication to apache if the user is identified * Called in acp_board while setting authentication plugins @@ -36,6 +44,15 @@ function login_apache(&$username, &$password) { global $db; + // do not allow empty password + if (!$password) + { + return array( + 'status' => LOGIN_BREAK, + 'error_msg' => 'NO_PASSWORD_SUPPLIED', + ); + } + if (!isset($_SERVER['PHP_AUTH_USER'])) { return array( @@ -59,7 +76,7 @@ function login_apache(&$username, &$password) ); } - $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type + $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type FROM ' . USERS_TABLE . " WHERE username = '" . $db->sql_escape($php_auth_user) . "'"; $result = $db->sql_query($sql); @@ -185,7 +202,7 @@ function user_row_apache($username, $password) // generate user account data return array( 'username' => $username, - 'user_password' => md5($password), + 'user_password' => phpbb_hash($password), 'user_email' => '', 'group_id' => (int) $row['group_id'], 'user_type' => USER_NORMAL, diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index 6df378b00a..432ae92d21 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -8,18 +8,35 @@ * * @package login * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Login function */ function login_db(&$username, &$password) { global $db, $config; + // do not allow empty password + if (!$password) + { + return array( + 'status' => LOGIN_BREAK, + 'error_msg' => 'NO_PASSWORD_SUPPLIED', + ); + } + $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts FROM ' . USERS_TABLE . " WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; @@ -116,15 +133,17 @@ function login_db(&$username, &$password) // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding if (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password']) { + $hash = phpbb_hash($password_new_format); + // Update the password in the users table to the new format and remove user_pass_convert flag $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_password = \'' . $db->sql_escape(md5($password_new_format)) . '\', + SET user_password = \'' . $db->sql_escape($hash) . '\', user_pass_convert = 0 WHERE user_id = ' . $row['user_id']; $db->sql_query($sql); $row['user_pass_convert'] = 0; - $row['user_password'] = md5($password_new_format); + $row['user_password'] = $hash; } else { @@ -145,8 +164,23 @@ function login_db(&$username, &$password) } // Check password ... - if (!$row['user_pass_convert'] && md5($password) == $row['user_password']) + if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password'])) { + // Check for old password hash... + if (strlen($row['user_password']) == 32) + { + $hash = phpbb_hash($password); + + // Update the password in the users table to the new format + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_password = '" . $db->sql_escape($hash) . "', + user_pass_convert = 0 + WHERE user_id = {$row['user_id']}"; + $db->sql_query($sql); + + $row['user_password'] = $hash; + } + if ($row['user_login_attempts'] != 0) { // Successful, reset login attempts (the user passed all stages) diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index a4e6365183..472927ace3 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -1,5 +1,5 @@ <?php -/** +/** * * LDAP auth plug-in for phpBB3 * @@ -7,12 +7,20 @@ * * @package login * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Connect to ldap server * Only allow changing authentication to ldap if we can connect to the ldap server * Called in acp_board while setting authentication plugins @@ -92,6 +100,15 @@ function login_ldap(&$username, &$password) { global $db, $config, $user; + // do not allow empty password + if (!$password) + { + return array( + 'status' => LOGIN_BREAK, + 'error_msg' => 'NO_PASSWORD_SUPPLIED', + ); + } + if (!@extension_loaded('ldap')) { return array( @@ -195,7 +212,7 @@ function login_ldap(&$username, &$password) // generate user account data $ldap_user_row = array( 'username' => $username, - 'user_password' => md5($password), + 'user_password' => phpbb_hash($password), 'user_email' => (!empty($config['ldap_email'])) ? $ldap_result[0][$config['ldap_email']][0] : '', 'group_id' => (int) $row['group_id'], 'user_type' => USER_NORMAL, diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index c877d56e2b..ef73762582 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * BBCode class * @package phpBB3 */ @@ -72,6 +80,7 @@ class bbcode $bitfield = new bitfield($this->bbcode_bitfield); $bbcodes_set = $bitfield->get_all_set(); + $undid_bbcode_specialchars = false; foreach ($bbcodes_set as $bbcode_id) { if (!empty($this->bbcode_cache[$bbcode_id])) @@ -92,6 +101,14 @@ class bbcode if (sizeof($preg['search'])) { + // we need to turn the entities back into their original form to allow the + // search patterns to work properly + if (!$undid_bbcode_specialchars) + { + $message = str_replace(array(':', '.'), array(':', '.'), $message); + $undid_bbcode_specialchars = true; + } + $message = preg_replace($preg['search'], $preg['replace'], $message); $preg = array('search' => array(), 'replace' => array()); } diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php index 97b98e1227..5198abdc3c 100644 --- a/phpBB/includes/cache.php +++ b/phpBB/includes/cache.php @@ -9,6 +9,7 @@ */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -293,14 +294,14 @@ class cache extends acm { case 'mssql': case 'mssql_odbc': - $sql = 'SELECT user_id, bot_agent, bot_ip + $sql = 'SELECT user_id, bot_agent, bot_ip FROM ' . BOTS_TABLE . ' WHERE bot_active = 1 ORDER BY LEN(bot_agent) DESC'; break; case 'firebird': - $sql = 'SELECT user_id, bot_agent, bot_ip + $sql = 'SELECT user_id, bot_agent, bot_ip FROM ' . BOTS_TABLE . ' WHERE bot_active = 1 ORDER BY CHAR_LENGTH(bot_agent) DESC'; @@ -308,7 +309,7 @@ class cache extends acm // LENGTH supported by MySQL, IBM DB2 and Oracle for sure... default: - $sql = 'SELECT user_id, bot_agent, bot_ip + $sql = 'SELECT user_id, bot_agent, bot_ip FROM ' . BOTS_TABLE . ' WHERE bot_active = 1 ORDER BY LENGTH(bot_agent) DESC'; @@ -403,6 +404,38 @@ class cache extends acm return $usernames; } + + /** + * Obtain hooks... + */ + function obtain_hooks() + { + global $phpbb_root_path, $phpEx; + + if (($hook_files = $this->get('_hooks')) === false) + { + $hook_files = array(); + + // Now search for hooks... + $dh = @opendir($phpbb_root_path . 'includes/hooks/'); + + if ($dh) + { + while (($file = readdir($dh)) !== false) + { + if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) + { + $hook_files[] = substr($file, 0, -(strlen($phpEx) + 1)); + } + } + closedir($dh); + } + + $this->put('_hooks', $hook_files); + } + + return $hook_files; + } } ?>
\ No newline at end of file diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php index df5813239b..9c9eb5eda7 100644 --- a/phpBB/includes/captcha/captcha_gd.php +++ b/phpBB/includes/captcha/captcha_gd.php @@ -1,14 +1,20 @@ <?php -/** +/** * * @package VC * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ - +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} /** * Original Author - Xore (Robert Hetzler) @@ -42,7 +48,7 @@ class captcha $scheme = $colour->colour_scheme('background', false); $scheme = $colour->mono_range($scheme, 10, false); shuffle($scheme); - + $bg_colours = array_splice($scheme, mt_rand(6, 12)); // Generate code characters @@ -1146,7 +1152,7 @@ class colour_manager // everything else is params return $this->random_colour($colour, $mode); } - + $rgb = colour_manager::model_convert($colour, $mode, 'rgb'); $store = ($this->mode == 'rgb') ? $rgb : colour_manager::model_convert($colour, $mode, $this->mode); $resource = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]); @@ -1269,7 +1275,7 @@ class colour_manager $colour = colour_manager::model_convert($this->colours[$resource], $this->mode, $mode); $results = ($include_original) ? array($resource) : array(); $colour2 = $colour3 = $colour4 = $colour; - $colour2[0] += 150; + $colour2[0] += 150; $colour3[0] += 180; $colour4[0] += 210; @@ -1383,15 +1389,12 @@ class colour_manager */ function hsv2rgb($hsv) { - colour_manager::normalize_hue($hsv[0]); - - $h = $hsv[0]; $s = min(1, max(0, $hsv[1] / 100)); $v = min(1, max(0, $hsv[2] / 100)); - + // calculate hue sector $hi = floor($hsv[0] / 60); @@ -1409,7 +1412,7 @@ class colour_manager // calculate adjacent colour $q = $v * (1 - ($f * $s)); - + switch ($hi) { case 0: @@ -1440,7 +1443,7 @@ class colour_manager return array(0, 0, 0); break; } - + return array(255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]); } diff --git a/phpBB/includes/captcha/captcha_non_gd.php b/phpBB/includes/captcha/captcha_non_gd.php index bb4e5af443..f82896f628 100644 --- a/phpBB/includes/captcha/captcha_non_gd.php +++ b/phpBB/includes/captcha/captcha_non_gd.php @@ -1,13 +1,20 @@ <?php -/** +/** * * @package VC * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} /** * Main non-gd captcha class @@ -235,149 +242,149 @@ class captcha { $this->filtered_pngs = array( '0' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==', 'width' => 40 - ), + ), '1' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '2' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '3' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '4' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '5' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '6' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '7' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '8' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), '9' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'A' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'B' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'C' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'D' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'E' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'F' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'G' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'H' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'I' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'J' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'K' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'L' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'M' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'N' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'O' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'P' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'Q' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'R' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'S' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'T' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'U' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'V' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'W' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'X' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'Y' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), 'Z' => array( - 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', + 'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=', 'width' => 40 - ), + ), ); } } diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 3c049a1153..18e92d70c0 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -1,14 +1,26 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* valid external constants: +* PHPBB_MSG_HANDLER +* PHPBB_ROOT_PATH +* PHPBB_ADMIN_PATH */ // User related @@ -136,7 +148,7 @@ define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files // BBCode UID length -define('BBCODE_UID_LEN', 5); +define('BBCODE_UID_LEN', 8); // Number of core BBCodes define('NUM_CORE_BBCODES', 12); diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php new file mode 100644 index 0000000000..589ca39258 --- /dev/null +++ b/phpBB/includes/db/db_tools.php @@ -0,0 +1,1413 @@ +<?php +/** +* +* @package dbal +* @version $Id$ +* @copyright (c) 2007 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Database Tools for handling cross-db actions such as altering columns, etc. +* Currently not supported is returning SQL for creating tables. +* +* @package dbal +* @note currently not used within phpBB3, but may be utilized later. +*/ +class phpbb_db_tools +{ + /** + * Current sql layer + */ + var $sql_layer = ''; + + 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_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', + ), + ); + + // A list of types being unsigned for better reference in some db's + var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); + + /** + * Set this to true if you only want to return the 'to-be-executed' SQL statement(s) (as an array). + */ + var $return_statements = false; + + /** + */ + function phpbb_db_tools(&$db) + { + $this->db = $db; + + // Determine mapping database type + switch ($this->db->sql_layer) + { + case 'mysql': + $this->sql_layer = 'mysql_40'; + break; + + case 'mysql4': + if (version_compare($this->db->mysql_version, '4.1.3', '>=')) + { + $this->sql_layer = 'mysql_41'; + } + else + { + $this->sql_layer = 'mysql_40'; + } + break; + + case 'mysqli': + $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; + } + } + + /** + * Handle passed database update array. + * Expected structure... + * Key being one of the following + * change_columns: Column changes (only type, not name) + * add_columns: Add columns to a table + * drop_keys: Dropping keys + * drop_columns: Removing/Dropping columns + * add_primary_keys: adding primary keys + * add_unique_index: adding an unique index + * add_index: adding an index + * + * The values are in this format: + * {TABLE NAME} => array( + * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}), + * {KEY/INDEX NAME} => array({COLUMN NAMES}), + * ) + * + * For more information have a look at /develop/create_schema_files.php (only available through CVS) + */ + function perform_schema_changes($schema_changes) + { + if (empty($schema_changes)) + { + return; + } + + $statements = array(); + + // Change columns? + if (!empty($schema_changes['change_columns'])) + { + foreach ($schema_changes['change_columns'] as $table => $columns) + { + foreach ($columns as $column_name => $column_data) + { + $result = $this->sql_column_change($table, $column_name, $column_data); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add columns? + if (!empty($schema_changes['add_columns'])) + { + foreach ($schema_changes['add_columns'] as $table => $columns) + { + foreach ($columns as $column_name => $column_data) + { + // Only add the column if it does not exist yet + if (!$this->sql_column_exists($table, $column_name)) + { + $result = $this->sql_column_add($table, $column_name, $column_data); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + } + + // Remove keys? + if (!empty($schema_changes['drop_keys'])) + { + foreach ($schema_changes['drop_keys'] as $table => $indexes) + { + foreach ($indexes as $index_name) + { + $result = $this->sql_index_drop($table, $index_name); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Drop columns? + if (!empty($schema_changes['drop_columns'])) + { + foreach ($schema_changes['drop_columns'] as $table => $columns) + { + foreach ($columns as $column) + { + $result = $this->sql_column_remove($table, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add primary keys? + if (!empty($schema_changes['add_primary_keys'])) + { + foreach ($schema_changes['add_primary_keys'] as $table => $columns) + { + $result = $this->sql_create_primary_key($table, $columns); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + + // Add unqiue indexes? + if (!empty($schema_changes['add_unique_index'])) + { + foreach ($schema_changes['add_unique_index'] as $table => $index_array) + { + foreach ($index_array as $index_name => $column) + { + $result = $this->sql_create_unique_index($table, $index_name, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + // Add indexes? + if (!empty($schema_changes['add_index'])) + { + foreach ($schema_changes['add_index'] as $table => $index_array) + { + foreach ($index_array as $index_name => $column) + { + $result = $this->sql_create_index($table, $index_name, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } + } + } + } + + if ($this->return_statements) + { + return $statements; + } + } + + /** + * Check if a specified column exist + * @return bool True if column exists, else false + */ + 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 table_name = '{$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 = '{$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; + } + + $row = $this->db->sql_fetchrow($result); + $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; + } + } + + /** + * Private method for performing sql statements (either execute them or return them) + * @private + */ + function _sql_run_sql($statements) + { + if ($this->return_statements) + { + return $statements; + } + + // We could add error handling here... + foreach ($statements as $sql) + { + if ($sql === 'begin') + { + $this->db->sql_transaction('begin'); + } + else if ($sql === 'commit') + { + $this->db->sql_transaction('commit'); + } + else + { + $this->db->sql_query($sql); + } + } + + return true; + } + + /** + * Function to prepare some column information for better usage + * @private + */ + function sql_prepare_column_data($table_name, $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->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); + } + else + { + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) + { + case 'div': + $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; + $column_length = ceil($column_length); + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + break; + } + } + + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) + { + case 'mult': + $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; + if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) + { + $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; + } + else + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + } + break; + } + } + } + $orig_column_type .= ':'; + } + else + { + $orig_column_type = $column_data[0]; + $column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]]; + } + + // Adjust default value if db-dependant specified + if (is_array($column_data[1])) + { + $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; + } + + $sql = ''; + + $return_array = array(); + + switch ($this->sql_layer) + { + case 'firebird': + $sql .= " {$column_type} "; + + if (!is_null($column_data[1])) + { + $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'; + } + + break; + + case 'mssql': + $sql .= " {$column_type} "; + + // we do not support MSSQL DEFAULTs for the near future + /*if (!is_null($column_data[1])) + { + // For hexadecimal values do not use single quotes + if (strpos($column_data[1], '0x') === 0) + { + $sql .= 'DEFAULT (' . $column_data[1] . ') '; + } + else + { + $sql .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; + } + }*/ + + $sql .= 'NOT NULL'; + 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'; + } + break; + + case 'postgres': + $return_array['column_type'] = $column_type; + + $sql .= " {$column_type} "; + + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $default_val = "nextval('{$table_name}_seq')"; + } + 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': + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $sql .= ' INTEGER PRIMARY KEY'; + } + else + { + $sql .= ' ' . $column_type; + } + + $sql .= ' NOT NULL '; + $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; + break; + } + + $return_array['column_type_sql'] = $sql; + + return $return_array; + } + + /** + * Add new column + */ + function sql_column_add($table_name, $column_name, $column_data) + { + $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 "' . $column_name . '" ' . $column_data['column_type_sql']; + break; + + case 'mssql': + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql']; + break; + + case 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql']; + break; + + case 'oracle': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; + break; + + case 'postgres': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; + break; + + case 'sqlite': + 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) + { + $statements = array(); + + switch ($this->sql_layer) + { + case 'firebird': + $statements[] = 'ALTER TABLE "' . $table_name . '" DROP "' . $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 (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 = $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); + } + + /** + * Add primary key + */ + function sql_create_primary_key($table_name, $column) + { + $statements = array(); + + switch ($this->sql_layer) + { + case 'firebird': + case 'postgres': + $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 'mysql_40': + case 'mysql_41': + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; + break; + + case 'oracle': + $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; + break; + + case 'sqlite': + $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; + } + + return $this->_sql_run_sql($statements); + } + + /** + * Add unique index + */ + 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; + } + + return $this->_sql_run_sql($statements); + } + + /** + * Add index + */ + 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; + } + + return $this->_sql_run_sql($statements); + } + + /** + * List all of the indices that belong to a table, + * does not count: + * * UNIQUE indices + * * PRIMARY keys + */ + function sql_list_index($table_name) + { + $index_array = array(); + + if ($this->sql_layer == 'mssql') + { + $sql = "EXEC sp_statistics '$table_name'"; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if ($row['TYPE'] == 3) + { + $index_array[] = $row['INDEX_NAME']; + } + } + $this->db->sql_freeresult($result); + } + 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 = '" . $table_name . "' + AND generated = 'N'"; + break; + + case 'sqlite': + $sql = "PRAGMA index_info('" . $table_name . "');"; + $col = 'name'; + break; + } + + $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']) + { + 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); + } + + return array_map('strtolower', $index_array); + } + + /** + * Change column type (not name!) + */ + function sql_column_change($table_name, $column_name, $column_data) + { + $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + $statements = array(); + + switch ($this->sql_layer) + { + case 'firebird': + // Change type... + $statements[] = 'ALTER TABLE "' . $table_name . '" ALTER COLUMN "' . $column_name . '" TYPE ' . ' ' . $column_data['column_type_sql']; + break; + + case 'mssql': + $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; + 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': + + $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; + } + + return $this->_sql_run_sql($statements); + } +} + +?>
\ No newline at end of file diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 79a2d6bf35..a68ce1e2a4 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Database Abstraction Layer * @package dbal */ @@ -99,8 +107,8 @@ class dbal */ function sql_add_num_queries($cached = false) { - $this->num_queries['cached'] += ($cached) ? 1 : 0; - $this->num_queries['normal'] += ($cached) ? 0 : 1; + $this->num_queries['cached'] += ($cached !== false) ? 1 : 0; + $this->num_queries['normal'] += ($cached !== false) ? 0 : 1; $this->num_queries['total'] += 1; } @@ -651,8 +659,10 @@ class dbal </div> </body> </html>'; - exit; - break; + + exit_handler(); + + break; case 'stop': $endtime = explode(' ', microtime()); @@ -775,13 +785,6 @@ class dbal } /** -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * This variable holds the class name to use later */ $sql_db = 'dbal_' . $dbms; diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index 771592a02a..d23d1866c1 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -250,7 +250,7 @@ class dbal_firebird extends dbal $query = 'SELECT FIRST ' . $total . ((!empty($offset)) ? ' SKIP ' . $offset : '') . substr($query, 6); - return $this->sql_query($query, $cache_ttl); + return $this->sql_query($query, $cache_ttl); } /** diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index f07d1adfe9..b222588cf2 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -168,7 +168,7 @@ class dbal_mssql extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { $this->query_result = false; @@ -234,7 +234,7 @@ class dbal_mssql extends dbal { foreach ($row as $key => $value) { - $row[$key] = ($value === ' ') ? '' : $value; + $row[$key] = ($value === ' ' || $value === NULL) ? '' : $value; } } @@ -345,7 +345,7 @@ class dbal_mssql extends dbal } // Get full error message if possible - $sql = 'SELECT CAST(description as varchar(255)) as message + $sql = 'SELECT CAST(description as varchar(255)) as message FROM master.dbo.sysmessages WHERE error = ' . $error['code']; $result_id = @mssql_query($sql); diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index 72a424f46d..7722f79952 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -180,7 +180,7 @@ class dbal_mssql_odbc extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { $this->query_result = false; diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index b3be4f9bd9..2d689f86f9 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -189,7 +189,7 @@ class dbal_mysql extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { $this->query_result = false; diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index 320171e852..32765d15f7 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -169,7 +169,7 @@ class dbal_mysqli extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { $this->query_result = false; diff --git a/phpBB/includes/db/oracle.php b/phpBB/includes/db/oracle.php index 18af5cbab0..a63c06e5c0 100644 --- a/phpBB/includes/db/oracle.php +++ b/phpBB/includes/db/oracle.php @@ -361,13 +361,13 @@ class dbal_oracle extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { - $this->query_result = false; + $this->query_result = false; $query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset; - return $this->sql_query($query, $cache_ttl); + return $this->sql_query($query, $cache_ttl); } /** diff --git a/phpBB/includes/db/postgres.php b/phpBB/includes/db/postgres.php index 340c32b37a..bb689a7394 100644 --- a/phpBB/includes/db/postgres.php +++ b/phpBB/includes/db/postgres.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -217,9 +217,9 @@ class dbal_postgres extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) - { - $this->query_result = false; + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + { + $this->query_result = false; // if $total is set to 0 we do not want to limit the number of rows if ($total == 0) @@ -229,7 +229,7 @@ class dbal_postgres extends dbal $query .= "\n LIMIT $total OFFSET $offset"; - return $this->sql_query($query, $cache_ttl); + return $this->sql_query($query, $cache_ttl); } /** diff --git a/phpBB/includes/db/sqlite.php b/phpBB/includes/db/sqlite.php index 3248b439c6..5ae36df4f5 100644 --- a/phpBB/includes/db/sqlite.php +++ b/phpBB/includes/db/sqlite.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package dbal * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -141,9 +141,9 @@ class dbal_sqlite extends dbal /** * Build LIMIT query */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { - $this->query_result = false; + $this->query_result = false; // if $total is set to 0 we do not want to limit the number of rows if ($total == 0) @@ -153,7 +153,7 @@ class dbal_sqlite extends dbal $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - return $this->sql_query($query, $cache_ttl); + return $this->sql_query($query, $cache_ttl); } /** diff --git a/phpBB/includes/diff/diff.php b/phpBB/includes/diff/diff.php index 0308297c4e..0b3d14dbda 100644 --- a/phpBB/includes/diff/diff.php +++ b/phpBB/includes/diff/diff.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package diff * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -66,7 +67,7 @@ class diff * </code> * * @return diff A Diff object representing the inverse of the original diff. - * Note that we purposely don't return a reference here, since + * Note that we purposely don't return a reference here, since * this essentially is a clone() method. */ function reverse() diff --git a/phpBB/includes/diff/engine.php b/phpBB/includes/diff/engine.php index c4802c2257..576839ea60 100644 --- a/phpBB/includes/diff/engine.php +++ b/phpBB/includes/diff/engine.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package diff * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { diff --git a/phpBB/includes/diff/renderer.php b/phpBB/includes/diff/renderer.php index feb741762a..4157bc2cde 100644 --- a/phpBB/includes/diff/renderer.php +++ b/phpBB/includes/diff/renderer.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package diff * @version $Id$ -* @copyright (c) 2006 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -269,7 +270,7 @@ class diff_renderer * Renders a unified diff * @package diff */ -class diff_renderer_unified extends diff_renderer +class diff_renderer_unified extends diff_renderer { var $_leading_context_lines = 4; var $_trailing_context_lines = 4; @@ -284,12 +285,12 @@ class diff_renderer_unified extends diff_renderer function _block_header($xbeg, $xlen, $ybeg, $ylen) { - if ($xlen != 1) + if ($xlen != 1) { $xbeg .= ',' . $xlen; } - if ($ylen != 1) + if ($ylen != 1) { $ybeg .= ',' . $ylen; } @@ -505,7 +506,7 @@ class diff_renderer_inline extends diff_renderer * * @package diff */ -class diff_renderer_raw extends diff_renderer +class diff_renderer_raw extends diff_renderer { var $_leading_context_lines = 4; var $_trailing_context_lines = 4; @@ -520,12 +521,12 @@ class diff_renderer_raw extends diff_renderer function _block_header($xbeg, $xlen, $ybeg, $ylen) { - if ($xlen != 1) + if ($xlen != 1) { $xbeg .= ',' . $xlen; } - if ($ylen != 1) + if ($ylen != 1) { $ybeg .= ',' . $ylen; } @@ -559,7 +560,7 @@ class diff_renderer_raw extends diff_renderer * * @package diff */ -class diff_renderer_side_by_side extends diff_renderer +class diff_renderer_side_by_side extends diff_renderer { var $_leading_context_lines = 3; var $_trailing_context_lines = 3; @@ -647,7 +648,7 @@ class diff_renderer_side_by_side extends diff_renderer break; case 'change': - // Pop the old/new stacks one by one, until both are empty. + // Pop the old/new stacks one by one, until both are empty. $oldsize = sizeof($change['old']); $newsize = sizeof($change['new']); $left = $right = ''; diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 142b1e8ce7..ab27b62656 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -8,6 +8,14 @@ * */ +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + // Common global functions /** @@ -204,7 +212,7 @@ function still_on_time($extra_time = 15) if (empty($max_execution_time)) { - $max_execution_time = (function_exists('ini_get')) ? (int) ini_get('max_execution_time') : (int) get_cfg_var('max_execution_time'); + $max_execution_time = (function_exists('ini_get')) ? (int) @ini_get('max_execution_time') : (int) @get_cfg_var('max_execution_time'); // If zero, then set to something higher to not let the user catch the ten seconds barrier. if ($max_execution_time === 0) @@ -225,162 +233,206 @@ function still_on_time($extra_time = 15) } /** -* Generate sort selection fields +* +* @version Version 0.1 / $Id$ +* +* Portable PHP password hashing framework. +* +* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in +* the public domain. +* +* There's absolutely no warranty. +* +* The homepage URL for this framework is: +* +* http://www.openwall.com/phpass/ +* +* Please be sure to update the Version line if you edit this file in any way. +* It is suggested that you leave the main version number intact, but indicate +* your project name (after the slash) and add your own revision information. +* +* Please do not change the "private" password hashing method implemented in +* here, thereby making your hashes incompatible. However, if you must, please +* change the hash type identifier (the "$P$") to something different. +* +* Obviously, since this code is in the public domain, the above are not +* requirements (there can be none), but merely suggestions. +* +* +* Hash the password */ -function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key, &$sort_dir, &$s_limit_days, &$s_sort_key, &$s_sort_dir, &$u_sort_param) +function phpbb_hash($password) { - global $user; + $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']); + $random_state = unique_id(); + $random = ''; + $count = 6; - // Check if the key is selectable. If not, we reset to the first key found. - // This ensures the values are always valid. - if (!isset($limit_days[$sort_days])) + if (($fh = @fopen('/dev/urandom', 'rb'))) { - @reset($limit_days); - $sort_days = key($limit_days); + $random = fread($fh, $count); + fclose($fh); } - if (!isset($sort_by_text[$sort_key])) + if (strlen($random) < $count) { - @reset($sort_by_text); - $sort_key = key($sort_by_text); - } + $random = ''; - if (!isset($sort_dir_text[$sort_dir])) - { - @reset($sort_dir_text); - $sort_dir = key($sort_dir_text); + for ($i = 0; $i < $count; $i += 16) + { + $random_state = md5(unique_id() . $random_state); + $random .= pack('H*', md5($random_state)); + } + $random = substr($random, 0, $count); } - $s_limit_days = '<select name="st">'; - foreach ($limit_days as $day => $text) - { - $selected = ($sort_days == $day) ? ' selected="selected"' : ''; - $s_limit_days .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>'; - } - $s_limit_days .= '</select>'; + $hash = _hash_crypt_private($password, _hash_gensalt_private($random, $itoa64), $itoa64); - $s_sort_key = '<select name="sk">'; - foreach ($sort_by_text as $key => $text) + if (strlen($hash) == 34) { - $selected = ($sort_key == $key) ? ' selected="selected"' : ''; - $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>'; + return $hash; } - $s_sort_key .= '</select>'; - $s_sort_dir = '<select name="sd">'; - foreach ($sort_dir_text as $key => $value) + return md5($password); +} + +/** +* Check for correct password +*/ +function phpbb_check_hash($password, $hash) +{ + $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + if (strlen($hash) == 34) { - $selected = ($sort_dir == $key) ? ' selected="selected"' : ''; - $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; + return (_hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false; } - $s_sort_dir .= '</select>'; - - $u_sort_param = "st=$sort_days&sk=$sort_key&sd=$sort_dir"; - return; + return (md5($password) === $hash) ? true : false; } /** -* Generate Jumpbox +* Generate salt for hash generation */ -function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list = false) +function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6) { - global $config, $auth, $template, $user, $db; - - if (!$config['load_jumpbox']) + if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) { - return; + $iteration_count_log2 = 8; } - $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id - FROM ' . FORUMS_TABLE . ' - ORDER BY left_id ASC'; - $result = $db->sql_query($sql, 600); + $output = '$H$'; + $output .= $itoa64[min($iteration_count_log2 + ((PHP_VERSION >= 5) ? 5 : 3), 30)]; + $output .= _hash_encode64($input, 6, $itoa64); - $right = $padding = 0; - $padding_store = array('0' => 0); - $display_jumpbox = false; - $iteration = 0; + return $output; +} - // Sometimes it could happen that forums will be displayed here not be displayed within the index page - // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions. - // If this happens, the padding could be "broken" +/** +* Encode hash +*/ +function _hash_encode64($input, $count, &$itoa64) +{ + $output = ''; + $i = 0; - while ($row = $db->sql_fetchrow($result)) + do { - if ($row['left_id'] < $right) - { - $padding++; - $padding_store[$row['parent_id']] = $padding; - } - else if ($row['left_id'] > $right + 1) + $value = ord($input[$i++]); + $output .= $itoa64[$value & 0x3f]; + + if ($i < $count) { - // Ok, if the $padding_store for this parent is empty there is something wrong. For now we will skip over it. - // @todo digging deep to find out "how" this can happen. - $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding; + $value |= ord($input[$i]) << 8; } - $right = $row['right_id']; + $output .= $itoa64[($value >> 6) & 0x3f]; - if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id'])) + if ($i++ >= $count) { - // Non-postable forum with no subforums, don't display - continue; + break; } - if (!$auth->acl_get('f_list', $row['forum_id'])) + if ($i < $count) { - // if the user does not have permissions to list this forum skip - continue; + $value |= ord($input[$i]) << 16; } - if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id'])) + $output .= $itoa64[($value >> 12) & 0x3f]; + + if ($i++ >= $count) { - continue; + break; } - if (!$display_jumpbox) - { - $template->assign_block_vars('jumpbox_forums', array( - 'FORUM_ID' => ($select_all) ? 0 : -1, - 'FORUM_NAME' => ($select_all) ? $user->lang['ALL_FORUMS'] : $user->lang['SELECT_FORUM'], - 'S_FORUM_COUNT' => $iteration) - ); + $output .= $itoa64[($value >> 18) & 0x3f]; + } + while ($i < $count); - $iteration++; - $display_jumpbox = true; - } + return $output; +} - $template->assign_block_vars('jumpbox_forums', array( - 'FORUM_ID' => $row['forum_id'], - 'FORUM_NAME' => $row['forum_name'], - 'SELECTED' => ($row['forum_id'] == $forum_id) ? ' selected="selected"' : '', - 'S_FORUM_COUNT' => $iteration, - 'S_IS_CAT' => ($row['forum_type'] == FORUM_CAT) ? true : false, - 'S_IS_LINK' => ($row['forum_type'] == FORUM_LINK) ? true : false, - 'S_IS_POST' => ($row['forum_type'] == FORUM_POST) ? true : false) - ); +/** +* The crypt function/replacement +*/ +function _hash_crypt_private($password, $setting, &$itoa64) +{ + $output = '*'; + + // Check for correct hash + if (substr($setting, 0, 3) != '$H$') + { + return $output; + } + + $count_log2 = strpos($itoa64, $setting[3]); + + if ($count_log2 < 7 || $count_log2 > 30) + { + return $output; + } + + $count = 1 << $count_log2; + $salt = substr($setting, 4, 8); - for ($i = 0; $i < $padding; $i++) + if (strlen($salt) != 8) + { + return $output; + } + + /** + * We're kind of forced to use MD5 here since it's the only + * cryptographic primitive available in all versions of PHP + * currently in use. To implement our own low-level crypto + * in PHP would result in much worse performance and + * consequently in lower iteration counts and hashes that are + * quicker to crack (by non-PHP code). + */ + if (PHP_VERSION >= 5) + { + $hash = md5($salt . $password, true); + do { - $template->assign_block_vars('jumpbox_forums.level', array()); + $hash = md5($hash . $password, true); } - $iteration++; + while (--$count); + } + else + { + $hash = pack('H*', md5($salt . $password)); + do + { + $hash = pack('H*', md5($hash . $password)); + } + while (--$count); } - $db->sql_freeresult($result); - unset($padding_store); - $template->assign_vars(array( - 'S_DISPLAY_JUMPBOX' => $display_jumpbox, - 'S_JUMPBOX_ACTION' => $action) - ); + $output = substr($setting, 0, 12); + $output .= _hash_encode64($hash, 16, $itoa64); - return; + return $output; } - // Compatibility functions if (!function_exists('array_combine')) @@ -426,7 +478,7 @@ if (!function_exists('str_split')) * the returned array will be broken down into chunks with each being split_length in length, * otherwise each chunk will be one character in length. FALSE is returned if split_length is * less than 1. If the split_length length exceeds the length of string, the entire string is - * returned as the first (and only) array element. + * returned as the first (and only) array element. */ function str_split($string, $split_length = 1) { @@ -457,7 +509,7 @@ if (!function_exists('stripos')) * * @return mixed Returns the numeric position of the first occurrence of needle in the haystack string. Unlike strpos(), stripos() is case-insensitive. * Note that the needle may be a string of one or more characters. - * If needle is not found, stripos() will return boolean FALSE. + * If needle is not found, stripos() will return boolean FALSE. */ function stripos($haystack, $needle) { @@ -472,184 +524,166 @@ if (!function_exists('stripos')) if (!function_exists('realpath')) { - if (DIRECTORY_SEPARATOR != '\\' && !(bool) ini_get('safe_mode') && function_exists('shell_exec') && trim(`realpath .`)) - { - /** - * @author Chris Smith <chris@project-minerva.org> - * @copyright 2006 Project Minerva Team - * @param string $path The path which we should attempt to resolve. - * @return mixed - * @ignore - */ - function phpbb_realpath($path) - { - $arg = escapeshellarg($path); - return trim(`realpath '$arg'`); - } + /** + * Checks if a path ($path) is absolute or relative + * + * @param string $path Path to check absoluteness of + * @return boolean + */ + function is_absolute($path) + { + return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:/#i', $path))) ? true : false; } - else + + /** + * @author Chris Smith <chris@project-minerva.org> + * @copyright 2006 Project Minerva Team + * @param string $path The path which we should attempt to resolve. + * @return mixed + */ + function phpbb_realpath($path) { - /** - * Checks if a path ($path) is absolute or relative - * - * @param string $path Path to check absoluteness of - * @return boolean - */ - function is_absolute($path) - { - return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:/#i', $path))) ? true : false; - } + // Now to perform funky shizzle - /** - * @author Chris Smith <chris@project-minerva.org> - * @copyright 2006 Project Minerva Team - * @param string $path The path which we should attempt to resolve. - * @return mixed - */ - function phpbb_realpath($path) - { - // Now to perform funky shizzle + // Switch to use UNIX slashes + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + $path_prefix = ''; - // Switch to use UNIX slashes - $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - $path_prefix = ''; + // Determine what sort of path we have + if (is_absolute($path)) + { + $absolute = true; - // Determine what sort of path we have - if (is_absolute($path)) + if ($path[0] == '/') + { + // Absolute path, *NIX style + $path_prefix = ''; + } + else { + // Absolute path, Windows style + // Remove the drive letter and colon + $path_prefix = $path[0] . ':'; + $path = substr($path, 2); + } + } + else + { + // Relative Path + // Prepend the current working directory + if (function_exists('getcwd')) + { + // This is the best method, hopefully it is enabled! + $path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path; $absolute = true; - - if ($path[0] == '/') + if (preg_match('#^[a-z]:#i', $path)) { - // Absolute path, *NIX style - $path_prefix = ''; + $path_prefix = $path[0] . ':'; + $path = substr($path, 2); } else { - // Absolute path, Windows style - // Remove the drive letter and colon - $path_prefix = $path[0] . ':'; - $path = substr($path, 2); + $path_prefix = ''; } } + else if (isset($_SERVER['SCRIPT_FILENAME']) && !empty($_SERVER['SCRIPT_FILENAME'])) + { + // Warning: If chdir() has been used this will lie! + // Warning: This has some problems sometime (CLI can create them easily) + $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($_SERVER['SCRIPT_FILENAME'])) . '/' . $path; + $absolute = true; + $path_prefix = ''; + } else { - // Relative Path - // Prepend the current working directory - if (function_exists('getcwd')) - { - // This is the best method, hopefully it is enabled! - $path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path; - $absolute = true; - if (preg_match('#^[a-z]:#i', $path)) - { - $path_prefix = $path[0] . ':'; - $path = substr($path, 2); - } - else - { - $path_prefix = ''; - } - } - else if (isset($_SERVER['SCRIPT_FILENAME']) && !empty($_SERVER['SCRIPT_FILENAME'])) - { - // Warning: If chdir() has been used this will lie! - // Warning: This has some problems sometime (CLI can create them easily) - $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($_SERVER['SCRIPT_FILENAME'])) . '/' . $path; - $absolute = true; - $path_prefix = ''; - } - else - { - // We have no way of getting the absolute path, just run on using relative ones. - $absolute = false; - $path_prefix = '.'; - } + // We have no way of getting the absolute path, just run on using relative ones. + $absolute = false; + $path_prefix = '.'; } + } - // Remove any repeated slashes - $path = preg_replace('#/{2,}#', '/', $path); + // Remove any repeated slashes + $path = preg_replace('#/{2,}#', '/', $path); - // Remove the slashes from the start and end of the path - $path = trim($path, '/'); + // Remove the slashes from the start and end of the path + $path = trim($path, '/'); - // Break the string into little bits for us to nibble on - $bits = explode('/', $path); + // Break the string into little bits for us to nibble on + $bits = explode('/', $path); - // Remove any . in the path, renumber array for the loop below - $bits = array_values(array_diff($bits, array('.'))); + // Remove any . in the path, renumber array for the loop below + $bits = array_values(array_diff($bits, array('.'))); - // Lets get looping, run over and resolve any .. (up directory) - for ($i = 0, $max = sizeof($bits); $i < $max; $i++) + // Lets get looping, run over and resolve any .. (up directory) + for ($i = 0, $max = sizeof($bits); $i < $max; $i++) + { + // @todo Optimise + if ($bits[$i] == '..' ) { - // @todo Optimise - if ($bits[$i] == '..' ) + if (isset($bits[$i - 1])) { - if (isset($bits[$i - 1])) + if ($bits[$i - 1] != '..') { - if ($bits[$i - 1] != '..') - { - // We found a .. and we are able to traverse upwards, lets do it! - unset($bits[$i]); - unset($bits[$i - 1]); - $i -= 2; - $max -= 2; - $bits = array_values($bits); - } - } - else if ($absolute) // ie. !isset($bits[$i - 1]) && $absolute - { - // We have an absolute path trying to descend above the root of the filesystem - // ... Error! - return false; + // We found a .. and we are able to traverse upwards, lets do it! + unset($bits[$i]); + unset($bits[$i - 1]); + $i -= 2; + $max -= 2; + $bits = array_values($bits); } } + else if ($absolute) // ie. !isset($bits[$i - 1]) && $absolute + { + // We have an absolute path trying to descend above the root of the filesystem + // ... Error! + return false; + } } + } - // Prepend the path prefix - array_unshift($bits, $path_prefix); + // Prepend the path prefix + array_unshift($bits, $path_prefix); - $resolved = ''; + $resolved = ''; - $max = sizeof($bits) - 1; + $max = sizeof($bits) - 1; - // Check if we are able to resolve symlinks, Windows cannot. - $symlink_resolve = (function_exists('readlink')) ? true : false; + // Check if we are able to resolve symlinks, Windows cannot. + $symlink_resolve = (function_exists('readlink')) ? true : false; - foreach ($bits as $i => $bit) + foreach ($bits as $i => $bit) + { + if (@is_dir("$resolved/$bit") || ($i == $max && @is_file("$resolved/$bit"))) { - if (@is_dir("$resolved/$bit") || ($i == $max && @is_file("$resolved/$bit"))) - { - // Path Exists - if ($symlink_resolve && is_link("$resolved/$bit") && ($link = readlink("$resolved/$bit"))) - { - // Resolved a symlink. - $resolved = $link . (($i == $max) ? '' : '/'); - continue; - } - } - else + // Path Exists + if ($symlink_resolve && is_link("$resolved/$bit") && ($link = readlink("$resolved/$bit"))) { - // Something doesn't exist here! - // This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic - // return false; + // Resolved a symlink. + $resolved = $link . (($i == $max) ? '' : '/'); + continue; } - $resolved .= $bit . (($i == $max) ? '' : '/'); } - - // @todo If the file exists fine and open_basedir only has one path we should be able to prepend it - // because we must be inside that basedir, the question is where... - // @internal The slash in is_dir() gets around an open_basedir restriction - if (!@file_exists($resolved) || (!is_dir($resolved . '/') && !is_file($resolved))) + else { - return false; + // Something doesn't exist here! + // This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic + // return false; } + $resolved .= $bit . (($i == $max) ? '' : '/'); + } - // Put the slashes back to the native operating systems slashes - $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved); - - return $resolved; // We got here, in the end! + // @todo If the file exists fine and open_basedir only has one path we should be able to prepend it + // because we must be inside that basedir, the question is where... + // @internal The slash in is_dir() gets around an open_basedir restriction + if (!@file_exists($resolved) || (!is_dir($resolved . '/') && !is_file($resolved))) + { + return false; } + + // Put the slashes back to the native operating systems slashes + $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved); + + return $resolved; // We got here, in the end! } } else @@ -701,7 +735,7 @@ function language_select($default = '') return $lang_options; } -/** +/** * Pick a template/theme combo, */ function style_select($default = '', $all = false) @@ -815,7 +849,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ if ($config['load_db_lastread'] && $user->data['is_registered']) { - $sql = 'DELETE FROM ' . TOPICS_TRACK_TABLE . " + $sql = 'DELETE FROM ' . TOPICS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']} AND " . $db->sql_in_set('forum_id', $forum_id); $db->sql_query($sql); @@ -1133,10 +1167,10 @@ function get_complete_topic_tracking($forum_id, $topic_ids, $global_announce_lis if (sizeof($topic_ids)) { - $sql = 'SELECT forum_id, mark_time + $sql = 'SELECT forum_id, mark_time FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']} - AND forum_id " . + AND forum_id " . (($global_announce_list && sizeof($global_announce_list)) ? "IN (0, $forum_id)" : "= $forum_id"); $result = $db->sql_query($sql); @@ -1518,7 +1552,7 @@ function generate_pagination($base_url, $num_items, $per_page, $start_item, $add if ($add_prevnext_text) { - if ($on_page != 1) + if ($on_page != 1) { $page_string = '<a href="' . $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page) . '">' . $user->lang['PREVIOUS'] . '</a> ' . $page_string; } @@ -1530,13 +1564,14 @@ function generate_pagination($base_url, $num_items, $per_page, $start_item, $add } $template->assign_vars(array( - $tpl_prefix . 'BASE_URL' => $base_url, - $tpl_prefix . 'PER_PAGE' => $per_page, + $tpl_prefix . 'BASE_URL' => $base_url, + 'A_' . $tpl_prefix . 'BASE_URL' => addslashes($base_url), + $tpl_prefix . 'PER_PAGE' => $per_page, $tpl_prefix . 'PREVIOUS_PAGE' => ($on_page == 1) ? '' : $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page), $tpl_prefix . 'NEXT_PAGE' => ($on_page == $total_pages) ? '' : $base_url . "{$url_delim}start=" . ($on_page * $per_page), - $tpl_prefix . 'TOTAL_PAGES' => $total_pages) - ); + $tpl_prefix . 'TOTAL_PAGES' => $total_pages, + )); return $page_string; } @@ -1563,7 +1598,8 @@ function on_page($num_items, $per_page, $start) // Server functions (building urls, redirecting...) /** -* Append session id to url +* Append session id to url. +* This function supports hooks. * * @param string $url The url the session id needs to be appended to (can have params) * @param mixed $params String or array of additional url parameters @@ -1577,16 +1613,20 @@ function on_page($num_items, $per_page, $start) * append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=1&f=2', false); * append_sid("{$phpbb_root_path}viewtopic.$phpEx", array('t' => 1, 'f' => 2)); * </code> +* */ function append_sid($url, $params = false, $is_amp = true, $session_id = false) { - global $_SID, $_EXTRA_URL; + global $_SID, $_EXTRA_URL, $phpbb_hook; // Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly. // They could mimick most of what is within this function - if (function_exists('append_sid_phpbb_hook')) + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id)) { - return append_sid_phpbb_hook($url, $params, $is_amp, $session_id); + if ($phpbb_hook->hook_return(__FUNCTION__)) + { + return $phpbb_hook->hook_return_result(__FUNCTION__); + } } // Assign sid if session id is not specified @@ -1657,8 +1697,8 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false) } /** -* Generate board url (example: http://www.foo.bar/phpBB) -* @param bool $without_script_path if set to true the script path gets not appended (example: http://www.foo.bar) +* Generate board url (example: http://www.example.com/phpBB) +* @param bool $without_script_path if set to true the script path gets not appended (example: http://www.example.com) */ function generate_board_url($without_script_path = false) { @@ -1810,6 +1850,15 @@ function redirect($url, $return = false) trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); } + // Now, also check the protocol and for a valid url the last time... + $allowed_protocols = array('http', 'https', 'ftp', 'ftps'); + $url_parts = parse_url($url); + + if ($url_parts === false || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], $allowed_protocols)) + { + trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); + } + if ($return) { return $url; @@ -1881,8 +1930,7 @@ function build_url($strip_vars = false) global $user, $phpbb_root_path; // Append SID - $redirect = (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name'] . (($user->page['query_string']) ? "?{$user->page['query_string']}" : ''); - $redirect = append_sid($redirect, false, false); + $redirect = append_sid($user->page['page'], false, false); // Add delimiter if not there... if (strpos($redirect, '?') === false) @@ -1950,13 +1998,81 @@ function meta_refresh($time, $url) ); } +//Form validation + +/** +* Add a secret token to the form (requires the S_FORM_TOKEN template variable) +* @param string $form_name The name of the form; has to match the name used in check_form_key, otherwise no restrictions apply +*/ +function add_form_key($form_name) +{ + global $config, $template, $user; + $now = time(); + $token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : ''; + $token = sha1($now . $user->data['user_form_salt'] . $form_name . $token_sid); + + $s_fields = build_hidden_fields(array( + 'creation_time' => $now, + 'form_token' => $token, + )); + $template->assign_vars(array( + 'S_FORM_TOKEN' => $s_fields, + )); +} + +/** +* Check the form key. Required for all altering actions not secured by confirm_box +* @param string $form_name The name of the form; has to match the name used in add_form_key, otherwise no restrictions apply +* @param int $timespan The maximum acceptable age for a submitted form in seconds. Defaults to the config setting. +* @param string $return_page The address for the return link +* @param bool $trigger If true, the function will triger an error when encountering an invalid form +* @param int $minimum_time The minimum acceptable age for a submitted form in seconds +*/ +function check_form_key($form_name, $timespan = false, $return_page = '', $trigger = false, $minimum_time = false) +{ + global $config, $user; + + if ($timespan === false) + { + $timespan = $config['form_token_lifetime']; + } + if ($minimum_time === false) + { + $minimum_time = $config['form_token_mintime']; + } + + if (isset($_POST['creation_time']) && isset($_POST['form_token'])) + { + $creation_time = abs(request_var('creation_time', 0)); + $token = request_var('form_token', ''); + + $diff = (time() - $creation_time); + + if (($diff >= $minimum_time) && (($diff <= $timespan) || $timespan == -1)) + { + $token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : ''; + + $key = sha1($creation_time . $user->data['user_form_salt'] . $form_name . $token_sid); + if ($key === $token) + { + return true; + } + } + } + if ($trigger) + { + trigger_error($user->lang['FORM_INVALID'] . $return_page); + } + return false; +} + // Message/Login boxes /** * Build Confirm box * @param boolean $check True for checking if confirmed (without any additional parameters) and false for displaying the confirm box * @param string $title Title/Message used for confirm box. -* message text is _CONFIRM appended to title. +* message text is _CONFIRM appended to title. * If title cannot be found in user->lang a default one is displayed * If title_CONFIRM cannot be found in user->lang the text given is used. * @param string $hidden Hidden variables @@ -2092,8 +2208,28 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa if (isset($_POST['login'])) { + // Get credential + if ($admin) + { + $credential = request_var('credential', ''); + + if (strspn($credential, 'abcdef0123456789') !== strlen($credential) || strlen($credential) != 32) + { + if ($user->data['is_registered']) + { + add_log('admin', 'LOG_ADMIN_AUTH_FAIL'); + } + trigger_error('NO_AUTH_ADMIN'); + } + + $password = request_var('password_' . $credential, '', true); + } + else + { + $password = request_var('password', '', true); + } + $username = request_var('username', '', true); - $password = request_var('password', '', true); $autologin = (!empty($_POST['autologin'])) ? true : false; $viewonline = (!empty($_POST['viewonline'])) ? 0 : 1; $admin = ($admin) ? 1 : 0; @@ -2107,17 +2243,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa trigger_error('NO_AUTH_ADMIN_USER_DIFFER'); } - // do not allow empty password - if (!$password) - { - trigger_error('NO_PASSWORD_SUPPLIED'); - } - // If authentication is successful we redirect user to previous page $result = $auth->login($username, $password, $autologin, $viewonline, $admin); // If admin authentication and login, we will log if it was a success or not... - // We also break the operation on the first non-success login - it could be argued that the user already knows + // We also break the operation on the first non-success login - it could be argued that the user already knows if ($admin) { if ($result['status'] == LOGIN_SUCCESS) @@ -2238,7 +2368,20 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa $redirect .= $user->page['page_name'] . (($user->page['query_string']) ? '?' . htmlspecialchars($user->page['query_string']) : ''); } - $s_hidden_fields = build_hidden_fields(array('redirect' => $redirect, 'sid' => $user->session_id)); + // Assign credential for username/password pair + $credential = ($admin) ? md5(unique_id()) : false; + + $s_hidden_fields = array( + 'redirect' => $redirect, + 'sid' => $user->session_id, + ); + + if ($admin) + { + $s_hidden_fields['credential'] = $credential; + } + + $s_hidden_fields = build_hidden_fields($s_hidden_fields); $template->assign_vars(array( 'LOGIN_ERROR' => $err, @@ -2254,8 +2397,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa 'S_HIDDEN_FIELDS' => $s_hidden_fields, 'S_ADMIN_AUTH' => $admin, - 'USERNAME' => ($admin) ? $user->data['username'] : '') - ); + 'USERNAME' => ($admin) ? $user->data['username'] : '', + + 'USERNAME_CREDENTIAL' => 'username', + 'PASSWORD_CREDENTIAL' => ($admin) ? 'password_' . $credential : 'password', + )); page_header($user->lang['LOGIN']); @@ -2315,7 +2461,7 @@ function login_forum_box($forum_data) } $db->sql_freeresult($result); - if ($password == $forum_data['forum_password']) + if (phpbb_check_hash($password, $forum_data['forum_password'])) { $sql_ary = array( 'forum_id' => (int) $forum_data['forum_id'], @@ -2344,856 +2490,6 @@ function login_forum_box($forum_data) page_footer(); } -// Content related functions - -/** -* Bump Topic Check - used by posting and viewtopic -*/ -function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_poster, $last_topic_poster) -{ - global $config, $auth, $user; - - // Check permission and make sure the last post was not already bumped - if (!$auth->acl_get('f_bump', $forum_id) || $topic_bumped) - { - return false; - } - - // Check bump time range, is the user really allowed to bump the topic at this time? - $bump_time = ($config['bump_type'] == 'm') ? $config['bump_interval'] * 60 : (($config['bump_type'] == 'h') ? $config['bump_interval'] * 3600 : $config['bump_interval'] * 86400); - - // Check bump time - if ($last_post_time + $bump_time > time()) - { - return false; - } - - // Check bumper, only topic poster and last poster are allowed to bump - if ($topic_poster != $user->data['user_id'] && $last_topic_poster != $user->data['user_id']) - { - return false; - } - - // A bump time of 0 will completely disable the bump feature... not intended but might be useful. - return $bump_time; -} - -/** -* Generates a text with approx. the specified length which contains the specified words and their context -* -* @param string $text The full text from which context shall be extracted -* @param string $words An array of words which should be contained in the result, has to be a valid part of a PCRE pattern (escape with preg_quote!) -* @param int $length The desired length of the resulting text, however the result might be shorter or longer than this value -* -* @return string Context of the specified words separated by "..." -*/ -function get_context($text, $words, $length = 400) -{ - // first replace all whitespaces with single spaces - $text = preg_replace('/ +/', ' ', strtr($text, "\t\n\r\x0C ", ' '), $text); - - $word_indizes = array(); - if (sizeof($words)) - { - $match = ''; - // find the starting indizes of all words - foreach ($words as $word) - { - if ($word) - { - if (preg_match('#(?:[^\w]|^)(' . $word . ')(?:[^\w]|$)#i', $text, $match)) - { - $pos = utf8_strpos($text, $match[1]); - if ($pos !== false) - { - $word_indizes[] = $pos; - } - } - } - } - unset($match); - - if (sizeof($word_indizes)) - { - $word_indizes = array_unique($word_indizes); - sort($word_indizes); - - $wordnum = sizeof($word_indizes); - // number of characters on the right and left side of each word - $sequence_length = (int) ($length / (2 * $wordnum)) - 2; - $final_text = ''; - $word = $j = 0; - $final_text_index = -1; - - // cycle through every character in the original text - for ($i = $word_indizes[$word], $n = utf8_strlen($text); $i < $n; $i++) - { - // if the current position is the start of one of the words then append $sequence_length characters to the final text - if (isset($word_indizes[$word]) && ($i == $word_indizes[$word])) - { - if ($final_text_index < $i - $sequence_length - 1) - { - $final_text .= '... ' . preg_replace('#^([^ ]*)#', '', utf8_substr($text, $i - $sequence_length, $sequence_length)); - } - else - { - // if the final text is already nearer to the current word than $sequence_length we only append the text - // from its current index on and distribute the unused length to all other sequenes - $sequence_length += (int) (($final_text_index - $i + $sequence_length + 1) / (2 * $wordnum)); - $final_text .= utf8_substr($text, $final_text_index + 1, $i - $final_text_index - 1); - } - $final_text_index = $i - 1; - - // add the following characters to the final text (see below) - $word++; - $j = 1; - } - - if ($j > 0) - { - // add the character to the final text and increment the sequence counter - $final_text .= utf8_substr($text, $i, 1); - $final_text_index++; - $j++; - - // if this is a whitespace then check whether we are done with this sequence - if (utf8_substr($text, $i, 1) == ' ') - { - // only check whether we have to exit the context generation completely if we haven't already reached the end anyway - if ($i + 4 < $n) - { - if (($j > $sequence_length && $word >= $wordnum) || utf8_strlen($final_text) > $length) - { - $final_text .= ' ...'; - break; - } - } - else - { - // make sure the text really reaches the end - $j -= 4; - } - - // stop context generation and wait for the next word - if ($j > $sequence_length) - { - $j = 0; - } - } - } - } - return $final_text; - } - } - - if (!sizeof($words) || !sizeof($word_indizes)) - { - return (utf8_strlen($text) >= $length + 3) ? utf8_substr($text, 0, $length) . '...' : $text; - } -} - -/** -* Decode text whereby text is coming from the db and expected to be pre-parsed content -* We are placing this outside of the message parser because we are often in need of it... -*/ -function decode_message(&$message, $bbcode_uid = '') -{ - global $config; - - if ($bbcode_uid) - { - $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid"); - $replace = array("\n", '', '', '', ''); - } - else - { - $match = array('<br />'); - $replace = array("\n"); - } - - $message = str_replace($match, $replace, $message); - - $match = get_preg_expression('bbcode_htm'); - $replace = array('\1', '\1', '\2', '\1', '', ''); - - $message = preg_replace($match, $replace, $message); -} - -/** -* Strips all bbcode from a text and returns the plain content -*/ -function strip_bbcode(&$text, $uid = '') -{ - if (!$uid) - { - $uid = '[0-9a-z]{5,}'; - } - - $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:".*"|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text); - - $match = get_preg_expression('bbcode_htm'); - $replace = array('\1', '\1', '\2', '\1', '', ''); - - $text = preg_replace($match, $replace, $text); -} - -/** -* For display of custom parsed text on user-facing pages -* Expects $text to be the value directly from the database (stored value) -*/ -function generate_text_for_display($text, $uid, $bitfield, $flags) -{ - static $bbcode; - - if (!$text) - { - return ''; - } - - $text = censor_text($text); - - // Parse bbcode if bbcode uid stored and bbcode enabled - if ($uid && ($flags & OPTION_FLAG_BBCODE)) - { - if (!class_exists('bbcode')) - { - global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/bbcode.' . $phpEx); - } - - if (empty($bbcode)) - { - $bbcode = new bbcode($bitfield); - } - else - { - $bbcode->bbcode($bitfield); - } - - $bbcode->bbcode_second_pass($text, $uid); - } - - $text = bbcode_nl2br($text); - $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES)); - - return $text; -} - -/** -* For parsing custom parsed text to be stored within the database. -* This function additionally returns the uid and bitfield that needs to be stored. -* Expects $text to be the value directly from request_var() and in it's non-parsed form -*/ -function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false) -{ - global $phpbb_root_path, $phpEx; - - $uid = $bitfield = ''; - - if (!$text) - { - return; - } - - if (!class_exists('parse_message')) - { - include($phpbb_root_path . 'includes/message_parser.' . $phpEx); - } - - $message_parser = new parse_message($text); - $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies); - - $text = $message_parser->message; - $uid = $message_parser->bbcode_uid; - - // If the bbcode_bitfield is empty, there is no need for the uid to be stored. - if (!$message_parser->bbcode_bitfield) - { - $uid = ''; - } - - $flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0); - $bitfield = $message_parser->bbcode_bitfield; - - return; -} - -/** -* For decoding custom parsed text for edits as well as extracting the flags -* Expects $text to be the value directly from the database (pre-parsed content) -*/ -function generate_text_for_edit($text, $uid, $flags) -{ - global $phpbb_root_path, $phpEx; - - decode_message($text, $uid); - - return array( - 'allow_bbcode' => ($flags & OPTION_FLAG_BBCODE) ? 1 : 0, - 'allow_smilies' => ($flags & OPTION_FLAG_SMILIES) ? 1 : 0, - 'allow_urls' => ($flags & OPTION_FLAG_LINKS) ? 1 : 0, - 'text' => $text - ); -} - -/** -* A subroutine of make_clickable used with preg_replace -* It places correct HTML around an url, shortens the displayed text -* and makes sure no entities are inside URLs -*/ -function make_clickable_callback($type, $whitespace, $url, $relative_url, $class) -{ - $append = ''; - $url = htmlspecialchars_decode($url); - $relative_url = htmlspecialchars_decode($relative_url); - - // make sure no HTML entities were matched - $chars = array('<', '>', '"'); - $split = false; - - foreach ($chars as $char) - { - $next_split = strpos($url, $char); - if ($next_split !== false) - { - $split = ($split !== false) ? min($split, $next_split) : $next_split; - } - } - - if ($split !== false) - { - // an HTML entity was found, so the URL has to end before it - $append = substr($url, $split) . $relative_url; - $url = substr($url, 0, $split); - $relative_url = ''; - } - else if ($relative_url) - { - // same for $relative_url - $split = false; - foreach ($chars as $char) - { - $next_split = strpos($relative_url, $char); - if ($next_split !== false) - { - $split = ($split !== false) ? min($split, $next_split) : $next_split; - } - } - - if ($split !== false) - { - $append = substr($relative_url, $split); - $relative_url = substr($relative_url, 0, $split); - } - } - - // if the last character of the url is a punctuation mark, exclude it from the url - $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1]; - - switch ($last_char) - { - case '.': - case '?': - case '!': - case ':': - case ',': - $append = $last_char; - if ($relative_url) - { - $relative_url = substr($relative_url, 0, -1); - } - else - { - $url = substr($url, 0, -1); - } - break; - } - - switch ($type) - { - case MAGIC_URL_LOCAL: - $tag = 'l'; - $relative_url = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url)); - $url = $url . '/' . $relative_url; - $text = ($relative_url) ? $relative_url : $url . '/'; - break; - - case MAGIC_URL_FULL: - $tag = 'm'; - $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; - break; - - case MAGIC_URL_WWW: - $tag = 'w'; - $url = 'http://' . $url; - $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; - break; - - case MAGIC_URL_EMAIL: - $tag = 'e'; - $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; - $url = 'mailto:' . $url; - break; - } - - $url = htmlspecialchars($url); - $text = htmlspecialchars($text); - $append = htmlspecialchars($append); - - $html = "$whitespace<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$append"; - - return $html; -} - -/** -* make_clickable function -* -* Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx. -* Cuts down displayed size of link if over 50 chars, turns absolute links -* into relative versions when the server/script path matches the link -*/ -function make_clickable($text, $server_url = false, $class = 'postlink') -{ - if ($server_url === false) - { - $server_url = generate_board_url(); - } - - static $magic_url_match; - static $magic_url_replace; - static $static_class; - - if (!is_array($magic_url_match) || $static_class != $class) - { - $static_class = $class; - $class = ($static_class) ? ' class="' . $static_class . '"' : ''; - $local_class = ($static_class) ? ' class="' . $static_class . '-local"' : ''; - - $magic_url_match = $magic_url_replace = array(); - // Be sure to not let the matches cross over. ;) - - // relative urls for this board - $magic_url_match[] = '#(^|[\n\t (>])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie'; - $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_LOCAL, '\$1', '\$2', '\$3', '$local_class')"; - - // matches a xxxx://aaaaa.bbb.cccc. ... - $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('url_inline') . ')#ie'; - $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')"; - - // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing - $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#ie'; - $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')"; - - // matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode. - $magic_url_match[] = '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/ie'; - $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_EMAIL, '\$1', '\$2', '', '')"; - } - - return preg_replace($magic_url_match, $magic_url_replace, $text); -} - -/** -* Censoring -*/ -function censor_text($text) -{ - static $censors; - global $cache; - - if (!isset($censors) || !is_array($censors)) - { - // obtain_word_list is taking care of the users censor option and the board-wide option - $censors = $cache->obtain_word_list(); - } - - if (sizeof($censors)) - { - return preg_replace($censors['match'], $censors['replace'], $text); - } - - return $text; -} - -/** -* custom version of nl2br which takes custom BBCodes into account -*/ -function bbcode_nl2br($text) -{ - // custom BBCodes might contain carriage returns so they - // are not converted into <br /> so now revert that - $text = str_replace(array("\n", "\r"), array('<br />', "\n"), $text); - return $text; -} - -/** -* Smiley processing -*/ -function smiley_text($text, $force_option = false) -{ - global $config, $user, $phpbb_root_path; - - if ($force_option || !$config['allow_smilies'] || !$user->optionget('viewsmilies')) - { - return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', '\1', $text); - } - else - { - return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img src="' . $phpbb_root_path . $config['smilies_path'] . '/\2 />', $text); - } -} - -/** -* General attachment parsing -* -* @param mixed $forum_id The forum id the attachments are displayed in (false if in private message) -* @param string &$message The post/private message -* @param array &$attachments The attachments to parse for (inline) display. The attachments array will hold templated data after parsing. -* @param array &$update_count The attachment counts to be updated - will be filled -* @param bool $preview If set to true the attachments are parsed for preview. Within preview mode the comments are fetched from the given $attachments array and not fetched from the database. -*/ -function parse_attachments($forum_id, &$message, &$attachments, &$update_count, $preview = false) -{ - if (!sizeof($attachments)) - { - return; - } - - global $template, $cache, $user; - global $extensions, $config, $phpbb_root_path, $phpEx; - - // - $compiled_attachments = array(); - - if (!isset($template->filename['attachment_tpl'])) - { - $template->set_filenames(array( - 'attachment_tpl' => 'attachment.html') - ); - } - - if (empty($extensions) || !is_array($extensions)) - { - $extensions = $cache->obtain_attach_extensions($forum_id); - } - - // Look for missing attachment information... - $attach_ids = array(); - foreach ($attachments as $pos => $attachment) - { - // If is_orphan is set, we need to retrieve the attachments again... - if (!isset($attachment['extension']) && !isset($attachment['physical_filename'])) - { - $attach_ids[(int) $attachment['attach_id']] = $pos; - } - } - - // Grab attachments (security precaution) - if (sizeof($attach_ids)) - { - global $db; - - $new_attachment_data = array(); - - $sql = 'SELECT * - FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $db->sql_in_set('attach_id', array_keys($attach_ids)); - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - if (!isset($attach_ids[$row['attach_id']])) - { - continue; - } - - // If we preview attachments we will set some retrieved values here - if ($preview) - { - $row['attach_comment'] = $attachments[$attach_ids[$row['attach_id']]]['attach_comment']; - } - - $new_attachment_data[$attach_ids[$row['attach_id']]] = $row; - } - $db->sql_freeresult($result); - - $attachments = $new_attachment_data; - unset($new_attachment_data); - } - - // Sort correctly - if ($config['display_order']) - { - // Ascending sort - krsort($attachments); - } - else - { - // Descending sort - ksort($attachments); - } - - foreach ($attachments as $attachment) - { - if (!sizeof($attachment)) - { - continue; - } - - // We need to reset/empty the _file block var, because this function might be called more than once - $template->destroy_block_vars('_file'); - - $block_array = array(); - - // Some basics... - $attachment['extension'] = strtolower(trim($attachment['extension'])); - $filename = $phpbb_root_path . $config['upload_path'] . '/' . basename($attachment['physical_filename']); - $thumbnail_filename = $phpbb_root_path . $config['upload_path'] . '/thumb_' . basename($attachment['physical_filename']); - - $upload_icon = ''; - - if (isset($extensions[$attachment['extension']])) - { - if ($user->img('icon_topic_attach', '') && !$extensions[$attachment['extension']]['upload_icon']) - { - $upload_icon = $user->img('icon_topic_attach', ''); - } - else if ($extensions[$attachment['extension']]['upload_icon']) - { - $upload_icon = '<img src="' . $phpbb_root_path . $config['upload_icons_path'] . '/' . trim($extensions[$attachment['extension']]['upload_icon']) . '" alt="" />'; - } - } - - $filesize = $attachment['filesize']; - $size_lang = ($filesize >= 1048576) ? $user->lang['MB'] : ( ($filesize >= 1024) ? $user->lang['KB'] : $user->lang['BYTES'] ); - $filesize = ($filesize >= 1048576) ? round((round($filesize / 1048576 * 100) / 100), 2) : (($filesize >= 1024) ? round((round($filesize / 1024 * 100) / 100), 2) : $filesize); - - $comment = bbcode_nl2br(censor_text($attachment['attach_comment'])); - - $block_array += array( - 'UPLOAD_ICON' => $upload_icon, - 'FILESIZE' => $filesize, - 'SIZE_LANG' => $size_lang, - 'DOWNLOAD_NAME' => basename($attachment['real_filename']), - 'COMMENT' => $comment, - ); - - $denied = false; - - if (!extension_allowed($forum_id, $attachment['extension'], $extensions)) - { - $denied = true; - - $block_array += array( - 'S_DENIED' => true, - 'DENIED_MESSAGE' => sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension']) - ); - } - - if (!$denied) - { - $l_downloaded_viewed = $download_link = ''; - $display_cat = $extensions[$attachment['extension']]['display_cat']; - - if ($display_cat == ATTACHMENT_CATEGORY_IMAGE) - { - if ($attachment['thumbnail']) - { - $display_cat = ATTACHMENT_CATEGORY_THUMB; - } - else - { - if ($config['img_display_inlined']) - { - if ($config['img_link_width'] || $config['img_link_height']) - { - $dimension = @getimagesize($filename); - - // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes - if ($dimension === false || empty($dimension[0]) || empty($dimension[1])) - { - $display_cat = ATTACHMENT_CATEGORY_NONE; - } - else - { - $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE; - } - } - } - else - { - $display_cat = ATTACHMENT_CATEGORY_NONE; - } - } - } - - // Make some descisions based on user options being set. - if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg')) - { - $display_cat = ATTACHMENT_CATEGORY_NONE; - } - - if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash')) - { - $display_cat = ATTACHMENT_CATEGORY_NONE; - } - - $download_link = append_sid("{$phpbb_root_path}download.$phpEx", 'id=' . $attachment['attach_id']); - - switch ($display_cat) - { - // Images - case ATTACHMENT_CATEGORY_IMAGE: - $l_downloaded_viewed = 'VIEWED_COUNT'; - $inline_link = append_sid("{$phpbb_root_path}download.$phpEx", 'id=' . $attachment['attach_id']); - $download_link .= '&mode=view'; - - $block_array += array( - 'S_IMAGE' => true, - 'U_INLINE_LINK' => $inline_link, - ); - - $update_count[] = $attachment['attach_id']; - break; - - // Images, but display Thumbnail - case ATTACHMENT_CATEGORY_THUMB: - $l_downloaded_viewed = 'VIEWED_COUNT'; - $thumbnail_link = append_sid("{$phpbb_root_path}download.$phpEx", 'id=' . $attachment['attach_id'] . '&t=1'); - $download_link .= '&mode=view'; - - $block_array += array( - 'S_THUMBNAIL' => true, - 'THUMB_IMAGE' => $thumbnail_link, - ); - break; - - // Windows Media Streams - case ATTACHMENT_CATEGORY_WM: - $l_downloaded_viewed = 'VIEWED_COUNT'; - - // Giving the filename directly because within the wm object all variables are in local context making it impossible - // to validate against a valid session (all params can differ) - // $download_link = $filename; - - $block_array += array( - 'U_FORUM' => generate_board_url(), - 'ATTACH_ID' => $attachment['attach_id'], - 'S_WM_FILE' => true, - ); - - // Viewed/Heared File ... update the download count - $update_count[] = $attachment['attach_id']; - break; - - // Real Media Streams - case ATTACHMENT_CATEGORY_RM: - case ATTACHMENT_CATEGORY_QUICKTIME: - $l_downloaded_viewed = 'VIEWED_COUNT'; - - $block_array += array( - 'S_RM_FILE' => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false, - 'S_QUICKTIME_FILE' => ($display_cat == ATTACHMENT_CATEGORY_QUICKTIME) ? true : false, - 'U_FORUM' => generate_board_url(), - 'ATTACH_ID' => $attachment['attach_id'], - ); - - // Viewed/Heared File ... update the download count - $update_count[] = $attachment['attach_id']; - break; - - // Macromedia Flash Files - case ATTACHMENT_CATEGORY_FLASH: - list($width, $height) = @getimagesize($filename); - - $l_downloaded_viewed = 'VIEWED_COUNT'; - - $block_array += array( - 'S_FLASH_FILE' => true, - 'WIDTH' => $width, - 'HEIGHT' => $height, - ); - - // Viewed/Heared File ... update the download count - $update_count[] = $attachment['attach_id']; - break; - - default: - $l_downloaded_viewed = 'DOWNLOAD_COUNT'; - - $block_array += array( - 'S_FILE' => true, - ); - break; - } - - $l_download_count = (!isset($attachment['download_count']) || $attachment['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (($attachment['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $attachment['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $attachment['download_count'])); - - $block_array += array( - 'U_DOWNLOAD_LINK' => $download_link, - 'L_DOWNLOAD_COUNT' => $l_download_count - ); - } - - $template->assign_block_vars('_file', $block_array); - - $compiled_attachments[] = $template->assign_display('attachment_tpl'); - } - - $attachments = $compiled_attachments; - unset($compiled_attachments); - - $tpl_size = sizeof($attachments); - - $unset_tpl = array(); - - preg_match_all('#<!\-\- ia([0-9]+) \-\->(.*?)<!\-\- ia\1 \-\->#', $message, $matches, PREG_PATTERN_ORDER); - - $replace = array(); - foreach ($matches[0] as $num => $capture) - { - // Flip index if we are displaying the reverse way - $index = ($config['display_order']) ? ($tpl_size-($matches[1][$num] + 1)) : $matches[1][$num]; - - $replace['from'][] = $matches[0][$num]; - $replace['to'][] = (isset($attachments[$index])) ? $attachments[$index] : sprintf($user->lang['MISSING_INLINE_ATTACHMENT'], $matches[2][array_search($index, $matches[1])]); - - $unset_tpl[] = $index; - } - - if (isset($replace['from'])) - { - $message = str_replace($replace['from'], $replace['to'], $message); - } - - $unset_tpl = array_unique($unset_tpl); - - // Needed to let not display the inlined attachments at the end of the post again - foreach ($unset_tpl as $index) - { - unset($attachments[$index]); - } -} - -/** -* Check if extension is allowed to be posted. -* -* @param mixed $forum_id The forum id to check or false if private message -* @param string $extension The extension to check, for example zip. -* @param array &$extensions The extension array holding the information from the cache (will be obtained if empty) -* -* @return bool False if the extension is not allowed to be posted, else true. -*/ -function extension_allowed($forum_id, $extension, &$extensions) -{ - if (empty($extensions)) - { - global $cache; - $extensions = $cache->obtain_attach_extensions($forum_id); - } - - return (!isset($extensions['_allowed_'][$extension])) ? false : true; -} - // Little helpers /** @@ -3418,7 +2714,7 @@ function get_backtrace() /** * This function returns a regular expression pattern for commonly used expressions * Use with / as delimiter for email mode and # for url modes -* mode can be: email|bbcode_htm|url|url_inline|www_url|www_url_inline|relative_url|relative_url_inline +* mode can be: email|bbcode_htm|url|url_inline|www_url|www_url_inline|relative_url|relative_url_inline|ipv4|ipv6 */ function get_preg_expression($mode) { @@ -3439,6 +2735,17 @@ function get_preg_expression($mode) ); break; + // Whoa these look impressive! + // The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses + // can be found in the develop directory + case 'ipv4': + return '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#'; + break; + + case 'ipv6': + return '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){5}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:))$#i'; + break; + case 'url': case 'url_inline': $inline = ($mode == 'url') ? ')' : ''; @@ -3494,140 +2801,12 @@ function short_ipv6($ip, $length) } /** -* Truncates string while retaining special characters if going over the max length -* The default max length is 60 at the moment -*/ -function truncate_string($string, $max_length = 60, $allow_reply = true, $append = '') -{ - $chars = array(); - - $strip_reply = false; - $stripped = false; - if ($allow_reply && strpos($string, 'Re: ') === 0) - { - $strip_reply = true; - $string = substr($string, 4); - } - - $_chars = utf8_str_split(htmlspecialchars_decode($string)); - $chars = array_map('utf8_htmlspecialchars', $_chars); - - // Now check the length ;) - if (sizeof($chars) > $max_length) - { - // Cut off the last elements from the array - $string = implode('', array_slice($chars, 0, $max_length)); - $stripped = true; - } - - if ($strip_reply) - { - $string = 'Re: ' . $string; - } - - if ($append != '' && $stripped) - { - $string = $string . $append; - } - - return $string; -} - -/** -* Get username details for placing into templates. -* -* @param string $mode Can be profile (for getting an url to the profile), username (for obtaining the username), colour (for obtaining the user colour) or full (for obtaining a html string representing a coloured link to the users profile). -* @param int $user_id The users id -* @param string $username The users name -* @param string $username_colour The users colour -* @param string $guest_username optional parameter to specify the guest username. It will be used in favor of the GUEST language variable then. -* @param string $custom_profile_url optional parameter to specify a profile url. The user id get appended to this url as &u={user_id} -* -* @return string A string consisting of what is wanted based on $mode. -*/ -function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false) -{ - global $phpbb_root_path, $phpEx, $user, $auth; - - $profile_url = ''; - $username_colour = ($username_colour) ? '#' . $username_colour : ''; - - if ($guest_username === false) - { - $username = ($username) ? $username : $user->lang['GUEST']; - } - else - { - $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']); - } - - // Only show the link if not anonymous - if ($user_id && $user_id != ANONYMOUS) - { - // Do not show the link if the user is already logged in but do not have u_viewprofile permissions (relevant for bots mostly). - // For all others the link leads to a login page or the profile. - if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) - { - $profile_url = ''; - } - else - { - $profile_url = ($custom_profile_url !== false) ? $custom_profile_url : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile'); - $profile_url .= '&u=' . (int) $user_id; - } - } - else - { - $profile_url = ''; - } - - switch ($mode) - { - case 'profile': - return $profile_url; - break; - - case 'username': - return $username; - break; - - case 'colour': - return $username_colour; - break; - - case 'full': - default: - - $tpl = ''; - if (!$profile_url && !$username_colour) - { - $tpl = '{USERNAME}'; - } - else if (!$profile_url && $username_colour) - { - $tpl = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; - } - else if ($profile_url && !$username_colour) - { - $tpl = '<a href="{PROFILE_URL}">{USERNAME}</a>'; - } - else if ($profile_url && $username_colour) - { - $tpl = '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>'; - } - - return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), $tpl); - break; - } -} - -/** * Wrapper for php's checkdnsrr function. * * The windows failover is from the php manual * Please make sure to check the return value for === true and === false, since NULL could * be returned too. -* +* * @return true if entry found, false if not, NULL if this function is not supported by this environment */ function phpbb_checkdnsrr($host, $type = '') @@ -3794,7 +2973,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) echo '</body>'; echo '</html>'; - exit; + exit_handler(); break; case E_USER_WARNING: @@ -3853,7 +3032,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) page_footer(); } - exit; + exit_handler(); break; } @@ -3925,7 +3104,7 @@ function page_header($page_title = '', $display_online_list = true) SELECT DISTINCT s.session_ip FROM ' . SESSIONS_TABLE . ' s WHERE s.session_user_id = ' . ANONYMOUS . ' - AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . + AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . $reading_sql . ')'; } @@ -3934,7 +3113,7 @@ function page_header($page_title = '', $display_online_list = true) $sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests FROM ' . SESSIONS_TABLE . ' s WHERE s.session_user_id = ' . ANONYMOUS . ' - AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . + AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . $reading_sql; } $result = $db->sql_query($sql); @@ -3944,10 +3123,10 @@ function page_header($page_title = '', $display_online_list = true) $sql = 'SELECT u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour, s.session_ip, s.session_viewonline FROM ' . USERS_TABLE . ' u, ' . SESSIONS_TABLE . ' s - WHERE s.session_time >= ' . (time() - (intval($config['load_online_time']) * 60)) . + WHERE s.session_time >= ' . (time() - (intval($config['load_online_time']) * 60)) . $reading_sql . ((!$config['load_online_guests']) ? ' AND s.session_user_id <> ' . ANONYMOUS : '') . ' - AND u.user_id = s.session_user_id + AND u.user_id = s.session_user_id ORDER BY u.username_clean ASC, s.session_ip ASC'; $result = $db->sql_query($sql); @@ -3959,38 +3138,19 @@ function page_header($page_title = '', $display_online_list = true) // Skip multiple sessions for one user if ($row['user_id'] != $prev_user_id) { - if ($row['user_colour']) - { - $user_colour = ' style="color:#' . $row['user_colour'] . '"'; - $row['username'] = '<strong>' . $row['username'] . '</strong>'; - } - else - { - $user_colour = ''; - } - if ($row['session_viewonline']) { - $user_online_link = $row['username']; $logged_visible_online++; } else { - $user_online_link = '<em>' . $row['username'] . '</em>'; + $row['username'] = '<em>' . $row['username'] . '</em>'; $logged_hidden_online++; } if (($row['session_viewonline']) || $auth->acl_get('u_viewonline')) { - if ($row['user_type'] <> USER_IGNORE) - { - $user_online_link = '<a href="' . append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['user_id']) . '"' . $user_colour . '>' . $user_online_link . '</a>'; - } - else - { - $user_online_link = ($user_colour) ? '<span' . $user_colour . '>' . $user_online_link . '</span>' : $user_online_link; - } - + $user_online_link = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']); $online_userlist .= ($online_userlist != '') ? ', ' . $user_online_link : $user_online_link; } } @@ -4147,9 +3307,8 @@ function page_header($page_title = '', $display_online_list = true) 'U_PRIVATEMSGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), 'U_RETURN_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), - 'UA_RETURN_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox', false), 'U_POPUP_PM' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup'), - 'UA_POPUP_PM' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup', false), + 'UA_POPUP_PM' => addslashes(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup')), 'U_MEMBERLIST' => append_sid("{$phpbb_root_path}memberlist.$phpEx"), 'U_MEMBERSLIST' => append_sid("{$phpbb_root_path}memberlist.$phpEx"), 'U_VIEWONLINE' => ($auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) ? append_sid("{$phpbb_root_path}viewonline.$phpEx") : '', @@ -4303,11 +3462,7 @@ function page_footer($run_cron = true) $template->display('body'); garbage_collection(); - - if (!defined('PHPBB_EMBEDDED')) - { - exit; - } + exit_handler(); } /** @@ -4332,97 +3487,43 @@ function garbage_collection() } /** -* @package phpBB3 +* Handler for exit calls in phpBB. +* This function supports hooks. +* +* Note: This function is called after the template has been outputted. */ -class bitfield +function exit_handler() { - var $data; - - function bitfield($bitfield = '') - { - $this->data = base64_decode($bitfield); - } - - /** - */ - function get($n) - { - // Get the ($n / 8)th char - $byte = $n >> 3; - - if (strlen($this->data) >= $byte + 1) - { - $c = $this->data[$byte]; - - // Lookup the ($n % 8)th bit of the byte - $bit = 7 - ($n & 7); - return (bool) (ord($c) & (1 << $bit)); - } - else - { - return false; - } - } + global $phpbb_hook; - function set($n) + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__)) { - $byte = $n >> 3; - $bit = 7 - ($n & 7); - - if (strlen($this->data) >= $byte + 1) - { - $this->data[$byte] = $this->data[$byte] | chr(1 << $bit); - } - else + if ($phpbb_hook->hook_return(__FUNCTION__)) { - $this->data .= str_repeat("\0", $byte - strlen($this->data)); - $this->data .= chr(1 << $bit); + return $phpbb_hook->hook_return_result(__FUNCTION__); } } - function clear($n) - { - $byte = $n >> 3; - - if (strlen($this->data) >= $byte + 1) - { - $bit = 7 - ($n & 7); - $this->data[$byte] = $this->data[$byte] &~ chr(1 << $bit); - } - } - - function get_blob() - { - return $this->data; - } + exit; +} - function get_base64() - { - return base64_encode($this->data); - } +/** +* Handler for init calls in phpBB. This function is called in user::setup(); +* This function supports hooks. +*/ +function phpbb_user_session_handler() +{ + global $phpbb_hook; - function get_bin() + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__)) { - $bin = ''; - $len = strlen($this->data); - - for ($i = 0; $i < $len; ++$i) + if ($phpbb_hook->hook_return(__FUNCTION__)) { - $bin .= str_pad(decbin(ord($this->data[$i])), 8, '0', STR_PAD_LEFT); + return $phpbb_hook->hook_return_result(__FUNCTION__); } - - return $bin; } - function get_all_set() - { - return array_keys(array_filter(str_split($this->get_bin()))); - } - - function merge($bitfield) - { - $this->data = $this->data | $bitfield->get_blob(); - } + return; } ?>
\ No newline at end of file diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 4dfd58e28c..05872a907a 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Recalculate Binary Tree function recalc_btree($sql_id, $sql_table, $module_class = '') { @@ -33,13 +41,13 @@ function recalc_btree($sql_id, $sql_table, $module_class = '') if ($substract > 0) { - $sql = "UPDATE $sql_table + $sql = "UPDATE $sql_table SET left_id = left_id - $substract, right_id = right_id - $substract $sql_where"; $db->sql_query($sql); } - $sql = "SELECT $sql_id, parent_id, left_id, right_id + $sql = "SELECT $sql_id, parent_id, left_id, right_id FROM $sql_table $sql_where ORDER BY left_id ASC, parent_id ASC, $sql_id ASC"; @@ -219,7 +227,7 @@ function group_select_options($group_id, $exclude_ids = false, $manage_founder = $sql_and = (!$config['coppa_enable']) ? (($exclude_sql) ? ' AND ' : ' WHERE ') . "group_name <> 'REGISTERED_COPPA'" : ''; $sql_founder = ($manage_founder !== false) ? (($exclude_sql || $sql_and) ? ' AND ' : ' WHERE ') . 'group_founder_manage = ' . (int) $manage_founder : ''; - $sql = 'SELECT group_id, group_name, group_type + $sql = 'SELECT group_id, group_name, group_type FROM ' . GROUPS_TABLE . " $exclude_sql $sql_and @@ -476,8 +484,8 @@ function move_posts($post_ids, $topic_id, $auto_sync = true) } $db->sql_freeresult($result); - $sql = 'SELECT forum_id - FROM ' . TOPICS_TABLE . ' + $sql = 'SELECT forum_id + FROM ' . TOPICS_TABLE . ' WHERE topic_id = ' . $topic_id; $result = $db->sql_query($sql); $forum_row = $db->sql_fetchrow($result); @@ -573,7 +581,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s foreach ($table_ary as $table) { - $sql = "DELETE FROM $table + $sql = "DELETE FROM $table WHERE " . $db->sql_in_set('topic_id', $topic_ids); $db->sql_query($sql); } @@ -596,7 +604,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s if (sizeof($moved_topic_ids)) { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $moved_topic_ids); $db->sql_query($sql); } @@ -685,7 +693,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = foreach ($table_ary as $table) { - $sql = "DELETE FROM $table + $sql = "DELETE FROM $table WHERE " . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } @@ -698,12 +706,12 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0 - WHERE user_id = ' . $poster_id . ' + WHERE user_id = ' . $poster_id . ' AND user_posts < ' . $substract; $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - ' . $substract . ' - WHERE user_id = ' . $poster_id . ' + WHERE user_id = ' . $poster_id . ' AND user_posts >= ' . $substract; $db->sql_query($sql); } @@ -790,7 +798,7 @@ function delete_attachments($mode, $ids, $resync = true) { global $db, $config; - if (is_array($ids)) + if (is_array($ids) && sizeof($ids)) { $ids = array_unique($ids); $ids = array_map('intval', $ids); @@ -890,7 +898,7 @@ function delete_attachments($mode, $ids, $resync = true) { if ($mode == 'post' || $mode == 'topic') { - $sql = 'UPDATE ' . POSTS_TABLE . ' + $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); @@ -901,7 +909,7 @@ function delete_attachments($mode, $ids, $resync = true) $remaining = array(); $sql = 'SELECT post_msg_id - FROM ' . ATTACHMENTS_TABLE . ' + FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . ' AND in_message = 0'; $result = $db->sql_query($sql); @@ -916,7 +924,7 @@ function delete_attachments($mode, $ids, $resync = true) if (sizeof($unset_ids)) { - $sql = 'UPDATE ' . POSTS_TABLE . ' + $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $unset_ids); $db->sql_query($sql); @@ -925,7 +933,7 @@ function delete_attachments($mode, $ids, $resync = true) $remaining = array(); $sql = 'SELECT post_msg_id - FROM ' . ATTACHMENTS_TABLE . ' + FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . ' AND in_message = 1'; $result = $db->sql_query($sql); @@ -940,7 +948,7 @@ function delete_attachments($mode, $ids, $resync = true) if (sizeof($unset_ids)) { - $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_attachment = 0 WHERE ' . $db->sql_in_set('msg_id', $unset_ids); $db->sql_query($sql); @@ -964,7 +972,7 @@ function delete_attachments($mode, $ids, $resync = true) $remaining = array(); $sql = 'SELECT topic_id - FROM ' . ATTACHMENTS_TABLE . ' + FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $result = $db->sql_query($sql); @@ -978,7 +986,7 @@ function delete_attachments($mode, $ids, $resync = true) if (sizeof($unset_ids)) { - $sql = 'UPDATE ' . TOPICS_TABLE . ' + $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 WHERE ' . $db->sql_in_set('topic_id', $unset_ids); $db->sql_query($sql); @@ -1864,7 +1872,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $topic_id = (int) $row['topic_id']; - // Ok, there should be a shadow topic. If there isn't, then there's something wrong with the db. + // Ok, there should be a shadow topic. If there isn't, then there's something wrong with the db. // However, there's not much we can do about it. if (!empty($shadow_topic_data[$topic_id])) { @@ -2047,7 +2055,7 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id) . " - AND poll_start = 0 + AND poll_start = 0 $sql_and"; $result = $db->sql_query($sql); @@ -2063,8 +2071,8 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id) . " - AND poll_start > 0 - AND poll_last_vote < $prune_date + AND poll_start > 0 + AND poll_last_vote < $prune_date $sql_and"; $result = $db->sql_query($sql); @@ -2423,7 +2431,7 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id if (isset($user->lang[$row['log_operation']])) { - // We supress the warning about inappropiate number of passed parameters here due to possible changes within LOG strings from one version to another. + // We supress the warning about inappropriate number of passed parameters here due to possible changes within LOG strings from one version to another. $log[$i]['action'] = @vsprintf($log[$i]['action'], $log_data_ary); // If within the admin panel we do not censor text out @@ -2455,7 +2463,7 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id { $topic_id_list = array_unique($topic_id_list); - // This query is not really needed if move_topics() updates the forum_id field, + // This query is not really needed if move_topics() updates the forum_id field, // although it's also used to determine if the topic still exists in the database $sql = 'SELECT topic_id, forum_id FROM ' . TOPICS_TABLE . ' @@ -2555,7 +2563,7 @@ function update_foes($group_id = false, $user_id = false) // update foes for some user if (is_array($user_id) && sizeof($user_id)) { - $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' + $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' WHERE ' . $db->sql_in_set('zebra_id', $user_id) . ' AND foe = 1'; $db->sql_query($sql); @@ -2565,7 +2573,7 @@ function update_foes($group_id = false, $user_id = false) // update foes for some group if (is_array($group_id) && sizeof($group_id)) { - // Grab group settings... + // Grab group settings... $sql = $db->sql_build_query('SELECT', array( 'SELECT' => 'a.group_id', @@ -2628,7 +2636,7 @@ function update_foes($group_id = false, $user_id = false) if (sizeof($users)) { - $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' + $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' WHERE ' . $db->sql_in_set('zebra_id', $users) . ' AND foe = 1'; $db->sql_query($sql); @@ -2651,7 +2659,7 @@ function update_foes($group_id = false, $user_id = false) if (sizeof($perms)) { - $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' + $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' WHERE ' . $db->sql_in_set('zebra_id', array_unique($perms)) . ' AND foe = 1'; $db->sql_query($sql); @@ -2667,9 +2675,9 @@ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $li global $db, $user; $sql = 'SELECT user_id, username, user_regdate, user_lastvisit, user_inactive_time, user_inactive_reason - FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_INACTIVE . - (($limit_days) ? " AND user_inactive_time >= $limit_days" : '') . " + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_INACTIVE . + (($limit_days) ? " AND user_inactive_time >= $limit_days" : '') . " ORDER BY $sort_by"; $result = $db->sql_query_limit($sql, $limit, $offset); @@ -2700,7 +2708,7 @@ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $li $sql = 'SELECT COUNT(user_id) AS user_count FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_INACTIVE . + WHERE user_type = ' . USER_INACTIVE . (($limit_days) ? " AND user_inactive_time >= $limit_days" : ''); $result = $db->sql_query($sql); $user_count = (int) $db->sql_fetchfield('user_count'); diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index ade844b262..36b7d575d9 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @version $Id$ +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Class for handling archives (compression/decompression) * @package phpBB3 */ @@ -121,7 +129,7 @@ class compress } /** -* Zip creation class from phpMyAdmin 2.3.0 (c) Tobias Ratschiller, Olivier Müller, Loïc Chapeaux, +* Zip creation class from phpMyAdmin 2.3.0 (c) Tobias Ratschiller, Olivier Müller, Loïc Chapeaux, * Marc Delisle, http://www.phpmyadmin.net/ * * Zip extraction function by Alexandre Tedeschi, alexandrebr at gmail dot com @@ -452,7 +460,7 @@ class compress_zip extends compress * * @package phpBB3 */ -class compress_tar extends compress +class compress_tar extends compress { var $isgz = false; var $isbz = false; @@ -545,7 +553,7 @@ class compress_tar extends compress { $fzclose = ($this->isbz && function_exists('bzclose')) ? 'bzclose' : (($this->isgz && @extension_loaded('zlib')) ? 'gzclose' : 'fclose'); - if ($this->wrote) + if ($this->wrote) { $fzwrite = ($this->isbz && function_exists('bzwrite')) ? 'bzwrite' : (($this->isgz && @extension_loaded('zlib')) ? 'gzwrite' : 'fwrite'); diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php new file mode 100644 index 0000000000..cbd38cd478 --- /dev/null +++ b/phpBB/includes/functions_content.php @@ -0,0 +1,1268 @@ +<?php +/** +* +* @package phpBB3 +* @version $Id$ +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* gen_sort_selects() +* make_jumpbox() +* bump_topic_allowed() +* get_context() +* decode_message() +* strip_bbcode() +* generate_text_for_display() +* generate_text_for_storage() +* generate_text_for_edit() +* make_clickable_callback() +* make_clickable() +* censor_text() +* bbcode_nl2br() +* smiley_text() +* parse_attachments() +* extension_allowed() +* truncate_string() +* get_username_string() +* class bitfield +*/ + +/** +* Generate sort selection fields +*/ +function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key, &$sort_dir, &$s_limit_days, &$s_sort_key, &$s_sort_dir, &$u_sort_param) +{ + global $user; + + $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']); + + // Check if the key is selectable. If not, we reset to the first key found. + // This ensures the values are always valid. + if (!isset($limit_days[$sort_days])) + { + @reset($limit_days); + $sort_days = key($limit_days); + } + + if (!isset($sort_by_text[$sort_key])) + { + @reset($sort_by_text); + $sort_key = key($sort_by_text); + } + + if (!isset($sort_dir_text[$sort_dir])) + { + @reset($sort_dir_text); + $sort_dir = key($sort_dir_text); + } + + $s_limit_days = '<select name="st">'; + foreach ($limit_days as $day => $text) + { + $selected = ($sort_days == $day) ? ' selected="selected"' : ''; + $s_limit_days .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>'; + } + $s_limit_days .= '</select>'; + + $s_sort_key = '<select name="sk">'; + foreach ($sort_by_text as $key => $text) + { + $selected = ($sort_key == $key) ? ' selected="selected"' : ''; + $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>'; + } + $s_sort_key .= '</select>'; + + $s_sort_dir = '<select name="sd">'; + foreach ($sort_dir_text as $key => $value) + { + $selected = ($sort_dir == $key) ? ' selected="selected"' : ''; + $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; + } + $s_sort_dir .= '</select>'; + + $u_sort_param = "st=$sort_days&sk=$sort_key&sd=$sort_dir"; + + return; +} + +/** +* Generate Jumpbox +*/ +function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list = false, $force_display = false) +{ + global $config, $auth, $template, $user, $db; + + // We only return if the jumpbox is not forced to be displayed (in case it is needed for functionality) + if (!$config['load_jumpbox'] && $force_display === false) + { + return; + } + + $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id + FROM ' . FORUMS_TABLE . ' + ORDER BY left_id ASC'; + $result = $db->sql_query($sql, 600); + + $right = $padding = 0; + $padding_store = array('0' => 0); + $display_jumpbox = false; + $iteration = 0; + + // Sometimes it could happen that forums will be displayed here not be displayed within the index page + // This is the result of forums not displayed at index, having list permissions and a parent of a forum with no permissions. + // If this happens, the padding could be "broken" + + while ($row = $db->sql_fetchrow($result)) + { + if ($row['left_id'] < $right) + { + $padding++; + $padding_store[$row['parent_id']] = $padding; + } + else if ($row['left_id'] > $right + 1) + { + // Ok, if the $padding_store for this parent is empty there is something wrong. For now we will skip over it. + // @todo digging deep to find out "how" this can happen. + $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding; + } + + $right = $row['right_id']; + + if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id'])) + { + // Non-postable forum with no subforums, don't display + continue; + } + + if (!$auth->acl_get('f_list', $row['forum_id'])) + { + // if the user does not have permissions to list this forum skip + continue; + } + + if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id'])) + { + continue; + } + + if (!$display_jumpbox) + { + $template->assign_block_vars('jumpbox_forums', array( + 'FORUM_ID' => ($select_all) ? 0 : -1, + 'FORUM_NAME' => ($select_all) ? $user->lang['ALL_FORUMS'] : $user->lang['SELECT_FORUM'], + 'S_FORUM_COUNT' => $iteration) + ); + + $iteration++; + $display_jumpbox = true; + } + + $template->assign_block_vars('jumpbox_forums', array( + 'FORUM_ID' => $row['forum_id'], + 'FORUM_NAME' => $row['forum_name'], + 'SELECTED' => ($row['forum_id'] == $forum_id) ? ' selected="selected"' : '', + 'S_FORUM_COUNT' => $iteration, + 'S_IS_CAT' => ($row['forum_type'] == FORUM_CAT) ? true : false, + 'S_IS_LINK' => ($row['forum_type'] == FORUM_LINK) ? true : false, + 'S_IS_POST' => ($row['forum_type'] == FORUM_POST) ? true : false) + ); + + for ($i = 0; $i < $padding; $i++) + { + $template->assign_block_vars('jumpbox_forums.level', array()); + } + $iteration++; + } + $db->sql_freeresult($result); + unset($padding_store); + + $template->assign_vars(array( + 'S_DISPLAY_JUMPBOX' => $display_jumpbox, + 'S_JUMPBOX_ACTION' => $action) + ); + + return; +} + +/** +* Bump Topic Check - used by posting and viewtopic +*/ +function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_poster, $last_topic_poster) +{ + global $config, $auth, $user; + + // Check permission and make sure the last post was not already bumped + if (!$auth->acl_get('f_bump', $forum_id) || $topic_bumped) + { + return false; + } + + // Check bump time range, is the user really allowed to bump the topic at this time? + $bump_time = ($config['bump_type'] == 'm') ? $config['bump_interval'] * 60 : (($config['bump_type'] == 'h') ? $config['bump_interval'] * 3600 : $config['bump_interval'] * 86400); + + // Check bump time + if ($last_post_time + $bump_time > time()) + { + return false; + } + + // Check bumper, only topic poster and last poster are allowed to bump + if ($topic_poster != $user->data['user_id'] && $last_topic_poster != $user->data['user_id']) + { + return false; + } + + // A bump time of 0 will completely disable the bump feature... not intended but might be useful. + return $bump_time; +} + +/** +* Generates a text with approx. the specified length which contains the specified words and their context +* +* @param string $text The full text from which context shall be extracted +* @param string $words An array of words which should be contained in the result, has to be a valid part of a PCRE pattern (escape with preg_quote!) +* @param int $length The desired length of the resulting text, however the result might be shorter or longer than this value +* +* @return string Context of the specified words separated by "..." +*/ +function get_context($text, $words, $length = 400) +{ + // first replace all whitespaces with single spaces + $text = preg_replace('/ +/', ' ', strtr($text, "\t\n\r\x0C ", ' '), $text); + + $word_indizes = array(); + if (sizeof($words)) + { + $match = ''; + // find the starting indizes of all words + foreach ($words as $word) + { + if ($word) + { + if (preg_match('#(?:[^\w]|^)(' . $word . ')(?:[^\w]|$)#i', $text, $match)) + { + $pos = utf8_strpos($text, $match[1]); + if ($pos !== false) + { + $word_indizes[] = $pos; + } + } + } + } + unset($match); + + if (sizeof($word_indizes)) + { + $word_indizes = array_unique($word_indizes); + sort($word_indizes); + + $wordnum = sizeof($word_indizes); + // number of characters on the right and left side of each word + $sequence_length = (int) ($length / (2 * $wordnum)) - 2; + $final_text = ''; + $word = $j = 0; + $final_text_index = -1; + + // cycle through every character in the original text + for ($i = $word_indizes[$word], $n = utf8_strlen($text); $i < $n; $i++) + { + // if the current position is the start of one of the words then append $sequence_length characters to the final text + if (isset($word_indizes[$word]) && ($i == $word_indizes[$word])) + { + if ($final_text_index < $i - $sequence_length - 1) + { + $final_text .= '... ' . preg_replace('#^([^ ]*)#', '', utf8_substr($text, $i - $sequence_length, $sequence_length)); + } + else + { + // if the final text is already nearer to the current word than $sequence_length we only append the text + // from its current index on and distribute the unused length to all other sequenes + $sequence_length += (int) (($final_text_index - $i + $sequence_length + 1) / (2 * $wordnum)); + $final_text .= utf8_substr($text, $final_text_index + 1, $i - $final_text_index - 1); + } + $final_text_index = $i - 1; + + // add the following characters to the final text (see below) + $word++; + $j = 1; + } + + if ($j > 0) + { + // add the character to the final text and increment the sequence counter + $final_text .= utf8_substr($text, $i, 1); + $final_text_index++; + $j++; + + // if this is a whitespace then check whether we are done with this sequence + if (utf8_substr($text, $i, 1) == ' ') + { + // only check whether we have to exit the context generation completely if we haven't already reached the end anyway + if ($i + 4 < $n) + { + if (($j > $sequence_length && $word >= $wordnum) || utf8_strlen($final_text) > $length) + { + $final_text .= ' ...'; + break; + } + } + else + { + // make sure the text really reaches the end + $j -= 4; + } + + // stop context generation and wait for the next word + if ($j > $sequence_length) + { + $j = 0; + } + } + } + } + return $final_text; + } + } + + if (!sizeof($words) || !sizeof($word_indizes)) + { + return (utf8_strlen($text) >= $length + 3) ? utf8_substr($text, 0, $length) . '...' : $text; + } +} + +/** +* Decode text whereby text is coming from the db and expected to be pre-parsed content +* We are placing this outside of the message parser because we are often in need of it... +*/ +function decode_message(&$message, $bbcode_uid = '') +{ + global $config; + + if ($bbcode_uid) + { + $match = array('<br />', "[/*:m:$bbcode_uid]", ":u:$bbcode_uid", ":o:$bbcode_uid", ":$bbcode_uid"); + $replace = array("\n", '', '', '', ''); + } + else + { + $match = array('<br />'); + $replace = array("\n"); + } + + $message = str_replace($match, $replace, $message); + + $match = get_preg_expression('bbcode_htm'); + $replace = array('\1', '\1', '\2', '\1', '', ''); + + $message = preg_replace($match, $replace, $message); +} + +/** +* Strips all bbcode from a text and returns the plain content +*/ +function strip_bbcode(&$text, $uid = '') +{ + if (!$uid) + { + $uid = '[0-9a-z]{5,}'; + } + + $text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:".*"|[^\]]*))?(?::[a-z])?(\:$uid)\]#", ' ', $text); + + $match = get_preg_expression('bbcode_htm'); + $replace = array('\1', '\1', '\2', '\1', '', ''); + + $text = preg_replace($match, $replace, $text); +} + +/** +* For display of custom parsed text on user-facing pages +* Expects $text to be the value directly from the database (stored value) +*/ +function generate_text_for_display($text, $uid, $bitfield, $flags) +{ + static $bbcode; + + if (!$text) + { + return ''; + } + + $text = censor_text($text); + + // Parse bbcode if bbcode uid stored and bbcode enabled + if ($uid && ($flags & OPTION_FLAG_BBCODE)) + { + if (!class_exists('bbcode')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/bbcode.' . $phpEx); + } + + if (empty($bbcode)) + { + $bbcode = new bbcode($bitfield); + } + else + { + $bbcode->bbcode($bitfield); + } + + $bbcode->bbcode_second_pass($text, $uid); + } + + $text = bbcode_nl2br($text); + $text = smiley_text($text, !($flags & OPTION_FLAG_SMILIES)); + + return $text; +} + +/** +* For parsing custom parsed text to be stored within the database. +* This function additionally returns the uid and bitfield that needs to be stored. +* Expects $text to be the value directly from request_var() and in it's non-parsed form +*/ +function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false) +{ + global $phpbb_root_path, $phpEx; + + $uid = $bitfield = ''; + + if (!$text) + { + return; + } + + if (!class_exists('parse_message')) + { + include($phpbb_root_path . 'includes/message_parser.' . $phpEx); + } + + $message_parser = new parse_message($text); + $message_parser->parse($allow_bbcode, $allow_urls, $allow_smilies); + + $text = $message_parser->message; + $uid = $message_parser->bbcode_uid; + + // If the bbcode_bitfield is empty, there is no need for the uid to be stored. + if (!$message_parser->bbcode_bitfield) + { + $uid = ''; + } + + $flags = (($allow_bbcode) ? OPTION_FLAG_BBCODE : 0) + (($allow_smilies) ? OPTION_FLAG_SMILIES : 0) + (($allow_urls) ? OPTION_FLAG_LINKS : 0); + $bitfield = $message_parser->bbcode_bitfield; + + return; +} + +/** +* For decoding custom parsed text for edits as well as extracting the flags +* Expects $text to be the value directly from the database (pre-parsed content) +*/ +function generate_text_for_edit($text, $uid, $flags) +{ + global $phpbb_root_path, $phpEx; + + decode_message($text, $uid); + + return array( + 'allow_bbcode' => ($flags & OPTION_FLAG_BBCODE) ? 1 : 0, + 'allow_smilies' => ($flags & OPTION_FLAG_SMILIES) ? 1 : 0, + 'allow_urls' => ($flags & OPTION_FLAG_LINKS) ? 1 : 0, + 'text' => $text + ); +} + +/** +* A subroutine of make_clickable used with preg_replace +* It places correct HTML around an url, shortens the displayed text +* and makes sure no entities are inside URLs +*/ +function make_clickable_callback($type, $whitespace, $url, $relative_url, $class) +{ + $append = ''; + $url = htmlspecialchars_decode($url); + $relative_url = htmlspecialchars_decode($relative_url); + + // make sure no HTML entities were matched + $chars = array('<', '>', '"'); + $split = false; + + foreach ($chars as $char) + { + $next_split = strpos($url, $char); + if ($next_split !== false) + { + $split = ($split !== false) ? min($split, $next_split) : $next_split; + } + } + + if ($split !== false) + { + // an HTML entity was found, so the URL has to end before it + $append = substr($url, $split) . $relative_url; + $url = substr($url, 0, $split); + $relative_url = ''; + } + else if ($relative_url) + { + // same for $relative_url + $split = false; + foreach ($chars as $char) + { + $next_split = strpos($relative_url, $char); + if ($next_split !== false) + { + $split = ($split !== false) ? min($split, $next_split) : $next_split; + } + } + + if ($split !== false) + { + $append = substr($relative_url, $split); + $relative_url = substr($relative_url, 0, $split); + } + } + + // if the last character of the url is a punctuation mark, exclude it from the url + $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1]; + + switch ($last_char) + { + case '.': + case '?': + case '!': + case ':': + case ',': + $append = $last_char; + if ($relative_url) + { + $relative_url = substr($relative_url, 0, -1); + } + else + { + $url = substr($url, 0, -1); + } + break; + } + + switch ($type) + { + case MAGIC_URL_LOCAL: + $tag = 'l'; + $relative_url = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url)); + $url = $url . '/' . $relative_url; + $text = ($relative_url) ? $relative_url : $url; + break; + + case MAGIC_URL_FULL: + $tag = 'm'; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + break; + + case MAGIC_URL_WWW: + $tag = 'w'; + $url = 'http://' . $url; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + break; + + case MAGIC_URL_EMAIL: + $tag = 'e'; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + $url = 'mailto:' . $url; + break; + } + + $url = htmlspecialchars($url); + $text = htmlspecialchars($text); + $append = htmlspecialchars($append); + + $html = "$whitespace<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$append"; + + return $html; +} + +/** +* make_clickable function +* +* Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx. +* Cuts down displayed size of link if over 50 chars, turns absolute links +* into relative versions when the server/script path matches the link +*/ +function make_clickable($text, $server_url = false, $class = 'postlink') +{ + if ($server_url === false) + { + $server_url = generate_board_url(); + } + + static $magic_url_match; + static $magic_url_replace; + static $static_class; + + if (!is_array($magic_url_match) || $static_class != $class) + { + $static_class = $class; + $class = ($static_class) ? ' class="' . $static_class . '"' : ''; + $local_class = ($static_class) ? ' class="' . $static_class . '-local"' : ''; + + $magic_url_match = $magic_url_replace = array(); + // Be sure to not let the matches cross over. ;) + + // relative urls for this board + $magic_url_match[] = '#(^|[\n\t (>])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_LOCAL, '\$1', '\$2', '\$3', '$local_class')"; + + // matches a xxxx://aaaaa.bbb.cccc. ... + $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')"; + + // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing + $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')"; + + // matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode. + $magic_url_match[] = '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_EMAIL, '\$1', '\$2', '', '')"; + } + + return preg_replace($magic_url_match, $magic_url_replace, $text); +} + +/** +* Censoring +*/ +function censor_text($text) +{ + static $censors; + global $cache; + + if (!isset($censors) || !is_array($censors)) + { + // obtain_word_list is taking care of the users censor option and the board-wide option + $censors = $cache->obtain_word_list(); + } + + if (sizeof($censors)) + { + return preg_replace($censors['match'], $censors['replace'], $text); + } + + return $text; +} + +/** +* custom version of nl2br which takes custom BBCodes into account +*/ +function bbcode_nl2br($text) +{ + // custom BBCodes might contain carriage returns so they + // are not converted into <br /> so now revert that + $text = str_replace(array("\n", "\r"), array('<br />', "\n"), $text); + return $text; +} + +/** +* Smiley processing +*/ +function smiley_text($text, $force_option = false) +{ + global $config, $user, $phpbb_root_path; + + if ($force_option || !$config['allow_smilies'] || !$user->optionget('viewsmilies')) + { + return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', '\1', $text); + } + else + { + return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img src="' . $phpbb_root_path . $config['smilies_path'] . '/\2 />', $text); + } +} + +/** +* General attachment parsing +* +* @param mixed $forum_id The forum id the attachments are displayed in (false if in private message) +* @param string &$message The post/private message +* @param array &$attachments The attachments to parse for (inline) display. The attachments array will hold templated data after parsing. +* @param array &$update_count The attachment counts to be updated - will be filled +* @param bool $preview If set to true the attachments are parsed for preview. Within preview mode the comments are fetched from the given $attachments array and not fetched from the database. +*/ +function parse_attachments($forum_id, &$message, &$attachments, &$update_count, $preview = false) +{ + if (!sizeof($attachments)) + { + return; + } + + global $template, $cache, $user; + global $extensions, $config, $phpbb_root_path, $phpEx; + + // + $compiled_attachments = array(); + + if (!isset($template->filename['attachment_tpl'])) + { + $template->set_filenames(array( + 'attachment_tpl' => 'attachment.html') + ); + } + + if (empty($extensions) || !is_array($extensions)) + { + $extensions = $cache->obtain_attach_extensions($forum_id); + } + + // Look for missing attachment information... + $attach_ids = array(); + foreach ($attachments as $pos => $attachment) + { + // If is_orphan is set, we need to retrieve the attachments again... + if (!isset($attachment['extension']) && !isset($attachment['physical_filename'])) + { + $attach_ids[(int) $attachment['attach_id']] = $pos; + } + } + + // Grab attachments (security precaution) + if (sizeof($attach_ids)) + { + global $db; + + $new_attachment_data = array(); + + $sql = 'SELECT * + FROM ' . ATTACHMENTS_TABLE . ' + WHERE ' . $db->sql_in_set('attach_id', array_keys($attach_ids)); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + if (!isset($attach_ids[$row['attach_id']])) + { + continue; + } + + // If we preview attachments we will set some retrieved values here + if ($preview) + { + $row['attach_comment'] = $attachments[$attach_ids[$row['attach_id']]]['attach_comment']; + } + + $new_attachment_data[$attach_ids[$row['attach_id']]] = $row; + } + $db->sql_freeresult($result); + + $attachments = $new_attachment_data; + unset($new_attachment_data); + } + + // Sort correctly + if ($config['display_order']) + { + // Ascending sort + krsort($attachments); + } + else + { + // Descending sort + ksort($attachments); + } + + foreach ($attachments as $attachment) + { + if (!sizeof($attachment)) + { + continue; + } + + // We need to reset/empty the _file block var, because this function might be called more than once + $template->destroy_block_vars('_file'); + + $block_array = array(); + + // Some basics... + $attachment['extension'] = strtolower(trim($attachment['extension'])); + $filename = $phpbb_root_path . $config['upload_path'] . '/' . basename($attachment['physical_filename']); + $thumbnail_filename = $phpbb_root_path . $config['upload_path'] . '/thumb_' . basename($attachment['physical_filename']); + + $upload_icon = ''; + + if (isset($extensions[$attachment['extension']])) + { + if ($user->img('icon_topic_attach', '') && !$extensions[$attachment['extension']]['upload_icon']) + { + $upload_icon = $user->img('icon_topic_attach', ''); + } + else if ($extensions[$attachment['extension']]['upload_icon']) + { + $upload_icon = '<img src="' . $phpbb_root_path . $config['upload_icons_path'] . '/' . trim($extensions[$attachment['extension']]['upload_icon']) . '" alt="" />'; + } + } + + $filesize = $attachment['filesize']; + $size_lang = ($filesize >= 1048576) ? $user->lang['MB'] : ( ($filesize >= 1024) ? $user->lang['KB'] : $user->lang['BYTES'] ); + $filesize = ($filesize >= 1048576) ? round((round($filesize / 1048576 * 100) / 100), 2) : (($filesize >= 1024) ? round((round($filesize / 1024 * 100) / 100), 2) : $filesize); + + $comment = bbcode_nl2br(censor_text($attachment['attach_comment'])); + + $block_array += array( + 'UPLOAD_ICON' => $upload_icon, + 'FILESIZE' => $filesize, + 'SIZE_LANG' => $size_lang, + 'DOWNLOAD_NAME' => basename($attachment['real_filename']), + 'COMMENT' => $comment, + ); + + $denied = false; + + if (!extension_allowed($forum_id, $attachment['extension'], $extensions)) + { + $denied = true; + + $block_array += array( + 'S_DENIED' => true, + 'DENIED_MESSAGE' => sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension']) + ); + } + + if (!$denied) + { + $l_downloaded_viewed = $download_link = ''; + $display_cat = $extensions[$attachment['extension']]['display_cat']; + + if ($display_cat == ATTACHMENT_CATEGORY_IMAGE) + { + if ($attachment['thumbnail']) + { + $display_cat = ATTACHMENT_CATEGORY_THUMB; + } + else + { + if ($config['img_display_inlined']) + { + if ($config['img_link_width'] || $config['img_link_height']) + { + $dimension = @getimagesize($filename); + + // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes + if ($dimension === false || empty($dimension[0]) || empty($dimension[1])) + { + $display_cat = ATTACHMENT_CATEGORY_NONE; + } + else + { + $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE; + } + } + } + else + { + $display_cat = ATTACHMENT_CATEGORY_NONE; + } + } + } + + // Make some descisions based on user options being set. + if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg')) + { + $display_cat = ATTACHMENT_CATEGORY_NONE; + } + + if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash')) + { + $display_cat = ATTACHMENT_CATEGORY_NONE; + } + + $download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']); + + switch ($display_cat) + { + // Images + case ATTACHMENT_CATEGORY_IMAGE: + $l_downloaded_viewed = 'VIEWED_COUNT'; + $inline_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']); + $download_link .= '&mode=view'; + + $block_array += array( + 'S_IMAGE' => true, + 'U_INLINE_LINK' => $inline_link, + ); + + $update_count[] = $attachment['attach_id']; + break; + + // Images, but display Thumbnail + case ATTACHMENT_CATEGORY_THUMB: + $l_downloaded_viewed = 'VIEWED_COUNT'; + $thumbnail_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id'] . '&t=1'); + $download_link .= '&mode=view'; + + $block_array += array( + 'S_THUMBNAIL' => true, + 'THUMB_IMAGE' => $thumbnail_link, + ); + break; + + // Windows Media Streams + case ATTACHMENT_CATEGORY_WM: + $l_downloaded_viewed = 'VIEWED_COUNT'; + + // Giving the filename directly because within the wm object all variables are in local context making it impossible + // to validate against a valid session (all params can differ) + // $download_link = $filename; + + $block_array += array( + 'U_FORUM' => generate_board_url(), + 'ATTACH_ID' => $attachment['attach_id'], + 'S_WM_FILE' => true, + ); + + // Viewed/Heared File ... update the download count + $update_count[] = $attachment['attach_id']; + break; + + // Real Media Streams + case ATTACHMENT_CATEGORY_RM: + case ATTACHMENT_CATEGORY_QUICKTIME: + $l_downloaded_viewed = 'VIEWED_COUNT'; + + $block_array += array( + 'S_RM_FILE' => ($display_cat == ATTACHMENT_CATEGORY_RM) ? true : false, + 'S_QUICKTIME_FILE' => ($display_cat == ATTACHMENT_CATEGORY_QUICKTIME) ? true : false, + 'U_FORUM' => generate_board_url(), + 'ATTACH_ID' => $attachment['attach_id'], + ); + + // Viewed/Heared File ... update the download count + $update_count[] = $attachment['attach_id']; + break; + + // Macromedia Flash Files + case ATTACHMENT_CATEGORY_FLASH: + list($width, $height) = @getimagesize($filename); + + $l_downloaded_viewed = 'VIEWED_COUNT'; + + $block_array += array( + 'S_FLASH_FILE' => true, + 'WIDTH' => $width, + 'HEIGHT' => $height, + ); + + // Viewed/Heared File ... update the download count + $update_count[] = $attachment['attach_id']; + break; + + default: + $l_downloaded_viewed = 'DOWNLOAD_COUNT'; + + $block_array += array( + 'S_FILE' => true, + ); + break; + } + + $l_download_count = (!isset($attachment['download_count']) || $attachment['download_count'] == 0) ? $user->lang[$l_downloaded_viewed . '_NONE'] : (($attachment['download_count'] == 1) ? sprintf($user->lang[$l_downloaded_viewed], $attachment['download_count']) : sprintf($user->lang[$l_downloaded_viewed . 'S'], $attachment['download_count'])); + + $block_array += array( + 'U_DOWNLOAD_LINK' => $download_link, + 'L_DOWNLOAD_COUNT' => $l_download_count + ); + } + + $template->assign_block_vars('_file', $block_array); + + $compiled_attachments[] = $template->assign_display('attachment_tpl'); + } + + $attachments = $compiled_attachments; + unset($compiled_attachments); + + $tpl_size = sizeof($attachments); + + $unset_tpl = array(); + + preg_match_all('#<!\-\- ia([0-9]+) \-\->(.*?)<!\-\- ia\1 \-\->#', $message, $matches, PREG_PATTERN_ORDER); + + $replace = array(); + foreach ($matches[0] as $num => $capture) + { + // Flip index if we are displaying the reverse way + $index = ($config['display_order']) ? ($tpl_size-($matches[1][$num] + 1)) : $matches[1][$num]; + + $replace['from'][] = $matches[0][$num]; + $replace['to'][] = (isset($attachments[$index])) ? $attachments[$index] : sprintf($user->lang['MISSING_INLINE_ATTACHMENT'], $matches[2][array_search($index, $matches[1])]); + + $unset_tpl[] = $index; + } + + if (isset($replace['from'])) + { + $message = str_replace($replace['from'], $replace['to'], $message); + } + + $unset_tpl = array_unique($unset_tpl); + + // Needed to let not display the inlined attachments at the end of the post again + foreach ($unset_tpl as $index) + { + unset($attachments[$index]); + } +} + +/** +* Check if extension is allowed to be posted. +* +* @param mixed $forum_id The forum id to check or false if private message +* @param string $extension The extension to check, for example zip. +* @param array &$extensions The extension array holding the information from the cache (will be obtained if empty) +* +* @return bool False if the extension is not allowed to be posted, else true. +*/ +function extension_allowed($forum_id, $extension, &$extensions) +{ + if (empty($extensions)) + { + global $cache; + $extensions = $cache->obtain_attach_extensions($forum_id); + } + + return (!isset($extensions['_allowed_'][$extension])) ? false : true; +} + +/** +* Truncates string while retaining special characters if going over the max length +* The default max length is 60 at the moment +*/ +function truncate_string($string, $max_length = 60, $allow_reply = true, $append = '') +{ + $chars = array(); + + $strip_reply = false; + $stripped = false; + if ($allow_reply && strpos($string, 'Re: ') === 0) + { + $strip_reply = true; + $string = substr($string, 4); + } + + $_chars = utf8_str_split(htmlspecialchars_decode($string)); + $chars = array_map('utf8_htmlspecialchars', $_chars); + + // Now check the length ;) + if (sizeof($chars) > $max_length) + { + // Cut off the last elements from the array + $string = implode('', array_slice($chars, 0, $max_length - utf8_strlen($append))); + $stripped = true; + } + + if ($strip_reply) + { + $string = 'Re: ' . $string; + } + + if ($append != '' && $stripped) + { + $string = $string . $append; + } + + return $string; +} + +/** +* Get username details for placing into templates. +* +* @param string $mode Can be profile (for getting an url to the profile), username (for obtaining the username), colour (for obtaining the user colour), full (for obtaining a html string representing a coloured link to the users profile) or no_profile (the same as full but forcing no profile link) +* @param int $user_id The users id +* @param string $username The users name +* @param string $username_colour The users colour +* @param string $guest_username optional parameter to specify the guest username. It will be used in favor of the GUEST language variable then. +* @param string $custom_profile_url optional parameter to specify a profile url. The user id get appended to this url as &u={user_id} +* +* @return string A string consisting of what is wanted based on $mode. +*/ +function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false) +{ + global $phpbb_root_path, $phpEx, $user, $auth; + + $profile_url = ''; + $username_colour = ($username_colour) ? '#' . $username_colour : ''; + + if ($guest_username === false) + { + $username = ($username) ? $username : $user->lang['GUEST']; + } + else + { + $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']); + } + + // Only show the link if not anonymous + if ($mode != 'no_profile' && $user_id && $user_id != ANONYMOUS) + { + // Do not show the link if the user is already logged in but do not have u_viewprofile permissions (relevant for bots mostly). + // For all others the link leads to a login page or the profile. + if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) + { + $profile_url = ''; + } + else + { + $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&u=' . (int) $user_id : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . (int) $user_id); + } + } + else + { + $profile_url = ''; + } + + switch ($mode) + { + case 'profile': + return $profile_url; + break; + + case 'username': + return $username; + break; + + case 'colour': + return $username_colour; + break; + + case 'no_profile': + case 'full': + default: + + $tpl = ''; + if (!$profile_url && !$username_colour) + { + $tpl = '{USERNAME}'; + } + else if (!$profile_url && $username_colour) + { + $tpl = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; + } + else if ($profile_url && !$username_colour) + { + $tpl = '<a href="{PROFILE_URL}">{USERNAME}</a>'; + } + else if ($profile_url && $username_colour) + { + $tpl = '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>'; + } + + return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), $tpl); + break; + } +} + +/** +* @package phpBB3 +*/ +class bitfield +{ + var $data; + + function bitfield($bitfield = '') + { + $this->data = base64_decode($bitfield); + } + + /** + */ + function get($n) + { + // Get the ($n / 8)th char + $byte = $n >> 3; + + if (strlen($this->data) >= $byte + 1) + { + $c = $this->data[$byte]; + + // Lookup the ($n % 8)th bit of the byte + $bit = 7 - ($n & 7); + return (bool) (ord($c) & (1 << $bit)); + } + else + { + return false; + } + } + + function set($n) + { + $byte = $n >> 3; + $bit = 7 - ($n & 7); + + if (strlen($this->data) >= $byte + 1) + { + $this->data[$byte] = $this->data[$byte] | chr(1 << $bit); + } + else + { + $this->data .= str_repeat("\0", $byte - strlen($this->data)); + $this->data .= chr(1 << $bit); + } + } + + function clear($n) + { + $byte = $n >> 3; + + if (strlen($this->data) >= $byte + 1) + { + $bit = 7 - ($n & 7); + $this->data[$byte] = $this->data[$byte] &~ chr(1 << $bit); + } + } + + function get_blob() + { + return $this->data; + } + + function get_base64() + { + return base64_encode($this->data); + } + + function get_bin() + { + $bin = ''; + $len = strlen($this->data); + + for ($i = 0; $i < $len; ++$i) + { + $bin .= str_pad(decbin(ord($this->data[$i])), 8, '0', STR_PAD_LEFT); + } + + return $bin; + } + + function get_all_set() + { + return array_keys(array_filter(str_split($this->get_bin()))); + } + + function merge($bitfield) + { + $this->data = $this->data | $bitfield->get_blob(); + } +} + +?>
\ No newline at end of file diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index 12b3109430..3a572e128c 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Default avatar width/height * @ignore */ @@ -216,7 +224,7 @@ function is_topic_locked($bool) */ function make_uid($timestamp) { - return substr(md5($timestamp), 0, BBCODE_UID_LEN); + return substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN); } /** @@ -372,7 +380,7 @@ function mimetype($filename) * There can be significant network overhead if there are a large number of remote avatars * @todo Look at the option of allowing the user to decide whether this is called or to force the dimensions */ -function remote_avatar_dims() +function remote_avatar_dims() { global $db; @@ -514,14 +522,14 @@ function base64_unpack($string) for ($i = 1; $i <= $length; $i++) { - $pos = $length - $i; + $pos = $length - $i; $operand = strpos($chars, substr($string, $pos, 1)); - $exponent = pow($base, $i-1); + $exponent = pow($base, $i-1); $dec_value = $operand * $exponent; - $number += $dec_value; + $number += $dec_value; } - return $number; + return $number; } function _import_check($config_var, $source, $use_target) @@ -535,7 +543,7 @@ function _import_check($config_var, $source, $use_target) ); // copy file will prepend $phpBB_root_path - $target = $config[$config_var] . '/' . basename(($use_target === false) ? $source : $use_target); + $target = $config[$config_var] . '/' . basename(($use_target === false) ? $source : $use_target); if (!empty($convert->convertor[$config_var]) && strpos($source, $convert->convertor[$config_var]) !== 0) { @@ -639,7 +647,6 @@ function import_smiley($source, $use_target = false) } /* -* */ function import_avatar($source, $use_target = false, $user_id = false) { @@ -998,15 +1005,15 @@ function set_user_options() // Key need to be set in row, else default value is chosen $keyoptions = array( - 'viewimg' => array('bit' => 0, 'default' => 1), + 'viewimg' => array('bit' => 0, 'default' => 1), 'viewflash' => array('bit' => 1, 'default' => 1), 'viewsmilies' => array('bit' => 2, 'default' => 1), 'viewsigs' => array('bit' => 3, 'default' => 1), - 'viewavatars' => array('bit' => 4, 'default' => 1), - 'viewcensors' => array('bit' => 5, 'default' => 1), - 'attachsig' => array('bit' => 6, 'default' => 0), - 'bbcode' => array('bit' => 8, 'default' => 1), - 'smilies' => array('bit' => 9, 'default' => 1), + 'viewavatars' => array('bit' => 4, 'default' => 1), + 'viewcensors' => array('bit' => 5, 'default' => 1), + 'attachsig' => array('bit' => 6, 'default' => 0), + 'bbcode' => array('bit' => 8, 'default' => 1), + 'smilies' => array('bit' => 9, 'default' => 1), 'popuppm' => array('bit' => 10, 'default' => 0), ); @@ -1458,7 +1465,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO) if (!isset($group_ids[$ug_id])) { $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " + FROM ' . GROUPS_TABLE . " WHERE group_name = '" . $db->sql_escape(strtoupper($ug_id)) . "'"; $result = $db->sql_query_limit($sql, 1); $id = (int) $db->sql_fetchfield('group_id'); @@ -1574,7 +1581,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO) case ACL_NO: if (isset($cur_auth[$forum][$auth_option_id])) { - $sql_ary['delete'][] = "DELETE FROM $table + $sql_ary['delete'][] = "DELETE FROM $table WHERE forum_id = $forum AND auth_option_id = $auth_option_id AND $id_field = $ug_id"; @@ -1588,10 +1595,10 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO) } else if ($cur_auth[$forum][$auth_option_id] != $setting) { - $sql_ary['update'][] = "UPDATE " . $table . " - SET auth_setting = $setting - WHERE $id_field = $ug_id - AND forum_id = $forum + $sql_ary['update'][] = "UPDATE " . $table . " + SET auth_setting = $setting + WHERE $id_field = $ug_id + AND forum_id = $forum AND auth_option_id = $auth_option_id"; } } @@ -1720,7 +1727,7 @@ function add_default_groups() } -/** +/** * Sync post count. We might need to do this in batches. */ function sync_post_count($offset, $limit) @@ -1784,7 +1791,7 @@ function add_bots() 'FAST WebCrawler [Crawler]' => array('FAST-WebCrawler/', ''), 'Francis [Bot]' => array('http://www.neomo.de/', ''), 'Gigabot [Bot]' => array('Gigabot/', ''), - 'Google Adsense [Bot]' => array('Mediapartners-Google/', ''), + 'Google Adsense [Bot]' => array('Mediapartners-Google', ''), 'Google Desktop' => array('Google Desktop', ''), 'Google Feedfetcher' => array('Feedfetcher-Google', ''), 'Google [Bot]' => array('Googlebot', ''), @@ -1898,7 +1905,7 @@ function update_dynamic_config() // set_config('record_online_users', 1, true); // set_config('record_online_date', time(), true); - $sql = 'SELECT COUNT(post_id) AS stat + $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' WHERE post_approved = 1'; $result = $db->sql_query($sql); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 208226257d..b75747a862 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Display Forums */ function display_forums($root_data = '', $display_moderators = true, $return_moderators = false) @@ -833,8 +841,8 @@ function display_reasons($reason_id = 0) { global $db, $user, $template; - $sql = 'SELECT * - FROM ' . REPORTS_REASONS_TABLE . ' + $sql = 'SELECT * + FROM ' . REPORTS_REASONS_TABLE . ' ORDER BY reason_order ASC'; $result = $db->sql_query($sql); @@ -1149,7 +1157,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $ switch ($avatar_type) { case AVATAR_UPLOAD: - $avatar_img = $phpbb_root_path . "download.$phpEx?avatar="; + $avatar_img = $phpbb_root_path . "download/file.$phpEx?avatar="; break; case AVATAR_GALLERY: diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index d5994f9f98..3e4bd27bcc 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Determine if we are able to load a specified PHP module and do so if possible */ function can_load_dll($dll) @@ -27,7 +35,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'firebird' => array( 'LABEL' => 'FireBird', 'SCHEMA' => 'firebird', - 'MODULE' => 'interbase', + 'MODULE' => 'interbase', 'DELIM' => ';;', 'COMMENTS' => 'remove_remarks', 'DRIVER' => 'firebird', @@ -47,7 +55,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'mysql' => array( 'LABEL' => 'MySQL', 'SCHEMA' => 'mysql', - 'MODULE' => 'mysql', + 'MODULE' => 'mysql', 'DELIM' => ';', 'COMMENTS' => 'remove_remarks', 'DRIVER' => 'mysql', @@ -57,7 +65,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'mssql' => array( 'LABEL' => 'MS SQL Server 2000+', 'SCHEMA' => 'mssql', - 'MODULE' => 'mssql', + 'MODULE' => 'mssql', 'DELIM' => 'GO', 'COMMENTS' => 'remove_comments', 'DRIVER' => 'mssql', @@ -67,7 +75,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'mssql_odbc'=> array( 'LABEL' => 'MS SQL Server [ ODBC ]', 'SCHEMA' => 'mssql', - 'MODULE' => 'odbc', + 'MODULE' => 'odbc', 'DELIM' => 'GO', 'COMMENTS' => 'remove_comments', 'DRIVER' => 'mssql_odbc', @@ -77,7 +85,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'oracle' => array( 'LABEL' => 'Oracle', 'SCHEMA' => 'oracle', - 'MODULE' => 'oci8', + 'MODULE' => 'oci8', 'DELIM' => '/', 'COMMENTS' => 'remove_comments', 'DRIVER' => 'oracle', @@ -87,7 +95,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'postgres' => array( 'LABEL' => 'PostgreSQL 7.x/8.x', 'SCHEMA' => 'postgres', - 'MODULE' => 'pgsql', + 'MODULE' => 'pgsql', 'DELIM' => ';', 'COMMENTS' => 'remove_comments', 'DRIVER' => 'postgres', @@ -97,7 +105,7 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20 'sqlite' => array( 'LABEL' => 'SQLite', 'SCHEMA' => 'sqlite', - 'MODULE' => 'sqlite', + 'MODULE' => 'sqlite', 'DELIM' => ';', 'COMMENTS' => 'remove_remarks', 'DRIVER' => 'sqlite', @@ -199,8 +207,8 @@ function get_tables($db) case 'mssql': case 'mssql_odbc': - $sql = "SELECT name - FROM sysobjects + $sql = "SELECT name + FROM sysobjects WHERE type='U'"; break; diff --git a/phpBB/includes/functions_jabber.php b/phpBB/includes/functions_jabber.php index 04f664139f..8575f339c1 100644 --- a/phpBB/includes/functions_jabber.php +++ b/phpBB/includes/functions_jabber.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * * Jabber class from Flyspray project * @@ -216,10 +224,6 @@ class jabber $server = $record[0]['target']; } } - else - { - $this->add_to_log('Warning: dns_get_record() function not found. GTalk will not work.'); - } $server = $use_ssl ? 'ssl://' . $server : $server; @@ -503,6 +507,13 @@ class jabber } else { + // Make sure we only use 'auth' for qop (relevant for $this->encrypt_password()) + // If the <response> is choking up on the changed parameter we may need to adjust encrypt_password() directly + if (isset($decoded['qop']) && $decoded['qop'] != 'auth' && strpos($decoded['qop'], 'auth') !== false) + { + $decoded['qop'] = 'auth'; + } + $response = array( 'username' => $this->username, 'response' => $this->encrypt_password(array_merge($decoded, array('nc' => '00000001'))), @@ -699,25 +710,34 @@ class jabber } /** - * parse_data like a="b",c="d",... + * parse_data like a="b",c="d",... or like a="a, b", c, d="e", f=g,... * @param string $data * @access public * @return array a => b ... */ function parse_data($data) { - // super basic, but should suffice $data = explode(',', $data); $pairs = array(); + $key = false; foreach ($data as $pair) { $dd = strpos($pair, '='); + if ($dd) { - $pairs[substr($pair, 0, $dd)] = trim(substr($pair, $dd + 1), '"'); + $key = trim(substr($pair, 0, $dd)); + $pairs[$key] = trim(trim(substr($pair, $dd + 1)), '"'); + } + else if (strpos(strrev(trim($pair)), '"') === 0 && $key) + { + // We are actually having something left from "a, b" values, add it to the last one we handled. + $pairs[$key] .= ',' . trim(trim($pair), '"'); + continue; } } + return $pairs; } diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index ae156436f0..6bce44209a 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Messenger * @package phpBB3 */ @@ -275,7 +283,7 @@ class messenger break; } - $message .= '<br /><em>' . htmlspecialchars($calling_page) . '<em><br /><br />' . $msg . '<br />'; + $message .= '<br /><em>' . htmlspecialchars($calling_page) . '</em><br /><br />' . $msg . '<br />'; add_log('critical', 'LOG_ERROR_' . $type, $message); } @@ -394,7 +402,7 @@ class messenger // Send message ... if (!$use_queue) { - $mail_to = ($to == '') ? 'Undisclosed-Recipient:;' : $to; + $mail_to = ($to == '') ? 'undisclosed-recipients:;' : $to; $err_msg = ''; if ($config['smtp_delivery']) @@ -465,13 +473,13 @@ class messenger if (!$this->jabber->connect()) { - $this->error('JABBER', 'Could not connect to Jabber server<br />' . $this->jabber->get_log()); + $this->error('JABBER', $user->lang['ERR_JAB_CONNECT'] . '<br />' . $this->jabber->get_log()); return false; } if (!$this->jabber->login()) { - $this->error('JABBER', 'Could not authorise on Jabber server<br />' . $this->jabber->get_log()); + $this->error('JABBER', $user->lang['ERR_JAB_AUTH'] . '<br />' . $this->jabber->get_log()); return false; } @@ -541,7 +549,7 @@ class queue */ function process() { - global $db, $config, $phpEx, $phpbb_root_path; + global $db, $config, $phpEx, $phpbb_root_path, $user; set_config('last_queue_run', time(), true); @@ -604,13 +612,13 @@ class queue if (!$this->jabber->connect()) { - messenger::error('JABBER', 'Could not connect to Jabber server'); + messenger::error('JABBER', $user->lang['ERR_JAB_CONNECT']); continue 2; } if (!$this->jabber->login()) { - messenger::error('JABBER', 'Could not authorise on Jabber server'); + messenger::error('JABBER', $user->lang['ERR_JAB_AUTH']); continue 2; } @@ -629,7 +637,7 @@ class queue { case 'email': $err_msg = ''; - $to = (!$to) ? 'Undisclosed-Recipient:;' : $to; + $to = (!$to) ? 'undisclosed-recipients:;' : $to; if ($config['smtp_delivery']) { @@ -922,7 +930,7 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = '') $smtp->server_send("Subject: $subject"); // Now the To Header. - $to_header = ($to_header == '') ? 'Undisclosed-Recipients:;' : $to_header; + $to_header = ($to_header == '') ? 'undisclosed-recipients:;' : $to_header; $smtp->server_send("To: $to_header"); // Now the CC Header. @@ -1058,7 +1066,7 @@ class smtp_class // If we are authenticating through pop-before-smtp, we // have to login ones before we get authenticated - // NOTE: on some configurations the time between an update of the auth database takes so + // NOTE: on some configurations the time between an update of the auth database takes so // long that the first email send does not work. This is not a biggie on a live board (only // the install mail will most likely fail) - but on a dynamic ip connection this might produce // severe problems and is not fixable! @@ -1311,7 +1319,7 @@ class smtp_class { $tokens[$matches[1]] = array($tokens[$matches[1]], preg_replace('/^"(.*)"$/', '\\1', $matches[2])); } - } + } else if (!empty($tokens[$matches[1]])) // Any other multiple instance = failure { $tokens = array(); diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 9db2c4fa25..b55c408b8c 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Class handling all types of 'plugins' (a future term) * @package phpBB3 */ diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 222f9a3843..485ba5028b 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Fill smiley templates (or just the variables) with smilies, either in a window or inline */ function generate_smilies($mode, $forum_id) @@ -59,7 +67,7 @@ function generate_smilies($mode, $forum_id) $last_url = ''; $sql = 'SELECT * - FROM ' . SMILIES_TABLE . + FROM ' . SMILIES_TABLE . (($mode == 'inline') ? ' WHERE display_on_posting = 1 ' : '') . ' ORDER BY smiley_order'; $result = $db->sql_query($sql, 3600); @@ -311,7 +319,7 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) $topic_type_array = array_merge(array(0 => array( 'VALUE' => POST_NORMAL, 'S_CHECKED' => ($topic_type == POST_NORMAL) ? ' checked="checked"' : '', - 'L_TOPIC_TYPE' => $user->lang['POST_NORMAL'])), + 'L_TOPIC_TYPE' => $user->lang['POST_NORMAL'])), $topic_type_array ); @@ -571,7 +579,7 @@ function get_supported_image_types($type = false) /** * Create Thumbnail */ -function create_thumbnail($source, $destination, $mimetype) +function create_thumbnail($source, $destination, $mimetype) { global $config; @@ -618,7 +626,7 @@ function create_thumbnail($source, $destination, $mimetype) } } - if (!$used_imagick) + if (!$used_imagick) { $type = get_supported_image_types($type); @@ -630,7 +638,7 @@ function create_thumbnail($source, $destination, $mimetype) return false; } - switch ($type['format']) + switch ($type['format']) { case IMG_GIF: $image = @imagecreatefromgif($source); @@ -769,10 +777,11 @@ function posting_gen_attachment_entry($attachment_data, &$filename_data) $hidden .= '<input type="hidden" name="attachment_data[' . $count . '][' . $key . ']" value="' . $value . '" />'; } - $download_link = append_sid("{$phpbb_root_path}download.$phpEx", 'mode=view&id=' . (int) $attach_row['attach_id'], true, ($attach_row['is_orphan']) ? $user->session_id : false); + $download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&id=' . (int) $attach_row['attach_id'], true, ($attach_row['is_orphan']) ? $user->session_id : false); $template->assign_block_vars('attach_row', array( 'FILENAME' => basename($attach_row['real_filename']), + 'A_FILENAME' => addslashes(basename($attach_row['real_filename'])), 'FILE_COMMENT' => $attach_row['attach_comment'], 'ATTACH_ID' => $attach_row['attach_id'], 'S_IS_ORPHAN' => $attach_row['is_orphan'], @@ -785,7 +794,7 @@ function posting_gen_attachment_entry($attachment_data, &$filename_data) } $template->assign_vars(array( - 'FILE_COMMENT' => $filename_data['filecomment'], + 'FILE_COMMENT' => $filename_data['filecomment'], 'FILESIZE' => $config['max_filesize']) ); @@ -1105,7 +1114,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $topic_title = censor_text($topic_title); // Get banned User ID's - $sql = 'SELECT ban_userid + $sql = 'SELECT ban_userid FROM ' . BANLIST_TABLE; $result = $db->sql_query($sql); @@ -1122,7 +1131,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $notify_rows = array(); // -- get forum_userids || topic_userids - $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber + $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . " AND w.user_id NOT IN ($sql_ignore_users) @@ -1137,11 +1146,11 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'user_id' => $row['user_id'], 'username' => $row['username'], 'user_email' => $row['user_email'], - 'user_jabber' => $row['user_jabber'], - 'user_lang' => $row['user_lang'], + 'user_jabber' => $row['user_jabber'], + 'user_lang' => $row['user_lang'], 'notify_type' => ($topic_notification) ? 'topic' : 'forum', 'template' => ($topic_notification) ? 'topic_notify' : 'newtopic_notify', - 'method' => $row['user_notify_type'], + 'method' => $row['user_notify_type'], 'allowed' => false ); } @@ -1155,7 +1164,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $sql_ignore_users .= ', ' . implode(', ', array_keys($notify_rows)); } - $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber + $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u WHERE fw.forum_id = $forum_id AND fw.user_id NOT IN ($sql_ignore_users) @@ -1170,11 +1179,11 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'user_id' => $row['user_id'], 'username' => $row['username'], 'user_email' => $row['user_email'], - 'user_jabber' => $row['user_jabber'], + 'user_jabber' => $row['user_jabber'], 'user_lang' => $row['user_lang'], 'notify_type' => 'forum', 'template' => 'forum_notify', - 'method' => $row['user_notify_type'], + 'method' => $row['user_notify_type'], 'allowed' => false ); } @@ -1223,7 +1232,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $msg_list_ary = array(); foreach ($msg_users as $row) - { + { $pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]); $msg_list_ary[$row['template']][$pos]['method'] = $row['method']; @@ -1252,7 +1261,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id", 'U_NEWEST_POST' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&p=$post_id&e=$post_id", 'U_STOP_WATCHING_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&unwatch=topic", - 'U_STOP_WATCHING_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id&unwatch=forum", + 'U_STOP_WATCHING_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id&unwatch=forum", )); $messenger->send($addr['method']); @@ -1627,6 +1636,12 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $sql_data[POSTS_TABLE]['stat'][] = 'post_edit_count = post_edit_count + 1'; } + else if (!$data['post_edit_reason'] && $mode == 'edit' && $auth->acl_get('m_edit', $data['forum_id'])) + { + $sql_data[POSTS_TABLE]['sql'] = array( + 'post_edit_reason' => '', + ); + } // If the person editing this post is different to the one having posted then we will add a log entry stating the edit // Could be simplified by only adding to the log if the edit is not tracked - but this may confuse admins/mods @@ -1923,9 +1938,10 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u } $sql_insert_ary = array(); + for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++) { - if (trim($poll['poll_options'][$i])) + if (strlen(trim($poll['poll_options'][$i]))) { if (empty($cur_poll_options[$i])) { @@ -1952,7 +1968,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if (sizeof($poll['poll_options']) < sizeof($cur_poll_options)) { $sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . ' - WHERE poll_option_id >= ' . sizeof($poll['poll_options']) . ' + WHERE poll_option_id > ' . sizeof($poll['poll_options']) . ' AND topic_id = ' . $data['topic_id']; $db->sql_query($sql); } diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index f0d0520a03..68e77ec421 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -329,11 +329,12 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) $user_id = (int) $user->data['user_id']; $action_ary = $move_into_folder = array(); + $num_not_moved = $num_removed = 0; // Newly processing on-hold messages if ($release) { - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_NO_BOX . ' WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . " AND user_id = $user_id"; @@ -384,6 +385,17 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) $user_new_privmsg = (int) $user->data['user_new_privmsg']; } } + else + { + // If not relasing we need to check the number of not moved messages... + $sql = 'SELECT COUNT(msg_id) as num_messages + FROM ' . PRIVMSGS_TO_TABLE . " + WHERE user_id = $user_id + AND folder_id = " . PRIVMSGS_HOLD_BOX; + $result = $db->sql_query($sql); + $num_not_moved = (int) $db->sql_fetchfield('num_messages'); + $db->sql_freeresult($result); + } // Get those messages not yet placed into any box $retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.group_id @@ -411,7 +423,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) $user_ids = $memberships = array(); // First of all, grab all rules and retrieve friends/foes - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . PRIVMSGS_RULES_TABLE . " WHERE user_id = $user_id"; $result = $db->sql_query($sql); @@ -454,7 +466,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) if (sizeof($user_ids)) { $sql = 'SELECT * - FROM ' . USER_GROUP_TABLE . ' + FROM ' . USER_GROUP_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $user_ids) . ' AND user_pending = 0'; $result = $db->sql_query($sql); @@ -558,7 +570,6 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) // Do not change the order of processing // The number of queries needed to be executed here highly depends on the defined rules and are // only gone through if new messages arrive. - $num_not_moved = $num_removed = 0; // Delete messages if (sizeof($delete_ids)) @@ -570,7 +581,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) // Set messages to Unread if (sizeof($unread_ids)) { - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET pm_unread = 0 WHERE ' . $db->sql_in_set('msg_id', $unread_ids) . " AND user_id = $user_id @@ -603,7 +614,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) $sql_folder[] = $full_folder_action; } - $sql = 'SELECT folder_id, pm_count + $sql = 'SELECT folder_id, pm_count FROM ' . PRIVMSGS_FOLDER_TABLE . ' WHERE ' . $db->sql_in_set('folder_id', $sql_folder) . " AND user_id = $user_id"; @@ -619,12 +630,11 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) if (in_array(PRIVMSGS_INBOX, array_keys($move_into_folder))) { - $sql = 'SELECT folder_id, COUNT(msg_id) as num_messages + $sql = 'SELECT COUNT(msg_id) as num_messages FROM ' . PRIVMSGS_TO_TABLE . " WHERE user_id = $user_id - AND folder_id = " . PRIVMSGS_INBOX . " - GROUP BY folder_id"; - $result = $db->sql_query_limit($sql, 1); + AND folder_id = " . PRIVMSGS_INBOX; + $result = $db->sql_query($sql); $folder[PRIVMSGS_INBOX] = (int) $db->sql_fetchfield('num_messages'); $db->sql_freeresult($result); } @@ -673,13 +683,14 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) delete_pm($user_id, $delete_ids, $dest_folder); } } - - // + + // if ($full_folder_action == FULL_FOLDER_HOLD) { $num_not_moved += sizeof($msg_ary); + $num_new -= sizeof($msg_ary); - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_HOLD_BOX . ' WHERE folder_id = ' . PRIVMSGS_NO_BOX . " AND user_id = $user_id @@ -688,7 +699,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) } else { - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . " + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . " SET folder_id = $dest_folder, pm_new = 0 WHERE folder_id = " . PRIVMSGS_NO_BOX . " AND user_id = $user_id @@ -715,7 +726,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) { // Move from OUTBOX to SENTBOX // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted) - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_SENTBOX . ' WHERE folder_id = ' . PRIVMSGS_OUTBOX . ' AND ' . $db->sql_in_set('msg_id', array_keys($action_ary)); @@ -759,7 +770,7 @@ function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_fol $move_msg_ids = array($move_msg_ids); } - if (sizeof($move_msg_ids) && !in_array($dest_folder, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)) && + if (sizeof($move_msg_ids) && !in_array($dest_folder, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX)) && !in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)) && $cur_folder_id != $dest_folder) { // We have to check the destination folder ;) @@ -832,7 +843,7 @@ function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_fol $db->sql_query($sql); } } - } + } else if (in_array($cur_folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX))) { trigger_error('CANNOT_MOVE_SPECIAL'); @@ -853,14 +864,14 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id) global $db, $user; - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . " + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . " SET pm_unread = 0 WHERE msg_id = $msg_id AND user_id = $user_id AND folder_id = $folder_id"; $db->sql_query($sql); - $sql = 'UPDATE ' . USERS_TABLE . " + $sql = 'UPDATE ' . USERS_TABLE . " SET user_unread_privmsg = user_unread_privmsg - 1 WHERE user_id = $user_id"; $db->sql_query($sql); @@ -872,7 +883,7 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id) // Try to cope with previous wrong conversions... if ($user->data['user_unread_privmsg'] < 0) { - $sql = 'UPDATE ' . USERS_TABLE . " + $sql = 'UPDATE ' . USERS_TABLE . " SET user_unread_privmsg = 0 WHERE user_id = $user_id"; $db->sql_query($sql); @@ -926,7 +937,7 @@ function handle_mark_actions($user_id, $mark_action) else { $s_hidden_fields = array( - 'cur_folder_id' => $cur_folder_id, + 'cur_folder_id' => $cur_folder_id, 'mark_option' => 'delete_marked', 'submit_mark' => true, 'marked_msg_id' => $msg_ids @@ -1036,8 +1047,8 @@ function delete_pm($user_id, $msg_ids, $folder_id) // if folder id is user defined folder then decrease pm_count if (!in_array($folder_id, array(PRIVMSGS_INBOX, PRIVMSGS_OUTBOX, PRIVMSGS_SENTBOX, PRIVMSGS_NO_BOX))) { - $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . " - SET pm_count = pm_count - $num_deleted + $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . " + SET pm_count = pm_count - $num_deleted WHERE folder_id = $folder_id"; $db->sql_query($sql); } @@ -1060,7 +1071,7 @@ function delete_pm($user_id, $msg_ids, $folder_id) } // Now we have to check which messages we can delete completely - $sql = 'SELECT msg_id + $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . ' WHERE ' . $db->sql_in_set('msg_id', array_keys($delete_rows)); $result = $db->sql_query($sql); @@ -1150,7 +1161,7 @@ function write_pm_addresses($check_ary, $author_id, $plaintext = false) $address = array(); if (sizeof($u)) { - $sql = 'SELECT user_id, username, user_colour + $sql = 'SELECT user_id, username, user_colour FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $u) . ' AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; @@ -1178,7 +1189,7 @@ function write_pm_addresses($check_ary, $author_id, $plaintext = false) if ($plaintext) { $sql = 'SELECT group_name, group_type - FROM ' . GROUPS_TABLE . ' + FROM ' . GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('group_id', $g); $result = $db->sql_query($sql); @@ -1279,7 +1290,7 @@ function get_folder_status($folder_id, $folder) } $return = array( - 'folder_name' => $folder['folder_name'], + 'folder_name' => $folder['folder_name'], 'cur' => $folder['num_messages'], 'remaining' => ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0, 'max' => $user->data['message_limit'], @@ -1348,11 +1359,11 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) if (isset($data['address_list']['g']) && sizeof($data['address_list']['g'])) { - $sql = 'SELECT u.user_type, ug.group_id, ug.user_id - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug + $sql = 'SELECT u.user_type, ug.group_id, ug.user_id + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . ' AND ug.user_pending = 0 - AND u.user_id = ug.user_id + AND u.user_id = ug.user_id AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; $result = $db->sql_query($sql); @@ -1378,7 +1389,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) { case 'reply': case 'quote': - $root_level = ($data['reply_from_root_level']) ? $data['reply_from_root_level'] : $data['reply_from_msg_id']; + $root_level = ($data['reply_from_root_level']) ? $data['reply_from_root_level'] : $data['reply_from_msg_id']; // Set message_replied switch for this user $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' @@ -1394,7 +1405,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) $sql_data = array( 'root_level' => $root_level, 'author_id' => $data['from_user_id'], - 'icon_id' => $data['icon_id'], + 'icon_id' => $data['icon_id'], 'author_ip' => $data['from_user_ip'], 'message_time' => $current_time, 'enable_bbcode' => $data['enable_bbcode'], @@ -1439,8 +1450,8 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) } else if ($mode == 'edit') { - $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' - SET message_edit_count = message_edit_count + 1, ' . $db->sql_build_array('UPDATE', $sql_data) . ' + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + SET message_edit_count = message_edit_count + 1, ' . $db->sql_build_array('UPDATE', $sql_data) . ' WHERE msg_id = ' . $data['msg_id']; $db->sql_query($sql); } @@ -1470,7 +1481,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) $db->sql_multi_insert(PRIVMSGS_TO_TABLE, $sql_ary); - $sql = 'UPDATE ' . USERS_TABLE . ' + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new_privmsg = user_new_privmsg + 1, user_unread_privmsg = user_unread_privmsg + 1, user_last_privmsg = ' . time() . ' WHERE ' . $db->sql_in_set('user_id', array_keys($recipients)); $db->sql_query($sql); @@ -1582,8 +1593,8 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) $draft_id = request_var('draft_loaded', 0); if ($draft_id) { - $sql = 'DELETE FROM ' . DRAFTS_TABLE . " - WHERE draft_id = $draft_id + $sql = 'DELETE FROM ' . DRAFTS_TABLE . " + WHERE draft_id = $draft_id AND user_id = " . $data['from_user_id']; $db->sql_query($sql); } @@ -1616,7 +1627,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message) } // Get banned User ID's - $sql = 'SELECT ban_userid + $sql = 'SELECT ban_userid FROM ' . BANLIST_TABLE . ' WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . ' AND ban_exclude = 0'; @@ -1633,7 +1644,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message) return; } - $sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber + $sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients))); $result = $db->sql_query($sql); @@ -1820,9 +1831,9 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode 'QUOTE_IMG' => $user->img('icon_post_quote', $user->lang['REPLY_WITH_QUOTE']), 'HISTORY_TITLE' => $title, - 'U_VIEW_NEXT_HISTORY' => "$url&p=" . (($next_history_pm) ? $next_history_pm : $msg_id), - 'U_VIEW_PREVIOUS_HISTORY' => "$url&p=" . (($previous_history_pm) ? $previous_history_pm : $msg_id)) - ); + 'U_VIEW_NEXT_HISTORY' => ($next_history_pm) ? "$url&p=" . $next_history_pm : '', + 'U_VIEW_PREVIOUS_HISTORY' => ($previous_history_pm) ? "$url&p=" . $previous_history_pm : '', + )); return true; } diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index cbad80e28e..97b71823ac 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Custom Profile Fields * @package phpBB3 */ @@ -49,11 +57,11 @@ class custom_profile } $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f WHERE f.field_active = 1 $sql_where AND l.lang_id = $lang_id - AND l.field_id = f.field_id + AND l.field_id = f.field_id ORDER BY f.field_order"; $result = $db->sql_query($sql); @@ -113,7 +121,7 @@ class custom_profile return 'FIELD_REQUIRED'; } - if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time())) + if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time()) + 50) { return 'FIELD_INVALID_DATE'; } @@ -141,7 +149,7 @@ class custom_profile { return 'FIELD_TOO_SMALL'; } - else if ($field_value > $field_data['field_maxlen']) + else if ($field_value > $field_data['field_maxlen']) { return 'FIELD_TOO_LARGE'; } @@ -200,12 +208,12 @@ class custom_profile // Display hidden/no_view fields for admin/moderator $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' AND f.field_active = 1 ' . ((!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND f.field_hide = 0 ' : '') . ' AND f.field_no_view = 0 - AND l.field_id = f.field_id + AND l.field_id = f.field_id ORDER BY f.field_order'; $result = $db->sql_query($sql); @@ -280,11 +288,11 @@ class custom_profile } $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f WHERE l.lang_id = $lang_id AND f.field_active = 1 $sql_where - AND l.field_id = f.field_id + AND l.field_id = f.field_id ORDER BY f.field_order"; $result = $db->sql_query($sql); @@ -800,8 +808,8 @@ class custom_profile } $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f - WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' + FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f + WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' ' . ((sizeof($sql_not_in)) ? ' AND ' . $db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' AND l.field_id = f.field_id'; $result = $db->sql_query($sql); diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index 0d8a39eaee..17d3328427 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ * @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -29,7 +30,7 @@ if (!defined('IN_PHPBB')) * (on its own and in whole) under the LGPL. Section 3 of the LGPL states that any code * derived from an LGPL application may be relicenced under the GPL, this applies * to this source -* +* * DEFINE directive inspired by a request by Cyberalien * * @package phpBB3 @@ -86,16 +87,9 @@ class template_compile } /** - * Straight-forward strategy: use PHP's tokenizer to escape everything that - * looks like a PHP tag. - * - * We open/close PHP tags at the beginning of the template to clearly indicate - * that we are in HTML mode. If we find a PHP tag, we escape it then we reiterate - * over the whole file. That can become quite slow if the file is stuffed with - * <?php tags, but there's only so much we can do. - * - * Known issue: templates need to be rechecked everytime the value of the php.ini - * settings asp_tags or short_tags are changed + * Remove any PHP tags that do not belong, these regular expressions are derived from + * the ones that exist in zend_language_scanner.l + * @access private */ function remove_php_tags(&$code) { diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php index 2a38c8c7ad..2925a2df77 100644 --- a/phpBB/includes/functions_transfer.php +++ b/phpBB/includes/functions_transfer.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Transfer class, wrapper for ftp/sftp/ssh * @package phpBB3 */ diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 68e06765a5..8e4bb6284a 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package phpBB3 -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @version $Id$ +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Responsible for holding all file relevant information, as well as doing file-specific operations. * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on. * @package phpBB3 @@ -76,7 +84,7 @@ class filespec /** * Cleans destination filename - * + * * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename * @param string $prefix Prefix applied to filename * @access public @@ -269,9 +277,9 @@ class filespec { case 'copy': - if (!@copy($this->filename, $this->destination_file)) + if (!@copy($this->filename, $this->destination_file)) { - if (!@move_uploaded_file($this->filename, $this->destination_file)) + if (!@move_uploaded_file($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); return false; @@ -284,9 +292,9 @@ class filespec case 'move': - if (!@move_uploaded_file($this->filename, $this->destination_file)) + if (!@move_uploaded_file($this->filename, $this->destination_file)) { - if (!@copy($this->filename, $this->destination_file)) + if (!@copy($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); return false; @@ -299,7 +307,7 @@ class filespec case 'local': - if (!@copy($this->filename, $this->destination_file)) + if (!@copy($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); return false; @@ -577,7 +585,7 @@ class fileupload if (function_exists('mime_content_type')) { - $mimetype = mime_content_type($filename); + $mimetype = mime_content_type($source_file); } // Some browsers choke on a mimetype of application/octet-stream @@ -653,7 +661,7 @@ class fileupload $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); return $file; } - + if (empty($match[2])) { $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']); @@ -813,7 +821,7 @@ class fileupload // check Filename if (preg_match("#[\\/:*?\"<>|]#i", $file->get('realname'))) - { + { $file->error[] = sprintf($user->lang[$this->error_prefix . 'INVALID_FILENAME'], $file->get('realname')); } @@ -842,8 +850,8 @@ class fileupload return true; } - if (($file->get('width') > $this->max_width && $this->max_width) || - ($file->get('height') > $this->max_height && $this->max_height) || + if (($file->get('width') > $this->max_width && $this->max_width) || + ($file->get('height') > $this->max_height && $this->max_height) || ($file->get('width') < $this->min_width && $this->min_width) || ($file->get('height') < $this->min_height && $this->min_height)) { @@ -862,7 +870,7 @@ class fileupload } /** - * Return image type/extension mapping + * Return image type/extension mapping */ function image_types() { diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index fed783e880..8501175d5f 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Obtain user_ids from usernames or vice versa. Returns false on * success else the error string * @@ -208,6 +216,8 @@ function user_add($user_row, $cp_data = false) 'user_sig' => '', 'user_sig_bbcode_uid' => '', 'user_sig_bbcode_bitfield' => '', + + 'user_form_salt' => unique_id(), ); // Now fill the sql array with not required variables @@ -243,7 +253,7 @@ function user_add($user_row, $cp_data = false) include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); } - $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . + $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data)); $db->sql_query($sql); } @@ -525,7 +535,7 @@ function user_delete($mode, $user_id, $post_username = false) continue; } - $sql = 'UPDATE ' . USERS_TABLE . ' + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' WHERE user_id = ' . $_user_id; @@ -551,7 +561,7 @@ function user_delete($mode, $user_id, $post_username = false) /** * Flips user_type from active to inactive and vice versa, handles group membership updates -* +* * @param string $mode can be flip for flipping from active/inactive, activate or deactivate */ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) @@ -580,8 +590,8 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) { $sql_ary = array(); - if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER || - ($mode == 'activate' && $row['user_type'] != USER_INACTIVE) || + if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER || + ($mode == 'activate' && $row['user_type'] != USER_INACTIVE) || ($mode == 'deactivate' && $row['user_type'] == USER_INACTIVE)) { continue; @@ -672,7 +682,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas else { $ban_other = explode('-', $ban_len_other); - if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) && + if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) && (strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2)) { $ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0])); @@ -1112,6 +1122,13 @@ function user_ipwhois($ip) { $ipwhois = ''; + // Check IP + // Only supporting IPv4 at the moment... + if (empty($ip) || !preg_match(get_preg_expression('ipv4'), $ip)) + { + return ''; + } + $match = array( '#RIPE\.NET#is' => 'whois.ripe.net', '#whois\.apnic\.net#is' => 'whois.apnic.net', @@ -1147,7 +1164,10 @@ function user_ipwhois($ip) } } - return $ipwhois; + $ipwhois = htmlspecialchars($ipwhois); + + // Magic URL ;) + return trim(make_clickable($ipwhois, false, '')); } /** @@ -1975,14 +1995,14 @@ function avatar_gallery($category, $avatar_select, $items_per_column, $block_var while (($file = readdir($dp)) !== false) { - if ($file[0] != '.' && is_dir("$path/$file")) + if ($file[0] != '.' && preg_match('#^[^&"\'<>]+$#i', $file) && is_dir("$path/$file")) { $avatar_row_count = $avatar_col_count = 0; $dp2 = @opendir("$path/$file"); while (($sub_file = readdir($dp2)) !== false) { - if (preg_match('#^[^&"<>]*\.(?:gif|png|jpe?g)$#i', $sub_file)) + if (preg_match('#^[^&\'"<>]+\.(?:gif|png|jpe?g)$#i', $sub_file)) { $avatar_list[$file][$avatar_row_count][$avatar_col_count] = array( 'file' => "$file/$sub_file", @@ -2198,7 +2218,7 @@ function avatar_process_user(&$error, $custom_userdata = false) } } } - if (($config['avatar_max_width'] || $config['avatar_max_height']) && + if (($config['avatar_max_width'] || $config['avatar_max_height']) && (($data['width'] != $userdata['user_avatar_width']) || $data['height'] != $userdata['user_avatar_height'])) { if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height']) @@ -2294,7 +2314,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow { $error[] = $user->lang[$err]; } - + if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE))) { $error[] = $user->lang['GROUP_ERR_TYPE']; @@ -2404,7 +2424,6 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow if (sizeof($sql_ary) && sizeof($user_ary)) { group_set_user_default($group_id, $user_ary, $sql_ary); - } $name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name; @@ -2450,7 +2469,7 @@ function avatar_remove_db($avatar_name) $sql = 'UPDATE ' . USERS_TABLE . " SET user_avatar = '', - user_avatar_type = 0 + user_avatar_type = 0 WHERE user_avatar = '" . $db->sql_escape($avatar_name) . '\''; $db->sql_query($sql); } @@ -2778,14 +2797,14 @@ function remove_default_avatar($group_id, $user_ids) } $db->sql_freeresult($result); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_avatar = \'\', - user_avatar_type = 0, - user_avatar_width = 0, - user_avatar_height = 0 - WHERE group_id = ' . (int)$group_id . ' - AND user_avatar = \'' . $db->sql_escape($row['group_avatar']) . '\' - AND ' . $db->sql_in_set('user_id', $user_ids); + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_avatar = '', + user_avatar_type = 0, + user_avatar_width = 0, + user_avatar_height = 0 + WHERE group_id = " . (int) $group_id . " + AND user_avatar = '" . $db->sql_escape($row['group_avatar']) . "' + AND " . $db->sql_in_set('user_id', $user_ids); $db->sql_query($sql); } @@ -2821,9 +2840,9 @@ function remove_default_rank($group_id, $user_ids) $sql = 'UPDATE ' . USERS_TABLE . ' SET user_rank = 0 - WHERE group_id = ' . (int)$group_id . ' - AND user_rank <> 0 - AND user_rank = ' . (int)$row['group_rank'] . ' + WHERE group_id = ' . (int)$group_id . ' + AND user_rank <> 0 + AND user_rank = ' . (int)$row['group_rank'] . ' AND ' . $db->sql_in_set('user_id', $user_ids); $db->sql_query($sql); } @@ -2916,7 +2935,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna break; case 'default': - $sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . ' + $sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $user_id_ary, false, true); $result = $db->sql_query($sql); @@ -2958,7 +2977,7 @@ function group_validate_groupname($group_id, $group_name) { global $config, $db; - $group_name = utf8_clean_string($group_name); + $group_name = utf8_clean_string($group_name); if (!empty($group_id)) { @@ -3035,8 +3054,6 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal $db->sql_freeresult($result); } - - foreach ($attribute_ary as $attribute => $type) { if (isset($group_attributes[$attribute])) diff --git a/phpBB/includes/hooks/index.php b/phpBB/includes/hooks/index.php new file mode 100644 index 0000000000..aa85e63f32 --- /dev/null +++ b/phpBB/includes/hooks/index.php @@ -0,0 +1,250 @@ +<?php +/** +* +* @package phpBB3 +* @version $Id$ +* @copyright (c) 2007 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* phpBB Hook Class +* @package phpBB3 +*/ +class phpbb_hook +{ + /** + * Registered hooks + */ + var $hooks = array(); + + /** + * Results returned by functions called + */ + var $hook_result = array(); + + /** + * internal pointer + */ + var $current_hook = NULL; + + /** + * Initialize hook class. + * + * @param array $valid_hooks array containing the hookable functions/methods + */ + function phpbb_hook($valid_hooks) + { + foreach ($valid_hooks as $_null => $method) + { + $this->add_hook($method); + } + + if (function_exists('phpbb_hook_register')) + { + phpbb_hook_register($this); + } + } + + /** + * Register function/method to be called within hook + * This function is normally called by the modification/application to attach/register the functions. + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + * @param mixed $hook The replacement function/method to be called. Passing function name or array with object/class definition + * @param string $mode Specify the priority/chain mode. 'normal' -> hook gets appended to the chain. 'standalone' -> only the specified hook gets called - later hooks are not able to overwrite this (E_NOTICE is triggered then). 'first' -> hook is called as the first one within the chain. 'last' -> hook is called as the last one within the chain. + */ + function register($definition, $hook, $mode = 'normal') + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + // Method able to be hooked? + if (isset($this->hooks[$class][$function])) + { + switch ($mode) + { + case 'standalone': + if (!isset($this->hooks[$class][$function]['standalone'])) + { + $this->hooks[$class][$function] = array('standalone' => $hook); + } + else + { + trigger_error('Hook not able to be called standalone, previous hook already standalone.', E_NOTICE); + } + break; + + case 'first': + case 'last': + $this->hooks[$class][$function][$mode][] = $hook; + break; + + case 'normal': + default: + $this->hooks[$class][$function]['normal'][] = $hook; + break; + } + } + } + + /** + * Calling all functions/methods attached to a specified hook. + * Called by the function allowing hooks... + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + * @return bool False if no hook got executed, true otherwise + */ + function call_hook($definition) + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + if (!empty($this->hooks[$class][$function])) + { + // Developer tries to call a hooked function within the hooked function... + if ($this->current_hook !== NULL && $this->current_hook['class'] === $class && $this->current_hook['function'] === $function) + { + return false; + } + + // Call the hook with the arguments attached and store result + $arguments = func_get_args(); + $this->current_hook = array('class' => $class, 'function' => $function); + $arguments[0] = &$this; + + // Call the hook chain... + if (isset($this->hooks[$class][$function]['standalone'])) + { + $this->hook_result[$class][$function] = call_user_func_array($this->hooks[$class][$function]['standalone'], $arguments); + } + else + { + foreach (array('first', 'normal', 'last') as $mode) + { + if (!isset($this->hooks[$class][$function][$mode])) + { + continue; + } + + foreach ($this->hooks[$class][$function][$mode] as $hook) + { + $this->hook_result[$class][$function] = call_user_func_array($hook, $arguments); + } + } + } + + $this->current_hook = NULL; + return true; + } + + $this->current_hook = NULL; + return false; + } + + /** + * Get result from previously called functions/methods for the same hook + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + * @return mixed False if nothing returned if there is no result, else array('result' => ... ) + */ + function previous_hook_result($definition) + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function])) + { + return array('result' => $this->hook_result[$class][$function]); + } + + return false; + } + + /** + * Check if the called functions/methods returned something. + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + * @return bool True if results are there, false if not + */ + function hook_return($definition) + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function])) + { + return true; + } + + return false; + } + + /** + * Give actual result from called functions/methods back. + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + * @return mixed The result + */ + function hook_return_result($definition) + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function])) + { + $result = $this->hook_result[$class][$function]; + unset($this->hook_result[$class][$function]); + return $result; + } + + return; + } + + /** + * Add new function to the allowed hooks. + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + */ + function add_hook($definition) + { + if (!is_array($definition)) + { + $definition = array('__global', $definition); + } + + $this->hooks[$definition[0]][$definition[1]] = array(); + } + + /** + * Remove function from the allowed hooks. + * + * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__) + */ + function remove_hook($definition) + { + $class = (!is_array($definition)) ? '__global' : $definition[0]; + $function = (!is_array($definition)) ? $definition : $definition[1]; + + if (isset($this->hooks[$class][$function])) + { + unset($this->hooks[$class][$function]); + + if (isset($this->hook_result[$class][$function])) + { + unset($this->hook_result[$class][$function]); + } + } + } +} + +?>
\ No newline at end of file diff --git a/phpBB/includes/mcp/info/mcp_ban.php b/phpBB/includes/mcp/info/mcp_ban.php index 75b30174df..383df30498 100644 --- a/phpBB/includes/mcp/info/mcp_ban.php +++ b/phpBB/includes/mcp/info/mcp_ban.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_logs.php b/phpBB/includes/mcp/info/mcp_logs.php index 5c3764a615..fe2f9fa1d7 100644 --- a/phpBB/includes/mcp/info/mcp_logs.php +++ b/phpBB/includes/mcp/info/mcp_logs.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_main.php b/phpBB/includes/mcp/info/mcp_main.php index 4833819168..9755cdfc07 100644 --- a/phpBB/includes/mcp/info/mcp_main.php +++ b/phpBB/includes/mcp/info/mcp_main.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_notes.php b/phpBB/includes/mcp/info/mcp_notes.php index 693bd62218..afe232e5b5 100644 --- a/phpBB/includes/mcp/info/mcp_notes.php +++ b/phpBB/includes/mcp/info/mcp_notes.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_queue.php b/phpBB/includes/mcp/info/mcp_queue.php index ee8b48f1aa..7a256642b9 100644 --- a/phpBB/includes/mcp/info/mcp_queue.php +++ b/phpBB/includes/mcp/info/mcp_queue.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_reports.php b/phpBB/includes/mcp/info/mcp_reports.php index 56987c18e9..3893ba5abb 100644 --- a/phpBB/includes/mcp/info/mcp_reports.php +++ b/phpBB/includes/mcp/info/mcp_reports.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/info/mcp_warn.php b/phpBB/includes/mcp/info/mcp_warn.php index d53f35e00d..2b0b09f75a 100644 --- a/phpBB/includes/mcp/info/mcp_warn.php +++ b/phpBB/includes/mcp/info/mcp_warn.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php index d7c1b28b77..cb6211abda 100644 --- a/phpBB/includes/mcp/mcp_ban.php +++ b/phpBB/includes/mcp/mcp_ban.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * @package mcp */ class mcp_ban @@ -35,7 +43,6 @@ class mcp_ban // Ban submitted? if ($bansubmit) { - // Grab the list of entries $ban = request_var('ban', '', ($mode === 'user') ? true : false); @@ -49,7 +56,6 @@ class mcp_ban $ban_exclude = request_var('banexclude', 0); $ban_reason = utf8_normalize_nfc(request_var('banreason', '', true)); $ban_give_reason = utf8_normalize_nfc(request_var('bangivereason', '', true)); - if ($ban) { @@ -142,7 +148,7 @@ class mcp_ban 'S_USERNAME_BAN' => ($mode == 'user') ? true : false, 'U_ACTION' => $this->u_action, - 'U_FIND_USER' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_ban&field=ban'), + 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_ban&field=ban'), )); if ($mode != 'user') diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index d4c6f1f395..5f736e62b4 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * MCP Forum View */ function mcp_forum_view($id, $mode, $action, $forum_info) @@ -78,7 +86,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) } } - make_jumpbox($url . "&i=$id&action=$action&mode=$mode", $forum_id . (($merge_select) ? $selected_ids : ''), false, 'm_'); + make_jumpbox($url . "&i=$id&action=$action&mode=$mode" . (($merge_select) ? $selected_ids : ''), $forum_id, false, 'm_', true); $topics_per_page = ($forum_info['forum_topics_per_page']) ? $forum_info['forum_topics_per_page'] : $config['topics_per_page']; diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index de607df297..d67a51cd89 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * MCP Front Panel */ function mcp_front_view($id, $mode, $action) @@ -258,7 +266,7 @@ function mcp_front_view($id, $mode, $action) } $template->assign_var('S_MCP_ACTION', append_sid("{$phpbb_root_path}mcp.$phpEx")); - make_jumpbox(append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=forum_view'), 0, false, 'm_'); + make_jumpbox(append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=forum_view'), 0, false, 'm_', true); } ?>
\ No newline at end of file diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index d16cdf0196..6c20cf85b4 100755 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_logs * Handling warning the users * @package mcp diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index a08e0e8c1d..3332ab04d8 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_main * Handling mcp actions * @package mcp @@ -949,7 +957,7 @@ function mcp_fork_topic($topic_ids) if (!sizeof($topic_ids)) { - $additional_msg = $user->lang['NO_TOPICS_SELECTED']; + $additional_msg = $user->lang['NO_TOPIC_SELECTED']; } else if (!sizeof($forum_data)) { diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 391d41b6fb..42a64055ce 100755 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_notes * Displays notes about a user * @package mcp @@ -42,11 +50,10 @@ class mcp_notes case 'front': $template->assign_vars(array( 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true', false), 'U_POST_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes'), - 'L_TITLE' => $user->lang['MCP_NOTES']) - ); + 'L_TITLE' => $user->lang['MCP_NOTES'], + )); $this->tpl_name = 'mcp_notes_front'; break; @@ -75,6 +82,8 @@ class mcp_notes $sk = request_var('sk', 'b'); $sd = request_var('sd', 'd'); + add_form_key('mcp_notes'); + $sql_where = ($user_id) ? "user_id = $user_id" : "username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; $sql = 'SELECT * @@ -122,15 +131,22 @@ class mcp_notes if ($where_sql || $deleteall) { - $sql = 'DELETE FROM ' . LOG_TABLE . ' - WHERE log_type = ' . LOG_USERS . " - AND reportee_id = $user_id - $where_sql"; - $db->sql_query($sql); + if (check_form_key('mcp_notes')) + { + $sql = 'DELETE FROM ' . LOG_TABLE . ' + WHERE log_type = ' . LOG_USERS . " + AND reportee_id = $user_id + $where_sql"; + $db->sql_query($sql); - add_log('admin', 'LOG_CLEAR_USER', $userrow['username']); + add_log('admin', 'LOG_CLEAR_USER', $userrow['username']); - $msg = ($deletemark) ? 'MARKED_NOTES_DELETED' : 'ALL_NOTES_DELETED'; + $msg = ($deletemark) ? 'MARKED_NOTES_DELETED' : 'ALL_NOTES_DELETED'; + } + else + { + $msg = 'FORM_INVALID'; + } $redirect = $this->u_action . '&u=' . $user_id; meta_refresh(3, $redirect); trigger_error($user->lang[$msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); @@ -139,15 +155,22 @@ class mcp_notes if ($usernote && $action == 'add_feedback') { - add_log('admin', 'LOG_USER_FEEDBACK', $userrow['username']); - add_log('mod', 0, 0, 'LOG_USER_FEEDBACK', $userrow['username']); - - add_log('user', $user_id, 'LOG_USER_GENERAL', $usernote); + if (check_form_key('mcp_notes')) + { + add_log('admin', 'LOG_USER_FEEDBACK', $userrow['username']); + add_log('mod', 0, 0, 'LOG_USER_FEEDBACK', $userrow['username']); + add_log('user', $user_id, 'LOG_USER_GENERAL', $usernote); + $msg = $user->lang['USER_FEEDBACK_ADDED']; + } + else + { + $msg = $user->lang['FORM_INVALID']; + } $redirect = $this->u_action; meta_refresh(3, $redirect); - trigger_error($user->lang['USER_FEEDBACK_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); + trigger_error($msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); } // Generate the appropriate user information for the user we are looking at diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index dd10750d99..8f4630bf4c 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Handling actions in post details screen */ function mcp_post_details($id, $mode, $action) @@ -24,6 +32,8 @@ function mcp_post_details($id, $mode, $action) // Get post data $post_info = get_post_data(array($post_id), false, true); + add_form_key('mcp_post_details'); + if (!sizeof($post_info)) { trigger_error('POST_NOT_EXIST'); @@ -36,20 +46,18 @@ function mcp_post_details($id, $mode, $action) { case 'whois': - $ip = request_var('ip', ''); - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - - $whois = user_ipwhois($ip); - - $whois = preg_replace('#(\s)([\w\-\._\+]+@[\w\-\.]+)(\s)#', '\1<a href="mailto:\2">\2</a>\3', $whois); - $whois = preg_replace('#(\s)(ht{2}p:/{2}\S*)(\s)#', '\1<a href="\2">\2</a>\3', $whois); - - $template->assign_vars(array( - 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id") . '">', '</a>'), - 'U_RETURN_POST' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id"), - 'L_RETURN_POST' => sprintf($user->lang['RETURN_POST'], '', ''), - 'WHOIS' => trim($whois)) - ); + if ($auth->acl_get('m_info', $post_info['forum_id'])) + { + $ip = request_var('ip', ''); + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + + $template->assign_vars(array( + 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id") . '">', '</a>'), + 'U_RETURN_POST' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id"), + 'L_RETURN_POST' => sprintf($user->lang['RETURN_POST'], '', ''), + 'WHOIS' => user_ipwhois($ip), + )); + } // We're done with the whois page so return return; @@ -84,7 +92,14 @@ function mcp_post_details($id, $mode, $action) if ($auth->acl_get('m_chgposter', $post_info['forum_id'])) { - change_poster($post_info, $row); + if (check_form_key('mcp_post_details')) + { + change_poster($post_info, $row); + } + else + { + trigger_error('FORM_INVALID'); + } } break; @@ -178,7 +193,6 @@ function mcp_post_details($id, $mode, $action) 'U_EDIT' => ($auth->acl_get('m_edit', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f={$post_info['forum_id']}&p={$post_info['post_id']}") : '', 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_chgposter&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_chgposter&field=username&select_single=true', false), 'U_MCP_APPROVE' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&f=' . $post_info['forum_id'] . '&p=' . $post_id), 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&f=' . $post_info['forum_id'] . '&p=' . $post_id), 'U_MCP_USER_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $post_info['user_id']), @@ -304,7 +318,7 @@ function mcp_post_details($id, $mode, $action) if (sizeof($users_ary)) { // Get the usernames - $sql = 'SELECT user_id, username + $sql = 'SELECT user_id, username FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', array_keys($users_ary)); $result = $db->sql_query($sql); @@ -406,7 +420,7 @@ function change_poster(&$post_info, $userdata) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - 1 - WHERE user_id = ' . $post_info['user_id'] .' + WHERE user_id = ' . $post_info['user_id'] .' AND user_posts > 0'; $db->sql_query($sql); diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 0d2ea76498..6d7f9ffaba 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_queue * Handling the moderation queue * @package mcp diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 9528eec33b..0faa1dc8b7 100755 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_reports * Handling the reports queue * @package mcp @@ -298,7 +306,7 @@ class mcp_reports $forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>'; foreach ($forum_list_reports as $row) { - $forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . $row['forum_name'] . '</option>'; + $forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat(' ', $row['padding']) . $row['forum_name'] . '</option>'; $forum_data[$row['forum_id']] = $row; } unset($forum_list_reports); diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 1002b1c918..f8214e4f1b 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * View topic in MCP */ function mcp_topic_view($id, $mode, $action) @@ -34,12 +42,13 @@ function mcp_topic_view($id, $mode, $action) $icon_id = request_var('icon', 0); $subject = utf8_normalize_nfc(request_var('subject', '', true)); $start = request_var('start', 0); + $sort_days_old = request_var('st_old', 0); $forum_id = request_var('f', 0); $to_topic_id = request_var('to_topic_id', 0); $to_forum_id = request_var('to_forum_id', 0); $post_id_list = request_var('post_id_list', array(0)); $sort = isset($_POST['sort']) ? true : false; - + // Split Topic? if ($action == 'split_all' || $action == 'split_beyond') { @@ -84,7 +93,7 @@ function mcp_topic_view($id, $mode, $action) } // Jumpbox, sort selects and that kind of things - make_jumpbox($url . "&i=$id&mode=forum_view", $topic_info['forum_id'], false, 'm_'); + make_jumpbox($url . "&i=$id&mode=forum_view", $topic_info['forum_id'], false, 'm_', true); $where_sql = ($action == 'reports') ? 'WHERE post_reported = 1 AND ' : 'WHERE'; $sort_days = $total = 0; @@ -104,6 +113,10 @@ function mcp_topic_view($id, $mode, $action) { $posts_per_page = $total; } + if (!empty($sort_days_old) && $sort_days_old != $sort_days) + { + $start = 0; + } $sql = 'SELECT u.username, u.username_clean, u.user_colour, p.* FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u @@ -264,6 +277,10 @@ function mcp_topic_view($id, $mode, $action) } } + $s_hidden_fields = build_hidden_fields(array( + 'st_old' => $sort_days, + )); + $template->assign_vars(array( 'TOPIC_TITLE' => $topic_info['topic_title'], 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_info['forum_id'] . '&t=' . $topic_info['topic_id']), @@ -290,10 +307,12 @@ function mcp_topic_view($id, $mode, $action) 'S_MERGE_VIEW' => ($action == 'merge') ? true : false, 'S_SPLIT_VIEW' => ($action == 'split') ? true : false, + 'S_HIDDEN_FIELDS' => $s_hidden_fields, + 'S_SHOW_TOPIC_ICONS' => $s_topic_icons, 'S_TOPIC_ICON' => $icon_id, - 'U_SELECT_TOPIC' => "$url&i=$id&mode=forum_view&action=merge_select", + 'U_SELECT_TOPIC' => "$url&i=$id&mode=forum_view&action=merge_select" . (($forum_id) ? "&f=$forum_id" : ''), 'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_info['forum_id']}&t={$topic_info['topic_id']}&start=$start") . '">', '</a>'), 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$topic_info['forum_id']}&start=$start") . '">', '</a>'), diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index 892929539f..cab102f1f7 100755 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package mcp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * mcp_warn * Handling warning the users * @package mcp @@ -37,6 +45,8 @@ class mcp_warn $this->page_title = 'MCP_WARN'; + add_form_key('mcp_warn'); + switch ($mode) { case 'front': @@ -71,7 +81,6 @@ class mcp_warn $template->assign_vars(array( 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp&field=username&select_single=true', false), 'U_POST_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user'), )); @@ -194,7 +203,7 @@ class mcp_warn $warning = utf8_normalize_nfc(request_var('warning', '', true)); $sql = 'SELECT u.*, p.* - FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u WHERE post_id = $post_id AND u.user_id = p.poster_id"; $result = $db->sql_query($sql); @@ -242,8 +251,15 @@ class mcp_warn if ($warning && $action == 'add_warning') { - add_warning($user_row, $warning, $notify, $post_id); - + if (check_form_key('mcp_warn')) + { + add_warning($user_row, $warning, $notify, $post_id); + $msg = $user->lang['USER_WARNING_ADDED']; + } + else + { + $msg = $user->lang['FORM_INVALID']; + } $redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=notes&mode=user_notes&u=$user_id"); meta_refresh(2, $redirect); trigger_error($user->lang['USER_WARNING_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); @@ -337,11 +353,18 @@ class mcp_warn if ($warning && $action == 'add_warning') { - add_warning($user_row, $warning, $notify); - + if (check_form_key('mcp_warn')) + { + add_warning($user_row, $warning, $notify); + $msg = $user->lang['USER_WARNING_ADDED']; + } + else + { + $msg = $user->lang['FORM_INVALID']; + } $redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=notes&mode=user_notes&u=$user_id"); meta_refresh(2, $redirect); - trigger_error($user->lang['USER_WARNING_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); + trigger_error($msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); } // Generate the appropriate user information for the user we are looking at @@ -423,7 +446,7 @@ function add_warning($user_row, $warning, $send_pm = true, $post_id = 0) $db->sql_query('INSERT INTO ' . WARNINGS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); - $sql = 'UPDATE ' . USERS_TABLE . ' + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_warnings = user_warnings + 1, user_last_warning = ' . time() . ' WHERE user_id = ' . $user_row['user_id']; diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index d2e54e1404..311c75b410 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -672,6 +672,11 @@ class bbcode_firstpass extends bbcode { global $config, $user; + /** + * If you change this code, make sure the cases described within the following reports are still working: + * #3572, #14667 + */ + $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in))); if (!$in) @@ -801,12 +806,19 @@ class bbcode_firstpass extends bbcode { // Search the text for the next tok... if an ending quote comes first, then change tok to [] $pos1 = strpos($in, '[/quote'); + // If the token ] comes first, we change it to ] $pos2 = strpos($in, ']'); + // If the token [ comes first, we change it to [ + $pos3 = strpos($in, '['); - if ($pos1 !== false && ($pos2 === false || $pos1 < $pos2)) + if ($pos1 !== false && ($pos2 === false || $pos1 < $pos2) && ($pos3 === false || $pos1 < $pos3)) { $tok = '[]'; } + else if ($pos3 !== false && ($pos2 === false || $pos3 < $pos2)) + { + $tok = '['; + } else { $tok = ']'; @@ -875,7 +887,7 @@ class bbcode_firstpass extends bbcode * Validate url * * @param string $var1 optional url parameter for url bbcode: [url(=$var1)]$var2[/url] - * @param string $var2 url bbcode content: [url(=$var1)]$var2[/url] + * @param string $var2 url bbcode content: [url(=$var1)]$var2[/url] */ function validate_url($var1, $var2) { @@ -921,7 +933,7 @@ class bbcode_firstpass extends bbcode $url = append_sid($url); } - return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']'; + return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']'; } return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]'; @@ -967,7 +979,7 @@ class bbcode_firstpass extends bbcode if ($pos_domain !== false && $pos_path >= $pos_domain && $pos_ext >= $pos_path) { // Ok, actually we allow linking to some files (this may be able to be extended in some way later...) - if (strpos($url, '/' . $check_path . '/download.' . $phpEx) !== 0) + if (strpos($url, '/' . $check_path . '/download/file.' . $phpEx) !== 0) { return false; } @@ -1006,7 +1018,7 @@ class parse_message extends bbcode_firstpass function parse_message($message = '') { // Init BBCode UID - $this->bbcode_uid = substr(md5(time()), 0, BBCODE_UID_LEN); + $this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN); if ($message) { @@ -1048,8 +1060,8 @@ class parse_message extends bbcode_firstpass $replace = array("\\1:"); $this->message = preg_replace($match, $replace, trim($this->message)); - // Message length check. -1 disables this check completely. - if ($config['max_' . $mode . '_chars'] != -1) + // Message length check. 0 disables this check completely. + if ($config['max_' . $mode . '_chars'] > 0) { $msg_len = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message)); @@ -1060,6 +1072,13 @@ class parse_message extends bbcode_firstpass } } + // Check for "empty" message + if (!utf8_clean_string($this->message)) + { + $this->warn_msg[] = $user->lang['TOO_FEW_CHARS']; + return $this->warn_msg; + } + // Prepare BBcode (just prepares some tags for better parsing) if ($allow_bbcode && strpos($this->message, '[') !== false) { @@ -1221,20 +1240,20 @@ class parse_message extends bbcode_firstpass { case 'mssql': case 'mssql_odbc': - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY LEN(code) DESC'; break; case 'firebird': - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY CHAR_LENGTH(code) DESC'; break; // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure... default: - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY LENGTH(code) DESC'; break; diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 38022a21c4..91d70d074e 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -9,6 +9,7 @@ */ /** +* @ignore */ if (!defined('IN_PHPBB')) { diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index ac3fc14f4f..bfcb02f8e6 100755 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package search * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { diff --git a/phpBB/includes/search/search.php b/phpBB/includes/search/search.php index f4a1ddac27..32d7ed595f 100755 --- a/phpBB/includes/search/search.php +++ b/phpBB/includes/search/search.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package search * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -249,7 +250,7 @@ class search_backend } $cache->put('_search_results_' . $search_key, $store, $config['search_store_results']); - $sql = 'UPDATE ' . SEARCH_RESULTS_TABLE . ' + $sql = 'UPDATE ' . SEARCH_RESULTS_TABLE . ' SET search_time = ' . time() . ' WHERE search_key = \'' . $db->sql_escape($search_key) . '\''; $db->sql_query($sql); diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index a029388101..6ddc97fff8 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Session class * @package phpBB3 */ @@ -51,18 +59,28 @@ class session $script_name = str_replace(array('\\', '//'), '/', $script_name); // Now, remove the sid and let us get a clean query string... + $use_args = array(); + + // Since some browser do not encode correctly we need to do this with some "special" characters... + // " -> %22, ' => %27, < -> %3C, > -> %3E + $find = array('"', "'", '<', '>'); + $replace = array('%22', '%27', '%3C', '%3E'); + foreach ($args as $key => $argument) { if (strpos($argument, 'sid=') === 0 || strpos($argument, '_f_=') === 0) { - unset($args[$key]); + continue; } + + $use_args[str_replace($find, $replace, $key)] = str_replace($find, $replace, $argument); } + unset($args); // The following examples given are for an request uri of {path to the phpbb directory}/adm/index.php?i=10&b=2 // The current query string - $query_string = trim(implode('&', $args)); + $query_string = trim(implode('&', $use_args)); // basenamed page name (for example: index.php) $page_name = basename($script_name); @@ -148,18 +166,12 @@ class session { $this->forwarded_for = preg_replace('#, +#', ', ', $this->forwarded_for); - // Whoa these look impressive! - // The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses - // can be found in the develop directory - $ipv4 = '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#'; - $ipv6 = '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){5}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:))$#i'; - // split the list of IPs $ips = explode(', ', $this->forwarded_for); foreach ($ips as $ip) { // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly - if (!empty($ip) && !preg_match($ipv4, $ip) && !preg_match($ipv6, $ip)) + if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) { // contains invalid data, don't use the forwarded for header $this->forwarded_for = ''; @@ -363,7 +375,7 @@ class session foreach ($active_bots as $row) { - if ($row['bot_agent'] && strpos(strtolower($this->browser), strtolower($row['bot_agent'])) !== false) + if ($row['bot_agent'] && preg_match('#' . str_replace('\*', '.*?', preg_quote($row['bot_agent'], '#')) . '#i', $this->browser)) { $bot = $row['user_id']; } @@ -637,6 +649,24 @@ class session $this->set_cookie('sid', $this->session_id, $cookie_expire); unset($cookie_expire); + + $sql = 'SELECT COUNT(session_id) AS sessions + FROM ' . SESSIONS_TABLE . ' + WHERE session_user_id = ' . (int) $this->data['user_id'] . ' + AND session_time >= ' . ($this->time_now - $config['form_token_lifetime']); + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if ((int) $row['sessions'] <= 1 || empty($this->data['user_form_salt'])) + { + $this->data['user_form_salt'] = unique_id(); + // Update the form key + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\' + WHERE user_id = ' . (int) $this->data['user_id']; + $db->sql_query($sql); + } } else { @@ -746,6 +776,8 @@ class session { global $db, $config; + $batch_size = 10; + if (!$this->time_now) { $this->time_now = time(); @@ -762,7 +794,7 @@ class session FROM ' . SESSIONS_TABLE . ' WHERE session_time < ' . ($this->time_now - $config['session_length']) . ' GROUP BY session_user_id, session_page'; - $result = $db->sql_query_limit($sql, 10); + $result = $db->sql_query_limit($sql, $batch_size); $del_user_id = array(); $del_sessions = 0; @@ -788,23 +820,55 @@ class session $db->sql_query($sql); } - if ($del_sessions < 10) + if ($del_sessions < $batch_size) { - // Less than 10 sessions, update gc timer ... else we want gc + // Less than 10 users, update gc timer ... else we want gc // called again to delete other sessions set_config('session_last_gc', $this->time_now, true); + + if ($config['max_autologin_time']) + { + $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' + WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time'])); + $db->sql_query($sql); + } + $this->confirm_gc(); } + + return; + } + + function confirm_gc($type = 0) + { + global $db, $config; + + $sql = 'SELECT DISTINCT c.session_id + FROM ' . CONFIRM_TABLE . ' c + LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) + WHERE s.session_id IS NULL' . + ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type); + $result = $db->sql_query($sql); - if ($config['max_autologin_time']) + if ($row = $db->sql_fetchrow($result)) { - $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' - WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time'])); - $db->sql_query($sql); - } + $sql_in = array(); + do + { + $sql_in[] = (string) $row['session_id']; + } + while ($row = $db->sql_fetchrow($result)); - return; + if (sizeof($sql_in)) + { + $sql = 'DELETE FROM ' . CONFIRM_TABLE . ' + WHERE ' . $db->sql_in_set('session_id', $sql_in); + $db->sql_query($sql); + } + } + $db->sql_freeresult($result); } - + + /** * Sets a cookie * @@ -921,7 +985,7 @@ class session { $ban_triggered_by = 'user'; } - else if (!empty($row['ban_ip']) && preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ips)) + else if ($ip_banned) { $ban_triggered_by = 'ip'; } @@ -1284,7 +1348,7 @@ class user extends session else { // Set up style - $style = ($style) ? $style : ((!$config['override_user_style'] && $this->data['user_id'] != ANONYMOUS) ? $this->data['user_style'] : $config['default_style']); + $style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']); } $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name @@ -1480,6 +1544,10 @@ class user extends session } } + // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes... + // After calling it we continue script execution... + phpbb_user_session_handler(); + // If this function got called from the error handler we are finished here. if (defined('IN_ERROR_HANDLER')) { diff --git a/phpBB/includes/template.php b/phpBB/includes/template.php index b13dbaa99a..2e60beb658 100644 --- a/phpBB/includes/template.php +++ b/phpBB/includes/template.php @@ -1,14 +1,15 @@ <?php -/** +/** * * @package phpBB3 * @version $Id$ * @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore */ if (!defined('IN_PHPBB')) { @@ -147,7 +148,15 @@ class template */ function display($handle, $include_once = true) { - global $user; + global $user, $phpbb_hook; + + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, __FUNCTION__), $handle, $include_once)) + { + if ($phpbb_hook->hook_return(array(__CLASS__, __FUNCTION__))) + { + return $phpbb_hook->hook_return_result(array(__CLASS__, __FUNCTION__)); + } + } if (defined('IN_ERROR_HANDLER')) { @@ -400,10 +409,10 @@ class template * * If key is false the position is set to 0 * If key is true the position is set to the last entry - * + * * @param string $mode Mode to execute (valid modes are 'insert' and 'change') * - * If insert, the vararray is inserted at the given position (position counting from zero). + * If insert, the vararray is inserted at the given position (position counting from zero). * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). * * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) diff --git a/phpBB/includes/ucp/info/ucp_attachments.php b/phpBB/includes/ucp/info/ucp_attachments.php index a6aa393da5..84edce446c 100644 --- a/phpBB/includes/ucp/info/ucp_attachments.php +++ b/phpBB/includes/ucp/info/ucp_attachments.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_groups.php b/phpBB/includes/ucp/info/ucp_groups.php index a9bdfc2847..2002123c50 100644 --- a/phpBB/includes/ucp/info/ucp_groups.php +++ b/phpBB/includes/ucp/info/ucp_groups.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_main.php b/phpBB/includes/ucp/info/ucp_main.php index a0c89606a3..722b7865e6 100644 --- a/phpBB/includes/ucp/info/ucp_main.php +++ b/phpBB/includes/ucp/info/ucp_main.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_pm.php b/phpBB/includes/ucp/info/ucp_pm.php index cfe19bd619..ade12005c0 100644 --- a/phpBB/includes/ucp/info/ucp_pm.php +++ b/phpBB/includes/ucp/info/ucp_pm.php @@ -2,8 +2,8 @@ /** * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_prefs.php b/phpBB/includes/ucp/info/ucp_prefs.php index 53a012ea3c..58359e8a19 100644 --- a/phpBB/includes/ucp/info/ucp_prefs.php +++ b/phpBB/includes/ucp/info/ucp_prefs.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_profile.php b/phpBB/includes/ucp/info/ucp_profile.php index 86b731c280..03a4c81f46 100644 --- a/phpBB/includes/ucp/info/ucp_profile.php +++ b/phpBB/includes/ucp/info/ucp_profile.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/info/ucp_zebra.php b/phpBB/includes/ucp/info/ucp_zebra.php index 0d2edddcf9..5fc1f8bee7 100644 --- a/phpBB/includes/ucp/info/ucp_zebra.php +++ b/phpBB/includes/ucp/info/ucp_zebra.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index 6b17b28ba0..134729ffe9 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_activate * User activation * @package ucp diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index b20e4a55ed..2732879913 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_attachments * User attachments * @package ucp @@ -31,6 +39,24 @@ class ucp_attachments if ($delete && sizeof($delete_ids)) { + // Validate $delete_ids... + $sql = 'SELECT attach_id + FROM ' . ATTACHMENTS_TABLE . ' + WHERE poster_id = ' . $user->data['user_id'] . ' + AND is_orphan = 0 + AND ' . $db->sql_in_set('attach_id', $delete_ids); + $result = $db->sql_query($sql); + + $delete_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_ids[] = $row['attach_id']; + } + $db->sql_freeresult($result); + } + + if ($delete && sizeof($delete_ids)) + { $s_hidden_fields = array( 'delete' => 1 ); @@ -46,6 +72,7 @@ class ucp_attachments { include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } + delete_attachments('attach', $delete_ids); meta_refresh(3, $this->u_action); @@ -94,7 +121,7 @@ class ucp_attachments $db->sql_freeresult($result); $sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title - FROM ' . ATTACHMENTS_TABLE . ' a + FROM ' . ATTACHMENTS_TABLE . ' a LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0) LEFT JOIN ' . PRIVMSGS_TABLE . ' p ON (a.post_msg_id = p.msg_id AND a.in_message = 1) WHERE a.poster_id = ' . $user->data['user_id'] . " @@ -134,30 +161,30 @@ class ucp_attachments 'S_IN_MESSAGE' => $row['in_message'], - 'U_VIEW_ATTACHMENT' => append_sid("{$phpbb_root_path}download.$phpEx", 'id=' . $row['attach_id']), + 'U_VIEW_ATTACHMENT' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $row['attach_id']), 'U_VIEW_TOPIC' => $view_topic) ); $row_count++; - } + } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); - $template->assign_vars(array( + $template->assign_vars(array( 'PAGE_NUMBER' => on_page($num_attachments, $config['topics_per_page'], $start), 'PAGINATION' => generate_pagination($this->u_action . "&sk=$sort_key&sd=$sort_dir", $num_attachments, $config['topics_per_page'], $start), 'TOTAL_ATTACHMENTS' => $num_attachments, 'L_TITLE' => $user->lang['UCP_ATTACHMENTS'], - 'U_SORT_FILENAME' => $this->u_action . "&sk=a&sd=" . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_FILE_COMMENT' => $this->u_action . "&sk=b&sd=" . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_EXTENSION' => $this->u_action . "&sk=c&sd=" . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_FILESIZE' => $this->u_action . "&sk=d&sd=" . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_DOWNLOADS' => $this->u_action . "&sk=e&sd=" . (($sort_key == 'e' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_POST_TIME' => $this->u_action . "&sk=f&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_TOPIC_TITLE' => $this->u_action . "&sk=g&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_FILENAME' => $this->u_action . "&sk=a&sd=" . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_FILE_COMMENT' => $this->u_action . "&sk=b&sd=" . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_EXTENSION' => $this->u_action . "&sk=c&sd=" . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_FILESIZE' => $this->u_action . "&sk=d&sd=" . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_DOWNLOADS' => $this->u_action . "&sk=e&sd=" . (($sort_key == 'e' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_POST_TIME' => $this->u_action . "&sk=f&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_TOPIC_TITLE' => $this->u_action . "&sk=g&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), 'S_DISPLAY_MARK_ALL' => ($num_attachments) ? true : false, 'S_DISPLAY_PAGINATION' => ($num_attachments) ? true : false, diff --git a/phpBB/includes/ucp/ucp_confirm.php b/phpBB/includes/ucp/ucp_confirm.php index e971dbb3ae..0f37c456fa 100644 --- a/phpBB/includes/ucp/ucp_confirm.php +++ b/phpBB/includes/ucp/ucp_confirm.php @@ -1,21 +1,29 @@ <?php -/** +/** * * @package VC * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_confirm * Visual confirmation * * Note to potential users of this code ... * * Remember this is released under the _GPL_ and is subject -* to that licence. Do not incorporate this within software +* to that licence. Do not incorporate this within software * released or distributed in any way under a licence other * than the GPL. We will be watching ... ;) * @@ -40,8 +48,8 @@ class ucp_confirm // Try and grab code for this id and session $sql = 'SELECT code, seed - FROM ' . CONFIRM_TABLE . " - WHERE session_id = '" . $db->sql_escape($user->session_id) . "' + FROM ' . CONFIRM_TABLE . " + WHERE session_id = '" . $db->sql_escape($user->session_id) . "' AND confirm_id = '" . $db->sql_escape($confirm_id) . "' AND confirm_type = $type"; $result = $db->sql_query($sql); diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 44b5498ca7..a4fc818343 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_groups * @package ucp */ @@ -393,11 +401,12 @@ class ucp_groups $this->page_title = 'UCP_USERGROUPS_MANAGE'; $action = (isset($_POST['addusers'])) ? 'addusers' : request_var('action', ''); $group_id = request_var('g', 0); + add_form_key('ucp_groups'); if ($group_id) { - $sql = 'SELECT * - FROM ' . GROUPS_TABLE . " + $sql = 'SELECT * + FROM ' . GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $group_row = $db->sql_fetchrow($result); @@ -479,10 +488,10 @@ class ucp_groups { // Avatar stuff $var_ary = array( - 'uploadurl' => array('string', true, 5, 255), - 'remotelink' => array('string', true, 5, 255), - 'width' => array('string', true, 1, 3), - 'height' => array('string', true, 1, 3), + 'uploadurl' => array('string', true, 5, 255), + 'remotelink' => array('string', true, 5, 255), + 'width' => array('string', true, 1, 3), + 'height' => array('string', true, 1, 3), ); if (!($error = validate_data($data, $var_ary))) @@ -552,10 +561,15 @@ class ucp_groups } } + if (!check_form_key('ucp_groups')) + { + $error[] = $user->lang['FORM_INVALID']; + } + if (!sizeof($error)) { // Only set the rank, colour, etc. if it's changed or if we're adding a new - // group. This prevents existing group members being updated if no changes + // group. This prevents existing group members being updated if no changes // were made. $group_attributes = array(); @@ -609,7 +623,7 @@ class ucp_groups $group_rank = $group_row['group_rank']; } - $sql = 'SELECT * + $sql = 'SELECT * FROM ' . RANKS_TABLE . ' WHERE rank_special = 1 ORDER BY rank_title'; @@ -636,6 +650,9 @@ class ucp_groups { avatar_gallery($category, $avatar_select, 4); } + + $avatars_enabled = ($can_upload || ($config['allow_avatar_local'] || $config['allow_avatar_remote'])) ? true : false; + $template->assign_vars(array( 'S_EDIT' => true, @@ -644,6 +661,7 @@ class ucp_groups 'S_FORM_ENCTYPE' => ($can_upload) ? ' enctype="multipart/form-data"' : '', 'S_ERROR' => (sizeof($error)) ? true : false, 'S_SPECIAL_GROUP' => ($group_type == GROUP_SPECIAL) ? true : false, + 'S_AVATARS_ENABLED' => $avatars_enabled, 'S_DISPLAY_GALLERY' => ($config['allow_avatar_local'] && !$display_gallery) ? true : false, 'S_IN_GALLERY' => ($config['allow_avatar_local'] && $display_gallery) ? true : false, @@ -678,7 +696,6 @@ class ucp_groups 'GROUP_HIDDEN' => $type_hidden, 'U_SWATCH' => append_sid("{$phpbb_root_path}adm/swatch.$phpEx", 'form=ucp&name=group_colour'), - 'UA_SWATCH' => append_sid("{$phpbb_root_path}adm/swatch.$phpEx", 'form=ucp&name=group_colour', false), 'S_UCP_ACTION' => $this->u_action . "&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], round($config['avatar_filesize'] / 1024))) ); @@ -707,9 +724,9 @@ class ucp_groups $start = request_var('start', 0); // Grab the leaders - always, on every page... - $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug - WHERE ug.group_id = $group_id + $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug + WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 1 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; @@ -731,18 +748,18 @@ class ucp_groups $db->sql_freeresult($result); // Total number of group members (non-leaders) - $sql = 'SELECT COUNT(user_id) AS total_members - FROM ' . USER_GROUP_TABLE . " - WHERE group_id = $group_id + $sql = 'SELECT COUNT(user_id) AS total_members + FROM ' . USER_GROUP_TABLE . " + WHERE group_id = $group_id AND group_leader = 0"; $result = $db->sql_query($sql); $total_members = (int) $db->sql_fetchfield('total_members'); $db->sql_freeresult($result); // Grab the members - $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending - FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug - WHERE ug.group_id = $group_id + $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending + FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug + WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 0 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; @@ -790,8 +807,7 @@ class ucp_groups 'U_ACTION' => $this->u_action . "&g=$group_id", 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=usernames'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=usernames', false)) - ); + )); break; @@ -850,9 +866,9 @@ class ucp_groups do { - $sql = 'SELECT user_id + $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . " - WHERE group_id = $group_id + WHERE group_id = $group_id ORDER BY user_id"; $result = $db->sql_query_limit($sql, 200, $start); diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index ba40397a55..c2fa50c79e 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_main * UCP Front Panel * @package ucp @@ -38,7 +46,7 @@ class ucp_main if ($config['load_db_track']) { - $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.topic_id = t.topic_id + $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.topic_id = t.topic_id AND tp.user_id = ' . $user->data['user_id'] . ')'; $sql_select .= ', tp.topic_posted'; } @@ -59,7 +67,7 @@ class ucp_main $forum_ary = array_unique(array_keys($forum_ary)); // Determine first forum the user is able to read into - for global announcement link - $sql = 'SELECT forum_id + $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST; @@ -71,7 +79,7 @@ class ucp_main $g_forum_id = (int) $db->sql_fetchfield('forum_id'); $db->sql_freeresult($result); - $sql = "SELECT t.* $sql_select + $sql = "SELECT t.* $sql_select FROM $sql_from WHERE t.forum_id = 0 AND t.topic_type = " . POST_GLOBAL . ' @@ -164,13 +172,13 @@ class ucp_main display_user_activity($user->data); } - // Do the relevant calculations + // Do the relevant calculations $memberdays = max(1, round((time() - $user->data['user_regdate']) / 86400)); $posts_per_day = $user->data['user_posts'] / $memberdays; $percentage = ($config['num_posts']) ? min(100, ($user->data['user_posts'] / $config['num_posts']) * 100) : 0; $template->assign_vars(array( - 'USER_COLOR' => (!empty($user->data['user_colour'])) ? $user->data['user_colour'] : '', + 'USER_COLOR' => (!empty($user->data['user_colour'])) ? $user->data['user_colour'] : '', 'JOINED' => $user->format_date($user->data['user_regdate']), 'VISITED' => (empty($last_visit)) ? ' - ' : $user->format_date($last_visit), 'WARNINGS' => ($user->data['user_warnings']) ? $user->data['user_warnings'] : 0, @@ -181,7 +189,7 @@ class ucp_main 'OCCUPATION' => (!empty($row['user_occ'])) ? $row['user_occ'] : '', 'INTERESTS' => (!empty($row['user_interests'])) ? $row['user_interests'] : '', -// 'S_GROUP_OPTIONS' => $group_options, +// 'S_GROUP_OPTIONS' => $group_options, 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user->data['user_id'] . '&sr=posts') : '', )); @@ -194,41 +202,51 @@ class ucp_main $user->add_lang('viewforum'); + add_form_key('ucp_front_subscribed'); + $unwatch = (isset($_POST['unwatch'])) ? true : false; if ($unwatch) { - $forums = array_keys(request_var('f', array(0 => 0))); - $topics = array_keys(request_var('t', array(0 => 0))); - - if (sizeof($forums) || sizeof($topics)) + if (check_form_key('ucp_front_subscribed')) { - $l_unwatch = ''; - if (sizeof($forums)) - { - $sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . ' - WHERE ' . $db->sql_in_set('forum_id', $forums) . ' - AND user_id = ' . $user->data['user_id']; - $db->sql_query($sql); + $forums = array_keys(request_var('f', array(0 => 0))); + $topics = array_keys(request_var('t', array(0 => 0))); + $msg = ''; - $l_unwatch .= '_FORUMS'; - } - - if (sizeof($topics)) + if (sizeof($forums) || sizeof($topics)) { - $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topics) . ' - AND user_id = ' . $user->data['user_id']; - $db->sql_query($sql); + $l_unwatch = ''; + if (sizeof($forums)) + { + $sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . ' + WHERE ' . $db->sql_in_set('forum_id', $forums) . ' + AND user_id = ' . $user->data['user_id']; + $db->sql_query($sql); + + $l_unwatch .= '_FORUMS'; + } + + if (sizeof($topics)) + { + $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topics) . ' + AND user_id = ' . $user->data['user_id']; + $db->sql_query($sql); + + $l_unwatch .= '_TOPICS'; + } + $msg = $user->lang['UNWATCHED' . $l_unwatch]; - $l_unwatch .= '_TOPICS'; } - - $message = $user->lang['UNWATCHED' . $l_unwatch] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=subscribed") . '">', '</a>'); - - meta_refresh(3, append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=subscribed")); - trigger_error($message); } + else + { + $msg = $user->lang['FORM_INVALID']; + } + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=subscribed") . '">', '</a>'); + meta_refresh(3, append_sid("{$phpbb_root_path}ucp.$phpEx", "i=$id&mode=subscribed")); + trigger_error($message); } $forbidden_forums = array(); @@ -246,7 +264,7 @@ class ucp_main FORUMS_TABLE => 'f' ), - 'WHERE' => 'fw.user_id = ' . $user->data['user_id'] . ' + 'WHERE' => 'fw.user_id = ' . $user->data['user_id'] . ' AND f.forum_id = fw.forum_id AND ' . $db->sql_in_set('f.forum_id', $forbidden_forums, true, true), @@ -312,7 +330,7 @@ class ucp_main } $template->assign_block_vars('forumrow', array( - 'FORUM_ID' => $forum_id, + 'FORUM_ID' => $forum_id, 'FORUM_FOLDER_IMG' => $user->img($folder_image, $folder_alt), 'FORUM_FOLDER_IMG_SRC' => $user->img($folder_image, $folder_alt, false, '', 'src'), 'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang[$folder_alt] . '" />' : '', @@ -326,7 +344,7 @@ class ucp_main 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), - 'U_LAST_POST' => $last_post_url, + 'U_LAST_POST' => $last_post_url, 'U_VIEWFORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id'])) ); } @@ -418,53 +436,65 @@ class ucp_main $s_hidden_fields = ($edit) ? '<input type="hidden" name="edit" value="' . $draft_id . '" />' : ''; $draft_subject = $draft_message = ''; + add_form_key('ucp_draft'); if ($delete) { - $drafts = array_keys(request_var('d', array(0 => 0))); - - if (sizeof($drafts)) + if (check_form_key('ucp_draft')) { - $sql = 'DELETE FROM ' . DRAFTS_TABLE . ' - WHERE ' . $db->sql_in_set('draft_id', $drafts) . ' - AND user_id = ' . $user->data['user_id']; - $db->sql_query($sql); - - $message = $user->lang['DRAFTS_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + $drafts = array_keys(request_var('d', array(0 => 0))); - meta_refresh(3, $this->u_action); - trigger_error($message); + if (sizeof($drafts)) + { + $sql = 'DELETE FROM ' . DRAFTS_TABLE . ' + WHERE ' . $db->sql_in_set('draft_id', $drafts) . ' + AND user_id = ' . $user->data['user_id']; + $db->sql_query($sql); + } + $msg = $user->lang['DRAFTS_DELETED']; + unset($drafts); } - - unset($drafts); + else + { + $msg = $user->lang['FORM_INVALID']; + } + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + meta_refresh(3, $this->u_action); + trigger_error($message); } if ($submit && $edit) { $draft_subject = utf8_normalize_nfc(request_var('subject', '', true)); $draft_message = utf8_normalize_nfc(request_var('message', '', true)); - - if ($draft_message && $draft_subject) + if (check_form_key('ucp_draft')) { - $draft_row = array( - 'draft_subject' => $draft_subject, - 'draft_message' => $draft_message - ); - - $sql = 'UPDATE ' . DRAFTS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $draft_row) . " - WHERE draft_id = $draft_id - AND user_id = " . $user->data['user_id']; - $db->sql_query($sql); + if ($draft_message && $draft_subject) + { + $draft_row = array( + 'draft_subject' => $draft_subject, + 'draft_message' => $draft_message + ); + + $sql = 'UPDATE ' . DRAFTS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $draft_row) . " + WHERE draft_id = $draft_id + AND user_id = " . $user->data['user_id']; + $db->sql_query($sql); - $message = $user->lang['DRAFT_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + $message = $user->lang['DRAFT_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); - meta_refresh(3, $this->u_action); - trigger_error($message); + meta_refresh(3, $this->u_action); + trigger_error($message); + } + else + { + $template->assign_var('ERROR', ($draft_message == '') ? $user->lang['EMPTY_DRAFT'] : (($draft_subject == '') ? $user->lang['EMPTY_DRAFT_TITLE'] : '')); + } } else { - $template->assign_var('ERROR', ($draft_message == '') ? $user->lang['EMPTY_DRAFT'] : (($draft_subject == '') ? $user->lang['EMPTY_DRAFT_TITLE'] : '')); + $template->assign_var('ERROR', $user->lang['FORM_INVALID']); } } @@ -482,7 +512,7 @@ class ucp_main $sql = 'SELECT * FROM ' . DRAFTS_TABLE . ' WHERE user_id = ' . $user->data['user_id'] . ' ' . (($edit) ? "AND draft_id = $draft_id" : '') . ' - AND forum_id = 0 + AND forum_id = 0 AND topic_id = 0 ORDER BY save_time DESC'; } @@ -578,10 +608,10 @@ class ucp_main } - $template->assign_vars(array( + $template->assign_vars(array( 'L_TITLE' => $user->lang['UCP_MAIN_' . strtoupper($mode)], - 'S_DISPLAY_MARK_ALL' => ($mode == 'watched' || ($mode == 'drafts' && !isset($_GET['edit']))) ? true : false, + 'S_DISPLAY_MARK_ALL' => ($mode == 'watched' || ($mode == 'drafts' && !isset($_GET['edit']))) ? true : false, 'S_HIDDEN_FIELDS' => (isset($s_hidden_fields)) ? $s_hidden_fields : '', 'S_UCP_ACTION' => $this->u_action, diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php index 63660b006d..e843e89139 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -7,7 +7,15 @@ * */ -/** +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Private Message Class * * $_REQUEST['folder'] display folder with the id used @@ -95,7 +103,7 @@ class ucp_pm $template->assign_vars(array( 'MESSAGE' => $l_new_message, 'S_NOT_LOGGED_IN' => ($user->data['user_id'] == ANONYMOUS) ? true : false, - 'CLICK_TO_VIEW' => sprintf($user->lang['CLICK_VIEW_PRIVMSG'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox') . '" onclick="jump_to_inbox(); return false;">', '</a>'), + 'CLICK_TO_VIEW' => sprintf($user->lang['CLICK_VIEW_PRIVMSG'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox') . '" onclick="jump_to_inbox(this.href); return false;">', '</a>'), 'U_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), 'UA_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox', false)) ); @@ -245,10 +253,10 @@ class ucp_pm if ($user->data['user_new_privmsg'] && $action == 'view_folder') { $return = place_pm_into_folder($global_privmsgs_rules, request_var('release', 0)); - $num_not_moved = $user->data['user_new_privmsg']; + $num_not_moved = $return['not_moved']; // Make sure num_not_moved is valid. - if ($num_not_moved < 0) + if ($user->data['user_new_privmsg'] < 0 || $num_not_moved < 0) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new_privmsg = 0, user_unread_privmsg = 0 @@ -271,7 +279,7 @@ class ucp_pm $sql = 'SELECT folder_id FROM ' . PRIVMSGS_TO_TABLE . " WHERE msg_id = $msg_id - AND folder_id <> " . PRIVMSGS_NO_BOX . ' + AND folder_id <> " . PRIVMSGS_NO_BOX . ' AND user_id = ' . $user->data['user_id']; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 20086e605e..ff5ab13716 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Compose private message * Called from ucp_pm with mode == 'compose' */ @@ -25,6 +33,7 @@ function compose_pm($id, $mode, $action) { $action = 'post'; } + add_form_key('ucp_pm_compose'); // Grab only parameters needed here $to_user_id = request_var('u', 0); @@ -105,8 +114,7 @@ function compose_pm($id, $mode, $action) 'S_ALLOW_MASS_PM' => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? true : false, 'S_GROUP_OPTIONS' => ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? $group_options : '', 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=searchuser&form=postform&field=username_list&select_single=$select_single"), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=searchuser&form=postform&field=username_list&select_single=$select_single", false)) - ); + )); } $sql = ''; @@ -533,6 +541,10 @@ function compose_pm($id, $mode, $action) if ($submit || $preview || $refresh) { + if (!check_form_key('ucp_pm_compose')) + { + $error[] = $user->lang['FORM_INVALID']; + } $subject = utf8_normalize_nfc(request_var('subject', '', true)); $message_parser->message = utf8_normalize_nfc(request_var('message', '', true)); @@ -605,7 +617,7 @@ function compose_pm($id, $mode, $action) $pm_data = array( 'msg_id' => (int) $msg_id, 'from_user_id' => $user->data['user_id'], - 'from_user_ip' => $user->data['user_ip'], + 'from_user_ip' => $user->ip, 'from_username' => $user->data['username'], 'reply_from_root_level' => (isset($post['root_level'])) ? (int) $post['root_level'] : 0, 'reply_from_msg_id' => (int) $msg_id, @@ -630,7 +642,7 @@ function compose_pm($id, $mode, $action) $return_folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=outbox'); meta_refresh(3, $return_message_url); - $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>') . '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $return_folder_url . '">', '</a>', $user->lang['PM_OUTBOX']); + $message = $user->lang['MESSAGE_STORED'] . '<br /><br />' . sprintf($user->lang['VIEW_PRIVATE_MESSAGE'], '<a href="' . $return_message_url . '">', '</a>') . '<br /><br />' . sprintf($user->lang['CLICK_RETURN_FOLDER'], '<a href="' . $return_folder_url . '">', '</a>', $user->lang['PM_OUTBOX']); trigger_error($message); } @@ -969,9 +981,8 @@ function compose_pm($id, $mode, $action) 'S_CLOSE_PROGRESS_WINDOW' => isset($_POST['add_file']), 'U_PROGRESS_BAR' => append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&mode=popup'), - 'UA_PROGRESS_BAR' => append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&mode=popup', false), - ) - ); + 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", 'f=0&mode=popup')), + )); // Build custom bbcodes array display_custom_bbcodes(); diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php index b4f2cbeb65..2d2ff23cab 100644 --- a/phpBB/includes/ucp/ucp_pm_options.php +++ b/phpBB/includes/ucp/ucp_pm_options.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Execute message options */ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_conditions) @@ -17,9 +25,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $redirect_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=options"); + add_form_key('ucp_pm_options'); // Change "full folder" setting - what to do if folder is full if (isset($_POST['fullfolder'])) { + check_form_key('ucp_pm_options', $config['form_token_lifetime'], $redirect_url); $full_action = request_var('full_action', 0); $set_folder_id = 0; @@ -60,79 +70,96 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit // Add Folder if (isset($_POST['addfolder'])) { - $folder_name = utf8_normalize_nfc(request_var('foldername', '', true)); - - if ($folder_name) + if (check_form_key('ucp_pm_options')) { - $sql = 'SELECT folder_name - FROM ' . PRIVMSGS_FOLDER_TABLE . " - WHERE folder_name = '" . $db->sql_escape($folder_name) . "' - AND user_id = " . $user->data['user_id']; - $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $folder_name = utf8_normalize_nfc(request_var('foldername', '', true)); + $msg = ''; - if ($row) + if ($folder_name) { - trigger_error(sprintf($user->lang['FOLDER_NAME_EXIST'], $folder_name)); - } + $sql = 'SELECT folder_name + FROM ' . PRIVMSGS_FOLDER_TABLE . " + WHERE folder_name = '" . $db->sql_escape($folder_name) . "' + AND user_id = " . $user->data['user_id']; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - $sql = 'SELECT COUNT(folder_id) as num_folder - FROM ' . PRIVMSGS_FOLDER_TABLE . ' - WHERE user_id = ' . $user->data['user_id']; - $result = $db->sql_query($sql); - $num_folder = (int) $db->sql_fetchfield('num_folder'); - $db->sql_freeresult($result); + if ($row) + { + trigger_error(sprintf($user->lang['FOLDER_NAME_EXIST'], $folder_name)); + } - if ($num_folder >= $config['pm_max_boxes']) - { - trigger_error('MAX_FOLDER_REACHED'); - } + $sql = 'SELECT COUNT(folder_id) as num_folder + FROM ' . PRIVMSGS_FOLDER_TABLE . ' + WHERE user_id = ' . $user->data['user_id']; + $result = $db->sql_query($sql); + $num_folder = (int) $db->sql_fetchfield('num_folder'); + $db->sql_freeresult($result); - $sql = 'INSERT INTO ' . PRIVMSGS_FOLDER_TABLE . ' ' . $db->sql_build_array('INSERT', array( - 'user_id' => (int) $user->data['user_id'], - 'folder_name' => $folder_name) - ); - $db->sql_query($sql); + if ($num_folder >= $config['pm_max_boxes']) + { + trigger_error('MAX_FOLDER_REACHED'); + } - $message = $user->lang['FOLDER_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); - meta_refresh(3, $redirect_url); - trigger_error($message); + $sql = 'INSERT INTO ' . PRIVMSGS_FOLDER_TABLE . ' ' . $db->sql_build_array('INSERT', array( + 'user_id' => (int) $user->data['user_id'], + 'folder_name' => $folder_name) + ); + $db->sql_query($sql); + $msg = $user->lang['FOLDER_ADDED']; + } + } + else + { + $msg = $user->lang['FORM_INVALID']; } + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); + meta_refresh(3, $redirect_url); + trigger_error($message); } // Rename folder if (isset($_POST['rename_folder'])) { - $new_folder_name = utf8_normalize_nfc(request_var('new_folder_name', '', true)); - $rename_folder_id= request_var('rename_folder_id', 0); - - if (!$new_folder_name) + if (check_form_key('ucp_pm_options')) { - trigger_error('NO_NEW_FOLDER_NAME'); - } + $new_folder_name = utf8_normalize_nfc(request_var('new_folder_name', '', true)); + $rename_folder_id= request_var('rename_folder_id', 0); - // Select custom folder - $sql = 'SELECT folder_name, pm_count - FROM ' . PRIVMSGS_FOLDER_TABLE . " - WHERE user_id = {$user->data['user_id']} - AND folder_id = $rename_folder_id"; - $result = $db->sql_query_limit($sql, 1); - $folder_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + if (!$new_folder_name) + { + trigger_error('NO_NEW_FOLDER_NAME'); + } - if (!$folder_row) + // Select custom folder + $sql = 'SELECT folder_name, pm_count + FROM ' . PRIVMSGS_FOLDER_TABLE . " + WHERE user_id = {$user->data['user_id']} + AND folder_id = $rename_folder_id"; + $result = $db->sql_query_limit($sql, 1); + $folder_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$folder_row) + { + trigger_error('CANNOT_RENAME_FOLDER'); + } + + $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . " + SET folder_name = '" . $db->sql_escape($new_folder_name) . "' + WHERE folder_id = $rename_folder_id + AND user_id = {$user->data['user_id']}"; + $db->sql_query($sql); + $msg = $user->lang['FOLDER_RENAMED']; + } + else { - trigger_error('CANNOT_RENAME_FOLDER'); + $msg = $user->lang['FORM_INVALID']; } - $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . " - SET folder_name = '" . $db->sql_escape($new_folder_name) . "' - WHERE folder_id = $rename_folder_id - AND user_id = {$user->data['user_id']}"; - $db->sql_query($sql); + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); - $message = $user->lang['FOLDER_RENAMED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); meta_refresh(3, $redirect_url); trigger_error($message); } @@ -177,7 +204,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit if (confirm_box(true)) { // Gather message ids - $sql = 'SELECT msg_id + $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . ' WHERE user_id = ' . $user->data['user_id'] . " AND folder_id = $remove_folder_id"; @@ -251,60 +278,68 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit // Add Rule if (isset($_POST['add_rule'])) { - $check_option = request_var('check_option', 0); - $rule_option = request_var('rule_option', 0); - $cond_option = request_var('cond_option', ''); - $action_option = explode('|', request_var('action_option', '')); - $rule_string = ($cond_option != 'none') ? utf8_normalize_nfc(request_var('rule_string', '', true)) : ''; - $rule_user_id = ($cond_option != 'none') ? request_var('rule_user_id', 0) : 0; - $rule_group_id = ($cond_option != 'none') ? request_var('rule_group_id', 0) : 0; - - $action = (int) $action_option[0]; - $folder_id = (int) $action_option[1]; - - if (!$action || !$check_option || !$rule_option || !$cond_option || ($cond_option != 'none' && !$rule_string)) + if (check_form_key('ucp_pm_options')) { - trigger_error('RULE_NOT_DEFINED'); - } + $check_option = request_var('check_option', 0); + $rule_option = request_var('rule_option', 0); + $cond_option = request_var('cond_option', ''); + $action_option = explode('|', request_var('action_option', '')); + $rule_string = ($cond_option != 'none') ? utf8_normalize_nfc(request_var('rule_string', '', true)) : ''; + $rule_user_id = ($cond_option != 'none') ? request_var('rule_user_id', 0) : 0; + $rule_group_id = ($cond_option != 'none') ? request_var('rule_group_id', 0) : 0; + + $action = (int) $action_option[0]; + $folder_id = (int) $action_option[1]; + + if (!$action || !$check_option || !$rule_option || !$cond_option || ($cond_option != 'none' && !$rule_string)) + { + trigger_error('RULE_NOT_DEFINED'); + } - if (($cond_option == 'user' && !$rule_user_id) || ($cond_option == 'group' && !$rule_group_id)) - { - trigger_error('RULE_NOT_DEFINED'); - } + if (($cond_option == 'user' && !$rule_user_id) || ($cond_option == 'group' && !$rule_group_id)) + { + trigger_error('RULE_NOT_DEFINED'); + } - $rule_ary = array( - 'user_id' => $user->data['user_id'], - 'rule_check' => $check_option, - 'rule_connection' => $rule_option, - 'rule_string' => $rule_string, - 'rule_user_id' => $rule_user_id, - 'rule_group_id' => $rule_group_id, - 'rule_action' => $action, - 'rule_folder_id' => $folder_id - ); + $rule_ary = array( + 'user_id' => $user->data['user_id'], + 'rule_check' => $check_option, + 'rule_connection' => $rule_option, + 'rule_string' => $rule_string, + 'rule_user_id' => $rule_user_id, + 'rule_group_id' => $rule_group_id, + 'rule_action' => $action, + 'rule_folder_id' => $folder_id + ); - $sql = 'SELECT rule_id - FROM ' . PRIVMSGS_RULES_TABLE . ' - WHERE ' . $db->sql_build_array('SELECT', $rule_ary); - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $sql = 'SELECT rule_id + FROM ' . PRIVMSGS_RULES_TABLE . ' + WHERE ' . $db->sql_build_array('SELECT', $rule_ary); + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - if ($row) - { - trigger_error('RULE_ALREADY_DEFINED'); - } + if ($row) + { + trigger_error('RULE_ALREADY_DEFINED'); + } - $sql = 'INSERT INTO ' . PRIVMSGS_RULES_TABLE . ' ' . $db->sql_build_array('INSERT', $rule_ary); - $db->sql_query($sql); + $sql = 'INSERT INTO ' . PRIVMSGS_RULES_TABLE . ' ' . $db->sql_build_array('INSERT', $rule_ary); + $db->sql_query($sql); - // Update users message rules - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_message_rules = 1 - WHERE user_id = ' . $user->data['user_id']; - $db->sql_query($sql); + // Update users message rules + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_message_rules = 1 + WHERE user_id = ' . $user->data['user_id']; + $db->sql_query($sql); - $message = $user->lang['RULE_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); + $msg = $user->lang['RULE_ADDED']; + } + else + { + $msg = $user->lang['FORM_INVALID']; + } + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $redirect_url . '">', '</a>'); meta_refresh(3, $redirect_url); trigger_error($message); } @@ -332,7 +367,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $message = $user->lang['RULE_DELETED']; // Reset user_message_rules if no more assigned - $sql = 'SELECT rule_id + $sql = 'SELECT rule_id FROM ' . PRIVMSGS_RULES_TABLE . ' WHERE user_id = ' . $user->data['user_id']; $result = $db->sql_query_limit($sql, 1); @@ -369,11 +404,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $db->sql_freeresult($result); $folder[PRIVMSGS_INBOX] = array( - 'folder_name' => $user->lang['PM_INBOX'], + 'folder_name' => $user->lang['PM_INBOX'], 'message_status' => sprintf($user->lang['FOLDER_MESSAGE_STATUS'], $num_messages, $user->data['message_limit']) ); - $sql = 'SELECT folder_id, folder_name, pm_count + $sql = 'SELECT folder_id, folder_name, pm_count FROM ' . PRIVMSGS_FOLDER_TABLE . ' WHERE user_id = ' . $user->data['user_id']; $result = $db->sql_query($sql); @@ -383,7 +418,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit { $num_user_folder++; $folder[$row['folder_id']] = array( - 'folder_name' => $row['folder_name'], + 'folder_name' => $row['folder_name'], 'message_status' => sprintf($user->lang['FOLDER_MESSAGE_STATUS'], $row['pm_count'], $user->data['message_limit']) ); } @@ -443,8 +478,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit 'DEFAULT_ACTION' => ($config['full_folder_action'] == 1) ? $user->lang['DELETE_OLDEST_MESSAGES'] : $user->lang['HOLD_NEW_MESSAGES'], 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=rule_string&select_single=true'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=rule_string&select_single=true', false)) - ); + )); $rule_lang = $action_lang = $check_lang = array(); @@ -533,7 +567,7 @@ function define_check_option($hardcoded, $check_option, $check_lang) { foreach ($check_lang as $value => $lang) { - $s_check_options .= '<option value="' . $value . '"' . (($value == $check_option) ? ' selected="selected"' : '') . '>' . $lang . '</option>'; + $s_check_options .= '<option value="' . $value . '"' . (($value == $check_option) ? ' selected="selected"' : '') . '>' . $lang . '</option>'; } } @@ -605,7 +639,7 @@ function define_rule_option($hardcoded, $rule_option, $rule_lang, $check_ary) { foreach ($check_ary as $value => $_check) { - $s_rule_options .= '<option value="' . $value . '"' . (($value == $rule_option) ? ' selected="selected"' : '') . '>' . $rule_lang[$value] . '</option>'; + $s_rule_options .= '<option value="' . $value . '"' . (($value == $rule_option) ? ' selected="selected"' : '') . '>' . $rule_lang[$value] . '</option>'; } } @@ -705,10 +739,10 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule case 'group': $rule_group_id = request_var('rule_group_id', 0); $rule_string = utf8_normalize_nfc(request_var('rule_string', '', true)); - + $sql = 'SELECT g.group_id, g.group_name, g.group_type FROM ' . GROUPS_TABLE . ' g '; - + if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) { $sql .= 'LEFT JOIN ' . USER_GROUP_TABLE . ' ug @@ -738,7 +772,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule $rule_string = (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']); } - $s_class = ($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : ''; + $s_class = ($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : ''; $s_selected = ($row['group_id'] == $rule_group_id) ? ' selected="selected"' : ''; $s_group_options .= '<option value="' . $row['group_id'] . '"' . $s_class . $s_selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>'; diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 79b663a39d..e9c337519a 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * View message folder * Called from ucp_pm with mode == 'view' && action == 'view_folder' */ @@ -132,7 +140,7 @@ function view_folder($id, $mode, $folder_id, $folder) { if ($ug_type == 'u') { - $sql = 'SELECT user_id as id, username as name, user_colour as colour + $sql = 'SELECT user_id as id, username as name, user_colour as colour FROM ' . USERS_TABLE . ' WHERE '; } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 492ce08b45..3f109b0771 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * View private message */ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) @@ -191,7 +199,14 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'EDITED_MESSAGE' => $l_edited_by, 'MESSAGE_ID' => $message_row['msg_id'], - 'U_INFO' => ($auth->acl_get('m_info') && $message_row['pm_forwarded']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'mode=pm_details&p=' . $message_row['msg_id'], true, $user->session_id) : '', + 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_info['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $author_id) : '', + 'U_WWW' => (!empty($user_info['user_website'])) ? $user_info['user_website'] : '', + 'U_ICQ' => ($user_info['user_icq']) ? 'http://www.icq.com/people/webmsg.php?to=' . urlencode($user_info['user_icq']) : '', + 'U_AIM' => ($user_info['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=aim&u=' . $author_id) : '', + 'U_YIM' => ($user_info['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($user_info['user_yim']) . '&.src=pg' : '', + 'U_MSN' => ($user_info['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=msnm&u=' . $author_id) : '', + 'U_JABBER' => ($user_info['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $author_id) : '', + 'U_DELETE' => ($auth->acl_get('u_pm_delete')) ? "$url&mode=compose&action=delete&f=$folder_id&p=" . $message_row['msg_id'] : '', 'U_EMAIL' => $user_info['email'], 'U_QUOTE' => ($auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&mode=compose&action=quote&f=$folder_id&p=" . $message_row['msg_id'] : '', diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index b0e8f098c2..3ce3ea73ed 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_prefs * Changing user preferences * @package ucp @@ -28,7 +36,7 @@ class ucp_prefs switch ($mode) { case 'personal': - + add_form_key('ucp_prefs_personal'); $data = array( 'notifymethod' => request_var('notifymethod', $user->data['user_notify_type']), 'dateformat' => request_var('dateformat', $user->data['user_dateformat'], true), @@ -55,6 +63,11 @@ class ucp_prefs 'tz' => array('num', false, -14, 14), )); + if (!check_form_key('ucp_prefs_personal')) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error)) { $user->optionset('popuppm', $data['popuppm']); @@ -140,6 +153,8 @@ class ucp_prefs case 'view': + add_form_key('ucp_prefs_view'); + $data = array( 'topic_sk' => request_var('topic_sk', (!empty($user->data['user_topic_sortby_type'])) ? $user->data['user_topic_sortby_type'] : 't'), 'topic_sd' => request_var('topic_sd', (!empty($user->data['user_topic_sortby_dir'])) ? $user->data['user_topic_sortby_dir'] : 'd'), @@ -166,6 +181,11 @@ class ucp_prefs 'post_sd' => array('string', false, 1, 1), )); + if (!check_form_key('ucp_prefs_view')) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error)) { $user->optionset('viewimg', $data['images']); @@ -276,25 +296,34 @@ class ucp_prefs 'sig' => request_var('sig', $user->optionget('attachsig')), 'notify' => request_var('notify', $user->data['user_notify']), ); + add_form_key('ucp_prefs_post'); if ($submit) { - $user->optionset('bbcode', $data['bbcode']); - $user->optionset('smilies', $data['smilies']); - $user->optionset('attachsig', $data['sig']); + if (check_form_key('ucp_prefs_post')) + { + $user->optionset('bbcode', $data['bbcode']); + $user->optionset('smilies', $data['smilies']); + $user->optionset('attachsig', $data['sig']); - $sql_ary = array( - 'user_options' => $user->data['user_options'], - 'user_notify' => $data['notify'], - ); + $sql_ary = array( + 'user_options' => $user->data['user_options'], + 'user_notify' => $data['notify'], + ); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE user_id = ' . $user->data['user_id']; - $db->sql_query($sql); + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE user_id = ' . $user->data['user_id']; + $db->sql_query($sql); + $msg = $user->lang['PREFERENCES_UPDATED']; + } + else + { + $msg = $user->lang['FORM_INVALID']; + } meta_refresh(3, $this->u_action); - $message = $user->lang['PREFERENCES_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + $message = $msg . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); trigger_error($message); } diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 269c3aad44..3fe3d72d59 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_profile * Changing profile settings * @@ -44,6 +52,8 @@ class ucp_profile 'password_confirm' => request_var('password_confirm', '', true), ); + add_form_key('ucp_reg_details'); + if ($submit) { // Do not check cur_password, it is the old one. @@ -73,13 +83,13 @@ class ucp_profile $error[] = 'NEW_PASSWORD_ERROR'; } - if (($data['new_password'] || ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email']) || ($data['username'] != $user->data['username'] && $auth->acl_get('u_chgname') && $config['allow_namechange'])) && md5($data['cur_password']) != $user->data['user_password']) + if (($data['new_password'] || ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email']) || ($data['username'] != $user->data['username'] && $auth->acl_get('u_chgname') && $config['allow_namechange'])) && !phpbb_check_hash($data['cur_password'], $user->data['user_password'])) { $error[] = 'CUR_PASSWORD_ERROR'; } // Only check the new password against the previous password if there have been no errors - if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && md5($data['new_password']) == $user->data['user_password']) + if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && phpbb_check_hash($data['new_password'], $user->data['user_password'])) { $error[] = 'SAME_PASSWORD_ERROR'; } @@ -89,6 +99,11 @@ class ucp_profile $error[] = 'NEW_EMAIL_ERROR'; } + if (!check_form_key('ucp_reg_details')) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error)) { $sql_ary = array( @@ -96,7 +111,7 @@ class ucp_profile 'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'], 'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'], 'user_email_hash' => ($auth->acl_get('u_chgemail')) ? crc32($data['email']) . strlen($data['email']) : $user->data['user_email_hash'], - 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? md5($data['new_password']) : $user->data['user_password'], + 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? phpbb_hash($data['new_password']) : $user->data['user_password'], 'user_passchg' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? time() : 0, ); @@ -105,7 +120,7 @@ class ucp_profile add_log('user', $user->data['user_id'], 'LOG_USER_UPDATE_NAME', $user->data['username'], $data['username']); } - if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && md5($data['new_password']) != $user->data['user_password']) + if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !phpbb_check_hash($data['new_password'], $user->data['user_password'])) { $user->reset_login_keys(); add_log('user', $user->data['user_id'], 'LOG_USER_NEW_PASSWORD', $data['username']); @@ -224,7 +239,7 @@ class ucp_profile trigger_error($message); } - + // Replace "error" strings with their real, localised form $error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error); } @@ -282,6 +297,8 @@ class ucp_profile $data['bday_year'] = request_var('bday_year', $data['bday_year']); } + add_form_key('ucp_profile_info'); + if ($submit) { $validate_array = array( @@ -307,7 +324,7 @@ class ucp_profile $validate_array = array_merge($validate_array, array( 'bday_day' => array('num', true, 1, 31), 'bday_month' => array('num', true, 1, 12), - 'bday_year' => array('num', true, 1901, gmdate('Y', time())), + 'bday_year' => array('num', true, 1901, gmdate('Y', time()) + 50), )); } @@ -321,6 +338,11 @@ class ucp_profile $error = array_merge($error, $cp_error); } + if (!check_form_key('ucp_profile_info')) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error)) { $sql_ary = array( @@ -446,6 +468,8 @@ class ucp_profile $signature = utf8_normalize_nfc(request_var('signature', (string) $user->data['user_sig'], true)); + add_form_key('ucp_sig'); + if ($submit || $preview) { include($phpbb_root_path . 'includes/message_parser.' . $phpEx); @@ -462,6 +486,11 @@ class ucp_profile $error[] = implode('<br />', $message_parser->warn_msg); } + if (!check_form_key('ucp_sig')) + { + $error[] = 'FORM_INVALID'; + } + if (!sizeof($error) && $submit) { $sql_ary = array( @@ -470,8 +499,8 @@ class ucp_profile 'user_sig_bbcode_bitfield' => $message_parser->bbcode_bitfield ); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $user->data['user_id']; $db->sql_query($sql); @@ -517,7 +546,7 @@ class ucp_profile 'S_BBCODE_FLASH' => ($config['allow_sig_flash']) ? true : false, 'S_LINKS_ALLOWED' => ($config['allow_sig_links']) ? true : false) ); - + // Build custom bbcodes array display_custom_bbcodes(); @@ -533,15 +562,23 @@ class ucp_profile $can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $auth->acl_get('u_chgavatar') && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false; + add_form_key('ucp_avatar'); + if ($submit) { - if (avatar_process_user($error)) + if (check_form_key('ucp_avatar')) { - meta_refresh(3, $this->u_action); - $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); - trigger_error($message); + if (avatar_process_user($error)) + { + meta_refresh(3, $this->u_action); + $message = $user->lang['PROFILE_UPDATED'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + trigger_error($message); + } + } + else + { + $error[] = 'FORM_INVALID'; } - // Replace "error" strings with their real, localised form $error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error); } diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index ca44260760..91660020e9 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -9,6 +9,14 @@ */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_register * Board registration * @package ucp @@ -36,6 +44,24 @@ class ucp_register $change_lang = request_var('change_lang', ''); $user_lang = request_var('lang', $user->lang_name); + + // not so fast, buddy + if (($submit && !check_form_key('ucp_register', false, '', false, $config['min_time_reg'])) + || (!$submit && !check_form_key('ucp_register_terms', false, '', false, $config['min_time_terms']))) + { + $agreed = false; + } + + if ($agreed) + { + add_form_key('ucp_register'); + } + else + { + add_form_key('ucp_register_terms'); + } + + if ($change_lang || $user_lang != $config['default_lang']) { $use_lang = ($change_lang) ? basename($change_lang) : basename($user_lang); @@ -103,8 +129,8 @@ class ucp_register 'S_SHOW_COPPA' => true, 'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields), - 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang)) - ); + 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang), + )); } else { @@ -114,7 +140,9 @@ class ucp_register 'S_SHOW_COPPA' => false, 'S_REGISTRATION' => true, 'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields), - 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang . $add_coppa)) + 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang . $add_coppa), + 'S_TIME' => 1000 * ((int) $config['min_time_terms']), + ) ); } @@ -122,6 +150,7 @@ class ucp_register return; } + // Try to manually determine the timezone and adjust the dst if the server date/time complies with the default setting +/- 1 $timezone = date('Z') / 3600; $is_dst = date('I'); @@ -289,7 +318,7 @@ class ucp_register $user_row = array( 'username' => $data['username'], - 'user_password' => md5($data['new_password']), + 'user_password' => phpbb_hash($data['new_password']), 'user_email' => $data['email'], 'group_id' => (int) $group_id, 'user_timezone' => (float) $data['tz'], @@ -427,31 +456,8 @@ class ucp_register $str = ''; if (!$change_lang) { - $sql = 'SELECT DISTINCT c.session_id - FROM ' . CONFIRM_TABLE . ' c - LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) - WHERE s.session_id IS NULL'; - $result = $db->sql_query($sql); - - if ($row = $db->sql_fetchrow($result)) - { - $sql_in = array(); - do - { - $sql_in[] = (string) $row['session_id']; - } - while ($row = $db->sql_fetchrow($result)); - - if (sizeof($sql_in)) - { - $sql = 'DELETE FROM ' . CONFIRM_TABLE . ' - WHERE ' . $db->sql_in_set('session_id', $sql_in) . ' - AND confirm_type = ' . CONFIRM_REG; - $db->sql_query($sql); - } - } - $db->sql_freeresult($result); - + $user->confirm_gc(CONFIRM_REG); + $sql = 'SELECT COUNT(session_id) AS attempts FROM ' . CONFIRM_TABLE . " WHERE session_id = '" . $db->sql_escape($user->session_id) . "' @@ -522,7 +528,9 @@ class ucp_register 'S_CONFIRM_CODE' => ($config['enable_confirm']) ? true : false, 'S_COPPA' => $coppa, 'S_HIDDEN_FIELDS' => $s_hidden_fields, - 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register')) + 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'), + 'S_TIME' => 1000 * ((int) $config['min_time_reg']), + ) ); // diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index b761e772f6..12de817099 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_remind * Sending password reminders * @package ucp @@ -67,7 +75,7 @@ class ucp_remind $user_password = gen_rand_string(8); $sql = 'UPDATE ' . USERS_TABLE . " - SET user_newpasswd = '" . $db->sql_escape(md5($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' + SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' WHERE user_id = " . $user_row['user_id']; $db->sql_query($sql); diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php index 10a1b672bd..48176a3989 100644 --- a/phpBB/includes/ucp/ucp_resend.php +++ b/phpBB/includes/ucp/ucp_resend.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_resend * Resending activation emails * @package ucp @@ -26,8 +34,15 @@ class ucp_resend $email = strtolower(request_var('email', '')); $submit = (isset($_POST['submit'])) ? true : false; + add_form_key('ucp_resend'); + if ($submit) { + if (!check_form_key('ucp_resend')) + { + trigger_error('FORM_INVALID'); + } + $sql = 'SELECT user_id, group_id, username, user_email, user_type, user_lang, user_actkey, user_inactive_reason FROM ' . USERS_TABLE . " WHERE user_email = '" . $db->sql_escape($email) . "' @@ -120,7 +135,7 @@ class ucp_resend $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($user_row['username']), - 'U_USER_DETAILS' => generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&u={$user->data['user_id']}", + 'U_USER_DETAILS' => generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&u={$user_row['user_id']}", 'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k={$user_row['user_actkey']}") ); @@ -131,7 +146,8 @@ class ucp_resend meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx")); - $message = $user->lang['ACTIVATION_EMAIL_SENT'] . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>'); + $message = ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? $user->lang['ACIVATION_EMAIL_SENT_ADMIN'] : $user->lang['ACTIVATION_EMAIL_SENT']; + $message .= '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>'); trigger_error($message); } diff --git a/phpBB/includes/ucp/ucp_zebra.php b/phpBB/includes/ucp/ucp_zebra.php index 49ba7329be..fb5df9394b 100644 --- a/phpBB/includes/ucp/ucp_zebra.php +++ b/phpBB/includes/ucp/ucp_zebra.php @@ -1,14 +1,22 @@ <?php -/** +/** * * @package ucp * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * ucp_zebra * @package ucp */ @@ -49,11 +57,11 @@ class ucp_zebra $data['add'] = array_map('trim', array_map('utf8_clean_string', explode("\n", $data['add']))); // Do these name/s exist on a list already? If so, ignore ... we could be - // 'nice' and automatically handle names added to one list present on + // 'nice' and automatically handle names added to one list present on // the other (by removing the existing one) ... but I have a feeling this // may lead to complaints - $sql = 'SELECT z.*, u.username, u.username_clean - FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u + $sql = 'SELECT z.*, u.username, u.username_clean + FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u WHERE z.user_id = ' . $user->data['user_id'] . ' AND u.user_id = z.zebra_id'; $result = $db->sql_query($sql); @@ -104,7 +112,7 @@ class ucp_zebra if (sizeof($data['add'])) { $sql = 'SELECT user_id, user_type - FROM ' . USERS_TABLE . ' + FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('username_clean', $data['add']) . ' AND user_type <> ' . USER_INACTIVE; $result = $db->sql_query($sql); @@ -180,8 +188,8 @@ class ucp_zebra // Force integer values $data['usernames'] = array_map('intval', $data['usernames']); - $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' - WHERE user_id = ' . $user->data['user_id'] . ' + $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' + WHERE user_id = ' . $user->data['user_id'] . ' AND ' . $db->sql_in_set('zebra_id', $data['usernames']); $db->sql_query($sql); @@ -212,10 +220,10 @@ class ucp_zebra } $sql_and = ($mode == 'friends') ? 'z.friend = 1' : 'z.foe = 1'; - $sql = 'SELECT z.*, u.username, u.username_clean - FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u + $sql = 'SELECT z.*, u.username, u.username_clean + FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u WHERE z.user_id = ' . $user->data['user_id'] . " - AND $sql_and + AND $sql_and AND u.user_id = z.zebra_id ORDER BY u.username_clean ASC"; $result = $db->sql_query($sql); @@ -227,11 +235,10 @@ class ucp_zebra } $db->sql_freeresult($result); - $template->assign_vars(array( + $template->assign_vars(array( 'L_TITLE' => $user->lang['UCP_ZEBRA_' . $l_mode], 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=add'), - 'UA_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ucp&field=add', false), 'S_USERNAME_OPTIONS' => $s_username_options, 'S_HIDDEN_FIELDS' => $s_hidden_fields, diff --git a/phpBB/includes/utf/utf_normalizer.php b/phpBB/includes/utf/utf_normalizer.php index 4c705b05cb..a77952499a 100644 --- a/phpBB/includes/utf/utf_normalizer.php +++ b/phpBB/includes/utf/utf_normalizer.php @@ -1,14 +1,21 @@ <?php -/** +/** * * @package utf -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @version $Id$ +* @copyright (c) 2005 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ /** +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** * Some Unicode characters encoded in UTF-8 * * Preserved for compatibility diff --git a/phpBB/includes/utf/utf_tools.php b/phpBB/includes/utf/utf_tools.php index a3499062fe..77971f7e68 100644 --- a/phpBB/includes/utf/utf_tools.php +++ b/phpBB/includes/utf/utf_tools.php @@ -240,7 +240,7 @@ else /** * UTF-8 aware alternative to strrpos * Find position of last occurrence of a char in a string - * + * * @author Harry Fuecks * @param string $str haystack * @param string $needle needle @@ -329,7 +329,7 @@ else * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does * not exist in the Chinese alphabet, for example. See Unicode Standard * Annex #21: Case Mappings - * + * * @param string * @return string string in lowercase */ @@ -394,7 +394,7 @@ else * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does * not exist in the Chinese alphabet, for example. See Unicode Standard * Annex #21: Case Mappings - * + * * @param string * @return string string in uppercase */ @@ -614,7 +614,7 @@ else /** * UTF-8 aware alternative to str_split * Convert a string to an array -* +* * @author Harry Fuecks * @param string $str UTF-8 encoded * @param int $split_len number to characters to split string by @@ -640,7 +640,7 @@ function utf8_str_split($str, $split_len = 1) /** * UTF-8 aware alternative to strspn * Find length of initial segment matching the mask -* +* * @author Harry Fuecks */ function utf8_strspn($str, $mask, $start = null, $length = null) @@ -663,7 +663,7 @@ function utf8_strspn($str, $mask, $start = null, $length = null) /** * UTF-8 aware alternative to ucfirst * Make a string's first character uppercase -* +* * @author Harry Fuecks * @param string * @return string with first character as upper case (if applicable) |
