diff options
author | Vjacheslav Trushkin <arty@phpbb.com> | 2012-03-24 11:45:53 +0200 |
---|---|---|
committer | Vjacheslav Trushkin <arty@phpbb.com> | 2012-03-24 11:45:53 +0200 |
commit | 583da4274f91d3e8228ce58e8a849aa861ef66f8 (patch) | |
tree | d1841433f1d54768c3fc9f01af138adff6fc50c9 /phpBB/includes | |
parent | f17449e5ffb87c4a63e6c27c52036c5812f970d7 (diff) | |
parent | cc13bac412442a1d72affcc3222b6bfca094e92a (diff) | |
download | forums-583da4274f91d3e8228ce58e8a849aa861ef66f8.tar forums-583da4274f91d3e8228ce58e8a849aa861ef66f8.tar.gz forums-583da4274f91d3e8228ce58e8a849aa861ef66f8.tar.bz2 forums-583da4274f91d3e8228ce58e8a849aa861ef66f8.tar.xz forums-583da4274f91d3e8228ce58e8a849aa861ef66f8.zip |
Merge branch 'develop' into feature/prosilver-cleanup/duplicate-colors
* develop: (117 commits)
[task/travis] Refactor php version check for dbunit install
[task/travis] Exclude functional and slow tests
[ticket/10719] Revert "Skip functional tests on PHP 5.2"
[task/travis-develop2] Update version from 5.3 to 5.3.2
[task/travis] Dropping support for 5.2 in develop branch
[task/travis] Some more small travis fixes
[task/travis] Rename travis phpunit config files
[task/travis] Fixing some travis issues
[ticket/10684] Adjust function and parameter name, minor changes.
[task/travis] Add automated testing to readme
[task/travis] Removing development information
[task/travis] Adding Travis Continuous Intergration Support
[ticket/10704] minor typo in a comment
[ticket/10717] Fix profile field sample in prosilver“s memberlist_view.html
[ticket/10691] Fixed the speed of creating search index
[task/php54-ascraeus] Bring p_master#module_auth into PHP 5 era.
[task/php54] Disable E_STRICT in Olympus when running on PHP 5.4.
[task/php54] Refactor error_reporting call slightly.
[ticket/10690] Fix undefined UNAPPROVED_POSTS_ZERO_TOTAL in queue
[ticket/10689] Fix "First character"-option in "Find a member"-search
...
Conflicts:
phpBB/styles/prosilver/theme/cp.css
Diffstat (limited to 'phpBB/includes')
30 files changed, 512 insertions, 151 deletions
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 60d5def4d1..511148baf9 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -508,11 +508,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 @@ -680,6 +703,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 97cfd35750..ec5a76df87 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -51,7 +51,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 c8fe748c02..7b449d3b35 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -83,11 +83,11 @@ version = {VERSION} $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} +'; // Execute overall actions switch ($action) @@ -1346,9 +1346,7 @@ version = {VERSION} // 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']) @@ -1362,7 +1360,8 @@ version = {VERSION} $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 a282ef1d7f..cf6716c322 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -128,7 +128,7 @@ class acp_users $dropdown_modes = array(); while ($row = $db->sql_fetchrow($result)) { - if (!$this->p_master->module_auth($row['module_auth'])) + if (!$this->p_master->module_auth_self($row['module_auth'])) { continue; } @@ -756,7 +756,6 @@ class acp_users 'username' => utf8_normalize_nfc(request_var('user', $user_row['username'], true)), 'user_founder' => request_var('user_founder', ($user_row['user_type'] == USER_FOUNDER) ? 1 : 0), 'email' => strtolower(request_var('user_email', $user_row['user_email'])), - 'email_confirm' => strtolower(request_var('email_confirm', '')), 'new_password' => request_var('new_password', '', true), 'password_confirm' => request_var('password_confirm', '', true), ); @@ -788,7 +787,6 @@ class acp_users array('string', false, 6, 60), array('email', $user_row['user_email']) ), - 'email_confirm' => array('string', true, 6, 60) ); } @@ -799,11 +797,6 @@ class acp_users $error[] = 'NEW_PASSWORD_ERROR'; } - if ($data['email'] != $user_row['user_email'] && $data['email_confirm'] != $data['email']) - { - $error[] = 'NEW_EMAIL_ERROR'; - } - if (!check_form_key($form_name)) { $error[] = 'FORM_INVALID'; diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 8564cb8426..6da854b6e2 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -920,6 +920,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 317b8d123d..eb38e3e913 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -318,6 +318,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 d6b64bf7c8..4210a58002 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -315,6 +315,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/extension/finder.php b/phpBB/includes/extension/finder.php index e5e5e4983e..23b9f1c658 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -375,6 +375,10 @@ class phpbb_extension_finder { $directory_pattern = preg_quote(DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#'); } + if ($is_dir) + { + $directory_pattern .= '$'; + } $directory_pattern = '#' . $directory_pattern . '#'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 438578e7e7..c38f0df32e 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -61,7 +61,7 @@ class phpbb_extension_manager * * @return null */ - protected function load_extensions() + public function load_extensions() { $sql = 'SELECT * FROM ' . $this->extension_table; @@ -167,6 +167,11 @@ class phpbb_extension_manager $this->db->sql_query($sql); } + if ($this->cache) + { + $this->cache->destroy($this->cache_name); + } + return !$active; } @@ -219,6 +224,11 @@ class phpbb_extension_manager WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); + if ($this->cache) + { + $this->cache->destroy($this->cache_name); + } + return true; } @@ -234,6 +244,11 @@ class phpbb_extension_manager WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); + if ($this->cache) + { + $this->cache->destroy($this->cache_name); + } + return false; } @@ -292,6 +307,11 @@ class phpbb_extension_manager WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); + if ($this->cache) + { + $this->cache->destroy($this->cache_name); + } + return true; } @@ -301,6 +321,11 @@ class phpbb_extension_manager WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; $this->db->sql_query($sql); + if ($this->cache) + { + $this->cache->destroy($this->cache_name); + } + return false; } @@ -329,7 +354,8 @@ class phpbb_extension_manager $available = array(); $iterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/')); + new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/'), + RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $file_info) { if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->phpEx) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index a60edb5cee..9913a80a70 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3091,6 +3091,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; } @@ -4627,7 +4632,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_admin.php b/phpBB/includes/functions_admin.php index 7fdf874456..9798e514c1 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -847,15 +847,13 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = } // Remove the message from the search index - $search_type = basename($config['search_type']); + $search_type = $config['search_type']; - if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) + if (!class_exists($search_type)) { trigger_error('NO_SUCH_SEARCH_MODULE'); } - include_once("{$phpbb_root_path}includes/search/$search_type.$phpEx"); - $error = false; $search = new $search_type($error); @@ -2330,7 +2328,7 @@ function cache_moderators() $ug_id_ary = array_keys($hold_ary); // Remove users who have group memberships with DENY moderator permissions - $sql_ary = array( + $sql_ary_deny = array( 'SELECT' => 'a.forum_id, ug.user_id, g.group_id', 'FROM' => array( @@ -2357,7 +2355,7 @@ function cache_moderators() AND ug.user_pending = 0 AND o.auth_option " . $db->sql_like_expression('m_' . $db->any_char), ); - $sql = $db->sql_build_query('SELECT', $sql_ary); + $sql = $db->sql_build_query('SELECT', $sql_ary_deny); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index de25e390fa..1486113013 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -126,7 +126,7 @@ function send_file_to_browser($attachment, $upload_dir, $category) if (!@file_exists($filename)) { send_status_line(404, 'Not Found'); - trigger_error($user->lang['ERROR_NO_ATTACHMENT'] . '<br /><br />' . sprintf($user->lang['FILE_NOT_FOUND_404'], $filename)); + trigger_error('ERROR_NO_ATTACHMENT'); } // Correct the mime type - we force application/octetstream for all files, except images diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 13d9b6a5cb..f4e49b1b18 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -1136,6 +1136,7 @@ class smtp_class { var $server_response = ''; var $socket = 0; + protected $socket_tls = false; var $responses = array(); var $commands = array(); var $numeric_response_code = 0; @@ -1286,30 +1287,29 @@ class smtp_class } } - // Try EHLO first - $this->server_send("EHLO {$local_host}"); - if ($err_msg = $this->server_parse('250', __LINE__)) + $hello_result = $this->hello($local_host); + if (!is_null($hello_result)) { - // a 503 response code means that we're already authenticated - if ($this->numeric_response_code == 503) - { - return false; - } - - // If EHLO fails, we try HELO - $this->server_send("HELO {$local_host}"); - if ($err_msg = $this->server_parse('250', __LINE__)) - { - return ($this->numeric_response_code == 503) ? false : $err_msg; - } + return $hello_result; } - foreach ($this->responses as $response) + // SMTP STARTTLS (RFC 3207) + if (!$this->socket_tls) { - $response = explode(' ', $response); - $response_code = $response[0]; - unset($response[0]); - $this->commands[$response_code] = implode(' ', $response); + $this->socket_tls = $this->starttls(); + + if ($this->socket_tls) + { + // Switched to TLS + // RFC 3207: "The client MUST discard any knowledge obtained from the server, [...]" + // So say hello again + $hello_result = $this->hello($local_host); + + if (!is_null($hello_result)) + { + return $hello_result; + } + } } // If we are not authenticated yet, something might be wrong if no username and passwd passed @@ -1356,6 +1356,79 @@ class smtp_class } /** + * SMTP EHLO/HELO + * + * @return mixed Null if the authentication process is supposed to continue + * False if already authenticated + * Error message (string) otherwise + */ + protected function hello($hostname) + { + // Try EHLO first + $this->server_send("EHLO $hostname"); + if ($err_msg = $this->server_parse('250', __LINE__)) + { + // a 503 response code means that we're already authenticated + if ($this->numeric_response_code == 503) + { + return false; + } + + // If EHLO fails, we try HELO + $this->server_send("HELO $hostname"); + if ($err_msg = $this->server_parse('250', __LINE__)) + { + return ($this->numeric_response_code == 503) ? false : $err_msg; + } + } + + foreach ($this->responses as $response) + { + $response = explode(' ', $response); + $response_code = $response[0]; + unset($response[0]); + $this->commands[$response_code] = implode(' ', $response); + } + } + + /** + * SMTP STARTTLS (RFC 3207) + * + * @return bool Returns true if TLS was started + * Otherwise false + */ + protected function starttls() + { + if (!function_exists('stream_socket_enable_crypto')) + { + return false; + } + + if (!isset($this->commands['STARTTLS'])) + { + return false; + } + + $this->server_send('STARTTLS'); + + if ($err_msg = $this->server_parse('220', __LINE__)) + { + return false; + } + + $result = false; + $stream_meta = stream_get_meta_data($this->socket); + + if (socket_set_blocking($this->socket, 1)); + { + $result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + socket_set_blocking($this->socket, (int) $stream_meta['blocked']); + } + + return $result; + } + + /** * Pop before smtp authentication */ function pop_before_smtp($hostname, $username, $password) diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index b7bb770031..ad76be9f2f 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -128,7 +128,7 @@ class p_master foreach ($this->module_cache['modules'] as $key => $row) { // Not allowed to view module? - if (!$this->module_auth($row['module_auth'])) + if (!$this->module_auth_self($row['module_auth'])) { unset($this->module_cache['modules'][$key]); continue; @@ -315,9 +315,23 @@ class p_master } /** - * Check module authorisation + * Check module authorisation. + * + * This is a non-static version that uses $this->acl_forum_id + * for the forum id. + */ + function module_auth_self($module_auth) + { + return self::module_auth($module_auth, $this->acl_forum_id); + } + + /** + * Check module authorisation. + * + * This is a static version, it must be given $forum_id. + * See also module_auth_self. */ - function module_auth($module_auth, $forum_id = false) + static function module_auth($module_auth, $forum_id) { global $auth, $config; global $request; @@ -362,11 +376,9 @@ class p_master $module_auth = implode(' ', $tokens); - // Make sure $id seperation is working fine + // Make sure $id separation is working fine $module_auth = str_replace(' , ', ',', $module_auth); - $forum_id = ($forum_id === false) ? $this->acl_forum_id : $forum_id; - $is_auth = false; eval('$is_auth = (int) (' . preg_replace(array('#acl_([a-z0-9_]+)(,\$id)?#', '#\$id#', '#aclf_([a-z0-9_]+)#', '#cfg_([a-z0-9_]+)#', '#request_([a-zA-Z0-9_]+)#'), array('(int) $auth->acl_get(\'\\1\'\\2)', '(int) $forum_id', '(int) $auth->acl_getf_global(\'\\1\')', '(int) $config[\'\\1\']', '$request->variable(\'\\1\', false)'), $module_auth) . ');'); @@ -923,6 +935,6 @@ class p_master */ protected function is_full_class($basename) { - return (substr($basename, 0, 6) === 'phpbb_' || substr($basename, 0, strlen($this->p_class) + 1) === $this->p_class . '_'); + return (preg_match('/^(phpbb|ucp|mcp|acp)_/', $basename)); } } diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 104fc841b6..b3816baedd 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1180,36 +1180,32 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $topic_title = ($topic_notification) ? $topic_title : $subject; $topic_title = censor_text($topic_title); - // Get banned User ID's - $sql = 'SELECT ban_userid - FROM ' . BANLIST_TABLE . ' - WHERE ban_userid <> 0 - AND ban_exclude <> 1'; - $result = $db->sql_query($sql); - - $sql_ignore_users = ANONYMOUS . ', ' . $user->data['user_id']; - while ($row = $db->sql_fetchrow($result)) + // Exclude guests, current user and banned users from notifications + if (!function_exists('phpbb_get_banned_user_ids')) { - $sql_ignore_users .= ', ' . (int) $row['ban_userid']; + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); } - $db->sql_freeresult($result); + $sql_ignore_users = phpbb_get_banned_user_ids(); + $sql_ignore_users[ANONYMOUS] = ANONYMOUS; + $sql_ignore_users[$user->data['user_id']] = $user->data['user_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 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) - AND w.notify_status = " . NOTIFY_YES . ' + WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . ' + AND ' . $db->sql_in_set('w.user_id', $sql_ignore_users, true) . ' + AND w.notify_status = ' . NOTIFY_YES . ' AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') AND u.user_id = w.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $notify_rows[$row['user_id']] = array( - 'user_id' => $row['user_id'], + $notify_user_id = (int) $row['user_id']; + $notify_rows[$notify_user_id] = array( + 'user_id' => $notify_user_id, 'username' => $row['username'], 'user_email' => $row['user_email'], 'user_jabber' => $row['user_jabber'], @@ -1219,30 +1215,29 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'method' => $row['user_notify_type'], 'allowed' => false ); + + // Add users who have been already notified to ignore list + $sql_ignore_users[$notify_user_id] = $notify_user_id; } $db->sql_freeresult($result); // forum notification is sent to those not already receiving topic notifications if ($topic_notification) { - if (sizeof($notify_rows)) - { - $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 FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u WHERE fw.forum_id = $forum_id - AND fw.user_id NOT IN ($sql_ignore_users) - AND fw.notify_status = " . NOTIFY_YES . ' + AND " . $db->sql_in_set('fw.user_id', $sql_ignore_users, true) . ' + AND fw.notify_status = ' . NOTIFY_YES . ' AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') AND u.user_id = fw.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $notify_rows[$row['user_id']] = array( - 'user_id' => $row['user_id'], + $notify_user_id = (int) $row['user_id']; + $notify_rows[$notify_user_id] = array( + 'user_id' => $notify_user_id, 'username' => $row['username'], 'user_email' => $row['user_email'], 'user_jabber' => $row['user_jabber'], @@ -1273,7 +1268,6 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id } } - // Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;) $msg_users = $delete_ids = $update_notification = array(); foreach ($notify_rows as $user_id => $row) @@ -1286,6 +1280,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_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 91e453b8e0..a6fb87536a 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1666,6 +1666,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i $subject = censor_text($subject); + // Exclude guests, current user and banned users from notifications unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]); if (!sizeof($recipients)) @@ -1673,18 +1674,12 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i return; } - // Get banned User ID's - $sql = 'SELECT ban_userid - FROM ' . BANLIST_TABLE . ' - WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . ' - AND ban_exclude = 0'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) + if (!function_exists('phpbb_get_banned_user_ids')) { - unset($recipients[$row['ban_userid']]); + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); } - $db->sql_freeresult($result); + $banned_users = phpbb_get_banned_user_ids(array_keys($recipients)); + $recipients = array_diff(array_keys($recipients), $banned_users); if (!sizeof($recipients)) { @@ -1693,7 +1688,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i $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))); + WHERE ' . $db->sql_in_set('user_id', $recipients); $result = $db->sql_query($sql); $msg_list_ary = array(); diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index 26c4283f67..34d973b3a6 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -570,7 +570,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/functions_user.php b/phpBB/includes/functions_user.php index 509e1a953c..18452c27e9 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -3691,3 +3691,36 @@ function remove_newly_registered($user_id, $user_data = false) return $user_data['group_id']; } + +/** +* Gets user ids of currently banned registered users. +* +* @param array $user_ids Array of users' ids to check for banning, +* leave empty to get complete list of banned ids +* @return array Array of banned users' ids if any, empty array otherwise +*/ +function phpbb_get_banned_user_ids($user_ids = array()) +{ + global $db; + + $sql_user_ids = (!empty($user_ids)) ? $db->sql_in_set('ban_userid', $user_ids) : 'ban_userid <> 0'; + + // Get banned User ID's + // Ignore stale bans which were not wiped yet + $banned_ids_list = array(); + $sql = 'SELECT ban_userid + FROM ' . BANLIST_TABLE . " + WHERE $sql_user_ids + AND ban_exclude <> 1 + AND (ban_end > " . time() . ' + OR ban_end = 0)'; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $user_id = (int) $row['ban_userid']; + $banned_ids_list[$user_id] = $user_id; + } + $db->sql_freeresult($result); + + return $banned_ids_list; +} diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 10e5956fc2..a21c67924d 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -907,16 +907,11 @@ function mcp_fork_topic($topic_ids) if (!isset($search_type) && $topic_row['enable_indexing']) { // Select the search method and do some additional checks to ensure it can actually be utilised - $search_type = basename($config['search_type']); - - if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) - { - trigger_error('NO_SUCH_SEARCH_MODULE'); - } + $search_type = $config['search_type']; if (!class_exists($search_type)) { - include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); + trigger_error('NO_SUCH_SEARCH_MODULE'); } $error = false; diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index ee79928eb1..2a52a858b3 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -464,12 +464,10 @@ function change_poster(&$post_info, $userdata) } // refresh search cache of this post - $search_type = basename($config['search_type']); + $search_type = $config['search_type']; - if (file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) + if (class_exists($search_type)) { - require("{$phpbb_root_path}includes/search/$search_type.$phpEx"); - // We do some additional checks in the module to ensure it can actually be utilised $error = false; $search = new $search_type($error); diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 598b470663..d4ba89b04c 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -49,6 +49,16 @@ function mcp_topic_view($id, $mode, $action) $submitted_id_list = request_var('post_ids', array(0)); $checked_ids = $post_id_list = request_var('post_id_list', array(0)); + // Resync Topic? + if ($action == 'resync') + { + if (!function_exists('mcp_resync_topics')) + { + include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx); + } + mcp_resync_topics(array($topic_id)); + } + // Split Topic? if ($action == 'split_all' || $action == 'split_beyond') { @@ -319,6 +329,7 @@ function mcp_topic_view($id, $mode, $action) 'S_CAN_APPROVE' => ($has_unapproved_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false, 'S_CAN_LOCK' => ($auth->acl_get('m_lock', $topic_info['forum_id'])) ? true : false, 'S_CAN_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? true : false, + 'S_CAN_SYNC' => $auth->acl_get('m_', $topic_info['forum_id']), 'S_REPORT_VIEW' => ($action == 'reports') ? true : false, 'S_MERGE_VIEW' => ($action == 'merge') ? true : false, 'S_SPLIT_VIEW' => ($action == 'split') ? true : false, diff --git a/phpBB/includes/request/type_cast_helper.php b/phpBB/includes/request/type_cast_helper.php index 5aa0372328..561e8fc251 100644 --- a/phpBB/includes/request/type_cast_helper.php +++ b/phpBB/includes/request/type_cast_helper.php @@ -34,7 +34,7 @@ class phpbb_request_type_cast_helper implements phpbb_request_type_cast_helper_i */ public function __construct() { - if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) + if (version_compare(PHP_VERSION, '5.4.0-dev', '>=')) { $this->strip = false; } diff --git a/phpBB/includes/search/base.php b/phpBB/includes/search/base.php index f691bc942f..b364dead9a 100644 --- a/phpBB/includes/search/base.php +++ b/phpBB/includes/search/base.php @@ -294,7 +294,7 @@ class phpbb_search_base $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/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 5372cfac7b..7c94038cc9 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -708,7 +708,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base */ function index_remove($post_ids, $author_ids, $forum_ids) { - $this->destroy_cache(array(), $author_ids); + $this->destroy_cache(array(), array_unique($author_ids)); } /** @@ -897,11 +897,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base } $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 b9085695ac..3e029c86d0 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -1335,7 +1335,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base $db->sql_query($sql); } - $this->destroy_cache(array_unique($word_texts), $author_ids); + $this->destroy_cache(array_unique($word_texts), array_unique($author_ids)); } /** @@ -1462,17 +1462,8 @@ class phpbb_search_fulltext_native extends phpbb_search_base { 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/startup.php b/phpBB/includes/startup.php index 2100fbd97e..fc45cd882b 100644 --- a/phpBB/includes/startup.php +++ b/phpBB/includes/startup.php @@ -19,7 +19,8 @@ if (!defined('E_DEPRECATED')) { define('E_DEPRECATED', 8192); } -error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); +$level = E_ALL & ~E_NOTICE & ~E_DEPRECATED; +error_reporting($level); /* * Remove variables created by register_globals from the global scope diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 65a3531bc5..ec09da1cf3 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -53,7 +53,9 @@ class phpbb_template_context } /** - * Assign a single variable to a single key + * Assign a single scalar value to a single key. + * + * Value can be a string, an integer or a boolean. * * @param string $varname Variable name * @param string $varval Value to assign to variable @@ -66,6 +68,21 @@ class phpbb_template_context } /** + * Append text to the string value stored in a key. + * + * Text is appended using the string concatenation operator (.). + * + * @param string $varname Variable name + * @param string $varval Value to append to variable + */ + public function append_var($varname, $varval) + { + $this->rootref[$varname] = (isset($this->rootref[$varname]) ? $this->rootref[$varname] : '') . $varval; + + return true; + } + + /** * Returns a reference to template data array. * * This function is public so that template renderer may invoke it. diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 989322320b..bac5445511 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -128,7 +128,7 @@ class phpbb_template { $templates = array($template_name => $template_path); - if ($fallback_template_path !== false) + if ($fallback_template_name !== false) { $templates[$fallback_template_name] = $fallback_template_path; } @@ -306,7 +306,7 @@ class phpbb_template * * @param string $handle Handle of the template to load * @return phpbb_template_renderer Template renderer object, or null on failure - * @uses template_compile is used to compile template source + * @uses phpbb_template_compile is used to compile template source */ private function _tpl_load($handle) { @@ -378,7 +378,9 @@ class phpbb_template } /** - * Assign a single variable to a single key + * Assign a single scalar value to a single key. + * + * Value can be a string, an integer or a boolean. * * @param string $varname Variable name * @param string $varval Value to assign to variable @@ -388,6 +390,19 @@ class phpbb_template $this->context->assign_var($varname, $varval); } + /** + * Append text to the string value stored in a key. + * + * Text is appended using the string concatenation operator (.). + * + * @param string $varname Variable name + * @param string $varval Value to append to variable + */ + public function append_var($varname, $varval) + { + $this->context->append_var($varname, $varval); + } + // Docstring is copied from phpbb_template_context method with the same name. /** * Assign key variable pairs from an array to a specified block diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index d0df70d2f5..9d81503f0a 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -46,7 +46,6 @@ class ucp_profile $data = array( 'username' => utf8_normalize_nfc(request_var('username', $user->data['username'], true)), 'email' => strtolower(request_var('email', $user->data['user_email'])), - 'email_confirm' => strtolower(request_var('email_confirm', '')), 'new_password' => request_var('new_password', '', true), 'cur_password' => request_var('cur_password', '', true), 'password_confirm' => request_var('password_confirm', '', true), @@ -65,7 +64,6 @@ class ucp_profile 'email' => array( array('string', false, 6, 60), array('email')), - 'email_confirm' => array('string', true, 6, 60), ); if ($auth->acl_get('u_chgname') && $config['allow_namechange']) @@ -78,11 +76,6 @@ class ucp_profile $error = validate_data($data, $check_ary); - if ($auth->acl_get('u_chgemail') && $data['email'] != $user->data['user_email'] && $data['email_confirm'] != $data['email']) - { - $error[] = ($data['email_confirm']) ? 'NEW_EMAIL_ERROR' : 'NEW_EMAIL_CONFIRM_EMPTY'; - } - if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && $data['password_confirm'] != $data['new_password']) { $error[] = ($data['password_confirm']) ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY'; diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 91729c7844..5d85029e62 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -99,7 +99,6 @@ class ucp_register $s_hidden_fields = array_merge($s_hidden_fields, array( 'username' => utf8_normalize_nfc(request_var('username', '', true)), 'email' => strtolower(request_var('email', '')), - 'email_confirm' => strtolower(request_var('email_confirm', '')), 'lang' => $user->lang_name, 'tz' => request_var('tz', (float) $config['board_timezone']), )); @@ -172,7 +171,6 @@ class ucp_register 'new_password' => request_var('new_password', '', true), 'password_confirm' => request_var('password_confirm', '', true), 'email' => strtolower(request_var('email', '')), - 'email_confirm' => strtolower(request_var('email_confirm', '')), 'lang' => basename(request_var('lang', $user->lang_name)), 'tz' => request_var('tz', (float) $timezone), ); @@ -191,7 +189,6 @@ class ucp_register 'email' => array( array('string', false, 6, 60), array('email')), - 'email_confirm' => array('string', false, 6, 60), 'tz' => array('num', false, -14, 14), 'lang' => array('language_iso_name'), )); @@ -236,11 +233,6 @@ class ucp_register { $error[] = $user->lang['NEW_PASSWORD_ERROR']; } - - if ($data['email'] != $data['email_confirm']) - { - $error[] = $user->lang['NEW_EMAIL_ERROR']; - } } if (!sizeof($error)) @@ -455,7 +447,6 @@ class ucp_register 'PASSWORD' => $data['new_password'], 'PASSWORD_CONFIRM' => $data['password_confirm'], 'EMAIL' => $data['email'], - 'EMAIL_CONFIRM' => $data['email_confirm'], 'L_REG_COND' => $l_reg_cond, 'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])), |