diff options
| author | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:09:02 +0100 |
|---|---|---|
| committer | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:09:02 +0100 |
| commit | 3b46681652ad0c235ccdcafc449c3d759335df17 (patch) | |
| tree | 2eb63a812afae4e9d78a0883f2d9c2409c1512d7 /phpBB/includes | |
| parent | 6606e4bffe91637701499afef34e9c847aa3a3b0 (diff) | |
| parent | 67e8cbdd0041e0cc0b77b09cad02ce29905ded01 (diff) | |
| download | forums-3b46681652ad0c235ccdcafc449c3d759335df17.tar forums-3b46681652ad0c235ccdcafc449c3d759335df17.tar.gz forums-3b46681652ad0c235ccdcafc449c3d759335df17.tar.bz2 forums-3b46681652ad0c235ccdcafc449c3d759335df17.tar.xz forums-3b46681652ad0c235ccdcafc449c3d759335df17.zip | |
Merge commit 'release-3.0.7-RC1'
Diffstat (limited to 'phpBB/includes')
44 files changed, 564 insertions, 143 deletions
diff --git a/phpBB/includes/acm/acm_eaccelerator.php b/phpBB/includes/acm/acm_eaccelerator.php index 1a3cf3c0f7..645067c199 100644 --- a/phpBB/includes/acm/acm_eaccelerator.php +++ b/phpBB/includes/acm/acm_eaccelerator.php @@ -30,6 +30,7 @@ if (!class_exists('acm_memory')) class acm extends acm_memory { var $extension = 'eaccelerator'; + var $function = 'eaccelerator_get'; var $serialize_header = '#phpbb-serialized#'; diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php index 234be5c5d1..5a758aa2bb 100644 --- a/phpBB/includes/acm/acm_file.php +++ b/phpBB/includes/acm/acm_file.php @@ -410,7 +410,7 @@ class acm { if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field] : false; + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; } return false; diff --git a/phpBB/includes/acm/acm_memcache.php b/phpBB/includes/acm/acm_memcache.php index 3077ee9615..52b8832749 100644 --- a/phpBB/includes/acm/acm_memcache.php +++ b/phpBB/includes/acm/acm_memcache.php @@ -105,7 +105,11 @@ class acm extends acm_memory */ function _write($var, $data, $ttl = 2592000) { - return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl); + if (!$this->memcache->replace($this->key_prefix . $var, $data, $this->flags, $ttl)) + { + return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl); + } + return true; } /** diff --git a/phpBB/includes/acm/acm_memory.php b/phpBB/includes/acm/acm_memory.php index 1ed4fb0d55..efbfd4dd62 100644 --- a/phpBB/includes/acm/acm_memory.php +++ b/phpBB/includes/acm/acm_memory.php @@ -47,6 +47,13 @@ class acm_memory trigger_error("Could not find required extension [{$this->extension}] for the ACM module $acm_type.", E_USER_ERROR); } + + if (isset($this->function) && !function_exists($this->function)) + { + global $acm_type; + + trigger_error("The required function [{$this->function}] is not available for the ACM module $acm_type.", E_USER_ERROR); + } } /** @@ -359,7 +366,7 @@ class acm_memory { if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) { - return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field] : false; + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++][$field] : false; } return false; diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 849c076f0e..25e51814c4 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -124,11 +124,11 @@ class acp_attachments 'legend2' => $l_legend_cat_images, 'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' px'), + 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => ' <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), - 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' px'), - 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' px'), + 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), + 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), ) ); diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 9f0bcf210f..20a63e646e 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -29,6 +29,7 @@ class acp_board { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $cache; $user->add_lang('acp/board'); @@ -266,14 +267,22 @@ class acp_board 'legend1' => 'ACP_FEED_GENERAL', 'feed_enable' => array('lang' => 'ACP_FEED_ENABLE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_item_statistics' => array('lang' => 'ACP_FEED_ITEM_STATISTICS', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), - 'feed_limit' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), - 'feed_overall_forums' => array('lang' => 'ACP_FEED_OVERALL_FORUMS', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), - 'feed_overall_forums_limit' => array('lang' => 'ACP_FEED_OVERALL_FORUMS_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => false), - 'feed_overall_topics' => array('lang' => 'ACP_FEED_OVERALL_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), - 'feed_overall_topics_limit' => array('lang' => 'ACP_FEED_OVERALL_TOPIC_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => false), + 'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), + + 'legend2' => 'ACP_FEED_POST_BASED', + 'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), + 'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), + + 'legend3' => 'ACP_FEED_TOPIC_BASED', + 'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5', 'type' => 'text:3:4', 'explain' => true), + 'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), + 'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true), + + 'legend4' => 'ACP_FEED_SETTINGS_OTHER', + 'feed_overall_forums' => array('lang' => 'ACP_FEED_OVERALL_FORUMS', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_exclude_id' => array('lang' => 'ACP_FEED_EXCLUDE_ID', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_exclude_forums', 'explain' => true), ) ); @@ -469,6 +478,9 @@ class acp_board // Store news and exclude ids if ($mode == 'feed' && $submit) { + $cache->destroy('_feed_news_forum_ids'); + $cache->destroy('_feed_excluded_forum_ids'); + $this->store_feed_forums(FORUM_OPTION_FEED_NEWS, 'feed_news_id'); $this->store_feed_forums(FORUM_OPTION_FEED_EXCLUDE, 'feed_exclude_id'); } @@ -910,7 +922,7 @@ class acp_board { global $user, $config; - $forum_list = make_forum_select(false, false, true, false, false, false, true); + $forum_list = make_forum_select(false, false, true, true, true, false, true); // Build forum options $s_forum_options = '<select id="' . $key . '" name="' . $key . '[]" multiple="multiple">'; diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index e1fa764191..56a57e319c 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -56,6 +56,7 @@ class acp_captcha 'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false), 'confirm_refresh' => array('tpl' => 'CONFIRM_REFRESH', 'default' => false), 'max_reg_attempts' => array('tpl' => 'REG_LIMIT', 'default' => 0), + 'max_login_attempts' => array('tpl' => 'MAX_LOGIN_ATTEMPTS', 'default' => 0), ); $this->tpl_name = 'acp_captcha'; diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 3d0c0a2780..1a12c4967c 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -90,22 +90,19 @@ class acp_inactive if ($action == 'activate') { - if ($config['require_activation'] == USER_ACTIVATION_ADMIN) + // Get those 'being activated'... + $sql = 'SELECT user_id, username' . (($config['require_activation'] == USER_ACTIVATION_ADMIN) ? ', user_email, user_lang' : '') . ' + FROM ' . USERS_TABLE . ' + WHERE ' . $db->sql_in_set('user_id', $mark) . ' + AND user_type = ' . USER_INACTIVE; + $result = $db->sql_query($sql); + + $inactive_users = array(); + while ($row = $db->sql_fetchrow($result)) { - // Get those 'being activated'... - $sql = 'SELECT user_id, username, user_email, user_lang - FROM ' . USERS_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', $mark) . ' - AND user_type = ' . USER_INACTIVE; - $result = $db->sql_query($sql); - - $inactive_users = array(); - while ($row = $db->sql_fetchrow($result)) - { - $inactive_users[] = $row; - } - $db->sql_freeresult($result); + $inactive_users[] = $row; } + $db->sql_freeresult($result); user_active_flip('activate', $mark); @@ -136,6 +133,15 @@ class acp_inactive $messenger->save_queue(); } + if (!empty($inactive_users)) + { + foreach ($inactive_users as $row) + { + add_log('admin', 'LOG_USER_ACTIVE', $row['username']); + add_log('user', $row['user_id'], 'LOG_USER_ACTIVE_USER'); + } + } + // For activate we really need to redirect, else a refresh can result in users being deactivated again $u_action = $this->u_action . "&$u_sort_param&start=$start"; $u_action .= ($per_page != $config['topics_per_page']) ? "&users_per_page=$per_page" : ''; diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php index 3ab6eb64ed..9925527b34 100644 --- a/phpBB/includes/acp/acp_jabber.php +++ b/phpBB/includes/acp/acp_jabber.php @@ -44,13 +44,13 @@ class acp_jabber $this->tpl_name = 'acp_jabber'; $this->page_title = 'ACP_JABBER_SETTINGS'; - $jab_enable = request_var('jab_enable', $config['jab_enable']); - $jab_host = request_var('jab_host', $config['jab_host']); - $jab_port = request_var('jab_port', $config['jab_port']); - $jab_username = request_var('jab_username', $config['jab_username']); - $jab_password = request_var('jab_password', $config['jab_password']); - $jab_package_size = request_var('jab_package_size', $config['jab_package_size']); - $jab_use_ssl = request_var('jab_use_ssl', $config['jab_use_ssl']); + $jab_enable = request_var('jab_enable', (bool) $config['jab_enable']); + $jab_host = request_var('jab_host', (string) $config['jab_host']); + $jab_port = request_var('jab_port', (int) $config['jab_port']); + $jab_username = request_var('jab_username', (string) $config['jab_username']); + $jab_password = request_var('jab_password', (string) $config['jab_password']); + $jab_package_size = request_var('jab_package_size', (int) $config['jab_package_size']); + $jab_use_ssl = request_var('jab_use_ssl', (bool) $config['jab_use_ssl']); $form_name = 'acp_jabber'; add_form_key($form_name); @@ -117,7 +117,7 @@ class acp_jabber 'JAB_ENABLE' => $jab_enable, 'L_JAB_SERVER_EXPLAIN' => sprintf($user->lang['JAB_SERVER_EXPLAIN'], '<a href="http://www.jabber.org/">', '</a>'), 'JAB_HOST' => $jab_host, - 'JAB_PORT' => $jab_port, + 'JAB_PORT' => ($jab_port) ? $jab_port : '', 'JAB_USERNAME' => $jab_username, 'JAB_PASSWORD' => $jab_password, 'JAB_PACKAGE_SIZE' => $jab_package_size, diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index cd83c52e01..b8712b2a3d 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -398,6 +398,14 @@ class acp_main // Version check $user->add_lang('install'); + if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.2.0', '<')) + { + $template->assign_vars(array( + 'S_PHP_VERSION_OLD' => true, + 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], '<a href="http://www.phpbb.com/community/viewtopic.php?f=14&t=1958605">', '</a>'), + )); + } + $latest_version_info = false; if (($latest_version_info = obtain_latest_version_info(request_var('versioncheck_force', false))) === false) { diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index fbf3eadcb2..d2a0f9210f 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -643,6 +643,11 @@ parse_css_file = {PARSE_CSS_FILE} { while (($file = readdir($dp)) !== false) { + if (!is_dir($phpbb_root_path . 'styles/' . $file)) + { + continue; + } + $subpath = ($mode != 'style') ? "$mode/" : ''; if ($file[0] != '.' && file_exists("{$phpbb_root_path}styles/$file/$subpath$mode.cfg")) { diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index afca056eb2..4905840e02 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1416,7 +1416,7 @@ class acp_users $now = getdate(); $s_birthday_year_options = '<option value="0"' . ((!$data['bday_year']) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = $now['year'] - 100; $i < $now['year']; $i++) + for ($i = $now['year'] - 100; $i <= $now['year']; $i++) { $selected = ($i == $data['bday_year']) ? ' selected="selected"' : ''; $s_birthday_year_options .= "<option value=\"$i\"$selected>$i</option>"; diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index 71f8a7c082..73c4f92976 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -62,16 +62,22 @@ function login_db(&$username, &$password) 'user_row' => array('user_id' => ANONYMOUS), ); } + $show_captcha = $config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']; // If there are too much login attempts, we need to check for an confirm image // Every auth module is able to define what to do by itself... - if ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']) + if ($show_captcha) { // Visual Confirmation handling + if (!class_exists('phpbb_captcha_factory')) + { + global $phpbb_root_path, $phpEx; + include ($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx); + } $captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']); $captcha->init(CONFIRM_LOGIN); - $vc_response = $captcha->validate(); + $vc_response = $captcha->validate($row); if ($vc_response) { return array( @@ -80,6 +86,10 @@ function login_db(&$username, &$password) 'user_row' => $row, ); } + else + { + $captcha->reset(); + } } @@ -189,8 +199,8 @@ function login_db(&$username, &$password) // Give status about wrong password... return array( - 'status' => LOGIN_ERROR_PASSWORD, - 'error_msg' => 'LOGIN_ERROR_PASSWORD', + 'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD, + 'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD', 'user_row' => $row, ); } diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php index 1effada666..a0142292ed 100644 --- a/phpBB/includes/cache.php +++ b/phpBB/includes/cache.php @@ -86,7 +86,7 @@ class cache extends acm { if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false) { - $censors['match'][] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#u'; + $censors['match'][] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#iu'; } else { diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php index db4b7649c7..e7b8742b05 100644 --- a/phpBB/includes/captcha/plugins/captcha_abstract.php +++ b/phpBB/includes/captcha/plugins/captcha_abstract.php @@ -193,6 +193,11 @@ class phpbb_default_captcha { global $config, $db, $user; + if (empty($user->lang)) + { + $user->setup(); + } + $error = ''; if (!$this->confirm_id) { diff --git a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php index 45811c5d26..ef4d8e9fac 100644 --- a/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_captcha_qa_plugin.php @@ -87,9 +87,9 @@ class phpbb_captcha_qa } $db->sql_freeresult($result); } - - // okay, if there is a confirm_id, we try to load that confirm's state - if (!strlen($this->confirm_id) || !$this->load_answer()) + + // okay, if there is a confirm_id, we try to load that confirm's state. If not, we try to find one + if (!$this->load_answer() && (!$this->load_confirm_id() || !$this->load_answer())) { // we have no valid confirm ID, better get ready to ask something $this->select_question(); @@ -214,6 +214,22 @@ class phpbb_captcha_qa */ function get_demo_template() { + global $config, $db, $template; + + if ($this->is_available()) + { + $sql = 'SELECT question_text + FROM ' . CAPTCHA_QUESTIONS_TABLE . " + WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; + $result = $db->sql_query_limit($sql, 1); + if ($row = $db->sql_fetchrow($result)) + { + $template->assign_vars(array( + 'QA_CONFIRM_QUESTION' => $row['question_text'], + )); + } + $db->sql_freeresult($result); + } return 'captcha_qa_acp_demo.html'; } @@ -237,11 +253,11 @@ class phpbb_captcha_qa /** * API function */ - function garbage_collect($type) + function garbage_collect($type = 0) { global $db, $config; - $sql = 'SELECT DISTINCT c.session_id + $sql = 'SELECT c.confirm_id FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' c LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) @@ -255,14 +271,14 @@ class phpbb_captcha_qa do { - $sql_in[] = (string) $row['session_id']; + $sql_in[] = (string) $row['confirm_id']; } while ($row = $db->sql_fetchrow($result)); if (sizeof($sql_in)) { $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' - WHERE ' . $db->sql_in_set('session_id', $sql_in); + WHERE ' . $db->sql_in_set('confirm_id', $sql_in); $db->sql_query($sql); } } @@ -393,7 +409,6 @@ class phpbb_captcha_qa { global $db, $user; - if (!sizeof($this->question_ids)) { return false; @@ -458,6 +473,32 @@ class phpbb_captcha_qa $this->load_answer(); } + + /** + * See if there is already an entry for the current session. + */ + function load_confirm_id() + { + global $db, $user; + + $sql = 'SELECT confirm_id + FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " + WHERE + session_id = '" . $db->sql_escape($user->session_id) . "' + AND lang_iso = '" . $db->sql_escape($this->question_lang) . "' + AND confirm_type = " . $this->type; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if ($row) + { + $this->confirm_id = $row['confirm_id']; + return true; + } + return false; + } + /** * Look up everything we need and populate the instance variables. */ @@ -465,7 +506,7 @@ class phpbb_captcha_qa { global $db, $user; - if (!sizeof($this->question_ids)) + if (!strlen($this->confirm_id) || !sizeof($this->question_ids)) { return false; } @@ -617,21 +658,28 @@ class phpbb_captcha_qa } else if ($question_id && $action == 'delete') { - if (confirm_box(true)) + if ($this->get_class_name() !== $config['captcha_plugin'] || !$this->acp_is_last($question_id)) { - $this->acp_delete_question($question_id); + if (confirm_box(true)) + { + $this->acp_delete_question($question_id); - trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url)); + trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url)); + } + else + { + confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( + 'question_id' => $question_id, + 'action' => $action, + 'configure' => 1, + 'select_captcha' => $this->get_class_name(), + )) + ); + } } else { - confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( - 'question_id' => $question_id, - 'action' => $action, - 'configure' => 1, - 'select_captcha' => $this->get_class_name(), - )) - ); + trigger_error($user->lang['QA_LAST_QUESTION'] . adm_back_link($list_url), E_USER_WARNING); } } else @@ -711,7 +759,7 @@ class phpbb_captcha_qa } else if ($submit) { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url)); + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url), E_USER_WARNING); } } } @@ -942,6 +990,33 @@ class phpbb_captcha_qa return $langs; } + + + + /** + * See if there is a question other than the one we have + */ + function acp_is_last($question_id) + { + global $config, $db; + + if ($question_id) + { + $sql = 'SELECT question_id + FROM ' . CAPTCHA_QUESTIONS_TABLE . " + WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "' + AND question_id <> " . (int) $question_id; + $result = $db->sql_query_limit($sql, 1); + $question = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$question) + { + return true; + } + return false; + } + } } ?>
\ No newline at end of file diff --git a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php index d4543dddfc..0f0bfc4156 100644 --- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php @@ -28,10 +28,17 @@ if (!class_exists('phpbb_default_captcha')) class phpbb_recaptcha extends phpbb_default_captcha { var $recaptcha_server = 'http://api.recaptcha.net'; + var $recaptcha_server_secure = 'https://api-secure.recaptcha.net'; // class constants :( var $recaptcha_verify_server = 'api-verify.recaptcha.net'; var $challenge; var $response; + // PHP4 Constructor + function phpbb_recaptcha() + { + $this->recaptcha_server = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? $this->recaptcha_server_secure : $this->recaptcha_server; + } + function init($type) { global $config, $db, $user; diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 398611d24e..c592e7ef57 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -25,7 +25,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.0.6'); +define('PHPBB_VERSION', '3.0.7-RC1'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index a762b31681..7123c83e51 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -1348,7 +1348,29 @@ class phpbb_db_tools break; case 'postgres': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; + if (version_compare($this->db->sql_server_info(true), '8.0', '>=')) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql']; + } + else + { + // old versions cannot add columns with default and null information + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type'] . ' ' . $column_data['constraint']; + + if (isset($column_data['null'])) + { + if ($column_data['null'] == 'NOT NULL') + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET NOT NULL'; + } + } + + if (isset($column_data['default'])) + { + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default']; + } + } + break; case 'sqlite': diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index c03b38708c..0487dfa6d2 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -44,7 +44,7 @@ class dbal_mysql extends dbal $this->sql_layer = 'mysql4'; - $this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $sqlpassword, $new_link) : @mysql_connect($this->server, $this->user, $sqlpassword, $new_link); + $this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $sqlpassword) : @mysql_connect($this->server, $this->user, $sqlpassword, $new_link); if ($this->db_connect_id && $this->dbname != '') { diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e787932441..823c71dbf0 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3921,6 +3921,108 @@ function phpbb_optionset($bit, $set, $data) } /** +* Login using http authenticate. +* +* @param array $param Parameter array, see $param_defaults array. +* +* @return void +*/ +function phpbb_http_login($param) +{ + global $auth, $user; + global $config; + + $param_defaults = array( + 'auth_message' => '', + + 'autologin' => false, + 'viewonline' => true, + 'admin' => false, + ); + + // Overwrite default values with passed values + $param = array_merge($param_defaults, $param); + + // User is already logged in + // We will not overwrite his session + if (!empty($user->data['is_registered'])) + { + return; + } + + // $_SERVER keys to check + $username_keys = array( + 'PHP_AUTH_USER', + 'Authorization', + 'REMOTE_USER', 'REDIRECT_REMOTE_USER', + 'HTTP_AUTHORIZATION', 'REDIRECT_HTTP_AUTHORIZATION', + 'REMOTE_AUTHORIZATION', 'REDIRECT_REMOTE_AUTHORIZATION', + 'AUTH_USER', + ); + + $password_keys = array( + 'PHP_AUTH_PW', + 'REMOTE_PASSWORD', + 'AUTH_PASSWORD', + ); + + $username = null; + foreach ($username_keys as $k) + { + if (isset($_SERVER[$k])) + { + $username = $_SERVER[$k]; + break; + } + } + + $password = null; + foreach ($password_keys as $k) + { + if (isset($_SERVER[$k])) + { + $password = $_SERVER[$k]; + break; + } + } + + // Decode encoded information (IIS, CGI, FastCGI etc.) + if (!is_null($username) && is_null($password) && strpos($username, 'Basic ') === 0) + { + list($username, $password) = explode(':', base64_decode(substr($username, 6)), 2); + } + + if (!is_null($username) && !is_null($password)) + { + set_var($username, $username, 'string', true); + set_var($password, $password, 'string', true); + + $auth_result = $auth->login($username, $password, $param['autologin'], $param['viewonline'], $param['admin']); + + if ($auth_result['status'] == LOGIN_SUCCESS) + { + return; + } + else if ($auth_result['status'] == LOGIN_ERROR_ATTEMPTS) + { + header('HTTP/1.0 401 Unauthorized'); + trigger_error('NOT_AUTHORISED'); + } + } + + // Prepend sitename to auth_message + $param['auth_message'] = ($param['auth_message'] === '') ? $config['sitename'] : $config['sitename'] . ' - ' . $param['auth_message']; + + // We should probably filter out non-ASCII characters - RFC2616 + $param['auth_message'] = preg_replace('/[\x80-\xFF]/', '?', $param['auth_message']); + + header('WWW-Authenticate: Basic realm="' . $param['auth_message'] . '"'); + header('HTTP/1.0 401 Unauthorized'); + + trigger_error('NOT_AUTHORISED'); +} + +/** * Generate page header */ function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum') @@ -3959,7 +4061,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 $s_last_visit = ($user->data['user_id'] != ANONYMOUS) ? $user->format_date($user->data['session_last_visit']) : ''; // Get users online list ... if required - $l_online_users = $online_userlist = $l_online_record = ''; + $l_online_users = $online_userlist = $l_online_record = $l_online_time = ''; if ($config['load_online'] && $config['load_online_time'] && $display_online_list) { @@ -3982,15 +4084,11 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 set_config('record_online_date', time(), true); } - $l_online_record = sprintf($user->lang['RECORD_ONLINE_USERS'], $config['record_online_users'], $user->format_date($config['record_online_date'])); + $l_online_record = sprintf($user->lang['RECORD_ONLINE_USERS'], $config['record_online_users'], $user->format_date($config['record_online_date'], false, true)); $l_online_time = ($config['load_online_time'] == 1) ? 'VIEW_ONLINE_TIME' : 'VIEW_ONLINE_TIMES'; $l_online_time = sprintf($user->lang[$l_online_time], $config['load_online_time']); } - else - { - $l_online_time = ''; - } $l_privmsgs_text = $l_privmsgs_text_unread = ''; $s_privmsg_new = false; @@ -4139,11 +4237,14 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_FORUM_ID' => $forum_id, 'S_TOPIC_ID' => $topic_id, - 'S_LOGIN_ACTION' => (!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') . '&redirect=' . urlencode(str_replace('&', '&', build_url())) : append_sid("index.$phpEx", false, true, $user->session_id) . '&redirect=' . urlencode(str_replace('&', '&', build_url())), + 'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("index.$phpEx", false, true, $user->session_id)), + 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => str_replace('&', '&', build_url()))), 'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false, + 'S_ENABLE_FEEDS_OVERALL' => ($config['feed_overall']) ? true : false, 'S_ENABLE_FEEDS_FORUMS' => ($config['feed_overall_forums']) ? true : false, - 'S_ENABLE_FEEDS_TOPICS' => ($config['feed_overall_topics']) ? true : false, + 'S_ENABLE_FEEDS_TOPICS' => ($config['feed_topics_new']) ? true : false, + 'S_ENABLE_FEEDS_TOPICS_ACTIVE' => ($config['feed_topics_active']) ? true : false, 'S_ENABLE_FEEDS_NEWS' => ($s_feed_news) ? true : false, 'T_THEME_PATH' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme', @@ -4158,7 +4259,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", - 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->data['user_lang']), + 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->data['user_lang'], true, $user->session_id), 'T_STYLESHEET_NAME' => $user->theme['theme_name'], 'T_THEME_NAME' => $user->theme['theme_path'], diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index ddadda8ed2..a1bc2e7795 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -66,8 +66,6 @@ function make_forum_select($select_id = false, $ignore_id = false, $ignore_acl = { global $db, $user, $auth; - $acl = ($ignore_acl) ? '' : (($only_acl_post) ? 'f_post' : array('f_list', 'a_forum', 'a_forumadd', 'a_forumdel')); - // This query is identical to the jumpbox one $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, forum_flags, forum_options, left_id, right_id FROM ' . FORUMS_TABLE . ' @@ -98,18 +96,21 @@ function make_forum_select($select_id = false, $ignore_id = false, $ignore_acl = $right = $row['right_id']; $disabled = false; - if ($acl && !$auth->acl_gets($acl, $row['forum_id'])) + if (!$ignore_acl && $auth->acl_get('f_list', $row['forum_id'])) { - // List permission? - if ($auth->acl_get('f_list', $row['forum_id'])) + if ($only_acl_post && !$auth->acl_get('f_post', $row['forum_id']) || (!$auth->acl_get('m_approve', $row['forum_id']) && !$auth->acl_get('f_noapprove', $row['forum_id']))) { $disabled = true; } - else + else if (!$only_acl_post && !$auth->acl_gets(array('a_forum', 'a_forumadd', 'a_forumdel'), $row['forum_id'])) { - continue; + $disabled = true; } } + else if (!$ignore_acl) + { + continue; + } if ( ((is_array($ignore_id) && in_array($row['forum_id'], $ignore_id)) || $row['forum_id'] == $ignore_id) diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index 590daabf1d..f17c780a65 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -80,6 +80,11 @@ class compress } } } + else + { + // $src does not exist + return false; + } return true; } @@ -89,6 +94,11 @@ class compress */ function add_custom_file($src, $filename) { + if (!file_exists($src)) + { + return false; + } + $this->data($filename, file_get_contents($src), false, stat($src)); return true; } diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index c265d0ae41..faff9dd0de 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -1106,10 +1106,11 @@ function extension_allowed($forum_id, $extension, &$extensions) * @param string $string The text to truncate to the given length. String is specialchared. * @param int $max_length Maximum length of string (multibyte character count as 1 char / Html entity count as 1 char) * @param int $max_store_length Maximum character length of string (multibyte character count as 1 char / Html entity count as entity chars). -* @param bool $allow_reply Allow Re: in front of string +* @param bool $allow_reply Allow Re: in front of string +* NOTE: This parameter can cause undesired behavior (returning strings longer than $max_store_legnth) and is deprecated. * @param string $append String to be appended */ -function truncate_string($string, $max_length = 60, $max_store_length = 255, $allow_reply = true, $append = '') +function truncate_string($string, $max_length = 60, $max_store_length = 255, $allow_reply = false, $append = '') { $chars = array(); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 58cbdaef5b..f49aa42324 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -594,7 +594,7 @@ function generate_forum_nav(&$forum_data) 'FORUM_NAME' => $forum_data['forum_name'], 'FORUM_DESC' => generate_text_for_display($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options']), - 'S_ENABLE_FEEDS_FORUM' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $forum_data['forum_options'])) ? true : false, + 'S_ENABLE_FEEDS_FORUM' => ($config['feed_forum'] && $forum_data['forum_type'] == FORUM_POST && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $forum_data['forum_options'])) ? true : false, )); return; diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index a5889224a1..1b9c66fc84 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -23,7 +23,14 @@ function can_load_dll($dll) { // SQLite2 is a tricky thing, from 5.0.0 it requires PDO; if PDO is not loaded we must state that SQLite is unavailable // as the installer doesn't understand that the extension has a prerequisite. - if ($dll == 'sqlite' && version_compare(PHP_VERSION, '5.0.0', '>=') && !extension_loaded('pdo')) + // + // On top of this sometimes the SQLite extension is compiled for a different version of PDO + // by some Linux distributions which causes phpBB to bomb out with a blank page. + // + // Net result we'll disable automatic inclusion of SQLite support + // + // See: r9618 and #56105 + if ($dll == 'sqlite') { return false; } diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 8f4e582b3c..99883cd9ca 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -184,6 +184,9 @@ class messenger if (!trim($template_lang)) { + // fall back to board default language if the user's language is + // missing $template_file. If this does not exist either, + // $tpl->set_custom_template will do a trigger_error $template_lang = basename($config['default_lang']); } @@ -193,13 +196,23 @@ class messenger $this->tpl_msg[$template_lang . $template_file] = new template(); $tpl = &$this->tpl_msg[$template_lang . $template_file]; + $fallback_template_path = false; + if (!$template_path) { $template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; $template_path .= $template_lang . '/email'; + + // we can only specify default language fallback when the path is not a custom one for which we + // do not know the default language alternative + if ($template_lang !== basename($config['default_lang'])) + { + $fallback_template_path = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; + $fallback_template_path .= basename($config['default_lang']) . '/email'; + } } - $tpl->set_custom_template($template_path, $template_lang . '_email', 'email'); + $tpl->set_custom_template($template_path, $template_lang . '_email', $fallback_template_path); $tpl->set_filenames(array( 'body' => $template_file . '.txt', diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 069740ebda..0a31ea49a8 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -88,7 +88,7 @@ function generate_smilies($mode, $forum_id) $sql = 'SELECT smiley_url, MIN(emotion) as emotion, MIN(code) AS code, smiley_width, smiley_height FROM ' . SMILIES_TABLE . ' GROUP BY smiley_url, smiley_width, smiley_height - ORDER BY smiley_order'; + ORDER BY MIN(smiley_order)'; $result = $db->sql_query_limit($sql, $config['smilies_per_page'], $start, 3600); } else @@ -2525,7 +2525,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u VALUES (' . $user->data['user_id'] . ', ' . $data['topic_id'] . ')'; $db->sql_query($sql); } - else if ($data['notify_set'] && !$data['notify']) + else if (($config['email_enable'] || $config['jab_enable']) && $data['notify_set'] && !$data['notify']) { $sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . ' WHERE user_id = ' . $user->data['user_id'] . ' diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index c93b6a6bba..4fc5034f7b 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -894,6 +894,13 @@ function handle_mark_actions($user_id, $mark_action) case 'delete_marked': + global $auth; + + if (!$auth->acl_get('u_pm_delete')) + { + trigger_error('NO_AUTH_DELETE_MESSAGE'); + } + if (confirm_box(true)) { delete_pm($user_id, $msg_ids, $cur_folder_id); diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index db1925bdcc..61e3587158 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -158,11 +158,11 @@ class custom_profile case FIELD_STRING: case FIELD_TEXT: - if (empty($field_value) && !$field_data['field_required']) + if (trim($field_value) === '' && !$field_data['field_required']) { return false; } - else if (empty($field_value) && $field_data['field_required']) + else if (trim($field_value) === '' && $field_data['field_required']) { return 'FIELD_REQUIRED'; } diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index 429e19b668..6da810a489 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -175,7 +175,7 @@ class mcp_logs $template->assign_vars(array( 'PAGE_NUMBER' => on_page($log_count, $config['topics_per_page'], $start), 'TOTAL' => ($log_count == 1) ? $user->lang['TOTAL_LOG'] : sprintf($user->lang['TOTAL_LOGS'], $log_count), - 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start, true), + 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start), 'L_TITLE' => $user->lang['MCP_LOGS'], diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 50b05e989f..80c3559649 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -568,7 +568,7 @@ function mcp_move_topic($topic_ids) { $additional_msg = $user->lang['FORUM_NOT_POSTABLE']; } - else if (!$auth->acl_get('f_post', $to_forum_id)) + else if (!$auth->acl_get('f_post', $to_forum_id) || (!$auth->acl_get('m_approve', $to_forum_id) && !$auth->acl_get('f_noapprove', $to_forum_id))) { $additional_msg = $user->lang['USER_CANNOT_POST']; } diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 757860e1af..c684eb6f52 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -198,7 +198,7 @@ class mcp_notes $log_data = array(); $log_count = 0; - view_log('user', $log_data, $log_count, $config['posts_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort, $keywords); + view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort, $keywords); if ($log_count) { @@ -226,8 +226,8 @@ class mcp_notes 'L_TITLE' => $user->lang['MCP_NOTES_USER'], - 'PAGE_NUMBER' => on_page($log_count, $config['posts_per_page'], $start), - 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start, true), + 'PAGE_NUMBER' => on_page($log_count, $config['topics_per_page'], $start), + 'PAGINATION' => generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start), 'TOTAL_REPORTS' => ($log_count == 1) ? $user->lang['LIST_REPORT'] : sprintf($user->lang['LIST_REPORTS'], $log_count), 'RANK_TITLE' => $rank_title, diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index abdb839e7b..9779478330 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -106,7 +106,14 @@ function mcp_topic_view($id, $mode, $action) if ($total == -1) { - $total = $topic_info['topic_replies'] + 1; + if ($auth->acl_get('m_approve', $topic_info['forum_id'])) + { + $total = $topic_info['topic_replies_real'] + 1; + } + else + { + $total = $topic_info['topic_replies'] + 1; + } } $posts_per_page = max(0, request_var('posts_per_page', intval($config['posts_per_page']))); diff --git a/phpBB/includes/questionnaire/questionnaire.php b/phpBB/includes/questionnaire/questionnaire.php index 659c088763..cbd7638809 100644 --- a/phpBB/includes/questionnaire/questionnaire.php +++ b/phpBB/includes/questionnaire/questionnaire.php @@ -162,25 +162,59 @@ class phpbb_questionnaire_system_data_provider $server_address = $_SERVER['LOCAL_ADDR']; } - $ip_address_ary = explode('.', $server_address); - - // build ip - if (!isset($ip_address_ary[0]) || !isset($ip_address_ary[1])) - { - $ip_address_ary = explode('.', '0.0.0.0'); - } - return array( 'os' => PHP_OS, 'httpd' => $_SERVER['SERVER_SOFTWARE'], // we don't want the real IP address (for privacy policy reasons) but only // a network address to see whether your installation is running on a private or public network. + 'private_ip' => $this->is_private_ip($server_address), + 'ipv6' => strpos($server_address, ':') !== false, + ); + } + + /** + * Checks whether the given IP is in a private network. + * + * @param string $ip IP in v4 dot-decimal or v6 hex format + * @return bool true if the IP is from a private network, else false + */ + function is_private_ip($ip) + { + // IPv4 + if (strpos($ip, ':') === false) + { + $ip_address_ary = explode('.', $ip); + + // build ip + if (!isset($ip_address_ary[0]) || !isset($ip_address_ary[1])) + { + $ip_address_ary = explode('.', '0.0.0.0'); + } + // IANA reserved addresses for private networks (RFC 1918) are: // - 10.0.0.0/8 // - 172.16.0.0/12 // - 192.168.0.0/16 - 'ip' => $ip_address_ary[0] . '.' . $ip_address_ary[1] . '.XXX.YYY', - ); + if ($ip_address_ary[0] == '10' || + ($ip_address_ary[0] == '172' && intval($ip_address_ary[1]) > 15 && intval($ip_address_ary[1]) < 32) || + ($ip_address_ary[0] == '192' && $ip_address_ary[1] == '168') || + ($ip_address_ary[0] == '192' && $ip_address_ary[1] == '168')) + { + return true; + } + } + // IPv6 + else + { + // unique local unicast + $prefix = substr($ip, 0, 2); + if ($prefix == 'fc' || $prefix == 'fd') + { + return true; + } + } + + return false; } } @@ -233,6 +267,7 @@ class phpbb_questionnaire_phpbb_data_provider { global $phpbb_root_path, $phpEx; include("{$phpbb_root_path}config.$phpEx"); + unset($dbhost, $dbport, $dbname, $dbuser, $dbpasswd); // Just a precaution // Only send certain config vars $config_vars = array( @@ -315,13 +350,15 @@ class phpbb_questionnaire_phpbb_data_provider 'enable_pm_icons' => true, 'enable_post_confirm' => true, 'feed_enable' => true, - 'feed_limit' => true, + 'feed_http_auth' => true, + 'feed_limit_post' => true, + 'feed_limit_topic' => true, + 'feed_overall' => true, 'feed_overall_forums' => true, - 'feed_overall_forums_limit' => true, - 'feed_overall_topics' => true, - 'feed_overall_topics_limit' => true, 'feed_forum' => true, 'feed_topic' => true, + 'feed_topics_new' => true, + 'feed_topics_active' => true, 'feed_item_statistics' => true, 'flood_interval' => true, 'force_server_vars' => true, @@ -445,10 +482,13 @@ class phpbb_questionnaire_phpbb_data_provider } } + global $db; + $result['dbms'] = $dbms; $result['acm_type'] = $acm_type; $result['load_extensions'] = $load_extensions; $result['user_agent'] = 'Unknown'; + $result['dbms_version'] = $db->sql_server_info(true); // Try to get user agent vendor and version $match = array(); diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index d1c1ff00d1..da3833754e 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -444,7 +444,7 @@ class fulltext_mysql extends search_backend if (sizeof($author_ary) && $author_name) { // first one matches post of registered users, second one guests and deleted users - $sql_author = '(' . $db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')'; + $sql_author = ' AND (' . $db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')'; } else if (sizeof($author_ary)) { @@ -473,7 +473,7 @@ class fulltext_mysql extends search_backend while ($row = $db->sql_fetchrow($result)) { - $id_ary[] = $row[$field]; + $id_ary[] = (int) $row[$field]; } $db->sql_freeresult($result); @@ -650,7 +650,7 @@ class fulltext_mysql extends search_backend while ($row = $db->sql_fetchrow($result)) { - $id_ary[] = $row[$field]; + $id_ary[] = (int) $row[$field]; } $db->sql_freeresult($result); diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 5af3929ccd..c89e92711e 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -202,7 +202,8 @@ class fulltext_native extends search_backend { $sql = 'SELECT word_id, word_text, word_common FROM ' . SEARCH_WORDLIST_TABLE . ' - WHERE ' . $db->sql_in_set('word_text', $exact_words); + WHERE ' . $db->sql_in_set('word_text', $exact_words) . ' + ORDER BY word_count ASC'; $result = $db->sql_query($sql); // store an array of words and ids, remove common words @@ -377,10 +378,6 @@ class fulltext_native extends search_backend return false; } - sort($this->must_contain_ids); - sort($this->must_not_contain_ids); - sort($this->must_exclude_one_ids); - if (!empty($this->search_query)) { return true; @@ -420,11 +417,19 @@ class fulltext_native extends search_backend return false; } + $must_contain_ids = $this->must_contain_ids; + $must_not_contain_ids = $this->must_not_contain_ids; + $must_exclude_one_ids = $this->must_exclude_one_ids; + + sort($must_contain_ids); + sort($must_not_contain_ids); + sort($must_exclude_one_ids); + // generate a search_key from all the options to identify the results $search_key = md5(implode('#', array( - serialize($this->must_contain_ids), - serialize($this->must_not_contain_ids), - serialize($this->must_exclude_one_ids), + serialize($must_contain_ids), + serialize($must_not_contain_ids), + serialize($must_exclude_one_ids), $type, $fields, $terms, @@ -739,7 +744,7 @@ class fulltext_native extends search_backend while ($row = $db->sql_fetchrow($result)) { - $id_ary[] = $row[(($type == 'posts') ? 'post_id' : 'topic_id')]; + $id_ary[] = (int) $row[(($type == 'posts') ? 'post_id' : 'topic_id')]; } $db->sql_freeresult($result); @@ -981,7 +986,7 @@ class fulltext_native extends search_backend while ($row = $db->sql_fetchrow($result)) { - $id_ary[] = $row[$field]; + $id_ary[] = (int) $row[$field]; } $db->sql_freeresult($result); diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index bf41fea7de..11f1896332 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1355,13 +1355,13 @@ class session { global $config, $db; - $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id; + $user_id = ($user_id === false) ? (int) $this->data['user_id'] : (int) $user_id; $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' WHERE user_id = ' . (int) $user_id; $db->sql_query($sql); - // Update last visit info first before deleting sessions + // If the user is logged in, update last visit info first before deleting sessions $sql = 'SELECT session_time, session_page FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . (int) $user_id . ' @@ -1370,15 +1370,18 @@ class session $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_lastvisit = ' . (int) $row['session_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "' - WHERE user_id = " . (int) $user_id; - $db->sql_query($sql); + if ($row) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_lastvisit = ' . (int) $row['session_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "' + WHERE user_id = " . (int) $user_id; + $db->sql_query($sql); + } // Let's also clear any current sessions for the specified user_id // If it's the current user then we'll leave this session intact $sql_where = 'session_user_id = ' . (int) $user_id; - $sql_where .= ($user_id === $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : ''; + $sql_where .= ($user_id === (int) $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : ''; $sql = 'DELETE FROM ' . SESSIONS_TABLE . " WHERE $sql_where"; @@ -1386,7 +1389,7 @@ class session // We're changing the password of the current user and they have a key // Lets regenerate it to be safe - if ($user_id === $this->data['user_id'] && $this->cookie_data['k']) + if ($user_id === (int) $this->data['user_id'] && $this->cookie_data['k']) { $this->set_login_key($user_id); } diff --git a/phpBB/includes/template.php b/phpBB/includes/template.php index af5c9d3a47..f1c8094a9b 100644 --- a/phpBB/includes/template.php +++ b/phpBB/includes/template.php @@ -90,7 +90,7 @@ class template * Set custom template location (able to use directory outside of phpBB) * @access public */ - function set_custom_template($template_path, $template_name, $template_mode = 'template') + function set_custom_template($template_path, $template_name, $fallback_template_path = false) { global $phpbb_root_path, $user; @@ -103,13 +103,25 @@ class template $this->root = $template_path; $this->cachepath = $phpbb_root_path . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_'; - // As the template-engine is used for more than the template (emails, etc.), we should not set $user->theme in all cases, but only on the real template. - if ($template_mode == 'template') + if ($fallback_template_path !== false) { - $user->theme['template_storedb'] = false; - $user->theme['template_inherits_id'] = false; + if (substr($fallback_template_path, -1) == '/') + { + $fallback_template_path = substr($fallback_template_path, 0, -1); + } + + $this->inherit_root = $fallback_template_path; + $this->orig_tpl_inherits_id = true; + } + else + { + $this->orig_tpl_inherits_id = false; } + // the database does not store the path or name of a custom template + // so there is no way we can properly store custom templates there + $this->orig_tpl_storedb = false; + $this->_rootref = &$this->_tpldata['.'][0]; return true; @@ -254,6 +266,12 @@ class template trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR); } + // reload these settings to have the values they had when this object was initialised + // using set_template or set_custom_template, they might otherwise have been overwritten + // by other template class instances in between. + $user->theme['template_storedb'] = $this->orig_tpl_storedb; + $user->theme['template_inherits_id'] = $this->orig_tpl_inherits_id; + $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . $phpEx; $this->files_template[$handle] = (isset($user->theme['template_id'])) ? $user->theme['template_id'] : 0; diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index d9e3deaa41..4d72d45f81 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -767,7 +767,7 @@ function compose_pm($id, $mode, $action) $parse_sig->bbcode_uid = $preview_signature_uid; $parse_sig->bbcode_bitfield = $preview_signature_bitfield; - $parse_sig->format_display($enable_bbcode, $enable_urls, $enable_smilies); + $parse_sig->format_display($config['allow_sig_bbcode'], $config['allow_sig_links'], $config['allow_sig_smilies']); $preview_signature = $parse_sig->message; unset($parse_sig); } diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php index e80c0672cf..58c2d087c8 100644 --- a/phpBB/includes/ucp/ucp_pm_options.php +++ b/phpBB/includes/ucp/ucp_pm_options.php @@ -637,12 +637,29 @@ function define_action_option($hardcoded, $action_option, $action_lang, $folder) function define_rule_option($hardcoded, $rule_option, $rule_lang, $check_ary) { global $template; + global $module; + + $exclude = array(); + + if (!$module->loaded('zebra', 'friends')) + { + $exclude[RULE_IS_FRIEND] = true; + } + + if (!$module->loaded('zebra', 'foes')) + { + $exclude[RULE_IS_FOE] = true; + } $s_rule_options = ''; if (!$hardcoded) { foreach ($check_ary as $value => $_check) { + if (isset($exclude[$value])) + { + continue; + } $s_rule_options .= '<option value="' . $value . '"' . (($value == $rule_option) ? ' selected="selected"' : '') . '>' . $rule_lang[$value] . '</option>'; } } diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 33d2c9fb6f..665dd2c83f 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -65,6 +65,12 @@ function view_folder($id, $mode, $folder_id, $folder) $mark_options = array('mark_important', 'delete_marked'); + // Minimise edits + if (!$auth->acl_get('u_pm_delete') && $key = array_search('delete_marked', $mark_options)) + { + unset($mark_options[$key]); + } + $s_mark_options = ''; foreach ($mark_options as $mark_option) { @@ -194,13 +200,15 @@ function view_folder($id, $mode, $folder_id, $folder) else { // Build Recipient List if in outbox/sentbox - $address = $data = array(); + + $address_temp = $address = $data = array(); if ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) { foreach ($folder_info['rowset'] as $message_id => $row) { - $address[$message_id] = rebuild_header(array('to' => $row['to_address'], 'bcc' => $row['bcc_address'])); + $address_temp[$message_id] = rebuild_header(array('to' => $row['to_address'], 'bcc' => $row['bcc_address'])); + $address[$message_id] = array(); } } @@ -224,8 +232,12 @@ function view_folder($id, $mode, $folder_id, $folder) $_types = array('u', 'g'); foreach ($_types as $ug_type) { - if (isset($address[$message_id][$ug_type]) && sizeof($address[$message_id][$ug_type])) + if (isset($address_temp[$message_id][$ug_type]) && sizeof($address_temp[$message_id][$ug_type])) { + if (!isset($address[$message_id][$ug_type])) + { + $address[$message_id][$ug_type] = array(); + } if ($ug_type == 'u') { $sql = 'SELECT user_id as id, username as name @@ -238,21 +250,31 @@ function view_folder($id, $mode, $folder_id, $folder) FROM ' . GROUPS_TABLE . ' WHERE '; } - $sql .= $db->sql_in_set(($ug_type == 'u') ? 'user_id' : 'group_id', array_map('intval', array_keys($address[$message_id][$ug_type]))); + $sql .= $db->sql_in_set(($ug_type == 'u') ? 'user_id' : 'group_id', array_map('intval', array_keys($address_temp[$message_id][$ug_type]))); $result = $db->sql_query($sql); while ($info_row = $db->sql_fetchrow($result)) { - $address[$message_id][$ug_type][$address[$message_id][$ug_type][$info_row['id']]][] = $info_row['name']; - unset($address[$message_id][$ug_type][$info_row['id']]); + $address[$message_id][$ug_type][$address_temp[$message_id][$ug_type][$info_row['id']]][] = $info_row['name']; + unset($address_temp[$message_id][$ug_type][$info_row['id']]); } $db->sql_freeresult($result); } } - decode_message($message_row['message_text'], $message_row['bbcode_uid']); + // There is the chance that all recipients of the message got deleted. To avoid creating + // exports without recipients, we add a bogus "undisclosed recipient". + if (!(isset($address[$message_id]['g']) && sizeof($address[$message_id]['g'])) && + !(isset($address[$message_id]['u']) && sizeof($address[$message_id]['u']))) + { + $address[$message_id]['u'] = array(); + $address[$message_id]['u']['to'] = array(); + $address[$message_id]['u']['to'][] = $user->lang['UNDISCLOSED_RECIPIENT']; + } + decode_message($message_row['message_text'], $message_row['bbcode_uid']); + $data[] = array( 'subject' => censor_text($row['message_subject']), 'sender' => $row['username'], diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index e24acd89fc..f4f4abad4a 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -133,7 +133,7 @@ class ucp_profile $message = 'PROFILE_UPDATED'; - if ($config['email_enable'] && $data['email'] != $user->data['user_email'] && $user->data['user_type'] != USER_FOUNDER && ($config['require_activation'] == USER_ACTIVATION_SELF || $config['require_activation'] == USER_ACTIVATION_ADMIN)) + if ($auth->acl_get('u_chgemail') && $config['email_enable'] && $data['email'] != $user->data['user_email'] && $user->data['user_type'] != USER_FOUNDER && ($config['require_activation'] == USER_ACTIVATION_SELF || $config['require_activation'] == USER_ACTIVATION_ADMIN)) { $message = ($config['require_activation'] == USER_ACTIVATION_SELF) ? 'ACCOUNT_EMAIL_CHANGED' : 'ACCOUNT_EMAIL_CHANGED_ADMIN'; diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 8359c223e0..9656a4a3af 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -333,6 +333,12 @@ class ucp_register trigger_error('NO_USER', E_USER_ERROR); } + // Okay, captcha, your job is done. + if ($config['enable_confirm'] && isset($captcha)) + { + $captcha->reset(); + } + if ($coppa && $config['email_enable']) { $message = $user->lang['ACCOUNT_COPPA']; |
