aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_board.php2
-rw-r--r--phpBB/includes/acp/acp_captcha.php2
-rw-r--r--phpBB/includes/acp/acp_profile.php35
-rw-r--r--phpBB/includes/acp/acp_ranks.php2
-rw-r--r--phpBB/includes/acp/acp_styles.php27
-rw-r--r--phpBB/includes/acp/acp_users.php57
-rw-r--r--phpBB/includes/db/dbal.php40
-rw-r--r--phpBB/includes/db/mysql.php70
-rw-r--r--phpBB/includes/db/mysqli.php70
-rw-r--r--phpBB/includes/functions.php21
-rw-r--r--phpBB/includes/functions_convert.php12
-rw-r--r--phpBB/includes/functions_messenger.php6
-rw-r--r--phpBB/includes/functions_posting.php14
-rw-r--r--phpBB/includes/functions_profile_fields.php11
-rw-r--r--phpBB/includes/search/fulltext_mysql.php8
-rw-r--r--phpBB/includes/search/fulltext_native.php15
-rw-r--r--phpBB/includes/search/search.php2
-rw-r--r--phpBB/includes/session.php57
-rw-r--r--phpBB/includes/ucp/ucp_register.php20
19 files changed, 353 insertions, 118 deletions
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 8c761e51fe..f437dca8f9 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -383,6 +383,8 @@ class acp_board
'referer_validation' => array('lang' => 'REFERER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true),
'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
+ 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true),
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index 1893eed14f..469a367bba 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -96,7 +96,7 @@ class acp_captcha
}
else if ($submit)
{
- trigger_error($user->lang['FORM_INVALID'] . adm_back_link(), E_USER_WARNING);
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
else
{
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index 2e43b0545a..a591474fce 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -504,11 +504,34 @@ class acp_profile
}
}
}
- /* else if ($field_type == FIELD_BOOL && $key == 'field_default_value')
+ else if ($field_type == FIELD_BOOL && $key == 'field_default_value')
{
- // Get the number of options if this key is 'field_maxlen'
- $var = request_var('field_default_value', 0);
- }*/
+ // 'field_length' == 1 defines radio buttons. Possible values are 1 or 2 only.
+ // 'field_length' == 2 defines checkbox. Possible values are 0 or 1 only.
+ // If we switch the type on step 2, we have to adjust field value.
+ // 1 is a common value for the checkbox and radio buttons.
+
+ // Adjust unchecked checkbox value.
+ // If we return or save settings from 2nd/3rd page
+ // and the checkbox is unchecked, set the value to 0.
+ if (isset($_REQUEST['step']) && !isset($_REQUEST[$key]))
+ {
+ $var = 0;
+ }
+
+ // If we switch to the checkbox type but former radio buttons value was 2,
+ // which is not the case for the checkbox, set it to 0 (unchecked).
+ if ($cp->vars['field_length'] == 2 && $var == 2)
+ {
+ $var = 0;
+ }
+ // If we switch to the radio buttons but the former checkbox value was 0,
+ // which is not the case for the radio buttons, set it to 0.
+ else if ($cp->vars['field_length'] == 1 && $var == 0)
+ {
+ $var = 2;
+ }
+ }
else if ($field_type == FIELD_INT && $key == 'field_default_value')
{
// Permit an empty string
@@ -676,6 +699,10 @@ class acp_profile
{
$_new_key_ary[$key] = utf8_normalize_nfc(request_var($key, array(array('')), true));
}
+ else if ($field_type == FIELD_BOOL && $key == 'field_default_value')
+ {
+ $_new_key_ary[$key] = request_var($key, $cp->vars[$key]);
+ }
else
{
if (!isset($_REQUEST[$key]))
diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php
index dfd7511427..ea057cd84c 100644
--- a/phpBB/includes/acp/acp_ranks.php
+++ b/phpBB/includes/acp/acp_ranks.php
@@ -52,7 +52,7 @@ class acp_ranks
}
$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);
+ $min_posts = ($special_rank) ? 0 : max(0, request_var('min_posts', 0));
$rank_image = request_var('rank_image', '');
// The rank image has to be a jpg, gif or png
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 5300265686..d7b0484af8 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -99,11 +99,11 @@ parse_css_file = {PARSE_CSS_FILE}
$this->template_cfg .= '
# Some configuration options
-#
-# You can use this function to inherit templates from another template.
-# The template of the given name has to be installed.
-# Templates cannot inherit from inheriting templates.
-#';
+# Template inheritance
+# See http://blog.phpbb.com/2008/07/31/templating-just-got-easier/
+# Set value to empty or this template name to ignore template inheritance.
+inherit_from = {INHERIT_FROM}
+';
$this->imageset_keys = array(
'logos' => array(
@@ -540,12 +540,14 @@ parse_css_file = {PARSE_CSS_FILE}
global $user, $template, $db, $config, $phpbb_root_path, $phpEx;
$sql_from = '';
+ $sql_sort = 'LOWER(' . $mode . '_name)';
$style_count = array();
switch ($mode)
{
case 'style':
$sql_from = STYLES_TABLE;
+ $sql_sort = 'style_active DESC, ' . $sql_sort;
$sql = 'SELECT user_style, COUNT(user_style) AS style_count
FROM ' . USERS_TABLE . '
@@ -571,6 +573,9 @@ parse_css_file = {PARSE_CSS_FILE}
case 'imageset':
$sql_from = STYLES_IMAGESET_TABLE;
break;
+
+ default:
+ trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$l_prefix = strtoupper($mode);
@@ -594,7 +599,8 @@ parse_css_file = {PARSE_CSS_FILE}
);
$sql = "SELECT *
- FROM $sql_from";
+ FROM $sql_from
+ ORDER BY $sql_sort ASC";
$result = $db->sql_query($sql);
$installed = array();
@@ -630,6 +636,8 @@ parse_css_file = {PARSE_CSS_FILE}
'NAME' => $row[$mode . '_name'],
'STYLE_COUNT' => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0,
+
+ 'S_INACTIVE' => ($mode == 'style' && !$row['style_active']) ? true : false,
)
);
}
@@ -2039,9 +2047,7 @@ parse_css_file = {PARSE_CSS_FILE}
// Export template core code
if ($mode == 'template' || $inc_template)
{
- $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg);
-
- $use_template_name = '';
+ $use_template_name = $style_row['template_name'];
// Add the inherit from variable, depending on it's use...
if ($style_row['template_inherits_id'])
@@ -2055,7 +2061,8 @@ parse_css_file = {PARSE_CSS_FILE}
$db->sql_freeresult($result);
}
- $template_cfg .= ($use_template_name) ? "\ninherit_from = $use_template_name" : "\n#inherit_from = ";
+ $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}', '{INHERIT_FROM}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version'], $use_template_name), $this->template_cfg);
+
$template_cfg .= "\n\nbbcode_bitfield = {$style_row['bbcode_bitfield']}";
$data[] = array(
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 4f58434a43..363c900edc 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -2339,47 +2339,62 @@ class acp_users
}
/**
- * Optionset replacement for this module based on $user->optionset
+ * Set option bit field for user options in a user row array.
+ *
+ * Optionset replacement for this module based on $user->optionset.
+ *
+ * @param array $user_row Row from the users table.
+ * @param int $key Option key, as defined in $user->keyoptions property.
+ * @param bool $value True to set the option, false to clear the option.
+ * @param int $data Current bit field value, or false to use $user_row['user_options']
+ * @return int|bool If $data is false, the bit field is modified and
+ * written back to $user_row['user_options'], and
+ * return value is true if the bit field changed and
+ * false otherwise. If $data is not false, the new
+ * bitfield value is returned.
*/
function optionset(&$user_row, $key, $value, $data = false)
{
global $user;
- $var = ($data) ? $data : $user_row['user_options'];
+ $var = ($data !== false) ? $data : $user_row['user_options'];
- if ($value && !($var & 1 << $user->keyoptions[$key]))
- {
- $var += 1 << $user->keyoptions[$key];
- }
- else if (!$value && ($var & 1 << $user->keyoptions[$key]))
- {
- $var -= 1 << $user->keyoptions[$key];
- }
- else
- {
- return ($data) ? $var : false;
- }
+ $new_var = phpbb_optionset($user->keyoptions[$key], $value, $var);
- if (!$data)
+ if ($data === false)
{
- $user_row['user_options'] = $var;
- return true;
+ if ($new_var != $var)
+ {
+ $user_row['user_options'] = $new_var;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
else
{
- return $var;
+ return $new_var;
}
}
/**
- * Optionget replacement for this module based on $user->optionget
+ * Get option bit field from user options in a user row array.
+ *
+ * Optionget replacement for this module based on $user->optionget.
+ *
+ * @param array $user_row Row from the users table.
+ * @param int $key option key, as defined in $user->keyoptions property.
+ * @param int $data bit field value to use, or false to use $user_row['user_options']
+ * @return bool true if the option is set in the bit field, false otherwise
*/
function optionget(&$user_row, $key, $data = false)
{
global $user;
- $var = ($data) ? $data : $user_row['user_options'];
- return ($var & 1 << $user->keyoptions[$key]) ? true : false;
+ $var = ($data !== false) ? $data : $user_row['user_options'];
+ return phpbb_optionget($user->keyoptions[$key], $var);
}
}
diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php
index b4c1a72e1c..5d456c2ff0 100644
--- a/phpBB/includes/db/dbal.php
+++ b/phpBB/includes/db/dbal.php
@@ -662,12 +662,7 @@ class dbal
// The DEBUG_EXTRA constant is for development only!
if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG_EXTRA'))
{
- // Print out a nice backtrace...
- $backtrace = get_backtrace();
-
$message .= ($sql) ? '<br /><br />SQL<br /><br />' . htmlspecialchars($sql) : '';
- $message .= ($backtrace) ? '<br /><br />BACKTRACE<br />' . $backtrace : '';
- $message .= '<br />';
}
else
{
@@ -905,6 +900,41 @@ class dbal
return true;
}
+
+ /**
+ * Gets the estimated number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Number of rows in $table_name.
+ * Prefixed with ~ if estimated (otherwise exact).
+ *
+ * @access public
+ */
+ function get_estimated_row_count($table_name)
+ {
+ return $this->get_row_count($table_name);
+ }
+
+ /**
+ * Gets the exact number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Exact number of rows in $table_name.
+ *
+ * @access public
+ */
+ function get_row_count($table_name)
+ {
+ $sql = 'SELECT COUNT(*) AS rows_total
+ FROM ' . $this->sql_escape($table_name);
+ $result = $this->sql_query($sql);
+ $rows_total = $this->sql_fetchfield('rows_total');
+ $this->sql_freeresult($result);
+
+ return $rows_total;
+ }
}
/**
diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php
index 1e24c79577..1ccb785150 100644
--- a/phpBB/includes/db/mysql.php
+++ b/phpBB/includes/db/mysql.php
@@ -319,6 +319,76 @@ class dbal_mysql extends dbal
}
/**
+ * Gets the estimated number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Number of rows in $table_name.
+ * Prefixed with ~ if estimated (otherwise exact).
+ *
+ * @access public
+ */
+ function get_estimated_row_count($table_name)
+ {
+ $table_status = $this->get_table_status($table_name);
+
+ if (isset($table_status['Engine']))
+ {
+ if ($table_status['Engine'] === 'MyISAM')
+ {
+ return $table_status['Rows'];
+ }
+ else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000)
+ {
+ return '~' . $table_status['Rows'];
+ }
+ }
+
+ return parent::get_row_count($table_name);
+ }
+
+ /**
+ * Gets the exact number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Exact number of rows in $table_name.
+ *
+ * @access public
+ */
+ function get_row_count($table_name)
+ {
+ $table_status = $this->get_table_status($table_name);
+
+ if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM')
+ {
+ return $table_status['Rows'];
+ }
+
+ return parent::get_row_count($table_name);
+ }
+
+ /**
+ * Gets some information about the specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return array
+ *
+ * @access protected
+ */
+ function get_table_status($table_name)
+ {
+ $sql = "SHOW TABLE STATUS
+ LIKE '" . $this->sql_escape($table_name) . "'";
+ $result = $this->sql_query($sql);
+ $table_status = $this->sql_fetchrow($result);
+ $this->sql_freeresult($result);
+
+ return $table_status;
+ }
+
+ /**
* Build LIKE expression
* @access private
*/
diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php
index 456ce906d0..a311b8cda6 100644
--- a/phpBB/includes/db/mysqli.php
+++ b/phpBB/includes/db/mysqli.php
@@ -316,6 +316,76 @@ class dbal_mysqli extends dbal
}
/**
+ * Gets the estimated number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Number of rows in $table_name.
+ * Prefixed with ~ if estimated (otherwise exact).
+ *
+ * @access public
+ */
+ function get_estimated_row_count($table_name)
+ {
+ $table_status = $this->get_table_status($table_name);
+
+ if (isset($table_status['Engine']))
+ {
+ if ($table_status['Engine'] === 'MyISAM')
+ {
+ return $table_status['Rows'];
+ }
+ else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000)
+ {
+ return '~' . $table_status['Rows'];
+ }
+ }
+
+ return parent::get_row_count($table_name);
+ }
+
+ /**
+ * Gets the exact number of rows in a specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return string Exact number of rows in $table_name.
+ *
+ * @access public
+ */
+ function get_row_count($table_name)
+ {
+ $table_status = $this->get_table_status($table_name);
+
+ if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM')
+ {
+ return $table_status['Rows'];
+ }
+
+ return parent::get_row_count($table_name);
+ }
+
+ /**
+ * Gets some information about the specified table.
+ *
+ * @param string $table_name Table name
+ *
+ * @return array
+ *
+ * @access protected
+ */
+ function get_table_status($table_name)
+ {
+ $sql = "SHOW TABLE STATUS
+ LIKE '" . $this->sql_escape($table_name) . "'";
+ $result = $this->sql_query($sql);
+ $table_status = $this->sql_fetchrow($result);
+ $this->sql_freeresult($result);
+
+ return $table_status;
+ }
+
+ /**
* Build LIKE expression
* @access private
*/
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 852fc683f2..0320230a7d 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -3322,6 +3322,11 @@ function parse_cfg_file($filename, $lines = false)
$parsed_items[$key] = $value;
}
+
+ if (isset($parsed_items['inherit_from']) && isset($parsed_items['name']) && $parsed_items['inherit_from'] == $parsed_items['name'])
+ {
+ unset($parsed_items['inherit_from']);
+ }
return $parsed_items;
}
@@ -3853,11 +3858,23 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
}
+ $log_text = $msg_text;
+ $backtrace = get_backtrace();
+ if ($backtrace)
+ {
+ $log_text .= '<br /><br />BACKTRACE<br />' . $backtrace;
+ }
+
+ if (defined('IN_INSTALL') || defined('DEBUG_EXTRA') || isset($auth) && $auth->acl_get('a_'))
+ {
+ $msg_text = $log_text;
+ }
+
if ((defined('DEBUG') || defined('IN_CRON') || defined('IMAGE_OUTPUT')) && isset($db))
{
// let's avoid loops
$db->sql_return_on_error(true);
- add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $msg_text);
+ add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $log_text);
$db->sql_return_on_error(false);
}
@@ -4536,7 +4553,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
foreach ($_EXTRA_URL as $url_param)
{
$url_param = explode('=', $url_param, 2);
- $s_hidden_fields[$url_param[0]] = $url_param[1];
+ $s_search_hidden_fields[$url_param[0]] = $url_param[1];
}
}
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 4a359dcade..3b26f417e9 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -424,7 +424,8 @@ function import_avatar_gallery($gallery_name = '', $subdirs_as_galleries = false
$relative_path = empty($convert->convertor['source_path_absolute']);
- if (empty($convert->convertor['avatar_gallery_path']))
+ // check for trailing slash
+ if (rtrim($convert->convertor['avatar_gallery_path'], '/') === '')
{
$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'import_avatar_gallery()'), __LINE__, __FILE__);
}
@@ -588,7 +589,8 @@ function import_attachment($source, $use_target = false)
global $convert, $phpbb_root_path, $config, $user;
- if (empty($convert->convertor['upload_path']))
+ // check for trailing slash
+ if (rtrim($convert->convertor['upload_path'], '/') === '')
{
$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment()'), __LINE__, __FILE__);
}
@@ -647,7 +649,8 @@ function import_smiley($source, $use_target = false)
global $convert, $phpbb_root_path, $config, $user;
- if (!isset($convert->convertor['smilies_path']))
+ // check for trailing slash
+ if (rtrim($convert->convertor['smilies_path'], '/') === '')
{
$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'import_smiley()'), __LINE__, __FILE__);
}
@@ -667,7 +670,8 @@ function import_avatar($source, $use_target = false, $user_id = false)
global $convert, $phpbb_root_path, $config, $user;
- if (!isset($convert->convertor['avatar_path']))
+ // check for trailing slash
+ if (rtrim($convert->convertor['avatar_path'], '/') === '')
{
$convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'import_avatar()'), __LINE__, __FILE__);
}
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 91b361183c..6549693333 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -568,7 +568,7 @@ class messenger
if (!$use_queue)
{
include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
- $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], $config['jab_password'], $config['jab_use_ssl']);
+ $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']);
if (!$this->jabber->connect())
{
@@ -769,7 +769,7 @@ class queue
}
include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx);
- $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], $config['jab_password'], $config['jab_use_ssl']);
+ $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']);
if (!$this->jabber->connect())
{
@@ -1022,7 +1022,7 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false)
}
// Let me in. This function handles the complete authentication process
- if ($err_msg = $smtp->log_into_server($config['smtp_host'], $config['smtp_username'], $config['smtp_password'], $config['smtp_auth_method']))
+ if ($err_msg = $smtp->log_into_server($config['smtp_host'], $config['smtp_username'], htmlspecialchars_decode($config['smtp_password']), $config['smtp_auth_method']))
{
$smtp->close_session($err_msg);
return false;
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 77d92e26e2..f920be9c4b 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1286,6 +1286,20 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id
{
$msg_users[] = $row;
$update_notification[$row['notify_type']][] = $row['user_id'];
+
+ /*
+ * We also update the forums watch table for this user when we are
+ * sending out a topic notification to prevent sending out another
+ * notification in case this user is also subscribed to the forum
+ * this topic was posted in.
+ * Since an UPDATE query is used, this has no effect on users only
+ * subscribed to the topic (i.e. no row is created) and should not
+ * be a performance issue.
+ */
+ if ($row['notify_type'] === 'topic')
+ {
+ $update_notification['forum'][] = $row['user_id'];
+ }
}
}
unset($notify_rows);
diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php
index 1eae2a9ad6..16c193c15a 100644
--- a/phpBB/includes/functions_profile_fields.php
+++ b/phpBB/includes/functions_profile_fields.php
@@ -571,7 +571,12 @@ class custom_profile
$this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false);
}
- if ($value == $ident_ary['data']['field_novalue'])
+ // If a dropdown field is required, users
+ // cannot choose the "no value" option.
+ // They must choose one of the other options.
+ // Therefore, here we treat a value equal to
+ // the "no value" as a lack of value, i.e. NULL.
+ if ($value == $ident_ary['data']['field_novalue'] && $ident_ary['data']['field_required'])
{
return NULL;
}
@@ -625,10 +630,10 @@ class custom_profile
$profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident'];
$user_ident = $profile_row['field_ident'];
- // checkbox - only testing for isset
+ // checkbox - set the value to "true" if it has been set to 1
if ($profile_row['field_type'] == FIELD_BOOL && $profile_row['field_length'] == 2)
{
- $value = (isset($_REQUEST[$profile_row['field_ident']])) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]);
+ $value = (isset($_REQUEST[$profile_row['field_ident']]) && request_var($profile_row['field_ident'], $default_value) == 1) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]);
}
else if ($profile_row['field_type'] == FIELD_INT)
{
diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php
index 29cdd8ee9a..779ec1d216 100644
--- a/phpBB/includes/search/fulltext_mysql.php
+++ b/phpBB/includes/search/fulltext_mysql.php
@@ -707,7 +707,7 @@ class fulltext_mysql extends search_backend
*/
function index_remove($post_ids, $author_ids, $forum_ids)
{
- $this->destroy_cache(array(), $author_ids);
+ $this->destroy_cache(array(), array_unique($author_ids));
}
/**
@@ -896,11 +896,7 @@ class fulltext_mysql extends search_backend
}
$db->sql_freeresult($result);
- $sql = 'SELECT COUNT(post_id) as total_posts
- FROM ' . POSTS_TABLE;
- $result = $db->sql_query($sql);
- $this->stats['total_posts'] = (int) $db->sql_fetchfield('total_posts');
- $db->sql_freeresult($result);
+ $this->stats['total_posts'] = empty($this->stats) ? 0 : $db->get_estimated_row_count(POSTS_TABLE);
}
/**
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index 727e3aaffb..dc961f3c8a 100644
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -1334,7 +1334,7 @@ class fulltext_native extends search_backend
$db->sql_query($sql);
}
- $this->destroy_cache(array_unique($word_texts), $author_ids);
+ $this->destroy_cache(array_unique($word_texts), array_unique($author_ids));
}
/**
@@ -1461,17 +1461,8 @@ class fulltext_native extends search_backend
{
global $db;
- $sql = 'SELECT COUNT(*) as total_words
- FROM ' . SEARCH_WORDLIST_TABLE;
- $result = $db->sql_query($sql);
- $this->stats['total_words'] = (int) $db->sql_fetchfield('total_words');
- $db->sql_freeresult($result);
-
- $sql = 'SELECT COUNT(*) as total_matches
- FROM ' . SEARCH_WORDMATCH_TABLE;
- $result = $db->sql_query($sql);
- $this->stats['total_matches'] = (int) $db->sql_fetchfield('total_matches');
- $db->sql_freeresult($result);
+ $this->stats['total_words'] = $db->get_estimated_row_count(SEARCH_WORDLIST_TABLE);
+ $this->stats['total_matches'] = $db->get_estimated_row_count(SEARCH_WORDMATCH_TABLE);
}
/**
diff --git a/phpBB/includes/search/search.php b/phpBB/includes/search/search.php
index 2f20d11495..df7c8a0892 100644
--- a/phpBB/includes/search/search.php
+++ b/phpBB/includes/search/search.php
@@ -295,7 +295,7 @@ class search_backend
$sql_where = '';
foreach ($authors as $author)
{
- $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors LIKE \'% ' . (int) $author . ' %\'';
+ $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors ' . $db->sql_like_expression($db->any_char . ' ' . (int) $author . ' ' . $db->any_char);
}
$sql = 'SELECT search_key
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index caadcbafaa..a894242a39 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -1507,7 +1507,6 @@ class user extends session
// Able to add new options (up to id 31)
var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17);
- var $keyvalues = array();
/**
* Constructor to set the lang path
@@ -2337,47 +2336,51 @@ class user extends session
}
/**
- * Get option bit field from user options
+ * Get option bit field from user options.
+ *
+ * @param int $key option key, as defined in $keyoptions property.
+ * @param int $data bit field value to use, or false to use $this->data['user_options']
+ * @return bool true if the option is set in the bit field, false otherwise
*/
function optionget($key, $data = false)
{
- if (!isset($this->keyvalues[$key]))
- {
- $var = ($data) ? $data : $this->data['user_options'];
- $this->keyvalues[$key] = ($var & 1 << $this->keyoptions[$key]) ? true : false;
- }
-
- return $this->keyvalues[$key];
+ $var = ($data !== false) ? $data : $this->data['user_options'];
+ return phpbb_optionget($this->keyoptions[$key], $var);
}
/**
- * Set option bit field for user options
+ * Set option bit field for user options.
+ *
+ * @param int $key Option key, as defined in $keyoptions property.
+ * @param bool $value True to set the option, false to clear the option.
+ * @param int $data Current bit field value, or false to use $this->data['user_options']
+ * @return int|bool If $data is false, the bit field is modified and
+ * written back to $this->data['user_options'], and
+ * return value is true if the bit field changed and
+ * false otherwise. If $data is not false, the new
+ * bitfield value is returned.
*/
function optionset($key, $value, $data = false)
{
- $var = ($data) ? $data : $this->data['user_options'];
+ $var = ($data !== false) ? $data : $this->data['user_options'];
- if ($value && !($var & 1 << $this->keyoptions[$key]))
- {
- $var += 1 << $this->keyoptions[$key];
- }
- else if (!$value && ($var & 1 << $this->keyoptions[$key]))
- {
- $var -= 1 << $this->keyoptions[$key];
- }
- else
- {
- return ($data) ? $var : false;
- }
+ $new_var = phpbb_optionset($this->keyoptions[$key], $value, $var);
- if (!$data)
+ if ($data === false)
{
- $this->data['user_options'] = $var;
- return true;
+ if ($new_var != $var)
+ {
+ $this->data['user_options'] = $new_var;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
else
{
- return $var;
+ return $new_var;
}
}
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 4e8729db56..6ad3a55589 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -165,24 +165,8 @@ class ucp_register
$captcha->init(CONFIRM_REG);
}
- // 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');
-
- if ($config['board_timezone'] == $timezone || $config['board_timezone'] == ($timezone - 1))
- {
- $timezone = ($is_dst) ? $timezone - 1 : $timezone;
-
- if (!isset($user->lang['tz_zones'][(string) $timezone]))
- {
- $timezone = $config['board_timezone'];
- }
- }
- else
- {
- $is_dst = $config['board_dst'];
- $timezone = $config['board_timezone'];
- }
+ $is_dst = $config['board_dst'];
+ $timezone = $config['board_timezone'];
$data = array(
'username' => utf8_normalize_nfc(request_var('username', '', true)),