Merge branch 'develop' of https://github.com/phpbb/phpbb3 into ticket/11531

This commit is contained in:
Marc Alexander 2013-06-18 18:08:44 +02:00
commit 2996120e97
70 changed files with 3770 additions and 1699 deletions

View file

@ -152,7 +152,7 @@
</dl>
<dl>
<dt><label for="forum_desc">{L_FORUM_DESC}{L_COLON}</label><br /><span>{L_FORUM_DESC_EXPLAIN}</span></dt>
<dd><textarea id="forum_desc" name="forum_desc" rows="5" cols="45">{FORUM_DESC}</textarea></dd>
<dd><textarea id="forum_desc" name="forum_desc" rows="5" cols="45" data-bbcode="true">{FORUM_DESC}</textarea></dd>
<dd><label><input type="checkbox" class="radio" name="desc_parse_bbcode"<!-- IF S_DESC_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label>
<label><input type="checkbox" class="radio" name="desc_parse_smilies"<!-- IF S_DESC_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label>
<label><input type="checkbox" class="radio" name="desc_parse_urls"<!-- IF S_DESC_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd>
@ -316,7 +316,7 @@
<!-- ENDIF -->
<dl>
<dt><label for="forum_rules">{L_FORUM_RULES}{L_COLON}</label><br /><span>{L_FORUM_RULES_EXPLAIN}</span></dt>
<dd><textarea id="forum_rules" name="forum_rules" rows="4" cols="70">{FORUM_RULES_PLAIN}</textarea></dd>
<dd><textarea id="forum_rules" name="forum_rules" rows="4" cols="70" data-bbcode="true">{FORUM_RULES_PLAIN}</textarea></dd>
<dd><label><input type="checkbox" class="radio" name="rules_parse_bbcode"<!-- IF S_BBCODE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_BBCODE}</label>
<label><input type="checkbox" class="radio" name="rules_parse_smilies"<!-- IF S_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label>
<label><input type="checkbox" class="radio" name="rules_parse_urls"<!-- IF S_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd>

View file

@ -92,7 +92,7 @@
// ]]>
</script>
</dt>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();">{SIGNATURE}</textarea></dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" data-bbcode="true">{SIGNATURE}</textarea></dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px; margin-top: 5px;">
<!-- IF S_BBCODE_ALLOWED -->
<label><input type="checkbox" class="radio" name="disable_bbcode"{S_BBCODE_CHECKED} /> {L_DISABLE_BBCODE}</label>

View file

@ -678,5 +678,164 @@ phpbb.resizeTextArea = function(items, options) {
});
};
/**
* Check if cursor in textarea is currently inside a bbcode tag
*
* @param {object} textarea Textarea DOM object
* @param {Array} startTags List of start tags to look for
* For example, Array('[code]', '[code=')
* @param {Array} endTags List of end tags to look for
* For example, Array('[/code]')
*
* @return {boolean} True if cursor is in bbcode tag
*/
phpbb.inBBCodeTag = function(textarea, startTags, endTags) {
var start = textarea.selectionStart,
lastEnd = -1,
lastStart = -1,
i, index, value;
if (typeof start !== 'number') {
return false;
}
value = textarea.value.toLowerCase();
for (i = 0; i < startTags.length; i++) {
var tagLength = startTags[i].length;
if (start >= tagLength) {
index = value.lastIndexOf(startTags[i], start - tagLength);
lastStart = Math.max(lastStart, index);
}
}
if (lastStart == -1) return false;
if (start > 0) {
for (i = 0; i < endTags.length; i++) {
index = value.lastIndexOf(endTags[i], start - 1);
lastEnd = Math.max(lastEnd, index);
}
}
return (lastEnd < lastStart);
}
/**
* Adjust textarea to manage code bbcode
*
* This function allows to use tab characters when typing code
* and keeps indentation of previous line of code when adding new
* line while typing code.
*
* Editor's functionality is changed only when cursor is between
* [code] and [/code] bbcode tags.
*
* @param {object} textarea Textarea DOM object to apply editor to
*/
phpbb.applyCodeEditor = function(textarea) {
// list of allowed start and end bbcode code tags, in lower case
var startTags = ['[code]', '[code='],
startTagsEnd = ']',
endTags = ['[/code]'];
if (!textarea || typeof textarea.selectionStart !== 'number') {
return;
}
if ($(textarea).data('code-editor') === true) {
return;
}
function inTag() {
return phpbb.inBBCodeTag(textarea, startTags, endTags);
}
/**
* Get line of text before cursor
*
* @param {boolean} stripCodeStart If true, only part of line
* after [code] tag will be returned.
*
* @return {string} Line of text
*/
function getLastLine(stripCodeStart) {
var start = textarea.selectionStart,
value = textarea.value,
index = value.lastIndexOf("\n", start - 1);
value = value.substring(index + 1, start);
if (stripCodeStart) {
for (var i = 0; i < startTags.length; i++) {
index = value.lastIndexOf(startTags[i]);
if (index >= 0) {
var tagLength = startTags[i].length;
value = value.substring(index + tagLength);
if (startTags[i].lastIndexOf(startTagsEnd) != tagLength) {
index = value.indexOf(startTagsEnd);
if (index >= 0) {
value = value.substr(index + 1);
}
}
}
}
}
return value;
}
/**
* Append text at cursor position
*
* @param {string} Text Text to append
*/
function appendText(text) {
var start = textarea.selectionStart,
end = textarea.selectionEnd,
value = textarea.value;
textarea.value = value.substr(0, start) + text + value.substr(end);
textarea.selectionStart = textarea.selectionEnd = start + text.length;
}
$(textarea).data('code-editor', true).on('keydown', function(event) {
var key = event.keyCode || event.which;
// intercept tabs
if (key == 9) {
if (inTag()) {
appendText("\t");
event.preventDefault();
return;
}
}
// intercept new line characters
if (key == 13) {
if (inTag()) {
var lastLine = getLastLine(true),
code = '' + /^\s*/g.exec(lastLine);
if (code.length > 0) {
appendText("\n" + code);
event.preventDefault();
return;
}
}
}
});
};
/**
* Apply code editor to all textarea elements with data-bbcode attribute
*/
$(document).ready(function() {
$('textarea[data-bbcode]').each(function() {
phpbb.applyCodeEditor(this);
});
});
})(jQuery); // Avoid conflicts with other libraries

98
phpBB/config/feed.yml Normal file
View file

@ -0,0 +1,98 @@
services:
feed.helper:
class: phpbb_feed_helper
arguments:
- @config
- @user
- %core.root_path%
feed.factory:
class: phpbb_feed_factory
arguments:
- @service_container
- @config
- @dbal.conn
feed.forum:
class: phpbb_feed_forum
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.forums:
class: phpbb_feed_forums
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.news:
class: phpbb_feed_news
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.overall:
class: phpbb_feed_overall
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topic:
class: phpbb_feed_topic
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topics:
class: phpbb_feed_topics
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%
feed.topics_active:
class: phpbb_feed_topics_active
scope: prototype
arguments:
- @feed.helper
- @config
- @dbal.conn
- @cache.driver
- @user
- @auth
- %core.php_ext%

View file

@ -4,6 +4,7 @@ imports:
- { resource: notifications.yml }
- { resource: migrator.yml }
- { resource: avatars.yml }
- { resource: feed.yml }
services:
auth:

View file

@ -279,7 +279,7 @@ else if ($download_id)
phpbb_increment_downloads($db, $attachment['attach_id']);
}
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && ((strpos(strtolower($user->browser), 'msie') !== false) && (strpos(strtolower($user->browser), 'msie 8.0') === false)))
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && (strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7))
{
wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']);
file_gc();

File diff suppressed because it is too large Load diff

View file

@ -591,7 +591,7 @@ class acp_groups
$avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
if (!$update)
if (isset($phpbb_avatar_manager) && !$update)
{
// Merge any avatar errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));

View file

@ -0,0 +1,259 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Base class with some generic functions and settings.
*
* @package phpBB3
*/
abstract class phpbb_feed_base
{
/**
* Feed helper object
* @var phpbb_feed_helper
*/
protected $helper;
/** @var phpbb_config */
protected $config;
/** @var phpbb_db_driver */
protected $db;
/** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_user */
protected $user;
/** @var phpbb_auth */
protected $auth;
/** @var string */
protected $phpEx;
/**
* SQL Query to be executed to get feed items
*/
var $sql = array();
/**
* Keys specified for retrieval of title, content, etc.
*/
var $keys = array();
/**
* Number of items to fetch. Usually overwritten by $config['feed_something']
*/
var $num_items = 15;
/**
* Separator for title elements to separate items (for example forum / topic)
*/
var $separator = "\xE2\x80\xA2"; // &bull;
/**
* Separator for the statistics row (Posted by, post date, replies, etc.)
*/
var $separator_stats = "\xE2\x80\x94"; // &mdash;
/**
* Constructor
*
* @param phpbb_feed_helper $helper Feed helper
* @param phpbb_config $config Config object
* @param phpbb_db_driver $db Database connection
* @param phpbb_cache_driver_interface $cache Cache object
* @param phpbb_user $user User object
* @param phpbb_auth $auth Auth object
* @param string $phpEx php file extension
* @return null
*/
function __construct(phpbb_feed_helper $helper, phpbb_config $config, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, phpbb_user $user, phpbb_auth $auth, $phpEx)
{
$this->config = $config;
$this->helper = $helper;
$this->db = $db;
$this->cache = $cache;
$this->user = $user;
$this->auth = $auth;
$this->phpEx = $phpEx;
$this->set_keys();
// Allow num_items to be string
if (is_string($this->num_items))
{
$this->num_items = (int) $this->config[$this->num_items];
// A precaution
if (!$this->num_items)
{
$this->num_items = 10;
}
}
}
/**
* Set keys.
*/
function set_keys()
{
}
/**
* Open feed
*/
function open()
{
}
/**
* Close feed
*/
function close()
{
if (!empty($this->result))
{
$this->db->sql_freeresult($this->result);
}
}
/**
* Set key
*/
function set($key, $value)
{
$this->keys[$key] = $value;
}
/**
* Get key
*/
function get($key)
{
return (isset($this->keys[$key])) ? $this->keys[$key] : NULL;
}
function get_readable_forums()
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_keys($this->auth->acl_getf('f_read', true));
}
return $forum_ids;
}
function get_moderator_approve_forums()
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_keys($this->auth->acl_getf('m_approve', true));
}
return $forum_ids;
}
function is_moderator_approve_forum($forum_id)
{
static $forum_ids;
if (!isset($forum_ids))
{
$forum_ids = array_flip($this->get_moderator_approve_forums());
}
return (isset($forum_ids[$forum_id])) ? true : false;
}
function get_excluded_forums()
{
static $forum_ids;
// Matches acp/acp_board.php
$cache_name = 'feed_excluded_forum_ids';
if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
{
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '<> 0');
$result = $this->db->sql_query($sql);
$forum_ids = array();
while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
{
$forum_ids[$forum_id] = $forum_id;
}
$this->db->sql_freeresult($result);
$this->cache->put('_' . $cache_name, $forum_ids);
}
return $forum_ids;
}
function is_excluded_forum($forum_id)
{
$forum_ids = $this->get_excluded_forums();
return isset($forum_ids[$forum_id]) ? true : false;
}
function get_passworded_forums()
{
return $this->user->get_passworded_forums();
}
function get_item()
{
static $result;
if (!isset($result))
{
if (!$this->get_sql())
{
return false;
}
// Query database
$sql = $this->db->sql_build_query('SELECT', $this->sql);
$result = $this->db->sql_query_limit($sql, $this->num_items);
}
return $this->db->sql_fetchrow($result);
}
function user_viewprofile($row)
{
$author_id = (int) $row[$this->get('author_id')];
if ($author_id == ANONYMOUS)
{
// Since we cannot link to a profile, we just return GUEST
// instead of $row['username']
return $this->user->lang['GUEST'];
}
return '<a href="' . $this->helper->append_sid('memberlist.' . $this->phpEx, 'mode=viewprofile&amp;u=' . $author_id) . '">' . $row[$this->get('creator')] . '</a>';
}
}

View file

@ -0,0 +1,129 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Factory class to return correct object
* @package phpBB3
*/
class phpbb_feed_factory
{
/**
* Service container object
* @var object
*/
protected $container;
/** @var phpbb_config */
protected $config;
/** @var phpbb_db_driver */
protected $db;
/**
* Constructor
*
* @param objec $container Container object
* @param phpbb_config $config Config object
* @param phpbb_db_driver $db Database connection
* @return null
*/
public function __construct($container, phpbb_config $config, phpbb_db_driver $db)
{
$this->container = $container;
$this->config = $config;
$this->db = $db;
}
/**
* Return correct object for specified mode
*
* @param string $mode The feeds mode.
* @param int $forum_id Forum id specified by the script if forum feed provided.
* @param int $topic_id Topic id specified by the script if topic feed provided.
*
* @return object Returns correct feeds object for specified mode.
*/
function get_feed($mode, $forum_id, $topic_id)
{
switch ($mode)
{
case 'forums':
if (!$this->config['feed_overall_forums'])
{
return false;
}
return $this->container->get('feed.forums');
break;
case 'topics':
case 'topics_new':
if (!$this->config['feed_topics_new'])
{
return false;
}
return $this->container->get('feed.topics');
break;
case 'topics_active':
if (!$this->config['feed_topics_active'])
{
return false;
}
return $this->container->get('feed.topics_active');
break;
case 'news':
// Get at least one news forum
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
$result = $this->db->sql_query_limit($sql, 1, 0, 600);
$s_feed_news = (int) $this->db->sql_fetchfield('forum_id');
$this->db->sql_freeresult($result);
if (!$s_feed_news)
{
return false;
}
return $this->container->get('feed.news');
break;
default:
if ($topic_id && $this->config['feed_topic'])
{
return $this->container->get('feed.topic')
->set_topic_id($topic_id);
}
else if ($forum_id && $this->config['feed_forum'])
{
return $this->container->get('feed.forum')
->set_forum_id($forum_id);
}
else if ($this->config['feed_overall'])
{
return $this->container->get('feed.overall');
}
return false;
break;
}
}
}

View file

@ -0,0 +1,147 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Forum feed
*
* This will give you the last {$this->num_items} posts made
* within a specific forum.
*
* @package phpBB3
*/
class phpbb_feed_forum extends phpbb_feed_post_base
{
var $forum_id = 0;
var $forum_data = array();
/**
* Set the Forum ID
*
* @param int $forum_id Forum ID
* @return phpbb_feed_forum
*/
public function set_forum_id($topic_id)
{
$this->forum_id = (int) $forum_id;
return $this;
}
function open()
{
// Check if forum exists
$sql = 'SELECT forum_id, forum_name, forum_password, forum_type, forum_options
FROM ' . FORUMS_TABLE . '
WHERE forum_id = ' . $this->forum_id;
$result = $this->db->sql_query($sql);
$this->forum_data = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (empty($this->forum_data))
{
trigger_error('NO_FORUM');
}
// Forum needs to be postable
if ($this->forum_data['forum_type'] != FORUM_POST)
{
trigger_error('NO_FEED');
}
// Make sure forum is not excluded from feed
if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->forum_data['forum_options']))
{
trigger_error('NO_FEED');
}
// Make sure we can read this forum
if (!$this->auth->acl_get('f_read', $this->forum_id))
{
trigger_error('SORRY_AUTH_READ');
}
// Make sure forum is not passworded or user is authed
if ($this->forum_data['forum_password'])
{
$forum_ids_passworded = $this->get_passworded_forums();
if (isset($forum_ids_passworded[$this->forum_id]))
{
trigger_error('SORRY_AUTH_READ');
}
unset($forum_ids_passworded);
}
}
function get_sql()
{
$m_approve = ($this->auth->acl_get('m_approve', $this->forum_id)) ? true : false;
// Determine topics with recent activity
$sql = 'SELECT topic_id, topic_last_post_time
FROM ' . TOPICS_TABLE . '
WHERE forum_id = ' . $this->forum_id . '
AND topic_moved_id = 0
' . ((!$m_approve) ? 'AND topic_approved = 1' : '') . '
ORDER BY topic_last_post_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$topic_ids = array();
$min_post_time = 0;
while ($row = $this->db->sql_fetchrow())
{
$topic_ids[] = (int) $row['topic_id'];
$min_post_time = (int) $row['topic_last_post_time'];
}
$this->db->sql_freeresult($result);
if (empty($topic_ids))
{
return false;
}
$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, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
USERS_TABLE => 'u',
),
'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . '
' . ((!$m_approve) ? 'AND p.post_approved = 1' : '') . '
AND p.post_time >= ' . $min_post_time . '
AND p.poster_id = u.user_id',
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
function adjust_item(&$item_row, &$row)
{
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
}
function get_item()
{
return ($row = parent::get_item()) ? array_merge($this->forum_data, $row) : $row;
}
}

View file

@ -0,0 +1,72 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* 'All Forums' feed
*
* This will give you a list of all postable forums where feeds are enabled
* including forum description, topic stats and post stats
*
* @package phpBB3
*/
class phpbb_feed_forums extends phpbb_feed_base
{
var $num_items = 0;
function set_keys()
{
$this->set('title', 'forum_name');
$this->set('text', 'forum_desc');
$this->set('bitfield', 'forum_desc_bitfield');
$this->set('bbcode_uid','forum_desc_uid');
$this->set('updated', 'forum_last_post_time');
$this->set('options', 'forum_desc_options');
}
function get_sql()
{
$in_fid_ary = array_diff($this->get_readable_forums(), $this->get_excluded_forums());
if (empty($in_fid_ary))
{
return false;
}
// Build SQL Query
$this->sql = array(
'SELECT' => 'f.forum_id, f.left_id, f.forum_name, f.forum_last_post_time,
f.forum_desc, f.forum_desc_bitfield, f.forum_desc_uid, f.forum_desc_options,
f.forum_topics, f.forum_posts',
'FROM' => array(FORUMS_TABLE => 'f'),
'WHERE' => 'f.forum_type = ' . FORUM_POST . '
AND ' . $this->db->sql_in_set('f.forum_id', $in_fid_ary),
'ORDER_BY' => 'f.left_id ASC',
);
return true;
}
function adjust_item(&$item_row, &$row)
{
$item_row['link'] = $this->helper->append_sid('viewforum.' . $this->phpEx, 'f=' . $row['forum_id']);
if ($this->config['feed_item_statistics'])
{
$item_row['statistics'] = $this->user->lang('TOTAL_TOPICS', (int) $row['forum_topics'])
. ' ' . $this->separator_stats . ' ' . $this->user->lang('TOTAL_POSTS_COUNT', (int) $row['forum_posts']);
}
}
}

View file

@ -0,0 +1,159 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Class with some helpful functions used in feeds
* @package phpBB3
*/
class phpbb_feed_helper
{
/** @var phpbb_config */
protected $config;
/** @var phpbb_user */
protected $user;
/** @var string */
protected $phpbb_root_path;
/**
* Constructor
*
* @param phpbb_config $config Config object
* @param phpbb_user $user User object
* @param string $phpbb_root_path Root path
* @return null
*/
public function __construct(phpbb_config $config, phpbb_user $user, $phpbb_root_path)
{
$this->config = $config;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
}
/**
* Run links through append_sid(), prepend generate_board_url() and remove session id
*/
public function get_board_url()
{
static $board_url;
if (empty($board_url))
{
$board_url = generate_board_url();
}
return $board_url;
}
/**
* Run links through append_sid(), prepend generate_board_url() and remove session id
*/
public function append_sid($url, $params)
{
return append_sid($this->get_board_url() . '/' . $url, $params, true, '');
}
/**
* Generate ISO 8601 date string (RFC 3339)
*/
public function format_date($time)
{
static $zone_offset;
static $offset_string;
if (empty($offset_string))
{
$zone_offset = $this->user->create_datetime()->getOffset();
$offset_string = phpbb_format_timezone_offset($zone_offset);
}
return gmdate("Y-m-d\TH:i:s", $time + $zone_offset) . $offset_string;
}
/**
* Generate text content
*/
public function generate_content($content, $uid, $bitfield, $options)
{
if (empty($content))
{
return '';
}
// Prepare some bbcodes for better parsing
$content = preg_replace("#\[quote(=&quot;.*?&quot;)?:$uid\]\s*(.*?)\s*\[/quote:$uid\]#si", "[quote$1:$uid]<br />$2<br />[/quote:$uid]", $content);
$content = generate_text_for_display($content, $uid, $bitfield, $options);
// Add newlines
$content = str_replace('<br />', '<br />' . "\n", $content);
// Convert smiley Relative paths to Absolute path, Windows style
$content = str_replace($this->phpbb_root_path . $this->config['smilies_path'], $this->get_board_url() . '/' . $this->config['smilies_path'], $content);
// Remove "Select all" link and mouse events
$content = str_replace('<a href="#" onclick="selectCode(this); return false;">' . $this->user->lang['SELECT_ALL_CODE'] . '</a>', '', $content);
$content = preg_replace('#(onkeypress|onclick)="(.*?)"#si', '', $content);
// Firefox does not support CSS for feeds, though
// Remove font sizes
// $content = preg_replace('#<span style="font-size: [0-9]+%; line-height: [0-9]+%;">([^>]+)</span>#iU', '\1', $content);
// Make text strong :P
// $content = preg_replace('#<span style="font-weight: bold?">(.*?)</span>#iU', '<strong>\1</strong>', $content);
// Italic
// $content = preg_replace('#<span style="font-style: italic?">([^<]+)</span>#iU', '<em>\1</em>', $content);
// Underline
// $content = preg_replace('#<span style="text-decoration: underline?">([^<]+)</span>#iU', '<u>\1</u>', $content);
// Remove embed Windows Media Streams
$content = preg_replace( '#<\!--\[if \!IE\]>-->([^[]+)<\!--<!\[endif\]-->#si', '', $content);
// Do not use &lt; and &gt;, because we want to retain code contained in [code][/code]
// Remove embed and objects
$content = preg_replace( '#<(object|embed)(.*?) (value|src)=(.*?) ([^[]+)(object|embed)>#si',' <a href=$4 target="_blank"><strong>$1</strong></a> ',$content);
// 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);
// Remove Comments from inline attachments [ia]
$content = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content);
// Replace some entities with their unicode counterpart
$entities = array(
'&nbsp;' => "\xC2\xA0",
'&bull;' => "\xE2\x80\xA2",
'&middot;' => "\xC2\xB7",
'&copy;' => "\xC2\xA9",
);
$content = str_replace(array_keys($entities), array_values($entities), $content);
// Remove CDATA blocks. ;)
$content = preg_replace('#\<\!\[CDATA\[(.*?)\]\]\>#s', '', $content);
// Other control characters
$content = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $content);
return $content;
}
}

View file

@ -0,0 +1,112 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* News feed
*
* This will give you {$this->num_items} first posts
* of all topics in the selected news forums.
*
* @package phpBB3
*/
class phpbb_feed_news extends phpbb_feed_topic_base
{
function get_news_forums()
{
static $forum_ids;
// Matches acp/acp_board.php
$cache_name = 'feed_news_forum_ids';
if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
{
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
$result = $this->db->sql_query($sql);
$forum_ids = array();
while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
{
$forum_ids[$forum_id] = $forum_id;
}
$this->db->sql_freeresult($result);
$this->cache->put('_' . $cache_name, $forum_ids);
}
return $forum_ids;
}
function get_sql()
{
// Determine forum ids
$in_fid_ary = array_intersect($this->get_news_forums(), $this->get_readable_forums());
if (empty($in_fid_ary))
{
return false;
}
$in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
if (empty($in_fid_ary))
{
return false;
}
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
AND topic_moved_id = 0
AND topic_approved = 1
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$post_ids = array();
while ($row = $this->db->sql_fetchrow($result))
{
$post_ids[] = (int) $row['topic_first_post_id'];
}
$this->db->sql_freeresult($result);
if (empty($post_ids))
{
return false;
}
$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',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(FORUMS_TABLE => 'f'),
'ON' => 'p.forum_id = f.forum_id',
),
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
}

View file

@ -0,0 +1,97 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Board wide feed (aka overall feed)
*
* This will give you the newest {$this->num_items} posts
* from the whole board.
*
* @package phpBB3
*/
class phpbb_feed_overall extends phpbb_feed_post_base
{
function get_sql()
{
$forum_ids = array_diff($this->get_readable_forums(), $this->get_excluded_forums(), $this->get_passworded_forums());
if (empty($forum_ids))
{
return false;
}
// m_approve forums
$fid_m_approve = $this->get_moderator_approve_forums();
$sql_m_approve = (!empty($fid_m_approve)) ? 'OR ' . $this->db->sql_in_set('forum_id', $fid_m_approve) : '';
// Determine topics with recent activity
$sql = 'SELECT topic_id, topic_last_post_time
FROM ' . TOPICS_TABLE . '
WHERE ' . $this->db->sql_in_set('forum_id', $forum_ids) . '
AND topic_moved_id = 0
AND (topic_approved = 1
' . $sql_m_approve . ')
ORDER BY topic_last_post_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$topic_ids = array();
$min_post_time = 0;
while ($row = $this->db->sql_fetchrow())
{
$topic_ids[] = (int) $row['topic_id'];
$min_post_time = (int) $row['topic_last_post_time'];
}
$this->db->sql_freeresult($result);
if (empty($topic_ids))
{
return false;
}
// 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, ' .
'u.username, u.user_id',
'FROM' => array(
USERS_TABLE => 'u',
POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(FORUMS_TABLE => 'f'),
'ON' => 'f.forum_id = p.forum_id',
),
),
'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . '
AND (p.post_approved = 1
' . str_replace('forum_id', 'p.forum_id', $sql_m_approve) . ')
AND p.post_time >= ' . $min_post_time . '
AND u.user_id = p.poster_id',
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
function adjust_item(&$item_row, &$row)
{
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
}
}

View file

@ -0,0 +1,57 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Abstract class for post based feeds
*
* @package phpBB3
*/
abstract class phpbb_feed_post_base extends phpbb_feed_base
{
var $num_items = 'feed_limit_post';
function set_keys()
{
$this->set('title', 'post_subject');
$this->set('title2', 'topic_title');
$this->set('author_id', 'user_id');
$this->set('creator', 'username');
$this->set('published', 'post_time');
$this->set('updated', 'post_edit_time');
$this->set('text', 'post_text');
$this->set('bitfield', 'bbcode_bitfield');
$this->set('bbcode_uid','bbcode_uid');
$this->set('enable_bbcode', 'enable_bbcode');
$this->set('enable_smilies', 'enable_smilies');
$this->set('enable_magic_url', 'enable_magic_url');
}
function adjust_item(&$item_row, &$row)
{
$item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, "t={$row['topic_id']}&amp;p={$row['post_id']}#p{$row['post_id']}");
if ($this->config['feed_item_statistics'])
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
. (($this->is_moderator_approve_forum($row['forum_id']) && !$row['post_approved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
}
}
}

View file

@ -0,0 +1,116 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Topic feed for a specific topic
*
* This will give you the last {$this->num_items} posts made within this topic.
*
* @package phpBB3
*/
class phpbb_feed_topic extends phpbb_feed_post_base
{
var $topic_id = 0;
var $forum_id = 0;
var $topic_data = array();
/**
* Set the Topic ID
*
* @param int $topic_id Topic ID
* @return phpbb_feed_topic
*/
public function set_topic_id($topic_id)
{
$this->topic_id = (int) $topic_id;
return $this;
}
function open()
{
$sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_approved, t.topic_title, t.topic_time, t.topic_views, t.topic_replies, t.topic_type
FROM ' . TOPICS_TABLE . ' t
LEFT JOIN ' . FORUMS_TABLE . ' f
ON (f.forum_id = t.forum_id)
WHERE t.topic_id = ' . $this->topic_id;
$result = $this->db->sql_query($sql);
$this->topic_data = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (empty($this->topic_data))
{
trigger_error('NO_TOPIC');
}
$this->forum_id = (int) $this->topic_data['forum_id'];
// Make sure topic is either approved or user authed
if (!$this->topic_data['topic_approved'] && !$this->auth->acl_get('m_approve', $this->forum_id))
{
trigger_error('SORRY_AUTH_READ');
}
// Make sure forum is not excluded from feed
if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->topic_data['forum_options']))
{
trigger_error('NO_FEED');
}
// Make sure we can read this forum
if (!$this->auth->acl_get('f_read', $this->forum_id))
{
trigger_error('SORRY_AUTH_READ');
}
// Make sure forum is not passworded or user is authed
if ($this->topic_data['forum_password'])
{
$forum_ids_passworded = $this->get_passworded_forums();
if (isset($forum_ids_passworded[$this->forum_id]))
{
trigger_error('SORRY_AUTH_READ');
}
unset($forum_ids_passworded);
}
}
function get_sql()
{
$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, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
USERS_TABLE => 'u',
),
'WHERE' => 'p.topic_id = ' . $this->topic_id . '
' . ($this->forum_id && !$this->auth->acl_get('m_approve', $this->forum_id) ? 'AND p.post_approved = 1' : '') . '
AND p.poster_id = u.user_id',
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
function get_item()
{
return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row;
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Abstract class for topic based feeds
*
* @package phpBB3
*/
abstract class phpbb_feed_topic_base extends phpbb_feed_base
{
var $num_items = 'feed_limit_topic';
function set_keys()
{
$this->set('title', 'topic_title');
$this->set('title2', 'forum_name');
$this->set('author_id', 'topic_poster');
$this->set('creator', 'topic_first_poster_name');
$this->set('published', 'post_time');
$this->set('updated', 'post_edit_time');
$this->set('text', 'post_text');
$this->set('bitfield', 'bbcode_bitfield');
$this->set('bbcode_uid','bbcode_uid');
$this->set('enable_bbcode', 'enable_bbcode');
$this->set('enable_smilies', 'enable_smilies');
$this->set('enable_magic_url', 'enable_magic_url');
}
function adjust_item(&$item_row, &$row)
{
$item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, 't=' . $row['topic_id'] . '&amp;p=' . $row['post_id'] . '#p' . $row['post_id']);
if ($this->config['feed_item_statistics'])
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
. ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . (($this->is_moderator_approve_forum($row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies'])
. ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views']
. (($this->is_moderator_approve_forum($row['forum_id']) && ($row['topic_replies_real'] != $row['topic_replies'])) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : '');
}
}
}

View file

@ -0,0 +1,91 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* New Topics feed
*
* This will give you the last {$this->num_items} created topics
* including the first post.
*
* @package phpBB3
*/
class phpbb_feed_topics extends phpbb_feed_topic_base
{
function get_sql()
{
$forum_ids_read = $this->get_readable_forums();
if (empty($forum_ids_read))
{
return false;
}
$in_fid_ary = array_diff($forum_ids_read, $this->get_excluded_forums(), $this->get_passworded_forums());
if (empty($in_fid_ary))
{
return false;
}
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
AND topic_moved_id = 0
AND topic_approved = 1
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$post_ids = array();
while ($row = $this->db->sql_fetchrow($result))
{
$post_ids[] = (int) $row['topic_first_post_id'];
}
$this->db->sql_freeresult($result);
if (empty($post_ids))
{
return false;
}
$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',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(FORUMS_TABLE => 'f'),
'ON' => 'p.forum_id = f.forum_id',
),
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
function adjust_item(&$item_row, &$row)
{
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
}
}

View file

@ -0,0 +1,136 @@
<?php
/**
*
* @package phpBB3
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
/**
* Active Topics feed
*
* This will give you the last {$this->num_items} topics
* with replies made withing the last {$this->sort_days} days
* including the last post.
*
* @package phpBB3
*/
class phpbb_feed_topics_active extends phpbb_feed_topic_base
{
var $sort_days = 7;
function set_keys()
{
parent::set_keys();
$this->set('author_id', 'topic_last_poster_id');
$this->set('creator', 'topic_last_poster_name');
}
function get_sql()
{
$forum_ids_read = $this->get_readable_forums();
if (empty($forum_ids_read))
{
return false;
}
$in_fid_ary = array_intersect($forum_ids_read, $this->get_forum_ids());
$in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
if (empty($in_fid_ary))
{
return false;
}
// Search for topics in last X days
$last_post_time_sql = ($this->sort_days) ? ' AND topic_last_post_time > ' . (time() - ($this->sort_days * 24 * 3600)) : '';
// We really have to get the post ids first!
$sql = 'SELECT topic_last_post_id, topic_last_post_time
FROM ' . TOPICS_TABLE . '
WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
AND topic_moved_id = 0
AND topic_approved = 1
' . $last_post_time_sql . '
ORDER BY topic_last_post_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
$post_ids = array();
while ($row = $this->db->sql_fetchrow($result))
{
$post_ids[] = (int) $row['topic_last_post_id'];
}
$this->db->sql_freeresult($result);
if (empty($post_ids))
{
return false;
}
$this->sql = array(
'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',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(FORUMS_TABLE => 'f'),
'ON' => 'p.forum_id = f.forum_id',
),
),
'WHERE' => 'p.topic_id = t.topic_id
AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
'ORDER_BY' => 'p.post_time DESC',
);
return true;
}
function get_forum_ids()
{
static $forum_ids;
$cache_name = 'feed_topic_active_forum_ids';
if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
{
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
WHERE forum_type = ' . FORUM_POST . '
AND ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '= 0') . '
AND ' . $this->db->sql_bit_and('forum_flags', log(FORUM_FLAG_ACTIVE_TOPICS, 2), '<> 0');
$result = $this->db->sql_query($sql);
$forum_ids = array();
while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
{
$forum_ids[$forum_id] = $forum_id;
}
$this->db->sql_freeresult($result);
$this->cache->put('_' . $cache_name, $forum_ids, 180);
}
return $forum_ids;
}
function adjust_item(&$item_row, &$row)
{
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
}
}

View file

@ -46,7 +46,7 @@ function send_avatar_to_browser($file, $browser)
$image_data = @getimagesize($file_path);
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
if (strpos(strtolower($browser), 'msie') !== false && strpos(strtolower($browser), 'msie 8.0') === false)
if ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
{
header('Content-Disposition: attachment; ' . header_filename($file));
@ -174,10 +174,9 @@ function send_file_to_browser($attachment, $upload_dir, $category)
header('Pragma: public');
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
$is_ie8 = (strpos(strtolower($user->browser), 'msie 8.0') !== false);
header('Content-Type: ' . $attachment['mimetype']);
if ($is_ie8)
if (phpbb_is_greater_ie_version($user->browser, 7))
{
header('X-Content-Type-Options: nosniff');
}
@ -189,7 +188,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
else
{
if (empty($user->browser) || (!$is_ie8 && (strpos(strtolower($user->browser), 'msie') !== false)))
if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
{
header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
@ -200,7 +199,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
else
{
header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if ($is_ie8 && (strpos($attachment['mimetype'], 'image') !== 0))
if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
{
header('X-Download-Options: noopen');
}
@ -410,7 +409,8 @@ function set_modified_headers($stamp, $browser)
// let's see if we have to send the file at all
$last_load = $request->header('Modified-Since') ? strtotime(trim($request->header('Modified-Since'))) : false;
if ((strpos(strtolower($browser), 'msie 6.0') === false) && (strpos(strtolower($browser), 'msie 8.0') === false))
if (strpos(strtolower($browser), 'msie 6.0') === false && !phpbb_is_greater_ie_version($browser, 7))
{
if ($last_load !== false && $last_load >= $stamp)
{
@ -721,3 +721,24 @@ function phpbb_download_clean_filename($filename)
return $filename;
}
/**
* Check if the browser is internet explorer version 7+
*
* @param string $user_agent User agent HTTP header
* @param int $version IE version to check against
*
* @return bool true if internet explorer version is greater than $version
*/
function phpbb_is_greater_ie_version($user_agent, $version)
{
if (preg_match('/msie (\d+)/', strtolower($user_agent), $matches))
{
$ie_version = (int) $matches[1];
return ($ie_version > $version);
}
else
{
return false;
}
}

View file

@ -1653,7 +1653,7 @@ function validate_username($username, $allowed_username = false)
*/
function validate_password($password)
{
global $config, $db, $user;
global $config;
if ($password === '' || $config['pass_complex'] === 'PASS_TYPE_ANY')
{

View file

@ -163,9 +163,16 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
$engine = $info['Type'];
}
if ($engine != 'MyISAM')
$fulltext_supported =
$engine === 'MyISAM' ||
// FULLTEXT is supported on InnoDB since MySQL 5.6.4 according to
// http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
$engine === 'InnoDB' &&
phpbb_version_compare($this->db->sql_server_info(true), '5.6.4', '>=');
if (!$fulltext_supported)
{
return $this->user->lang['FULLTEXT_MYSQL_NOT_MYISAM'];
return $this->user->lang['FULLTEXT_MYSQL_NOT_SUPPORTED'];
}
$sql = 'SHOW VARIABLES

View file

@ -416,9 +416,11 @@ class ucp_groups
if ($group_id)
{
$sql = 'SELECT *
FROM ' . GROUPS_TABLE . "
WHERE group_id = $group_id";
$sql = 'SELECT g.*, t.teampage_position AS group_teampage
FROM ' . GROUPS_TABLE . ' g
LEFT JOIN ' . TEAMPAGE_TABLE . ' t
ON (t.group_id = g.group_id)
WHERE g.group_id = ' . $group_id;
$result = $db->sql_query($sql);
$group_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
@ -514,6 +516,8 @@ class ucp_groups
'receive_pm' => isset($_REQUEST['group_receive_pm']) ? 1 : 0,
'message_limit' => request_var('group_message_limit', 0),
'max_recipients'=> request_var('group_max_recipients', 0),
'legend' => $group_row['group_legend'],
'teampage' => $group_row['group_teampage'],
);
if ($config['allow_avatar'])
@ -569,6 +573,9 @@ class ucp_groups
// Only set the rank, colour, etc. if it's changed or if we're adding a new
// group. This prevents existing group members being updated if no changes
// were made.
// However there are some attributes that need to be set everytime,
// otherwise the group gets removed from the feature.
$set_attributes = array('legend', 'teampage');
$group_attributes = array();
$test_variables = array(
@ -580,13 +587,14 @@ class ucp_groups
'avatar_height' => 'int',
'receive_pm' => 'int',
'legend' => 'int',
'teampage' => 'int',
'message_limit' => 'int',
'max_recipients'=> 'int',
);
foreach ($test_variables as $test => $type)
{
if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0))
if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0 || in_array($test, $set_attributes)))
{
settype($submit_ary[$test], $type);
$group_attributes['group_' . $test] = $group_row['group_' . $test] = $submit_ary[$test];
@ -596,6 +604,7 @@ class ucp_groups
if (!($error = group_create($group_id, $group_type, $group_name, $group_desc, $group_attributes, $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies)))
{
$cache->destroy('sql', GROUPS_TABLE);
$cache->destroy('sql', TEAMPAGE_TABLE);
$message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED';
trigger_error($user->lang[$message] . $return_page);
@ -682,7 +691,7 @@ class ucp_groups
}
}
if (!$update)
if (isset($phpbb_avatar_manager) && !$update)
{
// Merge any avatars errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));

View file

@ -1618,7 +1618,9 @@ class install_update extends module
{
case 'version_info':
global $phpbb_root_path, $phpEx;
$info = get_remote_file('www.phpbb.com', '/updatecheck', ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
$info = get_remote_file('version.phpbb.com', '/phpbb',
((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno);
if ($info !== false)
{

View file

@ -52,7 +52,7 @@ $lang = array_merge($lang, array(
'DELETING_INDEX_IN_PROGRESS_EXPLAIN' => 'The search backend is currently cleaning its index. This can take a few minutes.',
'FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE' => 'The MySQL fulltext backend can only be used with MySQL4 and above.',
'FULLTEXT_MYSQL_NOT_MYISAM' => 'MySQL fulltext indexes can only be used with MyISAM tables.',
'FULLTEXT_MYSQL_NOT_SUPPORTED' => 'MySQL fulltext indexes can only be used with MyISAM or InnoDB tables. MySQL 5.6.4 or later is required for fulltext indexes on InnoDB tables.',
'FULLTEXT_MYSQL_TOTAL_POSTS' => 'Total number of indexed posts',
'FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN' => 'Words with at least this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.',
'FULLTEXT_MYSQL_MAX_SEARCH_CHARS_EXPLAIN' => 'Words with no more than this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.',

View file

@ -401,7 +401,7 @@ function getCaretPosition(txtarea) {
*/
(function($) {
$(document).ready(function() {
var doc, textarea, startTags, endTags;
var doc, textarea;
// find textarea, make sure browser supports necessary functions
if (document.forms[form_name]) {
@ -415,81 +415,8 @@ function getCaretPosition(txtarea) {
}
textarea = doc.forms[form_name].elements[text_name];
if (!textarea || typeof textarea.selectionStart !== 'number') {
return;
}
// list of allowed start and end bbcode code tags, in lower case
startTags = ['[code]', '[code='];
endTags = ['[/code]'];
function inTag() {
var start = textarea.selectionStart,
lastEnd = -1,
lastStart = -1,
i, index, value;
value = textarea.value.toLowerCase();
for (i = 0; i < startTags.length; i++) {
var tagLength = startTags[i].length;
if (start >= tagLength) {
index = value.lastIndexOf(startTags[i], start - tagLength);
lastStart = Math.max(lastStart, index);
}
}
if (lastStart == -1) return false;
if (start > 0) {
for (i = 0; i < endTags.length; i++) {
index = value.lastIndexOf(endTags[i], start - 1);
lastEnd = Math.max(lastEnd, index);
}
}
return (lastEnd < lastStart);
}
function getLastLine() {
var start = textarea.selectionStart,
value = textarea.value,
index = value.lastIndexOf("\n", start - 1);
return value.substring(index + 1, start);
}
function appendCode(code) {
var start = textarea.selectionStart,
end = textarea.selectionEnd,
value = textarea.value;
textarea.value = value.substr(0, start) + code + value.substr(end);
textarea.selectionStart = textarea.selectionEnd = start + code.length;
}
$(textarea).on('keydown', function(event) {
var key = event.keyCode || event.which;
// intercept tabs
if (key == 9) {
if (inTag()) {
appendCode("\t");
event.preventDefault();
return;
}
}
// intercept new line characters
if (key == 13) {
if (inTag()) {
var lastLine = getLastLine(),
code = '' + /^\s*/g.exec(lastLine);
if (code.length > 0) {
appendCode("\n" + code);
event.preventDefault();
return;
}
}
}
});
phpbb.applyCodeEditor(textarea);
});
})(jQuery);

View file

@ -306,8 +306,12 @@ a#logo:hover {
ul.linklist {
display: block;
margin: 0;
height: 4%;
overflow: hidden;
}
ul.linklist:after {
content: '';
display: block;
clear: both;
}
#cp-main .panel {
@ -689,28 +693,33 @@ p.rules a {
vertical-align: text-bottom;
}
.icon-notification {
position: relative;
}
#notification_list {
display: none;
position: absolute;
left: 0;
width: 330px;
z-index: 1;
border: 1px solid;
box-shadow: 3px 3px 5px darkgray;
border-radius: 5px;
margin-top: 8px;
top: 32px;
}
#notification_list ul {
max-height: 350px;
overflow-y: auto;
overflow-x: hidden;
clear: both;
}
#notification_list ul li {
width: 310px;
padding: 10px;
margin: 0;
float: left;
float: none;
border-bottom: 1px solid;
list-style-type: none;
font-size: 0.95em;

View file

@ -9,6 +9,10 @@ tweaks required due to its poor CSS support.
zoom: 1;
}
ul.linklist {
zoom: 1;
}
/* Align checkboxes/radio buttons nicely */
dd label input {
vertical-align: text-bottom;
@ -47,3 +51,18 @@ dd.lastpost, dd.redirect, dd.moderation, dd.time, dd.info {
dd.option {
*width: 124px;
}
/* Notifications list for IE7 */
#notification_list {
*left: 0;
}
#notification_list .header_settings {
*position: absolute;
*right: 10px;
*top: 0;
}
.icon-notification {
*z-index: 2;
}

View file

@ -38,6 +38,7 @@ function initInsertions() {
}
var textarea = doc.forms[form_name].elements[text_name];
phpbb.applyCodeEditor(textarea);
if (is_ie && typeof(baseHeight) !== 'number') {
textarea.focus();

View file

@ -0,0 +1,130 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_download.php';
class phpbb_download_http_user_agent_test extends phpbb_test_case
{
public function user_agents_check_greater_ie_version()
{
return array(
// user agent
// IE version
// expected
array(
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
7,
true,
),
array(
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
7,
true,
),
array(
'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)',
7,
true,
),
array(
'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)',
7,
false,
),
array(
'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
7,
false,
),
array(
'Mozilla/4.0 (compatible; MSIE 6.01; Windows NT 6.0)',
7,
false,
),
array(
'Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)',
7,
false,
),
array(
'Mozilla/5.0 (Windows NT 6.2; Win64; x64;) Gecko/20100101 Firefox/20.0',
7,
false,
),
array(
'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1464.0 Safari/537.36',
7,
false,
),
array(
'Googlebot-Image/1.0',
7,
false,
),
array(
'Googlebot/2.1 ( http://www.google.com/bot.html)',
7,
false,
),
array(
'Lynx/2.8.3dev.9 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.6',
7,
false,
),
array(
'Links (0.9x; Linux 2.4.7-10 i686)',
7,
false,
),
array(
'Opera/9.60 (Windows NT 5.1; U; de) Presto/2.1.1',
7,
false,
),
array(
'Mozilla/4.0 (compatible; MSIE 5.0; Windows NT;)',
7,
false,
),
array(
'Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 4.0) Opera 6.01 [en]',
7,
false,
),
array(
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.24',
7,
false,
),
array(
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
8,
true,
),
array(
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
9,
true,
),
array(
'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .NET CLR 3.3.69573; WOW64; en-US)',
10,
false,
),
);
}
/**
* @dataProvider user_agents_check_greater_ie_version
*/
public function test_is_greater_ie_version($user_agent, $version, $expected)
{
$this->assertEquals($expected, phpbb_is_greater_ie_version($user_agent, $version));
}
}

View file

@ -14,8 +14,107 @@ require_once dirname(__FILE__) . '/common_groups_test.php';
*/
class phpbb_functional_acp_groups_test extends phpbb_functional_common_groups_test
{
protected $form_data;
protected function get_url()
{
return 'adm/index.php?i=groups&mode=manage&action=edit';
}
public function acp_group_test_data()
{
return array(
'both_yes' => array(
5,
true,
true,
),
'legend_no_teampage' => array(
5,
true,
false,
),
'no_legend_teampage' => array(
5,
false,
true,
),
'both_no' => array(
5,
false,
false,
),
'no_change' => array(
5,
NULL,
NULL,
),
'back_to_default' => array(
5,
true,
true,
),
// Remove and add moderators back in order to reset
// group order to default one
'mods_both_no' => array(
4,
false,
false,
),
'mods_back_to_default' => array(
4,
true,
true,
),
);
}
/**
* @dataProvider acp_group_test_data
*/
public function test_acp_groups_teampage($group_id, $tick_legend, $tick_teampage)
{
$this->group_manage_login();
// Manage Administrators group
$form = $this->get_group_manage_form($group_id);
$this->form_data[0] = $form->getValues();
if (isset($tick_legend) && isset($tick_teampage))
{
if ($tick_legend)
{
$form['group_legend']->tick();
}
else
{
$form['group_legend']->untick();
}
if ($tick_teampage)
{
$form['group_teampage']->tick();
}
else
{
$form['group_teampage']->untick();
}
}
$crawler = self::submit($form);
$this->assertContains($this->lang('GROUP_UPDATED'), $crawler->text());
$form = $this->get_group_manage_form($group_id);
if (!isset($tick_legend) && !isset($tick_teampage))
{
$this->form_data[1] = $form->getValues();
unset($this->form_data[0]['creation_time'], $this->form_data[0]['form_token'], $this->form_data[1]['creation_time'], $this->form_data[1]['form_token']);
$this->assertEquals($this->form_data[0], $this->form_data[1]);
}
else
{
$this->form_data = $form->getValues();
$this->assertEquals($tick_legend, $this->form_data['group_legend']);
$this->assertEquals($tick_teampage, $this->form_data['group_teampage']);
}
}
}

View file

@ -25,25 +25,22 @@ class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case
{
// Permissions tab
// XXX hardcoded id
$crawler = $this->request('GET', 'adm/index.php?i=16&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=16&sid=' . $this->sid);
// these language strings are html
$this->assertContains($this->lang('ACP_PERMISSIONS_EXPLAIN'), $this->client->getResponse()->getContent());
$this->assertContains($this->lang('ACP_PERMISSIONS_EXPLAIN'), $this->get_content());
}
public function test_select_user()
{
// User permissions
$crawler = $this->request('GET', 'adm/index.php?i=acp_permissions&icat=16&mode=setting_user_global&sid=' . $this->sid);
$this->assert_response_success();
$this->assertContains($this->lang('ACP_USERS_PERMISSIONS_EXPLAIN'), $this->client->getResponse()->getContent());
$crawler = self::request('GET', 'adm/index.php?i=acp_permissions&icat=16&mode=setting_user_global&sid=' . $this->sid);
$this->assertContains($this->lang('ACP_USERS_PERMISSIONS_EXPLAIN'), $this->get_content());
// Select admin
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$data = array('username[0]' => 'admin');
$form->setValues($data);
$crawler = $this->client->submit($form);
$this->assert_response_success();
$crawler = self::submit($form);
$this->assertContains($this->lang('ACL_SET'), $crawler->filter('h1')->eq(1)->text());
}
@ -91,8 +88,7 @@ class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case
public function test_change_permission($description, $permission_type, $permission, $mode, $object_name, $object_id)
{
// Get the form
$crawler = $this->request('GET', "adm/index.php?i=acp_permissions&icat=16&mode=$mode&${object_name}[0]=$object_id&type=$permission_type&sid=" . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', "adm/index.php?i=acp_permissions&icat=16&mode=$mode&${object_name}[0]=$object_id&type=$permission_type&sid=" . $this->sid);
$this->assertContains($this->lang('ACL_SET'), $crawler->filter('h1')->eq(1)->text());
// XXX globals for phpbb_auth, refactor it later
@ -114,8 +110,7 @@ class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case
// set to never
$data = array("setting[$object_id][0][$permission]" => '0');
$form->setValues($data);
$crawler = $this->client->submit($form);
$this->assert_response_success();
$crawler = self::submit($form);
$this->assertContains($this->lang('AUTH_UPDATED'), $crawler->text());
// check acl again

View file

@ -17,8 +17,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
$this->login();
// check for logout link
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains($this->lang('LOGOUT_USER', 'admin'), $crawler->filter('.navbar')->text());
}
@ -26,8 +25,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
{
$this->create_user('anothertestuser');
$this->login('anothertestuser');
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains('anothertestuser', $crawler->filter('.icon-logout')->text());
}
@ -40,13 +38,11 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
$this->add_lang('ucp');
// logout
$crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text());
// look for a register link, which should be visible only when logged out
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertContains($this->lang('REGISTER'), $crawler->filter('.navbar')->text());
}
@ -56,8 +52,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
$this->admin_login();
// check that we are logged in
$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid);
$this->assertContains($this->lang('ADMIN_PANEL'), $crawler->filter('h1')->text());
}
}

View file

@ -14,22 +14,19 @@ class phpbb_functional_browse_test extends phpbb_functional_test_case
{
public function test_index()
{
$crawler = $this->request('GET', 'index.php');
$this->assert_response_success();
$crawler = self::request('GET', 'index.php');
$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());
}
public function test_viewforum()
{
$crawler = $this->request('GET', 'viewforum.php?f=2');
$this->assert_response_success();
$crawler = self::request('GET', 'viewforum.php?f=2');
$this->assertGreaterThan(0, $crawler->filter('.topiclist')->count());
}
public function test_viewtopic()
{
$crawler = $this->request('GET', 'viewtopic.php?t=1');
$this->assert_response_success();
$crawler = self::request('GET', 'viewtopic.php?t=1');
$this->assertGreaterThan(0, $crawler->filter('.postbody')->count());
}
}

View file

@ -14,6 +14,28 @@ abstract class phpbb_functional_common_groups_test extends phpbb_functional_test
{
abstract protected function get_url();
/**
* Get group_manage form
* @param int $group_id ID of the group that should be managed
*/
protected function get_group_manage_form($group_id = 5)
{
// Manage Administrators group
$crawler = self::request('GET', $this->get_url() . "&g=$group_id&sid=" . $this->sid);
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
return $form;
}
/**
* Execute login calls and add_lang() calls for tests
*/
protected function group_manage_login()
{
$this->login();
$this->admin_login();
$this->add_lang(array('ucp', 'acp/groups'));
}
public function groups_manage_test_data()
{
return array(
@ -30,22 +52,12 @@ abstract class phpbb_functional_common_groups_test extends phpbb_functional_test
*/
public function test_groups_manage($input, $expected)
{
$this->markTestIncomplete(
'Test fails on develop due to another test deleting the Administrators group.'
);
// See https://github.com/phpbb/phpbb3/pull/1407#issuecomment-18465480
// and https://gist.github.com/bantu/22dc4f6c6c0b8f9e0fa1
$this->login();
$this->admin_login();
$this->add_lang(array('ucp', 'acp/groups'));
$this->group_manage_login();
// Manage Administrators group
$crawler = $this->request('GET', $this->get_url() . '&g=5&sid=' . $this->sid);
$this->assert_response_success();
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$form = $this->get_group_manage_form();
$form['group_colour']->setValue($input);
$crawler = $this->client->submit($form);
$crawler = self::submit($form);
$this->assertContains($this->lang($expected), $crawler->text());
}
}

View file

@ -12,34 +12,25 @@
*/
class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
{
static private $copied_files = array();
static private $helper;
/**
* This should only be called once before the tests are run.
* This is used to copy the extensions to the phpBB install
*/
static protected $fixtures = array(
'./',
);
static public function setUpBeforeClass()
{
global $phpbb_root_path;
parent::setUpBeforeClass();
self::$helper = new phpbb_test_case_helpers(self);
self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/../extension/ext/', self::$fixtures);
}
self::$copied_files = array();
static public function tearDownAfterClass()
{
parent::tearDownAfterClass();
if (file_exists($phpbb_root_path . 'ext/'))
{
// First, move any extensions setup on the board to a temp directory
self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/');
// Then empty the ext/ directory on the board (for accurate test cases)
self::$helper->empty_dir($phpbb_root_path . 'ext/');
}
// Copy our ext/ files from the test case to the board
self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/../extension/ext/', $phpbb_root_path . 'ext/'));
self::$helper->restore_original_ext_dir();
}
public function setUp()
@ -84,32 +75,9 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
$this->add_lang('acp/extensions');
}
/**
* This should only be called once after the tests are run.
* This is used to remove the files copied to the phpBB install
*/
static public function tearDownAfterClass()
{
global $phpbb_root_path;
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
// Copy back the board installed extensions from the temp directory
self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/');
}
// Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext)
self::$helper->remove_files(self::$copied_files);
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/');
}
}
public function test_list()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
$this->assertCount(1, $crawler->filter('.ext_enabled'));
$this->assertCount(5, $crawler->filter('.ext_disabled'));
@ -131,7 +99,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
public function test_details()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo&sid=' . $this->sid);
$validation = array(
'DISPLAY_NAME' => 'phpBB Foo Extension',
@ -174,46 +142,46 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
public function test_enable_pre()
{
// Foo is already enabled (redirect to list)
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=foo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=foo&sid=' . $this->sid);
$this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text());
$this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text());
$this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text());
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$this->assertContainsLang('ENABLE_CONFIRM', $crawler->filter('html')->text());
}
public function test_disable_pre()
{
// Moo is not enabled (redirect to list)
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text());
$this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text());
$this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text());
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=foo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=foo&sid=' . $this->sid);
$this->assertContainsLang('DISABLE_CONFIRM', $crawler->filter('html')->text());
}
public function test_purge_pre()
{
// test2 is not available (error)
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=test2&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=test2&sid=' . $this->sid);
$this->assertContains('The required file does not exist', $crawler->filter('html')->text());
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=foo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=foo&sid=' . $this->sid);
$this->assertContainsLang('PURGE_CONFIRM', $crawler->filter('html')->text());
}
public function test_actions()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$this->assertContainsLang('ENABLE_SUCCESS', $crawler->filter('html')->text());
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$this->assertContainsLang('DISABLE_SUCCESS', $crawler->filter('html')->text());
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge&ext_name=vendor%2Fmoo&sid=' . $this->sid);
$this->assertContainsLang('PURGE_SUCCESS', $crawler->filter('html')->text());
}
}

View file

@ -6,6 +6,7 @@
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php';
/**
* @group functional
@ -14,65 +15,27 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
{
protected $phpbb_extension_manager;
static private $helper;
static protected $fixtures = array(
'foo/bar/config/routing.yml',
'foo/bar/config/services.yml',
'foo/bar/controller/controller.php',
'foo/bar/styles/prosilver/template/foo_bar_body.html',
'foo/bar/config/',
'foo/bar/controller/',
'foo/bar/styles/prosilver/template/',
);
/**
* This should only be called once before the tests are run.
* This is used to copy the fixtures to the phpBB install
*/
static public function setUpBeforeClass()
{
global $phpbb_root_path;
parent::setUpBeforeClass();
$directories = array(
$phpbb_root_path . 'ext/foo/bar/',
$phpbb_root_path . 'ext/foo/bar/config/',
$phpbb_root_path . 'ext/foo/bar/controller/',
$phpbb_root_path . 'ext/foo/bar/styles/prosilver/template',
);
foreach ($directories as $dir)
{
if (!is_dir($dir))
{
mkdir($dir, 0777, true);
}
}
foreach (self::$fixtures as $fixture)
{
copy(
"tests/functional/fixtures/ext/$fixture",
"{$phpbb_root_path}ext/$fixture");
}
self::$helper = new phpbb_test_case_helpers(self);
self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures);
}
/**
* This should only be called once after the tests are run.
* This is used to remove the fixtures from the phpBB install
*/
static public function tearDownAfterClass()
{
global $phpbb_root_path;
parent::tearDownAfterClass();
foreach (self::$fixtures as $fixture)
{
unlink("{$phpbb_root_path}ext/$fixture");
}
rmdir("{$phpbb_root_path}ext/foo/bar/config");
rmdir("{$phpbb_root_path}ext/foo/bar/controller");
rmdir("{$phpbb_root_path}ext/foo/bar/styles/prosilver/template");
rmdir("{$phpbb_root_path}ext/foo/bar/styles/prosilver");
rmdir("{$phpbb_root_path}ext/foo/bar/styles");
rmdir("{$phpbb_root_path}ext/foo/bar");
rmdir("{$phpbb_root_path}ext/foo");
self::$helper->restore_original_ext_dir();
}
public function setUp()
@ -90,8 +53,8 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
public function test_foo_bar()
{
$this->phpbb_extension_manager->enable('foo/bar');
$crawler = $this->request('GET', 'app.php?controller=foo/bar');
$this->assert_response_success();
$crawler = self::request('GET', 'app.php?controller=foo/bar', array(), false);
self::assert_response_status_code();
$this->assertContains("foo/bar controller handle() method", $crawler->filter('body')->text());
$this->phpbb_extension_manager->purge('foo/bar');
}
@ -102,8 +65,7 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
public function test_controller_with_template()
{
$this->phpbb_extension_manager->enable('foo/bar');
$crawler = $this->request('GET', 'app.php?controller=foo/template');
$this->assert_response_success();
$crawler = self::request('GET', 'app.php?controller=foo/template');
$this->assertContains("I am a variable", $crawler->filter('#content')->text());
$this->phpbb_extension_manager->purge('foo/bar');
}
@ -115,8 +77,8 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
public function test_missing_argument()
{
$this->phpbb_extension_manager->enable('foo/bar');
$crawler = $this->request('GET', 'app.php?controller=foo/baz');
$this->assertEquals(500, $this->client->getResponse()->getStatus());
$crawler = self::request('GET', 'app.php?controller=foo/baz', array(), false);
$this->assert_response_html(500);
$this->assertContains('Missing value for argument #1: test in class phpbb_ext_foo_bar_controller:baz', $crawler->filter('body')->text());
$this->phpbb_extension_manager->purge('foo/bar');
}
@ -127,8 +89,8 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
public function test_exception_should_result_in_500_status_code()
{
$this->phpbb_extension_manager->enable('foo/bar');
$crawler = $this->request('GET', 'app.php?controller=foo/exception');
$this->assertEquals(500, $this->client->getResponse()->getStatus());
$crawler = self::request('GET', 'app.php?controller=foo/exception', array(), false);
$this->assert_response_html(500);
$this->assertContains('Exception thrown from foo/exception route', $crawler->filter('body')->text());
$this->phpbb_extension_manager->purge('foo/bar');
}
@ -144,8 +106,8 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
*/
public function test_error_ext_disabled_or_404()
{
$crawler = $this->request('GET', 'app.php?controller=does/not/exist');
$this->assertEquals(404, $this->client->getResponse()->getStatus());
$crawler = self::request('GET', 'app.php?controller=does/not/exist', array(), false);
$this->assert_response_html(404);
$this->assertContains('No route found for "GET /does/not/exist"', $crawler->filter('body')->text());
}
}

View file

@ -16,56 +16,26 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/acp/acp_modules.php';
class phpbb_functional_extension_module_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
static private $copied_files = array();
static private $helper;
/**
* This should only be called once before the tests are run.
* This is used to copy the fixtures to the phpBB install
*/
static protected $fixtures = array(
'./',
);
static public function setUpBeforeClass()
{
global $phpbb_root_path;
parent::setUpBeforeClass();
self::$helper = new phpbb_test_case_helpers(self);
self::$copied_files = array();
if (file_exists($phpbb_root_path . 'ext/'))
{
// First, move any extensions setup on the board to a temp directory
self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/');
// Then empty the ext/ directory on the board (for accurate test cases)
self::$helper->empty_dir($phpbb_root_path . 'ext/');
}
// Copy our ext/ files from the test case to the board
self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/fixtures/ext/', $phpbb_root_path . 'ext/'));
self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures);
}
/**
* This should only be called once after the tests are run.
* This is used to remove the fixtures from the phpBB install
*/
static public function tearDownAfterClass()
{
global $phpbb_root_path;
parent::tearDownAfterClass();
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
// Copy back the board installed extensions from the temp directory
self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/');
}
// Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext)
self::$helper->remove_files(self::$copied_files);
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/');
}
self::$helper->restore_original_ext_dir();
}
public function setUp()
@ -122,8 +92,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
{
$this->login();
$this->admin_login();
$crawler = $this->request('GET', 'adm/index.php?i=phpbb_ext_foo_bar_acp_main_module&mode=mode&sid=' . $this->sid, array(), true);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=phpbb_ext_foo_bar_acp_main_module&mode=mode&sid=' . $this->sid);
$this->assertContains("Bertie rulez!", $crawler->filter('#main')->text());
$this->phpbb_extension_manager->purge('foo/bar');
}

View file

@ -16,59 +16,23 @@ class phpbb_functional_extension_permission_lang_test extends phpbb_functional_t
static private $helper;
static private $copied_files = array();
static protected $fixtures = array(
'foo/bar/language/en/',
);
/**
* This should only be called once before the tests are run.
* This is used to copy the fixtures to the phpBB install
*/
static public function setUpBeforeClass()
{
global $phpbb_root_path;
parent::setUpBeforeClass();
self::$helper = new phpbb_test_case_helpers(self);
self::$copied_files = array();
if (file_exists($phpbb_root_path . 'ext/'))
{
// First, move any extensions setup on the board to a temp directory
self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/');
// Then empty the ext/ directory on the board (for accurate test cases)
self::$helper->empty_dir($phpbb_root_path . 'ext/');
}
// Copy our ext/ files from the test case to the board
self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/fixtures/ext/' . $fixture, $phpbb_root_path . 'ext/' . $fixture));
self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures);
}
/**
* This should only be called once after the tests are run.
* This is used to remove the fixtures from the phpBB install
*/
static public function tearDownAfterClass()
{
global $phpbb_root_path;
parent::tearDownAfterClass();
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
// Copy back the board installed extensions from the temp directory
self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/');
}
// Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext)
self::$helper->remove_files(self::$copied_files);
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/');
}
self::$helper->restore_original_ext_dir();
}
public function setUp()
@ -99,15 +63,13 @@ class phpbb_functional_extension_permission_lang_test extends phpbb_functional_t
$this->phpbb_extension_manager->enable('foo/bar');
// User permissions
$crawler = $this->request('GET', 'adm/index.php?i=acp_permissions&icat=16&mode=setting_user_global&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=acp_permissions&icat=16&mode=setting_user_global&sid=' . $this->sid);
// Select admin
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$data = array('username[0]' => 'admin');
$form->setValues($data);
$crawler = $this->client->submit($form);
$this->assert_response_success();
$crawler = self::submit($form);
// language from language/en/acp/permissions_phpbb.php
$this->assertContains('Can attach files', $crawler->filter('body')->text());

View file

@ -32,7 +32,7 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case
'error' => UPLOAD_ERR_OK,
);
$crawler = $this->client->request(
$crawler = self::$client->request(
'POST',
'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid,
array('add_file' => $this->lang('ADD_FILE')),
@ -66,9 +66,8 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case
{
$this->markTestIncomplete('Test fails intermittently.');
$crawler = $this->upload_file('valid.jpg', 'image/jpeg');
$this->assert_response_success();
// ensure there was no error message rendered
$this->assertNotContains('<h2>' . $this->lang('INFORMATION') . '</h2>', $this->client->getResponse()->getContent());
$this->assertNotContains('<h2>' . $this->lang('INFORMATION') . '</h2>', $this->get_content());
$this->assertContains($this->lang('POSTED_ATTACHMENTS'), $crawler->filter('#postform h3')->eq(1)->text());
}
}

View file

@ -58,7 +58,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
public function test_successful_upload()
{
$upload = new fileupload('', array('gif'), 1000);
$file = $upload->remote_upload($this->root_url . 'styles/prosilver/theme/images/forum_read.gif');
$file = $upload->remote_upload(self::$root_url . 'styles/prosilver/theme/images/forum_read.gif');
$this->assertEquals(0, sizeof($file->error));
$this->assertTrue(file_exists($file->filename));
}
@ -66,7 +66,8 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
public function test_too_large()
{
$upload = new fileupload('', array('gif'), 100);
$file = $upload->remote_upload($this->root_url . 'styles/prosilver/theme/images/forum_read.gif');
$file = $upload->remote_upload(self::$root_url . 'styles/prosilver/theme/images/forum_read.gif');
$this->assertEquals(1, sizeof($file->error));
$this->assertEquals('WRONG_FILESIZE', $file->error[0]);
}
}

View file

@ -16,8 +16,7 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case
{
global $config;
$this->add_lang('ucp');
$crawler = $this->request('GET', 'ucp.php?mode=sendpassword');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?mode=sendpassword');
$this->assertEquals($this->lang('SEND_PASSWORD'), $crawler->filter('h2')->text());
}
@ -26,24 +25,18 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case
$this->login();
$this->admin_login();
$this->add_lang('ucp');
$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security');
$this->assertEquals(200, $this->client->getResponse()->getStatus());
$content = $this->client->getResponse()->getContent();
$this->assertNotContains('Fatal error:', $content);
$this->assertNotContains('Notice:', $content);
$this->assertNotContains('[phpBB Debug]', $content);
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security');
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$values["config[allow_password_reset]"] = 0;
$form->setValues($values);
$crawler = $this->client->submit($form);
$crawler = self::submit($form);
$this->logout();
$crawler = $this->request('GET', 'ucp.php?mode=sendpassword');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?mode=sendpassword');
$this->assertContains($this->lang('UCP_PASSWORD_RESET_DISABLED', '', ''), $crawler->text());
}

View file

@ -17,18 +17,15 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case
$this->create_user('memberlist-test-user');
// logs in as admin
$this->login();
$crawler = $this->request('GET', 'memberlist.php?sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'memberlist.php?sid=' . $this->sid);
$this->assertContains('memberlist-test-user', $crawler->text());
// restrict by first character
$crawler = $this->request('GET', 'memberlist.php?first_char=m&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'memberlist.php?first_char=m&sid=' . $this->sid);
$this->assertContains('memberlist-test-user', $crawler->text());
// make sure results for wrong character are not returned
$crawler = $this->request('GET', 'memberlist.php?first_char=a&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'memberlist.php?first_char=a&sid=' . $this->sid);
$this->assertNotContains('memberlist-test-user', $crawler->text());
}
@ -36,16 +33,13 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case
{
$this->login();
// XXX hardcoded user id
$crawler = $this->request('GET', 'memberlist.php?mode=viewprofile&u=2&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'memberlist.php?mode=viewprofile&u=2&sid=' . $this->sid);
$this->assertContains('admin', $crawler->filter('h2')->text());
}
protected function get_memberlist_leaders_table_crawler()
{
$crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid);
return $crawler->filter('.forumbg-table');
}
@ -95,5 +89,17 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case
$crawler = $this->get_memberlist_leaders_table_crawler();
$this->assertNotContains('memberlist-test-moderator', $crawler->eq(0)->text());
$this->assertContains('memberlist-test-moderator', $crawler->eq(1)->text());
// Add admin to moderators, should be visible as moderator
$this->add_user_group('GLOBAL_MODERATORS', array('admin'), true);
$crawler = $this->get_memberlist_leaders_table_crawler();
$this->assertNotContains('admin', $crawler->eq(0)->text());
$this->assertContains('admin', $crawler->eq(1)->text());
// Add admin to admins as leader, should be visible as admin, not moderator
$this->add_user_group('ADMINISTRATORS', array('admin'), true, true);
$crawler = $this->get_memberlist_leaders_table_crawler();
$this->assertContains('admin', $crawler->eq(0)->text());
$this->assertNotContains('admin', $crawler->eq(1)->text());
}
}

View file

@ -16,47 +16,25 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case
{
protected $phpbb_extension_manager;
static private $helpers;
static private $helper;
static protected $fixtures = array(
'foo/bar/',
);
/**
* This should only be called once before the tests are run.
* This is used to copy the fixtures to the phpBB install
*/
static public function setUpBeforeClass()
{
global $phpbb_root_path;
parent::setUpBeforeClass();
self::$helpers = new phpbb_test_case_helpers(self);
if (!file_exists($phpbb_root_path . 'ext/foo/bar/'))
{
self::$helpers->makedirs($phpbb_root_path . 'ext/foo/bar/');
}
foreach (self::$fixtures as $fixture)
{
self::$helpers->copy_dir(dirname(__FILE__) . '/fixtures/ext/' . $fixture, $phpbb_root_path . 'ext/' . $fixture);
}
self::$helper = new phpbb_test_case_helpers(self);
self::$helper->copy_ext_fixtures(dirname(__FILE__) . '/fixtures/ext/', self::$fixtures);
}
/**
* This should only be called once after the tests are run.
* This is used to remove the fixtures from the phpBB install
*/
static public function tearDownAfterClass()
{
global $phpbb_root_path;
parent::tearDownAfterClass();
foreach (self::$fixtures as $fixture)
{
self::$helpers->empty_dir($phpbb_root_path . 'ext/' . $fixture);
}
self::$helpers->empty_dir($phpbb_root_path . 'ext/foo/');
self::$helper->restore_original_ext_dir();
}
public function setUp()
@ -75,9 +53,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case
public function test_extensions_list()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
$this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $crawler->filter('#main')->text());
$this->assertContains('phpBB 3.1 Extension Testing', $crawler->filter('#main')->text());
$this->assertContains('Details', $crawler->filter('#main')->text());
@ -85,8 +61,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case
public function test_extensions_details()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo%2Fbar&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo%2Fbar&sid=' . $this->sid);
// Test whether the details are displayed
$this->assertContains($this->lang('CLEAN_NAME'), $crawler->filter('#main')->text());
@ -97,13 +72,12 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case
// Details should be html escaped
// However, text() only returns the displayed text, so HTML Special Chars are decoded.
// So we test this directly on the content of the response.
$this->assertContains('<p id="require_php">&gt;=5.3</p>', $this->client->getResponse()->getContent());
$this->assertContains('<p id="require_php">&gt;=5.3</p>', $this->get_content());
}
public function test_extensions_details_notexists()
{
$crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=not%2Fexists&sid=' . $this->sid);
$this->assert_response_success();
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=not%2Fexists&sid=' . $this->sid);
// Error message because the files do not exist
$this->assertContains('The required file does not exist:', $crawler->filter('#main')->text());

View file

@ -40,8 +40,7 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case
public function test_user_subscriptions($checkbox_name, $expected_status)
{
$this->login();
$crawler = $this->request('GET', 'ucp.php?i=ucp_notifications&mode=notification_options');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?i=ucp_notifications&mode=notification_options');
$cplist = $crawler->filter('.table1');
if ($expected_status)

View file

@ -19,18 +19,17 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// Test creating topic
$post = $this->create_topic(2, 'Test Topic 1', 'This is a test topic posted by the testing framework.');
$crawler = $this->request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
$crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
$this->assertContains('This is a test topic posted by the testing framework.', $crawler->filter('html')->text());
// Test creating a reply
$post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test post posted by the testing framework.');
$crawler = $this->request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
// Test quoting a message
$crawler = $this->request('GET', "posting.php?mode=quote&f=2&t={$post2['topic_id']}&p={$post2['post_id']}&sid={$this->sid}");
$this->assert_response_success();
$crawler = self::request('GET', "posting.php?mode=quote&f=2&t={$post2['topic_id']}&p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
}
@ -55,7 +54,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
'post' => true,
), $additional_form_data);
return $this->submit_post($posting_url, 'POST_TOPIC', $form_data);
return self::submit_post($posting_url, 'POST_TOPIC', $form_data);
}
/**
@ -79,7 +78,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
'post' => true,
), $additional_form_data);
return $this->submit_post($posting_url, 'POST_REPLY', $form_data);
return self::submit_post($posting_url, 'POST_REPLY', $form_data);
}
/**
@ -94,8 +93,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
{
$this->add_lang('posting');
$crawler = $this->request('GET', $posting_url);
$this->assert_response_success();
$crawler = self::request('GET', $posting_url);
$this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text());
$hidden_fields = array(
@ -119,8 +117,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// I use a request because the form submission method does not allow you to send data that is not
// contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs)
// Instead, I send it as a request with the submit button "post" set to true.
$crawler = $this->client->request('POST', $posting_url, $form_data);
$this->assert_response_success();
$crawler = self::request('POST', $posting_url, $form_data);
$this->assertContains($this->lang('POST_STORED'), $crawler->filter('html')->text());
$url = $crawler->selectLink($this->lang('VIEW_MESSAGE', '', ''))->link()->getUri();

View file

@ -14,8 +14,40 @@ require_once dirname(__FILE__) . '/common_groups_test.php';
*/
class phpbb_functional_ucp_groups_test extends phpbb_functional_common_groups_test
{
protected $db;
protected function get_url()
{
return 'ucp.php?i=groups&mode=manage&action=edit';
}
protected function get_teampage_settings()
{
if (!isset($this->db))
{
$this->db = $this->get_db();
}
$sql = 'SELECT g.group_legend AS group_legend, t.teampage_position AS group_teampage
FROM ' . GROUPS_TABLE . ' g
LEFT JOIN ' . TEAMPAGE_TABLE . ' t
ON (t.group_id = g.group_id)
WHERE g.group_id = 5';
$result = $this->db->sql_query($sql);
$group_row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
return $group_row;
}
public function test_ucp_groups_teampage()
{
$this->group_manage_login();
// Test if group_legend or group_teampage are modified while
// submitting the ucp_group_manage page
$form = $this->get_group_manage_form();
$teampage_settings = $this->get_teampage_settings();
$crawler = self::submit($form);
$this->assertContains($this->lang('GROUP_UPDATED'), $crawler->text());
$this->assertEquals($teampage_settings, $this->get_teampage_settings());
}
}

View file

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_sessions">
<column>session_id</column>
<column>session_user_id</column>
<column>session_forum_id</column>
<column>session_time</column>
<column>session_ip</column>
<column>session_viewonline</column>
</table>
<table name="phpbb_users">
<column>user_id</column>
<column>username_clean</column>
<column>username</column>
<column>user_allow_viewonline</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<row>
<value>1</value>
<value>anonymous</value>
<value>anonymous</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>2</value>
<value>2</value>
<value>2</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>3</value>
<value>3</value>
<value>3</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>4</value>
<value>4</value>
<value>4</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>5</value>
<value>5</value>
<value>5</value>
<value>1</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>6</value>
<value>6</value>
<value>6</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>7</value>
<value>7</value>
<value>7</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>8</value>
<value>8</value>
<value>8</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>9</value>
<value>9</value>
<value>9</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>10</value>
<value>10</value>
<value>10</value>
<value>0</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
</table>
</dataset>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_users">
<column>user_id</column>
<column>username</column>
<column>username_clean</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<column>user_email_hash</column>
<row>
<value>1</value>
<value>admin</value>
<value>admin</value>
<value></value>
<value></value>
<value></value>
<value></value>
<value>143317126117</value>
</row>
</table>
</dataset>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<table name="phpbb_groups">
<column>group_name</column>
<column>group_desc</column>
<row>
<value>foobar_group</value>
<value>test123</value>
</row>
</table>
<table name="phpbb_users">
<column>user_id</column>
<column>username</column>
<column>username_clean</column>
<column>user_permissions</column>
<column>user_sig</column>
<column>user_occ</column>
<column>user_interests</column>
<row>
<value>1</value>
<value>admin</value>
<value>admin</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
<row>
<value>2</value>
<value>moderator</value>
<value>moderator</value>
<value></value>
<value></value>
<value></value>
<value></value>
</row>
</table>
</dataset>

View file

@ -0,0 +1,227 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';
class phpbb_functions_obtain_online_test extends phpbb_database_test_case
{
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/obtain_online.xml');
}
protected function setUp()
{
parent::setUp();
global $config, $db;
$db = $this->db = $this->new_dbal();
$config = array(
'load_online_time' => 5,
);
}
static public function obtain_guest_count_data()
{
return array(
array(0, 2),
array(1, 1),
);
}
/**
* @dataProvider obtain_guest_count_data
*/
public function test_obtain_guest_count($forum_id, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
$time = time();
$this->create_guest_sessions($time);
$this->assertEquals($expected, obtain_guest_count($forum_id));
}
static public function obtain_users_online_data()
{
return array(
array(0, false, array(
'online_users' => array(2 => 2, 3 => 3, 6 => 6, 7 => 7, 10 => 10),
'hidden_users' => array(6 => 6, 7 => 7, 10 => 10),
'total_online' => 5,
'visible_online' => 2,
'hidden_online' => 3,
'guests_online' => 0,
)),
array(0, true, array(
'online_users' => array(2 => 2, 3 => 3, 6 => 6, 7 => 7, 10 => 10),
'hidden_users' => array(6 => 6, 7 => 7, 10 => 10),
'total_online' => 7,
'visible_online' => 2,
'hidden_online' => 3,
'guests_online' => 2,
)),
array(1, false, array(
'online_users' => array(3 => 3, 7 => 7),
'hidden_users' => array(7 => 7),
'total_online' => 2,
'visible_online' => 1,
'hidden_online' => 1,
'guests_online' => 0,
)),
array(1, true, array(
'online_users' => array(3 => 3, 7 => 7),
'hidden_users' => array(7 => 7),
'total_online' => 3,
'visible_online' => 1,
'hidden_online' => 1,
'guests_online' => 1,
)),
array(2, false, array(
'online_users' => array(),
'hidden_users' => array(),
'total_online' => 0,
'visible_online' => 0,
'hidden_online' => 0,
'guests_online' => 0,
)),
array(2, true, array(
'online_users' => array(),
'hidden_users' => array(),
'total_online' => 0,
'visible_online' => 0,
'hidden_online' => 0,
'guests_online' => 0,
)),
);
}
/**
* @dataProvider obtain_users_online_data
*/
public function test_obtain_users_online($forum_id, $display_guests, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
global $config;
$config['load_online_guests'] = $display_guests;
$time = time();
$this->create_guest_sessions($time);
$this->create_user_sessions($time);
$this->assertEquals($expected, obtain_users_online($forum_id));
}
static public function obtain_users_online_string_data()
{
return array(
array(0, false, array(
'online_userlist' => 'REGISTERED_USERS 2, 3',
'l_online_users' => 'ONLINE_USERS_TOTAL 5 REG_USERS_TOTAL 2 HIDDEN_USERS_TOTAL 3',
)),
array(0, true, array(
'online_userlist' => 'REGISTERED_USERS 2, 3',
'l_online_users' => 'ONLINE_USERS_TOTAL_GUESTS 7 REG_USERS_TOTAL 2 HIDDEN_USERS_TOTAL 3 GUEST_USERS_TOTAL 2',
)),
array(1, false, array(
'online_userlist' => 'BROWSING_FORUM 3',
'l_online_users' => 'ONLINE_USERS_TOTAL 2 REG_USERS_TOTAL 1 HIDDEN_USERS_TOTAL 1',
)),
array(1, true, array(
'online_userlist' => 'BROWSING_FORUM_GUESTS 1 3',
'l_online_users' => 'ONLINE_USERS_TOTAL_GUESTS 3 REG_USERS_TOTAL 1 HIDDEN_USERS_TOTAL 1 GUEST_USERS_TOTAL 1',
)),
array(2, false, array(
'online_userlist' => 'BROWSING_FORUM NO_ONLINE_USERS',
'l_online_users' => 'ONLINE_USERS_TOTAL 0 REG_USERS_TOTAL 0 HIDDEN_USERS_TOTAL 0',
)),
array(2, true, array(
'online_userlist' => 'BROWSING_FORUM_GUESTS 0 NO_ONLINE_USERS',
'l_online_users' => 'ONLINE_USERS_TOTAL_GUESTS 0 REG_USERS_TOTAL 0 HIDDEN_USERS_TOTAL 0 GUEST_USERS_TOTAL 0',
)),
);
}
/**
* @dataProvider obtain_users_online_string_data
*/
public function test_obtain_users_online_string($forum_id, $display_guests, $expected)
{
$this->db->sql_query('DELETE FROM phpbb_sessions');
global $config, $user, $auth, $phpbb_dispatcher;
$config['load_online_guests'] = $display_guests;
$user = new phpbb_mock_lang();
$user->lang = $this->load_language();
$auth = $this->getMock('phpbb_auth');
$acl_get_map = array(
array('u_viewonline', true),
array('u_viewprofile', true),
);
$auth->expects($this->any())
->method('acl_get')
->with($this->stringContains('_'),
$this->anything())
->will($this->returnValueMap($acl_get_map));
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$time = time();
$this->create_guest_sessions($time);
$this->create_user_sessions($time);
$online_users = obtain_users_online($forum_id);
$this->assertEquals($expected, obtain_users_online_string($online_users, $forum_id));
}
protected function create_guest_sessions($time)
{
$this->add_session(1, '0001', '192.168.0.1', 0, true, $time);
$this->add_session(1, '0002', '192.168.0.2', 1, true, $time);
$this->add_session(1, '0003', '192.168.0.3', 0, true, $time, 10);
$this->add_session(1, '0004', '192.168.0.4', 1, true, $time, 10);
}
protected function create_user_sessions($time)
{
$this->add_session(2, '0005', '192.168.0.5', 0, true, $time);
$this->add_session(3, '0006', '192.168.0.6', 1, true, $time);
$this->add_session(4, '0007', '192.168.0.7', 0, true, $time, 10);
$this->add_session(5, '0008', '192.168.0.8', 1, true, $time, 10);
$this->add_session(6, '0005', '192.168.0.9', 0, false, $time);
$this->add_session(7, '0006', '192.168.0.10', 1, false, $time);
$this->add_session(8, '0007', '192.168.0.11', 0, false, $time, 10);
$this->add_session(9, '0008', '192.168.0.12', 1, false, $time, 10);
$this->add_session(10, '009', '192.168.0.13', 0, false, $time);
}
protected function add_session($user_id, $session_id, $user_ip, $forum_id, $view_online, $time, $time_delta = 0)
{
$sql_ary = array(
'session_id' => $user_id . '_' . $forum_id . '_session00000000000000000' . $session_id,
'session_user_id' => $user_id,
'session_ip' => $user_ip,
'session_forum_id' => $forum_id,
'session_time' => $time - $time_delta * 60,
'session_viewonline' => $view_online,
);
$this->db->sql_query('INSERT INTO phpbb_sessions ' . $this->db->sql_build_array('INSERT', $sql_ary));
}
protected function load_language()
{
return array(
'NO_ONLINE_USERS' => 'NO_ONLINE_USERS',
'REGISTERED_USERS' => 'REGISTERED_USERS',
'BROWSING_FORUM' => 'BROWSING_FORUM %s',
'BROWSING_FORUM_GUEST' => 'BROWSING_FORUM_GUEST %s %d',
'BROWSING_FORUM_GUESTS' => 'BROWSING_FORUM_GUESTS %s %d',
);
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
class phpbb_functions_validate_data_helper
{
protected $test_case;
public function __construct($test_case)
{
$this->test_case = $test_case;
}
/**
* Test provided input data with supplied checks and compare to expected
* results
*
* @param array $data Array containing one or more subarrays with the
* test data. The first element of a subarray is the
* expected result, the second one is the input, and the
* third is the data that should be passed to the function
* validate_data().
*/
public function assert_valid_data($data)
{
foreach ($data as $key => $test)
{
$this->test_case->assertEquals($test[0], validate_data(array($test[1]), array($test[2])));
}
}
}

View file

@ -0,0 +1,82 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_date_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_date()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array('INVALID'),
'',
array('date'),
),
'empty_opt' => array(
array(),
'',
array('date', true),
),
'double_single' => array(
array(),
'17-06-1990',
array('date'),
),
'single_single' => array(
array(),
'05-05-2009',
array('date'),
),
'double_double' => array(
array(),
'17-12-1990',
array('date'),
),
'month_high' => array(
array('INVALID'),
'17-17-1990',
array('date'),
),
'month_low' => array(
array('INVALID'),
'01-00-1990',
array('date'),
),
'day_high' => array(
array('INVALID'),
'64-01-1990',
array('date'),
),
'day_low' => array(
array('INVALID'),
'00-12-1990',
array('date'),
),
// Currently fails
/*
'zero_year' => array(
array(),
'01-01-0000',
array('date'),
),
*/
));
}
}

View file

@ -0,0 +1,108 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../mock/user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_email_test extends phpbb_database_test_case
{
protected $db;
protected $user;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/validate_email.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->user = new phpbb_mock_user;
$this->helper = new phpbb_functions_validate_data_helper($this);
}
/**
* Get validation prerequesites
*
* @param bool $check_mx Whether mx records should be checked
*/
protected function set_validation_prerequisites($check_mx)
{
global $config, $db, $user;
$config['email_check_mx'] = $check_mx;
$db = $this->db;
$user = $this->user;
$user->optionset('banned_users', array('banned@example.com'));
}
public function test_validate_email()
{
$this->set_validation_prerequisites(false);
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('email'),
),
'allowed' => array(
array(),
'foobar@example.com',
array('email', 'foobar@example.com'),
),
'invalid' => array(
array('EMAIL_INVALID'),
'fööbar@example.com',
array('email'),
),
'valid_complex' => array(
array(),
"'%$~test@example.com",
array('email'),
),
'taken' => array(
array('EMAIL_TAKEN'),
'admin@example.com',
array('email'),
),
'banned' => array(
array('EMAIL_BANNED'),
'banned@example.com',
array('email'),
),
));
}
/**
* @group slow
*/
public function test_validate_email_mx()
{
$this->set_validation_prerequisites(true);
$this->helper->assert_valid_data(array(
'valid' => array(
array(),
'foobar@phpbb.com',
array('email'),
),
'no_mx' => array(
array('DOMAIN_NO_MX_RECORD'),
'test@does-not-exist.phpbb.com',
array('email'),
),
));
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_jabber_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_jabber()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('jabber'),
),
'no_seperator' => array(
array('WRONG_DATA'),
'testjabber.ccc',
array('jabber'),
),
'no_user' => array(
array('WRONG_DATA'),
'@jabber.ccc',
array('jabber'),
),
'no_realm' => array(
array('WRONG_DATA'),
'user@',
array('jabber'),
),
'dot_realm' => array(
array('WRONG_DATA'),
'user@.....',
array('jabber'),
),
'-realm' => array(
array('WRONG_DATA'),
'user@-jabber.ccc',
array('jabber'),
),
'realm-' => array(
array('WRONG_DATA'),
'user@jabber.ccc-',
array('jabber'),
),
'correct' => array(
array(),
'user@jabber.09A-z.org',
array('jabber'),
),
'prohibited' => array(
array('WRONG_DATA'),
'u@ser@jabber.ccc.org',
array('jabber'),
),
'prohibited_char' => array(
array('WRONG_DATA'),
'u<s>er@jabber.ccc.org',
array('jabber'),
),
));
}
}

View file

@ -0,0 +1,60 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_lang_iso_test extends phpbb_database_test_case
{
protected $db;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/language_select.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_lang_iso()
{
global $db;
$db = $this->db;
$this->helper->assert_valid_data(array(
'empty' => array(
array('WRONG_DATA'),
'',
array('language_iso_name'),
),
'en' => array(
array(),
'en',
array('language_iso_name'),
),
'cs' => array(
array(),
'cs',
array('language_iso_name'),
),
'de' => array(
array('WRONG_DATA'),
'de',
array('language_iso_name'),
),
));
}
}

View file

@ -0,0 +1,49 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_match_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_match()
{
$this->helper->assert_valid_data(array(
'empty_opt' => array(
array(),
'',
array('match', true, '/[a-z]$/'),
),
'empty_empty_match' => array(
array(),
'',
array('match'),
),
'foobar' => array(
array(),
'foobar',
array('match', false, '/[a-z]$/'),
),
'foobar_fail' => array(
array('WRONG_DATA'),
'foobar123',
array('match', false, '/[a-z]$/'),
),
));
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_num_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_num()
{
$this->helper->assert_valid_data(array(
'empty' => array(
array(),
'',
array('num'),
),
'zero' => array(
array(),
'0',
array('num'),
),
'five_minmax_correct' => array(
array(),
'5',
array('num', false, 2, 6),
),
'five_minmax_short' => array(
array('TOO_SMALL'),
'5',
array('num', false, 7, 10),
),
'five_minmax_long' => array(
array('TOO_LARGE'),
'5',
array('num', false, 2, 3),
),
'string' => array(
array(),
'foobar',
array('num'),
),
));
}
}

View file

@ -0,0 +1,96 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_password_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function validate_password_data()
{
return array(
array('PASS_TYPE_ANY', array(
'empty' => array(),
'foobar_any' => array(),
'foobar_mixed' => array(),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_CASE', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array(),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_ALPHA', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_symbol' => array(),
)),
array('PASS_TYPE_SYMBOL', array(
'empty' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_mixed' => array('INVALID_CHARS'),
'foobar_alpha' => array('INVALID_CHARS'),
'foobar_symbol' => array(),
)),
);
}
/**
* @dataProvider validate_password_data
*/
public function test_validate_password($pass_complexity, $expected)
{
global $config;
// Set complexity to mixed case letters, numbers and symbols
$config['pass_complex'] = $pass_complexity;
$this->helper->assert_valid_data(array(
'empty' => array(
$expected['empty'],
'',
array('password'),
),
'foobar_any' => array(
$expected['foobar_any'],
'foobar',
array('password'),
),
'foobar_mixed' => array(
$expected['foobar_mixed'],
'FooBar',
array('password'),
),
'foobar_alpha' => array(
$expected['foobar_alpha'],
'F00bar',
array('password'),
),
'foobar_symbol' => array(
$expected['foobar_symbol'],
'fooBar123*',
array('password'),
),
));
}
}

View file

@ -0,0 +1,70 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_string_test extends phpbb_test_case
{
protected $helper;
protected function setUp()
{
parent::setUp();
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function test_validate_string()
{
$this->helper->assert_valid_data(array(
'empty_opt' => array(
array(),
'',
array('string', true),
),
'empty' => array(
array(),
'',
array('string'),
),
'foo' => array(
array(),
'foobar',
array('string'),
),
'foo_minmax_correct' => array(
array(),
'foobar',
array('string', false, 2, 6),
),
'foo_minmax_short' => array(
array('TOO_SHORT'),
'foobar',
array('string', false, 7, 9),
),
'foo_minmax_long' => array(
array('TOO_LONG'),
'foobar',
array('string', false, 2, 5),
),
'empty_short' => array(
array('TOO_SHORT'),
'',
array('string', false, 1, 6),
),
'empty_length_opt' => array(
array(),
'',
array('string', true, 1, 6),
),
));
}
}

View file

@ -0,0 +1,190 @@
<?php
/**
*
* @package testing
* @copyright (c) 2013 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
require_once dirname(__FILE__) . '/../mock/cache.php';
require_once dirname(__FILE__) . '/validate_data_helper.php';
class phpbb_functions_validate_data_test extends phpbb_database_test_case
{
protected $db;
protected $cache;
protected $helper;
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/validate_username.xml');
}
protected function setUp()
{
parent::setUp();
$this->db = $this->new_dbal();
$this->cache = new phpbb_mock_cache;
$this->helper = new phpbb_functions_validate_data_helper($this);
}
public function validate_username_data()
{
return array(
array('USERNAME_CHARS_ANY', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array(),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array(),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_ALPHA_ONLY', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array('INVALID_CHARS'),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('INVALID_CHARS'),
)),
array('USERNAME_ALPHA_SPACERS', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_LETTER_NUM', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array('INVALID_CHARS'),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('INVALID_CHARS'),
)),
array('USERNAME_LETTER_NUM_SPACERS', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array('INVALID_CHARS'),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array(),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
array('USERNAME_ASCII', array(
'foobar_allow' => array(),
'foobar_ascii' => array(),
'foobar_any' => array(),
'foobar_alpha' => array(),
'foobar_alpha_spacers' => array(),
'foobar_letter_num' => array(),
'foobar_letter_num_sp' => array('INVALID_CHARS'),
'foobar_quot' => array('INVALID_CHARS'),
'barfoo_disallow' => array('USERNAME_DISALLOWED'),
'admin_taken' => array('USERNAME_TAKEN'),
'group_taken' => array('USERNAME_TAKEN'),
)),
);
}
/**
* @dataProvider validate_username_data
*/
public function test_validate_username($allow_name_chars, $expected)
{
global $cache, $config, $db;
$db = $this->db;
$cache = $this->cache;
$cache->put('_disallowed_usernames', array('barfoo'));
$config['allow_name_chars'] = $allow_name_chars;
$this->helper->assert_valid_data(array(
'foobar_allow' => array(
$expected['foobar_allow'],
'foobar',
array('username', 'foobar'),
),
'foobar_ascii' => array(
$expected['foobar_ascii'],
'foobar',
array('username'),
),
'foobar_any' => array(
$expected['foobar_any'],
'f*~*^=oo_bar1',
array('username'),
),
'foobar_alpha' => array(
$expected['foobar_alpha'],
'fo0Bar',
array('username'),
),
'foobar_alpha_spacers' => array(
$expected['foobar_alpha_spacers'],
'Fo0-[B]_a+ R',
array('username'),
),
'foobar_letter_num' => array(
$expected['foobar_letter_num'],
'fo0Bar0',
array('username'),
),
'foobar_letter_num_sp' => array(
$expected['foobar_letter_num_sp'],
'Fö0-[B]_a+ R',
array('username'),
),
'foobar_quot' => array(
$expected['foobar_quot'],
'"foobar"',
array('username'),
),
'barfoo_disallow' => array(
$expected['barfoo_disallow'],
'barfoo',
array('username'),
),
'admin_taken' => array(
$expected['admin_taken'],
'admin',
array('username'),
),
'group_taken' => array(
$expected['group_taken'],
'foobar_group',
array('username'),
),
));
}
}

View file

@ -53,6 +53,21 @@ class phpbb_mock_cache implements phpbb_cache_driver_interface
);
}
/**
* Obtain disallowed usernames. Input data via standard put method.
*/
public function obtain_disallowed_usernames()
{
if (($usernames = $this->get('_disallowed_usernames')) !== false)
{
return $usernames;
}
else
{
return array();
}
}
public function checkVar(PHPUnit_Framework_Assert $test, $var_name, $data)
{
$test->assertTrue(isset($this->data[$var_name]));

View file

@ -30,4 +30,9 @@ class phpbb_mock_lang implements ArrayAccess
public function offsetUnset($offset)
{
}
public function lang()
{
return implode(' ', func_get_args());
}
}

View file

@ -33,4 +33,17 @@ class phpbb_mock_user
{
$this->options[$item] = $value;
}
public function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
{
$banned_users = $this->optionget('banned_users');
foreach ($banned_users as $banned)
{
if ($banned == $user_id || $banned == $user_ips || $banned == $user_email)
{
return true;
}
}
return false;
}
}

View file

@ -11,6 +11,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
{
static private $already_connected;
private $db_connections;
protected $test_case_helpers;
protected $fixture_xml_data;
@ -28,6 +30,22 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
'phpbb_database_test_case' => array('already_connected'),
);
$this->db_connections = array();
}
protected function tearDown()
{
parent::tearDown();
// Close all database connections from this test
if (!empty($this->db_connections))
{
foreach ($this->db_connections as $db)
{
$db->sql_close();
}
}
}
protected function setUp()
@ -44,6 +62,21 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
}
}
/**
* Performs synchronisations for a given table/column set on the database
*
* @param array $table_column_map Information about the tables/columns to synchronise
*
* @return null
*/
protected function database_synchronisation($table_column_map)
{
$config = $this->get_database_config();
$manager = $this->create_connection_manager($config);
$manager->connect();
$manager->database_synchronisation($table_column_map);
}
public function createXMLDataSet($path)
{
$db_config = $this->get_database_config();
@ -121,6 +154,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
$db = new $config['dbms']();
$db->sql_connect($config['dbhost'], $config['dbuser'], $config['dbpasswd'], $config['dbname'], $config['dbport']);
$this->db_connections[] = $db;
return $db;
}

View file

@ -479,12 +479,33 @@ class phpbb_database_test_connection_manager
* @return null
*/
public function post_setup_synchronisation($xml_data_set)
{
$table_names = $xml_data_set->getTableNames();
$tables = array();
foreach ($table_names as $table)
{
$tables[$table] = $xml_data_set->getTableMetaData($table)->getColumns();
}
$this->database_synchronisation($tables);
}
/**
* Performs synchronisations on the database after a fixture has been loaded
*
* @param array $table_column_map Array of tables/columns to synchronise
* array(table1 => array(column1, column2))
*
* @return null
*/
public function database_synchronisation($table_column_map)
{
$this->ensure_connected(__METHOD__);
$queries = array();
// Get escaped versions of the table names used in the fixture
$table_names = array_map(array($this->pdo, 'PDO::quote'), $xml_data_set->getTableNames());
// Get escaped versions of the table names to synchronise
$table_names = array_map(array($this->pdo, 'PDO::quote'), array_keys($table_column_map));
switch ($this->config['dbms'])
{
@ -541,7 +562,7 @@ class phpbb_database_test_connection_manager
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
// Get the columns used in the fixture for this table
$column_names = $xml_data_set->getTableMetaData($row['table_name'])->getColumns();
$column_names = $table_column_map[$row['table_name']];
// Skip sequences that weren't specified in the fixture
if (!in_array($row['column_name'], $column_names))

View file

@ -12,8 +12,9 @@ require_once __DIR__ . '/../../phpBB/includes/functions_install.php';
class phpbb_functional_test_case extends phpbb_test_case
{
protected $client;
protected $root_url;
static protected $client;
static protected $cookieJar;
static protected $root_url;
protected $cache = null;
protected $db = null;
@ -39,6 +40,7 @@ class phpbb_functional_test_case extends phpbb_test_case
parent::setUpBeforeClass();
self::$config = phpbb_test_case_helpers::get_test_config();
self::$root_url = self::$config['phpbb_functional_url'];
// Important: this is used both for installation and by
// test cases for querying the tables.
@ -64,12 +66,12 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->bootstrap();
$this->cookieJar = new CookieJar;
$this->client = new Goutte\Client(array(), null, $this->cookieJar);
self::$cookieJar = new CookieJar;
self::$client = new Goutte\Client(array(), null, self::$cookieJar);
// Reset the curl handle because it is 0 at this point and not a valid
// resource
$this->client->getClient()->getCurlMulti()->reset(true);
$this->root_url = self::$config['phpbb_functional_url'];
self::$client->getClient()->getCurlMulti()->reset(true);
// Clear the language array so that things
// that were added in other tests are gone
$this->lang = array();
@ -77,9 +79,55 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->purge_cache();
}
public function request($method, $path)
/**
* Perform a request to page
*
* @param string $method HTTP Method
* @param string $path Page path, relative from phpBB root path
* @param array $form_data An array of form field values
* @param bool $assert_response_html Should we perform standard assertions for a normal html page
* @return Symfony\Component\DomCrawler\Crawler
*/
static public function request($method, $path, $form_data = array(), $assert_response_html = true)
{
return $this->client->request($method, $this->root_url . $path);
$crawler = self::$client->request($method, self::$root_url . $path, $form_data);
if ($assert_response_html)
{
self::assert_response_html();
}
return $crawler;
}
/**
* Submits a form
*
* @param Symfony\Component\DomCrawler\Form $form A Form instance
* @param array $values An array of form field values
* @param bool $assert_response_html Should we perform standard assertions for a normal html page
* @return Symfony\Component\DomCrawler\Crawler
*/
static public function submit(Symfony\Component\DomCrawler\Form $form, array $values = array(), $assert_response_html = true)
{
$crawler = self::$client->submit($form, $values);
if ($assert_response_html)
{
self::assert_response_html();
}
return $crawler;
}
/**
* Get Client Content
*
* @return string HTML page
*/
static public function get_content()
{
return self::$client->getResponse()->getContent();
}
// bootstrap, called after board is set up
@ -183,26 +231,73 @@ class phpbb_functional_test_case extends phpbb_test_case
}
}
// begin data
$data = array();
self::$cookieJar = new CookieJar;
self::$client = new Goutte\Client(array(), null, self::$cookieJar);
// Set client manually so we can increase the cURL timeout
self::$client->setClient(new Guzzle\Http\Client('', array(
Guzzle\Http\Client::DISABLE_REDIRECTS => true,
'curl.options' => array(
CURLOPT_TIMEOUT => 120,
),
)));
$data = array_merge($data, self::$config);
$data = array_merge($data, array(
'default_lang' => 'en',
'admin_name' => 'admin',
'admin_pass1' => 'admin',
'admin_pass2' => 'admin',
'board_email' => 'nobody@example.com',
));
// Reset the curl handle because it is 0 at this point and not a valid
// resource
self::$client->getClient()->getCurlMulti()->reset(true);
$parseURL = parse_url(self::$config['phpbb_functional_url']);
$data = array_merge($data, array(
$crawler = self::request('GET', 'install/index.php?mode=install');
self::assertContains('Welcome to Installation', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
$crawler = self::submit($form);
self::assertContains('Installation compatibility', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
$crawler = self::submit($form);
self::assertContains('Database configuration', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form(array(
// Installer uses 3.0-style dbms name
'dbms' => str_replace('phpbb_db_driver_', '', self::$config['dbms']),
'dbhost' => self::$config['dbhost'],
'dbport' => self::$config['dbport'],
'dbname' => self::$config['dbname'],
'dbuser' => self::$config['dbuser'],
'dbpasswd' => self::$config['dbpasswd'],
'table_prefix' => self::$config['table_prefix'],
));
$crawler = self::submit($form);
self::assertContains('Successful connection', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
$crawler = self::submit($form);
self::assertContains('Administrator configuration', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form(array(
'default_lang' => 'en',
'admin_name' => 'admin',
'admin_pass1' => 'adminadmin',
'admin_pass2' => 'adminadmin',
'board_email' => 'nobody@example.com',
));
$crawler = self::submit($form);
self::assertContains('Tests passed', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
$crawler = self::submit($form);
self::assertContains('The configuration file has been written.', $crawler->filter('#main')->text());
file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, true));
$form = $crawler->selectButton('submit')->form();
$crawler = self::submit($form);
self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form(array(
'email_enable' => true,
'smtp_delivery' => true,
'smtp_host' => 'nxdomain.phpbb.com',
'smtp_auth' => '',
'smtp_auth' => 'PLAIN',
'smtp_user' => 'nxuser',
'smtp_pass' => 'nxpass',
'cookie_secure' => false,
@ -212,50 +307,17 @@ class phpbb_functional_test_case extends phpbb_test_case
'server_port' => isset($parseURL['port']) ? (int) $parseURL['port'] : 80,
'script_path' => $parseURL['path'],
));
// end data
$content = self::do_request('install');
self::assertNotSame(false, $content);
self::assertContains('Welcome to Installation', $content);
$crawler = self::submit($form);
self::assertContains('The database tables used by phpBB', $crawler->filter('#main')->text());
self::assertContains('have been created and populated with some initial data.', $crawler->filter('#main')->text());
$form = $crawler->selectButton('submit')->form();
// Installer uses 3.0-style dbms name
$data['dbms'] = str_replace('phpbb_db_driver_', '', $data['dbms']);
$content = self::do_request('create_table', $data);
self::assertNotSame(false, $content);
self::assertContains('The database tables used by phpBB', $content);
// 3.0 or 3.1
self::assertContains('have been created and populated with some initial data.', $content);
$content = self::do_request('config_file', $data);
self::assertNotSame(false, $content);
self::assertContains('Configuration file', $content);
file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], true, true));
$content = self::do_request('final', $data);
self::assertNotSame(false, $content);
self::assertContains('You have successfully installed', $content);
$crawler = self::submit($form);
self::assertContains('You have successfully installed', $crawler->text());
copy($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_test.$phpEx");
}
static private function do_request($sub, $post_data = null)
{
$context = null;
if ($post_data)
{
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($post_data),
'ignore_errors' => true,
),
));
}
return file_get_contents(self::$config['phpbb_functional_url'] . 'install/index.php?mode=install&sub=' . $sub, false, $context);
}
static private function recreate_database($config)
{
$db_conn_mgr = new phpbb_database_test_connection_manager($config);
@ -314,7 +376,7 @@ class phpbb_functional_test_case extends phpbb_test_case
'user_lang' => 'en',
'user_timezone' => 0,
'user_dateformat' => '',
'user_password' => phpbb_hash($username),
'user_password' => phpbb_hash($username . $username),
);
return user_add($user_row);
}
@ -361,7 +423,7 @@ class phpbb_functional_test_case extends phpbb_test_case
return group_user_del($group_id, false, $usernames, $group_name);
}
protected function add_user_group($group_name, $usernames)
protected function add_user_group($group_name, $usernames, $default = false, $leader = false)
{
global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container, $phpbb_root_path, $phpEx;
@ -400,22 +462,21 @@ class phpbb_functional_test_case extends phpbb_test_case
$group_id = (int) $db->sql_fetchfield('group_id');
$db->sql_freeresult($result);
return group_user_add($group_id, false, $usernames, $group_name);
return group_user_add($group_id, false, $usernames, $group_name, $default, $leader);
}
protected function login($username = 'admin')
{
$this->add_lang('ucp');
$crawler = $this->request('GET', 'ucp.php');
$crawler = self::request('GET', 'ucp.php');
$this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text());
$form = $crawler->selectButton($this->lang('LOGIN'))->form();
$crawler = $this->client->submit($form, array('username' => $username, 'password' => $username));
$this->assert_response_success();
$crawler = self::submit($form, array('username' => $username, 'password' => $username . $username));
$this->assertContains($this->lang('LOGIN_REDIRECT'), $crawler->filter('html')->text());
$cookies = $this->cookieJar->all();
$cookies = self::$cookieJar->all();
// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie
foreach ($cookies as $cookie);
@ -431,8 +492,7 @@ class phpbb_functional_test_case extends phpbb_test_case
{
$this->add_lang('ucp');
$crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assert_response_success();
$crawler = self::request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout');
$this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text());
unset($this->sid);
@ -453,7 +513,7 @@ class phpbb_functional_test_case extends phpbb_test_case
return;
}
$crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid);
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid);
$this->assertContains($this->lang('LOGIN_ADMIN_CONFIRM'), $crawler->filter('html')->text());
$form = $crawler->selectButton($this->lang('LOGIN'))->form();
@ -462,11 +522,10 @@ class phpbb_functional_test_case extends phpbb_test_case
{
if (strpos($field, 'password_') === 0)
{
$crawler = $this->client->submit($form, array('username' => $username, $field => $username));
$this->assert_response_success();
$crawler = self::submit($form, array('username' => $username, $field => $username . $username));
$this->assertContains($this->lang('LOGIN_ADMIN_SUCCESS'), $crawler->filter('html')->text());
$cookies = $this->cookieJar->all();
$cookies = self::$cookieJar->all();
// The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie
foreach ($cookies as $cookie);
@ -531,22 +590,38 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->assertContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message);
}
/*
* Perform some basic assertions for the page
*
* Checks for debug/error output before the actual page content and the status code
*
* @param mixed $status_code Expected status code, false to disable check
* @return null
*/
static public function assert_response_html($status_code = 200)
{
if ($status_code !== false)
{
self::assert_response_status_code($status_code);
}
// Any output before the doc type means there was an error
$content = self::$client->getResponse()->getContent();
self::assertStringStartsWith('<!DOCTYPE', trim($content), 'Output found before DOCTYPE specification.');
}
/**
* Heuristic function to check that the response is success.
*
* When php decides to die with a fatal error, it still sends 200 OK
* status code. This assertion tries to catch that.
*
* @param int $status_code Expected status code
* @return null
*/
public function assert_response_success()
static public function assert_response_status_code($status_code = 200)
{
$this->assertEquals(200, $this->client->getResponse()->getStatus());
$content = $this->client->getResponse()->getContent();
$this->assertNotContains('Fatal error:', $content);
$this->assertNotContains('Notice:', $content);
$this->assertNotContains('Warning:', $content);
$this->assertNotContains('[phpBB Debug]', $content);
self::assertEquals($status_code, self::$client->getResponse()->getStatus());
}
public function assert_filter($crawler, $expr, $msg = null)

View file

@ -18,6 +18,56 @@ class phpbb_test_case_helpers
$this->test_case = $test_case;
}
/**
* This should only be called once before the tests are run.
* This is used to copy the fixtures to the phpBB install
*/
public function copy_ext_fixtures($fixtures_dir, $fixtures)
{
global $phpbb_root_path;
if (file_exists($phpbb_root_path . 'ext/'))
{
// First, move any extensions setup on the board to a temp directory
$this->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/');
// Then empty the ext/ directory on the board (for accurate test cases)
$this->empty_dir($phpbb_root_path . 'ext/');
}
// Copy our ext/ files from the test case to the board
foreach ($fixtures as $fixture)
{
$this->copy_dir($fixtures_dir . $fixture, $phpbb_root_path . 'ext/' . $fixture);
}
}
/**
* This should only be called once after the tests are run.
* This is used to remove the fixtures from the phpBB install
*/
public function restore_original_ext_dir()
{
global $phpbb_root_path;
// Remove all of the files we copied from test ext -> board ext
$this->empty_dir($phpbb_root_path . 'ext/');
// Copy back the board installed extensions from the temp directory
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
$this->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/');
// Remove all of the files we copied from board ext -> temp_ext
$this->empty_dir($phpbb_root_path . 'store/temp_ext/');
}
if (file_exists($phpbb_root_path . 'store/temp_ext/'))
{
$this->empty_dir($phpbb_root_path . 'store/temp_ext/');
}
}
public function setExpectedTriggerError($errno, $message = '')
{
$exceptionName = '';
@ -202,27 +252,6 @@ class phpbb_test_case_helpers
return $copied_files;
}
/**
* Remove files/directories that are listed in an array
* Designed for use with $this->copy_dir()
*
* @param array $file_list
*/
public function remove_files($file_list)
{
foreach ($file_list as $file)
{
if (is_dir($file))
{
rmdir($file);
}
else
{
unlink($file);
}
}
}
/**
* Empty directory (remove any subdirectories/files below)
*

View file

@ -59,27 +59,52 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case
$this->set = new phpbb_tree_nestedset_forum($this->db, $this->lock, 'phpbb_forums');
$this->set_up_forums();
$sql = "UPDATE phpbb_forums
SET forum_parents = 'a:0:{}'";
$this->db->sql_query($sql);
}
protected function set_up_forums()
{
$this->create_forum('Parent with two flat children');
$this->create_forum('Flat child #1', 1);
$this->create_forum('Flat child #2', 1);
static $forums;
$this->create_forum('Parent with two nested children');
$this->create_forum('Nested child #1', 4);
$this->create_forum('Nested child #2', 5);
if (empty($forums))
{
$this->create_forum('Parent with two flat children');
$this->create_forum('Flat child #1', 1);
$this->create_forum('Flat child #2', 1);
$this->create_forum('Parent with flat and nested children');
$this->create_forum('Mixed child #1', 7);
$this->create_forum('Mixed child #2', 7);
$this->create_forum('Nested child #1 of Mixed child #2', 9);
$this->create_forum('Mixed child #3', 7);
$this->create_forum('Parent with two nested children');
$this->create_forum('Nested child #1', 4);
$this->create_forum('Nested child #2', 5);
$this->create_forum('Parent with flat and nested children');
$this->create_forum('Mixed child #1', 7);
$this->create_forum('Mixed child #2', 7);
$this->create_forum('Nested child #1 of Mixed child #2', 9);
$this->create_forum('Mixed child #3', 7);
// Updating forum_parents column here so it's not empty
// This is required, so we can see whether the methods
// correctly clear the values.
$sql = "UPDATE phpbb_forums
SET forum_parents = 'a:0:{}'";
$this->db->sql_query($sql);
// Copy the forums into a static array, so we can reuse the list later
$sql = 'SELECT *
FROM phpbb_forums';
$result = $this->db->sql_query($sql);
$forums = $this->db->sql_fetchrowset($result);
$this->db->sql_freeresult($result);
}
else
{
$buffer = new phpbb_db_sql_insert_buffer($this->db, 'phpbb_forums');
$buffer->insert_all($forums);
$buffer->flush();
$this->database_synchronisation(array(
'phpbb_forums' => array('forum_id'),
));
}
}
protected function create_forum($name, $parent_id = 0)