aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml10
-rw-r--r--build/build.xml2
-rwxr-xr-xcomposer.pharbin799883 -> 960311 bytes
-rw-r--r--phpBB/adm/style/acp_users_overview.html2
-rw-r--r--phpBB/feed.php79
-rw-r--r--phpBB/includes/acp/acp_users.php10
-rw-r--r--phpBB/includes/functions.php8
-rw-r--r--phpBB/includes/functions_module.php6
-rw-r--r--phpBB/includes/mcp/mcp_queue.php6
-rw-r--r--phpBB/includes/search/fulltext_native.php39
-rw-r--r--phpBB/install/index.php3
-rw-r--r--phpBB/install/install_install.php4
-rw-r--r--phpBB/install/schemas/schema_data.sql2
-rw-r--r--phpBB/language/en/acp/ban.php4
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/language/en/acp/common.php2
-rw-r--r--phpBB/language/en/acp/users.php1
-rw-r--r--phpBB/language/en/common.php3
-rw-r--r--phpBB/search.php6
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/subsilver2/style.cfg2
-rw-r--r--phpBB/viewtopic.php8
-rw-r--r--tests/functional/acp_users_test.php45
-rw-r--r--tests/functions/parse_cfg_file_test.php103
-rw-r--r--tests/test_framework/phpbb_functional_test_case.php9
25 files changed, 297 insertions, 63 deletions
diff --git a/.travis.yml b/.travis.yml
index 44067cba3f..6915ba4304 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,14 +8,13 @@ php:
- 5.6
env:
- - DB=mariadb
- DB=mysql
- - DB=postgres
before_script:
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mariadb' ]; then travis/setup-mariadb.sh; fi"
+ - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3' -a '$DB' = 'mysql' ]; then mysql -e 'SET GLOBAL storage_engine=MyISAM;'; fi"
- sh -c "if [ '$DB' = 'mysql' -o '$DB' = 'mariadb' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; phpenv rehash; fi"
- cd phpBB
@@ -26,3 +25,10 @@ before_script:
script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then phpunit --configuration travis/phpunit-$DB-travis.xml; else phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysql' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi"
+
+matrix:
+ include:
+ - php: 5.4
+ env: DB=mariadb
+ - php: 5.4
+ env: DB=postgres
diff --git a/build/build.xml b/build/build.xml
index 83ddcd29c4..a86cb9c36b 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -221,7 +221,7 @@
command="git archive ${revision} composer.phar | tar -xf - -C ${dir}"
checkreturn="true" />
<exec dir="${dir}"
- command="php composer.phar install"
+ command="php composer.phar install --no-dev"
checkreturn="true"
passthru="true" />
<delete file="${dir}/composer.phar" />
diff --git a/composer.phar b/composer.phar
index a035fdc911..1e9ca731cd 100755
--- a/composer.phar
+++ b/composer.phar
Binary files differ
diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html
index ba350a13fb..964d6e5c17 100644
--- a/phpBB/adm/style/acp_users_overview.html
+++ b/phpBB/adm/style/acp_users_overview.html
@@ -30,7 +30,7 @@
</dl>
<dl>
<dt><label>{L_POSTS}:</label></dt>
- <dd><strong>{USER_POSTS}</strong><!-- IF POSTS_IN_QUEUE and U_MCP_QUEUE --> (<a href="{U_MCP_QUEUE}">{L_POSTS_IN_QUEUE}</a>)<!-- ELSEIF POSTS_IN_QUEUE --> ({L_POSTS_IN_QUEUE})<!-- ENDIF --></dd>
+ <dd><strong><!-- IF USER_HAS_POSTS and U_SEARCH_USER --><a href="{U_SEARCH_USER}">{USER_POSTS}</a><!-- ELSE -->{USER_POSTS}<!-- ENDIF --></strong><!-- IF POSTS_IN_QUEUE and U_MCP_QUEUE --> (<a href="{U_MCP_QUEUE}">{L_POSTS_IN_QUEUE}</a>)<!-- ELSEIF POSTS_IN_QUEUE --> ({L_POSTS_IN_QUEUE})<!-- ENDIF --></dd>
</dl>
<dl>
<dt><label>{L_WARNINGS}:</label></dt>
diff --git a/phpBB/feed.php b/phpBB/feed.php
index 9816f0f303..04bb0f40ea 100644
--- a/phpBB/feed.php
+++ b/phpBB/feed.php
@@ -71,6 +71,9 @@ if ($feed === false)
trigger_error('NO_FEED');
}
+// Get attachments for this feed
+$feed->fetch_attachments();
+
// Open Feed
$feed->open();
@@ -106,7 +109,7 @@ while ($row = $feed->get_item())
'title' => censor_text($title),
'category' => ($config['feed_item_statistics'] && !empty($row['forum_id'])) ? $board_url . '/viewforum.' . $phpEx . '?f=' . $row['forum_id'] : '',
'category_name' => ($config['feed_item_statistics'] && isset($row['forum_name'])) ? $row['forum_name'] : '',
- 'description' => censor_text(feed_generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options)),
+ 'description' => censor_text(feed_generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options, $row['forum_id'], (($row['post_attachment']) ? $feed->attachments[$row['post_id']] : array()))),
'statistics' => '',
);
@@ -272,8 +275,16 @@ function feed_format_date($time)
/**
* Generate text content
+*
+* @param string $content is feed text content
+* @param string $uid is bbcode_uid
+* @param string $bitfield is bbcode bitfield
+* @param int $options bbcode flag options
+* @param int $forum_id is the forum id
+* @param array $post_attachments is an array containing the attachments and their respective info
+* @return string the html content to be printed for the feed
**/
-function feed_generate_content($content, $uid, $bitfield, $options)
+function feed_generate_content($content, $uid, $bitfield, $options, $forum_id, $post_attachments)
{
global $user, $config, $phpbb_root_path, $phpEx, $board_url;
@@ -322,8 +333,15 @@ function feed_generate_content($content, $uid, $bitfield, $options)
// Remove some specials html tag, because somewhere there are a mod to allow html tags ;)
$content = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' <strong>$1</strong> ', $content);
+ // Parse inline images to display with the feed
+ if (!empty($post_attachments))
+ {
+ $update_count = array();
+ parse_attachments($forum_id, $content, $post_attachments, $update_count);
+ }
+
// Remove Comments from inline attachments [ia]
- $content = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content);
+ $content = preg_replace('#<dd>(.*?)</dd>#','',$content);
// Replace some entities with their unicode counterpart
$entities = array(
@@ -341,6 +359,9 @@ function feed_generate_content($content, $uid, $bitfield, $options)
// Other control characters
$content = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $content);
+ // Convert attachments' relative path to absolute path
+ $content = str_replace($phpbb_root_path . 'download/file.' . $phpEx, $board_url . '/download/file.' . $phpEx, $content);
+
return $content;
}
@@ -660,6 +681,7 @@ class phpbb_feed_base
class phpbb_feed_post_base extends phpbb_feed_base
{
var $num_items = 'feed_limit_post';
+ var $attachments = array();
function set_keys()
{
@@ -693,6 +715,45 @@ class phpbb_feed_post_base extends phpbb_feed_base
. (($this->is_moderator_approve_forum($row['forum_id']) && !$row['post_approved']) ? ' ' . $this->separator_stats . ' ' . $user->lang['POST_UNAPPROVED'] : '');
}
}
+
+ function fetch_attachments()
+ {
+ global $db;
+
+ $sql_array = array(
+ 'SELECT' => 'a.*',
+ 'FROM' => array(
+ ATTACHMENTS_TABLE => 'a'
+ ),
+ 'WHERE' => 'a.in_message = 0 ',
+ 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
+ );
+
+ if (isset($this->topic_id))
+ {
+ $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
+ }
+ else if (isset($this->forum_id))
+ {
+ $sql_array['LEFT_JOIN'] = array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't'),
+ 'ON' => 'a.topic_id = t.topic_id',
+ )
+ );
+ $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
+ }
+
+ $sql = $db->sql_build_query('SELECT', $sql_array);
+ $result = $db->sql_query($sql);
+
+ // Set attachments in feed items
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $this->attachments[$row['post_msg_id']][] = $row;
+ }
+ $db->sql_freeresult($result);
+ }
}
/**
@@ -795,7 +856,7 @@ class phpbb_feed_overall extends phpbb_feed_post_base
// Get the actual data
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name, ' .
- 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
USERS_TABLE => 'u',
@@ -927,7 +988,7 @@ class phpbb_feed_forum extends phpbb_feed_post_base
}
$this->sql = array(
- 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
@@ -1092,7 +1153,7 @@ class phpbb_feed_topic extends phpbb_feed_post_base
global $auth, $db;
$this->sql = array(
- 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
@@ -1257,7 +1318,7 @@ class phpbb_feed_news extends phpbb_feed_topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
@@ -1330,7 +1391,7 @@ class phpbb_feed_topics extends phpbb_feed_topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
@@ -1427,7 +1488,7 @@ class phpbb_feed_topics_active extends phpbb_feed_topic_base
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_replies, t.topic_replies_real, t.topic_views,
t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 70e08f79f2..8aaefb02c5 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -172,8 +172,7 @@ class acp_users
if ($submit)
{
- // You can't delete the founder
- if ($delete && $user_row['user_type'] != USER_FOUNDER)
+ if ($delete)
{
if (!$auth->acl_get('a_userdel'))
{
@@ -186,6 +185,12 @@ class acp_users
trigger_error($user->lang['CANNOT_REMOVE_ANONYMOUS'] . adm_back_link($this->u_action . '&amp;u=' . $user_id), E_USER_WARNING);
}
+ // Founders can not be deleted.
+ if ($user_row['user_type'] == USER_FOUNDER)
+ {
+ trigger_error($user->lang['CANNOT_REMOVE_FOUNDER'] . adm_back_link($this->u_action . '&amp;u=' . $user_id), E_USER_WARNING);
+ }
+
if ($user_id == $user->data['user_id'])
{
trigger_error($user->lang['CANNOT_REMOVE_YOURSELF'] . adm_back_link($this->u_action . '&amp;u=' . $user_id), E_USER_WARNING);
@@ -1032,6 +1037,7 @@ class acp_users
'U_SHOW_IP' => $this->u_action . "&amp;u=$user_id&amp;ip=" . (($ip == 'ip') ? 'hostname' : 'ip'),
'U_WHOIS' => $this->u_action . "&amp;action=whois&amp;user_ip={$user_row['user_ip']}",
'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
+ 'U_SEARCH_USER' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$user_row['user_id']}&amp;sr=posts") : '',
'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_row['user_id']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_row['user_id']}&amp;hash=" . generate_link_hash('switchperm')) : '',
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index eef4ade4e7..f0657b9016 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -3367,7 +3367,7 @@ function parse_cfg_file($filename, $lines = false)
}
// Determine first occurrence, since in values the equal sign is allowed
- $key = strtolower(trim(substr($line, 0, $delim_pos)));
+ $key = htmlspecialchars(strtolower(trim(substr($line, 0, $delim_pos))));
$value = trim(substr($line, $delim_pos + 1));
if (in_array($value, array('off', 'false', '0')))
@@ -3384,7 +3384,11 @@ function parse_cfg_file($filename, $lines = false)
}
else if (($value[0] == "'" && $value[sizeof($value) - 1] == "'") || ($value[0] == '"' && $value[sizeof($value) - 1] == '"'))
{
- $value = substr($value, 1, sizeof($value)-2);
+ $value = htmlspecialchars(substr($value, 1, sizeof($value)-2));
+ }
+ else
+ {
+ $value = htmlspecialchars($value);
}
$parsed_items[$key] = $value;
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index d0e7c8cfc8..0cc2425b28 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -436,21 +436,21 @@ class p_master
if ($this->active_module === false)
{
- trigger_error('Module not accessible', E_USER_ERROR);
+ trigger_error('MODULE_NOT_ACCESS', E_USER_ERROR);
}
if (!class_exists("{$this->p_class}_$this->p_name"))
{
if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx"))
{
- trigger_error("Cannot find module $module_path/{$this->p_class}_$this->p_name.$phpEx", E_USER_ERROR);
+ trigger_error($user->lang('MODULE_NOT_FIND', "$module_path/{$this->p_class}_$this->p_name.$phpEx"), E_USER_ERROR);
}
include("$module_path/{$this->p_class}_$this->p_name.$phpEx");
if (!class_exists("{$this->p_class}_$this->p_name"))
{
- trigger_error("Module file $module_path/{$this->p_class}_$this->p_name.$phpEx does not contain correct class [{$this->p_class}_$this->p_name]", E_USER_ERROR);
+ trigger_error($user->lang('MODULE_FILE_INCORRECT_CLASS', "$module_path/{$this->p_class}_$this->p_name.$phpEx", "{$this->p_class}_$this->p_name"), E_USER_ERROR);
}
if (!empty($mode))
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 764461fa53..acf344fd3c 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -660,15 +660,17 @@ function approve_post($post_id_list, $id, $mode)
foreach ($post_info as $post_id => $post_data)
{
+ $username = ($post_data['post_username']) ? $post_data['post_username'] : $post_data['username'];
+
if ($post_id == $post_data['topic_first_post_id'] && $post_id == $post_data['topic_last_post_id'])
{
// Forum Notifications
- user_notification('post', $post_data['topic_title'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id);
+ user_notification('post', $post_data['topic_title'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id, $username);
}
else
{
// Topic Notifications
- user_notification('reply', $post_data['post_subject'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id);
+ user_notification('reply', $post_data['post_subject'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id, $username);
}
}
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index dc961f3c8a..29c5a72874 100644
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -231,7 +231,12 @@ class fulltext_native extends search_backend
}
$db->sql_freeresult($result);
}
- unset($exact_words);
+
+ // Handle +, - without preceeding whitespace character
+ $match = array('#(\S)\+#', '#(\S)-#');
+ $replace = array('$1 +', '$1 +');
+
+ $keywords = preg_replace($match, $replace, $keywords);
// now analyse the search query, first split it using the spaces
$query = explode(' ', $keywords);
@@ -357,39 +362,21 @@ class fulltext_native extends search_backend
$this->{$mode . '_ids'}[] = $words[$word];
}
}
- // throw an error if we shall not ignore unexistant words
- else if (!$ignore_no_id)
+ else
{
if (!isset($common_ids[$word]))
{
$len = utf8_strlen($word);
- if ($len >= $this->word_length['min'] && $len <= $this->word_length['max'])
- {
- trigger_error(sprintf($user->lang['WORD_IN_NO_POST'], $word));
- }
- else
+ if ($len < $this->word_length['min'] || $len > $this->word_length['max'])
{
$this->common_words[] = $word;
}
}
}
- else
- {
- $len = utf8_strlen($word);
- if ($len < $this->word_length['min'] || $len > $this->word_length['max'])
- {
- $this->common_words[] = $word;
- }
- }
- }
-
- // we can't search for negatives only
- if (!sizeof($this->must_contain_ids))
- {
- return false;
}
- if (!empty($this->search_query))
+ // Return true if all words are not common words
+ if (sizeof($exact_words) - sizeof($this->common_words) > 0)
{
return true;
}
@@ -428,6 +415,12 @@ class fulltext_native extends search_backend
return false;
}
+ // we can't search for negatives only
+ if (empty($this->must_contain_ids))
+ {
+ 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;
diff --git a/phpBB/install/index.php b/phpBB/install/index.php
index ad46e273c2..35e7c70e1d 100644
--- a/phpBB/install/index.php
+++ b/phpBB/install/index.php
@@ -641,8 +641,9 @@ class module
case 'password':
$size = (int) $tpl_type[1];
$maxlength = (int) $tpl_type[2];
+ $autocomplete = (isset($options['autocomplete']) && $options['autocomplete'] == 'off') ? ' autocomplete="off"' : '';
- $tpl = '<input id="' . $name . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '" value="' . $value . '" />';
+ $tpl = '<input id="' . $name . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '"' . $autocomplete . ' value="' . $value . '" />';
break;
case 'textarea':
diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php
index 4618cff855..0a100ae71b 100644
--- a/phpBB/install/install_install.php
+++ b/phpBB/install/install_install.php
@@ -2045,8 +2045,8 @@ class install_install extends module
'smtp_delivery' => array('lang' => 'USE_SMTP', 'type' => 'radio:yes_no', 'explain' => true),
'smtp_host' => array('lang' => 'SMTP_SERVER', 'type' => 'text:25:50', 'explain' => false),
'smtp_auth' => array('lang' => 'SMTP_AUTH_METHOD', 'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true),
- 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true),
- 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true),
+ 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
+ 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
'legend2' => 'SERVER_URL_SETTINGS',
'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'type' => 'radio:enabled_disabled', 'explain' => true),
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index e1b36e64a2..b266025c86 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -668,7 +668,7 @@ INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id,
# Bots having bot access
INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (6, 2, 0, 19, 0);
-# NEW MEMBERS aren't allowed to PM
+# NEW MEMBERS are not allowed to send private messages
INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (7, 0, 0, 23, 0);
# NEW MEMBERS on the queue
diff --git a/phpBB/language/en/acp/ban.php b/phpBB/language/en/acp/ban.php
index 7b2ef59a7a..bc547b6d8f 100644
--- a/phpBB/language/en/acp/ban.php
+++ b/phpBB/language/en/acp/ban.php
@@ -74,11 +74,11 @@ $lang = array_merge($lang, array(
'PERMANENT' => 'Permanent',
'UNTIL' => 'Until',
- 'USER_BAN' => 'Ban one or more usernames',
+ 'USER_BAN' => 'Ban one or more users by username',
'USER_BAN_EXCLUDE_EXPLAIN' => 'Enable this to exclude the entered users from all current bans.',
'USER_BAN_EXPLAIN' => 'You can ban multiple users in one go by entering each name on a new line. Use the <span style="text-decoration: underline;">Find a member</span> facility to look up and add one or more users automatically.',
'USER_NO_BANNED' => 'No banned usernames',
- 'USER_UNBAN' => 'Un-ban or un-exclude usernames',
+ 'USER_UNBAN' => 'Un-ban or un-exclude users by username',
'USER_UNBAN_EXPLAIN' => 'You can unban (or un-exclude) multiple users in one go using the appropriate combination of mouse and keyboard for your computer and browser. Excluded users are emphasised.',
));
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index ccd12fcb6a..f9a40c2bc7 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -44,7 +44,7 @@ $lang = array_merge($lang, array(
'DEFAULT_LANGUAGE' => 'Default language',
'DEFAULT_STYLE' => 'Default style',
'DISABLE_BOARD' => 'Disable board',
- 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.',
+ 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users who are neither administrators nor moderators. You can also enter a short (255 character) message to display if you wish.',
'OVERRIDE_STYLE' => 'Override user style',
'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.',
'SITE_DESC' => 'Site description',
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 04d614c80d..f2ab15335d 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -50,7 +50,7 @@ $lang = array_merge($lang, array(
'ACP_BAN' => 'Banning',
'ACP_BAN_EMAILS' => 'Ban e-mails',
'ACP_BAN_IPS' => 'Ban IPs',
- 'ACP_BAN_USERNAMES' => 'Ban usernames',
+ 'ACP_BAN_USERNAMES' => 'Ban users',
'ACP_BBCODES' => 'BBCodes',
'ACP_BOARD_CONFIGURATION' => 'Board configuration',
'ACP_BOARD_FEATURES' => 'Board features',
diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php
index 3b82a7022d..25e5ff8269 100644
--- a/phpBB/language/en/acp/users.php
+++ b/phpBB/language/en/acp/users.php
@@ -52,6 +52,7 @@ $lang = array_merge($lang, array(
'CANNOT_FORCE_REACT_FOUNDER' => 'You are not allowed to force reactivation on founder accounts.',
'CANNOT_FORCE_REACT_YOURSELF' => 'You are not allowed to force reactivation of your own account.',
'CANNOT_REMOVE_ANONYMOUS' => 'You are not able to remove the guest user account.',
+ 'CANNOT_REMOVE_FOUNDER' => 'You are not allowed to remove founder accounts.',
'CANNOT_REMOVE_YOURSELF' => 'You are not allowed to remove your own user account.',
'CANNOT_SET_FOUNDER_IGNORED' => 'You are not able to promote ignored users to be founders.',
'CANNOT_SET_FOUNDER_INACTIVE' => 'You need to activate users before you promote them to founders, only activated users are able to be promoted.',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index f37f6d3b30..62c18c109c 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -341,6 +341,9 @@ $lang = array_merge($lang, array(
'MODERATE' => 'Moderate',
'MODERATOR' => 'Moderator',
'MODERATORS' => 'Moderators',
+ 'MODULE_NOT_ACCESS' => 'Module not accessible',
+ 'MODULE_NOT_FIND' => 'Cannot find module %s',
+ 'MODULE_FILE_INCORRECT_CLASS' => 'Module file %s does not contain correct class [%s]',
'MONTH' => 'Month',
'MOVE' => 'Move',
'MSNM' => 'MSNM/WLM',
diff --git a/phpBB/search.php b/phpBB/search.php
index ad9c371f63..0f13dbbfa0 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -540,12 +540,6 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page);
}
- // For some searches we need to print out the "no results" page directly to allow re-sorting/refining the search options.
- if (!sizeof($id_ary) && !$search_id)
- {
- trigger_error('NO_SEARCH_RESULTS');
- }
-
$sql_where = '';
if (sizeof($id_ary))
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index 811e5f4376..abd5a5dd22 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -18,5 +18,5 @@
# General Information about this style
name = prosilver
-copyright = &copy; phpBB Group, 2007
-version = 3.0.12 \ No newline at end of file
+copyright = © phpBB Group, 2007
+version = 3.0.12
diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg
index b99c433ff1..b0fe5e6639 100644
--- a/phpBB/styles/subsilver2/style.cfg
+++ b/phpBB/styles/subsilver2/style.cfg
@@ -18,5 +18,5 @@
# General Information about this style
name = subsilver2
-copyright = &copy; 2005 phpBB Group
+copyright = © 2005 phpBB Group
version = 3.0.12
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index fb12dd925a..e08d6e1ef5 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -1509,13 +1509,19 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
$edit_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_edit', $forum_id) || (
$user->data['user_id'] == $poster_id &&
$auth->acl_get('f_edit', $forum_id) &&
+ $topic_data['topic_status'] != ITEM_LOCKED &&
!$row['post_edit_locked'] &&
($row['post_time'] > time() - ($config['edit_time'] * 60) || !$config['edit_time'])
)));
+ $quote_allowed = $auth->acl_get('m_edit', $forum_id) || ($topic_data['topic_status'] != ITEM_LOCKED &&
+ ($user->data['user_id'] == ANONYMOUS || $auth->acl_get('f_reply', $forum_id))
+ );
+
$delete_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_delete', $forum_id) || (
$user->data['user_id'] == $poster_id &&
$auth->acl_get('f_delete', $forum_id) &&
+ $topic_data['topic_status'] != ITEM_LOCKED &&
$topic_data['topic_last_post_id'] == $row['post_id'] &&
($row['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']) &&
// we do not want to allow removal of the last post if a moderator locked it!
@@ -1556,7 +1562,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
'S_ONLINE' => ($poster_id == ANONYMOUS || !$config['load_onlinetrack']) ? false : (($user_cache[$poster_id]['online']) ? true : false),
'U_EDIT' => ($edit_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
- 'U_QUOTE' => ($auth->acl_get('f_reply', $forum_id)) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
+ 'U_QUOTE' => ($quote_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
'U_INFO' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&amp;mode=post_details&amp;f=$forum_id&amp;p=" . $row['post_id'], true, $user->session_id) : '',
'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
diff --git a/tests/functional/acp_users_test.php b/tests/functional/acp_users_test.php
new file mode 100644
index 0000000000..50d9a67dc1
--- /dev/null
+++ b/tests/functional/acp_users_test.php
@@ -0,0 +1,45 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @group functional
+*/
+class phpbb_functional_acp_users_test extends phpbb_functional_test_case
+{
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->login();
+ $this->admin_login();
+ $this->add_lang('acp/users');
+ }
+
+ public function test_founder_deletion()
+ {
+ $username = 'founder-account';
+ $user_id = $this->create_user($username);
+ $this->make_founder($user_id);
+
+ $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}");
+ $form = $crawler->filter('#user_delete')->selectButton($this->lang('SUBMIT'))->form();
+ $crawler = self::submit($form);
+ $this->assertContains($this->lang('CANNOT_REMOVE_FOUNDER'), $this->get_content());
+ }
+
+ protected function make_founder($user_id)
+ {
+ $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}");
+ $form = $crawler->filter('#user_overview')->selectButton($this->lang('SUBMIT'))->form();
+ $data = array('user_founder' => '1');
+ $form->setValues($data);
+ $crawler = self::submit($form);
+ $this->assertContains($this->lang('USER_OVERVIEW_UPDATED'), $this->get_content());
+ }
+}
diff --git a/tests/functions/parse_cfg_file_test.php b/tests/functions/parse_cfg_file_test.php
new file mode 100644
index 0000000000..69000ddf72
--- /dev/null
+++ b/tests/functions/parse_cfg_file_test.php
@@ -0,0 +1,103 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
+
+class phpbb_functions_parse_cfg_file extends phpbb_test_case
+{
+ public function parse_cfg_file_data()
+ {
+ return array(
+ array(
+ array(
+ '#',
+ '# phpBB Style Configuration File',
+ '#',
+ '# @package phpBB3',
+ '# @copyright (c) 2005 phpBB Group',
+ '# @license http://opensource.org/licenses/gpl-license.php GNU Public License',
+ '#',
+ '#',
+ '# At the left is the name, please do not change this',
+ '# At the right the value is entered',
+ '# For on/off options the valid values are on, off, 1, 0, true and false',
+ '#',
+ '# Values get trimmed, if you want to add a space in front or at the end of',
+ '# the value, then enclose the value with single or double quotes.',
+ '# Single and double quotes do not need to be escaped.',
+ '#',
+ '',
+ '# General Information about this style',
+ 'name = prosilver',
+ 'copyright = © phpBB Group, 2007',
+ 'version = 3.0.12',
+ ),
+ array(
+ 'name' => 'prosilver',
+ 'copyright' => '© phpBB Group, 2007',
+ 'version' => '3.0.12',
+ ),
+ ),
+ array(
+ array(
+ 'name = subsilver2',
+ 'copyright = © 2005 phpBB Group',
+ 'version = 3.0.12',
+ ),
+ array(
+ 'name' => 'subsilver2',
+ 'copyright' => '© 2005 phpBB Group',
+ 'version' => '3.0.12',
+ ),
+ ),
+ array(
+ array(
+ 'foo = on',
+ 'foo1 = true',
+ 'foo2 = 1',
+ 'bar = off',
+ 'bar1 = false',
+ 'bar2 = 0',
+ 'foobar =',
+ 'foobar1 = "asdf"',
+ 'foobar2 = \'qwer\'',
+ ),
+ array(
+ 'foo' => true,
+ 'foo1' => true,
+ 'foo2' => true,
+ 'bar' => false,
+ 'bar1' => false,
+ 'bar2' => false,
+ 'foobar' => '',
+ 'foobar1' => 'asdf',
+ 'foobar2' => 'qwer',
+ ),
+ ),
+ array(
+ array(
+ 'foo = &amp; bar',
+ 'bar = <a href="test">Test</a>',
+ ),
+ array(
+ 'foo' => '&amp;amp; bar',
+ 'bar' => '&lt;a href=&quot;test&quot;&gt;Test&lt;/a&gt;',
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider parse_cfg_file_data
+ */
+ public function test_parse_cfg_file($file_contents, $expected)
+ {
+ $this->assertEquals($expected, parse_cfg_file(false, $file_contents));
+ }
+}
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index 00b31212b2..5dfe07d380 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -423,6 +423,15 @@ class phpbb_functional_test_case extends phpbb_test_case
$config = array();
}
+ /*
+ * Add required config entries to the config array to prevent
+ * set_config() sending an INSERT query for already existing entries,
+ * resulting in a SQL error.
+ * This is because set_config() first sends an UPDATE query, then checks
+ * sql_affectedrows() which can be 0 (e.g. on MySQL) when the new
+ * data is already there.
+ */
+ $config['newest_user_colour'] = '';
$config['rand_seed'] = '';
$config['rand_seed_last_update'] = time() + 600;