aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml7
-rw-r--r--phpBB/adm/style/admin.css10
-rw-r--r--phpBB/config/feed.yml1
-rw-r--r--phpBB/feed.php6
-rw-r--r--phpBB/includes/acp/acp_users.php9
-rw-r--r--phpBB/includes/functions.php10
-rw-r--r--phpBB/includes/functions_admin.php67
-rw-r--r--phpBB/includes/functions_module.php27
-rw-r--r--phpBB/includes/ucp/ucp_pm.php7
-rw-r--r--phpBB/language/en/acp/common.php3
-rw-r--r--phpBB/language/en/acp/permissions.php86
-rw-r--r--phpBB/language/en/acp/users.php1
-rw-r--r--phpBB/language/en/common.php5
-rw-r--r--phpBB/language/en/ucp.php6
-rw-r--r--phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php128
-rw-r--r--phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php62
-rw-r--r--phpBB/phpbb/feed/forum.php2
-rw-r--r--phpBB/phpbb/feed/helper.php31
-rw-r--r--phpBB/phpbb/feed/news.php2
-rw-r--r--phpBB/phpbb/feed/overall.php2
-rw-r--r--phpBB/phpbb/feed/post_base.php38
-rw-r--r--phpBB/phpbb/feed/topic.php2
-rw-r--r--phpBB/phpbb/feed/topics.php2
-rw-r--r--phpBB/phpbb/feed/topics_active.php2
-rw-r--r--phpBB/phpbb/search/fulltext_native.php6
-rw-r--r--phpBB/search.php1
-rw-r--r--phpBB/styles/prosilver/template/jumpbox.html6
-rw-r--r--phpBB/styles/prosilver/template/posting_editor.html72
-rw-r--r--phpBB/styles/prosilver/template/posting_pm_header.html82
-rw-r--r--phpBB/styles/prosilver/template/posting_pm_layout.html6
-rw-r--r--phpBB/styles/prosilver/template/search_results.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_message_header.html2
-rw-r--r--phpBB/styles/prosilver/theme/bidi.css2
-rw-r--r--phpBB/styles/prosilver/theme/buttons.css2
-rw-r--r--phpBB/styles/prosilver/theme/common.css26
-rw-r--r--phpBB/styles/prosilver/theme/forms.css1
-rw-r--r--phpBB/viewtopic.php1
-rw-r--r--tests/functional/acp_users_test.php45
-rw-r--r--tests/functional/extension_controller_test.php23
-rw-r--r--tests/functional/fixtures/ext/foo/bar/config/routing.yml4
-rw-r--r--tests/functional/fixtures/ext/foo/bar/config/services.yml1
-rw-r--r--tests/functional/fixtures/ext/foo/bar/controller/controller.php16
-rw-r--r--tests/functional/ucp_pm_test.php48
-rw-r--r--tests/search/native_test.php49
-rw-r--r--tests/test_framework/phpbb_functional_test_case.php32
45 files changed, 777 insertions, 166 deletions
diff --git a/.travis.yml b/.travis.yml
index 4d14c16977..a4e8bdedd3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,9 +8,7 @@ php:
- hhvm
env:
- - DB=mariadb
- DB=mysql
- - DB=postgres
services:
- redis-server
@@ -36,5 +34,10 @@ script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysql' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi"
matrix:
+ include:
+ - php: 5.4
+ env: DB=mariadb
+ - php: 5.4
+ env: DB=postgres
allow_failures:
- php: hhvm
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index 7ef74e4db0..d6377453d1 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -43,6 +43,10 @@ body {
margin: 10px 15px;
}
+code, samp {
+ font-size: 1.2em;
+}
+
img {
border: 0;
}
@@ -571,12 +575,6 @@ li {
padding: 3px 8px 3px 3px;
}
-#menu li span, #menu .header {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
#menu li a:hover, #menu li a:hover span {
text-decoration: none;
background-color: #FFFFFF;
diff --git a/phpBB/config/feed.yml b/phpBB/config/feed.yml
index 7712a832f3..48bd9fe76f 100644
--- a/phpBB/config/feed.yml
+++ b/phpBB/config/feed.yml
@@ -5,6 +5,7 @@ services:
- @config
- @user
- %core.root_path%
+ - %core.php_ext%
feed.factory:
class: phpbb\feed\factory
diff --git a/phpBB/feed.php b/phpBB/feed.php
index 35cd7fda3f..c31a6b6b1d 100644
--- a/phpBB/feed.php
+++ b/phpBB/feed.php
@@ -18,6 +18,7 @@ define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
+include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
if (!$config['feed_enable'])
{
@@ -72,6 +73,9 @@ if ($feed === false)
trigger_error('NO_FEED');
}
+// Get attachments for this feed
+$feed->fetch_attachments();
+
// Open Feed
$feed->open();
@@ -107,7 +111,7 @@ while ($row = $feed->get_item())
'title' => censor_text($title),
'category' => ($config['feed_item_statistics'] && !empty($row['forum_id'])) ? $board_url . '/viewforum.' . $phpEx . '?f=' . $row['forum_id'] : '',
'category_name' => ($config['feed_item_statistics'] && isset($row['forum_name'])) ? $row['forum_name'] : '',
- 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options)),
+ 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options, $row['forum_id'], (($row['post_attachment']) ? $feed->attachments[$row['post_id']] : array()))),
'statistics' => '',
);
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 603cb17941..c944f5f96f 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -173,8 +173,7 @@ class acp_users
if ($submit)
{
- // You can't delete the founder
- if ($delete && $user_row['user_type'] != USER_FOUNDER)
+ if ($delete)
{
if (!$auth->acl_get('a_userdel'))
{
@@ -187,6 +186,12 @@ class acp_users
trigger_error($user->lang['CANNOT_REMOVE_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
}
+ // Founders can not be deleted.
+ if ($user_row['user_type'] == USER_FOUNDER)
+ {
+ trigger_error($user->lang['CANNOT_REMOVE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
+ }
+
if ($user_id == $user->data['user_id'])
{
trigger_error($user->lang['CANNOT_REMOVE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 03cd235f86..5e5f508b6b 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2344,7 +2344,7 @@ function reapply_sid($url)
*/
function build_url($strip_vars = false)
{
- global $user, $phpbb_root_path;
+ global $config, $user, $phpEx, $phpbb_root_path;
$page = $user->page['page'];
@@ -2357,6 +2357,12 @@ function build_url($strip_vars = false)
// URL
if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host']))
{
+ // Remove 'app.php/' from the page, when rewrite is enabled
+ if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $phpEx . '/') === 0)
+ {
+ $page = substr($page, strlen('app.' . $phpEx . '/'));
+ }
+
$page = $phpbb_root_path . $page;
}
@@ -4902,7 +4908,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'S_TOPIC_ID' => $topic_id,
'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id)),
- 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => build_url())),
+ 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url()))),
'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false,
'S_ENABLE_FEEDS_OVERALL' => ($config['feed_overall']) ? true : false,
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 722d3c9c67..0e28b48d8a 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -731,7 +731,32 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s
*/
function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true, $post_count_sync = true, $call_delete_topics = true)
{
- global $db, $config, $phpbb_root_path, $phpEx, $auth, $user, $phpbb_container;
+ global $db, $config, $phpbb_root_path, $phpEx, $auth, $user, $phpbb_container, $phpbb_dispatcher;
+
+ // Notifications types to delete
+ $delete_notifications_types = array(
+ 'quote',
+ 'bookmark',
+ 'post',
+ 'approve_post',
+ 'post_in_queue',
+ );
+
+ /**
+ * Perform additional actions before post(s) deletion
+ *
+ * @event core.delete_posts_before
+ * @var string where_type Variable containing posts deletion mode
+ * @var mixed where_ids Array or comma separated list of posts ids to delete
+ * @var bool auto_sync Flag indicating if topics/forums should be synchronized
+ * @var bool posted_sync Flag indicating if topics_posted table should be resynchronized
+ * @var bool post_count_sync Flag indicating if posts count should be resynchronized
+ * @var bool call_delete_topics Flag indicating if topics having no posts should be deleted
+ * @var array delete_notifications_types Array with notifications types to delete
+ * @since 3.1.0-a4
+ */
+ $vars = array('where_type', 'where_ids', 'auto_sync', 'posted_sync', 'post_count_sync', 'call_delete_topics', 'delete_notifications_types');
+ extract($phpbb_dispatcher->trigger_event('core.delete_posts_before', compact($vars)));
if ($where_type === 'range')
{
@@ -874,8 +899,40 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
delete_attachments('post', $post_ids, false);
+ /**
+ * Perform additional actions during post(s) deletion
+ *
+ * @event core.delete_posts_in_transaction
+ * @var array post_ids Array with deleted posts' ids
+ * @var array poster_ids Array with deleted posts' author ids
+ * @var array topic_ids Array with deleted posts' topic ids
+ * @var array forum_ids Array with deleted posts' forum ids
+ * @var string where_type Variable containing posts deletion mode
+ * @var mixed where_ids Array or comma separated list of posts ids to delete
+ * @var array delete_notifications_types Array with notifications types to delete
+ * @since 3.1.0-a4
+ */
+ $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types');
+ extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction', compact($vars)));
+
$db->sql_transaction('commit');
+ /**
+ * Perform additional actions after post(s) deletion
+ *
+ * @event core.delete_posts_after
+ * @var array post_ids Array with deleted posts' ids
+ * @var array poster_ids Array with deleted posts' author ids
+ * @var array topic_ids Array with deleted posts' topic ids
+ * @var array forum_ids Array with deleted posts' forum ids
+ * @var string where_type Variable containing posts deletion mode
+ * @var mixed where_ids Array or comma separated list of posts ids to delete
+ * @var array delete_notifications_types Array with notifications types to delete
+ * @since 3.1.0-a4
+ */
+ $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types');
+ extract($phpbb_dispatcher->trigger_event('core.delete_posts_after', compact($vars)));
+
// Resync topics_posted table
if ($posted_sync)
{
@@ -902,13 +959,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->delete_notifications(array(
- 'quote',
- 'bookmark',
- 'post',
- 'approve_post',
- 'post_in_queue',
- ), $post_ids);
+ $phpbb_notifications->delete_notifications($delete_notifications_types, $post_ids);
return sizeof($post_ids);
}
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index 28af7994c8..e043883145 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -125,8 +125,17 @@ class p_master
// Clean up module cache array to only let survive modules the user can access
$right_id = false;
+
+ $hide_categories = array();
foreach ($this->module_cache['modules'] as $key => $row)
{
+ // When the module has no mode (category) we check whether it has visible children
+ // before listing it as well.
+ if (!$row['module_mode'])
+ {
+ $hide_categories[(int) $row['module_id']] = $key;
+ }
+
// Not allowed to view module?
if (!$this->module_auth_self($row['module_auth']))
{
@@ -161,6 +170,22 @@ class p_master
$right_id = $row['right_id'];
continue;
}
+
+ if ($row['module_mode'])
+ {
+ // The parent category has a visible child
+ // So remove it and all its parents from the hide array
+ unset($hide_categories[(int) $row['parent_id']]);
+ foreach ($this->module_cache['parents'][$row['module_id']] as $module_id => $row_id)
+ {
+ unset($hide_categories[$module_id]);
+ }
+ }
+ }
+
+ foreach ($hide_categories as $module_id => $row_id)
+ {
+ unset($this->module_cache['modules'][$row_id]);
}
// Re-index (this is needed, else we are not able to array_slice later)
@@ -510,7 +535,7 @@ class p_master
if (!class_exists($this->p_name))
{
- trigger_error($user->lang('MODULE_FILE_RIGHT_CLASS', "$module_path/{$this->p_name}.$phpEx", $this->p_name), E_USER_ERROR);
+ trigger_error($user->lang('MODULE_FILE_INCORRECT_CLASS', "$module_path/{$this->p_name}.$phpEx", $this->p_name), E_USER_ERROR);
}
}
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index 517ae0b08c..7e13b5b9c6 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -352,9 +352,10 @@ class ucp_pm
else if ($action == 'view_message')
{
$template->assign_vars(array(
- 'S_VIEW_MESSAGE' => true,
- 'MSG_ID' => $msg_id)
- );
+ 'S_VIEW_MESSAGE' => true,
+ 'L_RETURN_TO_FOLDER' => $user->lang('RETURN_TO', $folder_status['folder_name']),
+ 'MSG_ID' => $msg_id,
+ ));
if (!$msg_id)
{
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 0e867c64a9..428b9ffd3b 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -83,7 +83,7 @@ $lang = array_merge($lang, array(
'ACP_EMAIL_SETTINGS' => 'Email settings',
'ACP_EXTENSION_GROUPS' => 'Manage attachment extension groups',
'ACP_EXTENSION_MANAGEMENT' => 'Extension management',
- 'ACP_EXTENSIONS' => 'Extensions',
+ 'ACP_EXTENSIONS' => 'Manage extensions',
'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions',
@@ -288,7 +288,6 @@ $lang = array_merge($lang, array(
'RESYNC' => 'Resynchronise',
'RESYNC_FILES_STATS' => 'Resynchronise files statistics',
'RESYNC_FILES_STATS_EXPLAIN' => 'Recalculates the total number and size of files attached to posts and private messages.',
- 'RETURN_TO' => 'Return to…',
'SELECT_ANONYMOUS' => 'Select anonymous user',
'SELECT_OPTION' => 'Select option',
diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php
index 709836e828..6e3ba6876a 100644
--- a/phpBB/language/en/acp/permissions.php
+++ b/phpBB/language/en/acp/permissions.php
@@ -57,7 +57,7 @@ $lang = array_merge($lang, array(
'ACL_NEVER' => 'Never',
'ACL_SET' => 'Setting permissions',
- 'ACL_SET_EXPLAIN' => 'Permissions are based on a simple <samp>YES</samp>/<samp>NO</samp> system. Setting an option to <samp>NEVER</samp> for a user or usergroup overrides any other value assigned to it. If you do not wish to assign a value for an option for this user or group select <samp>NO</samp>. If values are assigned for this option elsewhere they will be used in preference, else <samp>NEVER</samp> is assumed. All objects marked (with the checkbox in front of them) will copy the permission set you defined.',
+ 'ACL_SET_EXPLAIN' => 'Permissions are based on a simple <strong>YES</strong>/<strong>NO</strong> system. Setting an option to <strong>NEVER</strong> for a user or usergroup overrides any other value assigned to it. If you do not wish to assign a value for an option for this user or group select <strong>NO</strong>. If values are assigned for this option elsewhere they will be used in preference, else <strong>NEVER</strong> is assumed. All objects marked (with the checkbox in front of them) will copy the permission set you defined.',
'ACL_SETTING' => 'Setting',
'ACL_TYPE_A_' => 'Administrative permissions',
@@ -100,10 +100,10 @@ $lang = array_merge($lang, array(
'ADD_USERS' => 'Add users',
'ADVANCED_PERMISSIONS' => 'Advanced Permissions',
'ALL_GROUPS' => 'Select all groups',
- 'ALL_NEVER' => 'All <samp>NEVER</samp>',
- 'ALL_NO' => 'All <samp>NO</samp>',
+ 'ALL_NEVER' => 'All <strong>NEVER</strong>',
+ 'ALL_NO' => 'All <strong>NO</strong>',
'ALL_USERS' => 'Select all users',
- 'ALL_YES' => 'All <samp>YES</samp>',
+ 'ALL_YES' => 'All <strong>YES</strong>',
'APPLY_ALL_PERMISSIONS' => 'Apply all permissions',
'APPLY_PERMISSIONS' => 'Apply permissions',
'APPLY_PERMISSIONS_EXPLAIN' => 'The permissions and role defined for this item will only be applied to this item and all checked items.',
@@ -137,7 +137,7 @@ $lang = array_merge($lang, array(
'NO_AUTH_SETTING_FOUND' => 'Permission settings not defined.',
'NO_ROLE_ASSIGNED' => 'No role assigned…',
- 'NO_ROLE_ASSIGNED_EXPLAIN' => 'Setting to this role does not change permissions on the right. If you want to unset/remove all permissions you should use the “All <samp>NO</samp>” link.',
+ 'NO_ROLE_ASSIGNED_EXPLAIN' => 'Setting to this role does not change permissions on the right. If you want to unset/remove all permissions you should use the “All <strong>NO</strong>” link.',
'NO_ROLE_AVAILABLE' => 'No role available',
'NO_ROLE_NAME_SPECIFIED' => 'Please give the role a name.',
'NO_ROLE_SELECTED' => 'Role could not be found.',
@@ -196,7 +196,7 @@ $lang = array_merge($lang, array(
'ROLE_DESCRIPTION_FORUM_POLLS' => 'Like Standard Access but can also create polls.',
'ROLE_DESCRIPTION_FORUM_READONLY' => 'Can read the forum, but cannot create new topics or reply to posts.',
'ROLE_DESCRIPTION_FORUM_STANDARD' => 'Can use most forum features including attachments and deleting own topics, but cannot lock own topics, and cannot create polls.',
- 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <samp>NEVER</samp> permissions to lock features for new users.',
+ 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <strong>NEVER</strong> permissions to lock features for new users.',
'ROLE_DESCRIPTION_MOD_FULL' => 'Can use all moderating features, including banning.',
'ROLE_DESCRIPTION_MOD_QUEUE' => 'Can use the Moderation Queue to validate and edit posts, but nothing else.',
'ROLE_DESCRIPTION_MOD_SIMPLE' => 'Can only use basic topic actions. Cannot send warnings or use moderation queue.',
@@ -206,7 +206,7 @@ $lang = array_merge($lang, array(
'ROLE_DESCRIPTION_USER_NOAVATAR' => 'Has a limited feature set and is not allowed to use the Avatar feature.',
'ROLE_DESCRIPTION_USER_NOPM' => 'Has a limited feature set, and is not allowed to use Private Messages.',
'ROLE_DESCRIPTION_USER_STANDARD' => 'Can access most but not all user features. Cannot change user name or ignore the flood limit, for instance.',
- 'ROLE_DESCRIPTION_USER_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <samp>NEVER</samp> permissions to lock features for new users.',
+ 'ROLE_DESCRIPTION_USER_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <strong>NEVER</strong> permissions to lock features for new users.',
'ROLE_DESCRIPTION_EXPLAIN' => 'You are able to enter a short explanation of what the role is doing or for what it is meant for. The text you enter here will be displayed within the permissions screens too.',
'ROLE_DESCRIPTION_LONG' => 'The role description is too long, please limit it to 4000 characters.',
@@ -227,48 +227,48 @@ $lang = array_merge($lang, array(
'SET_USERS_PERMISSIONS' => 'Set user permissions',
'SET_USERS_FORUM_PERMISSIONS' => 'Set user forum permissions',
- 'TRACE_DEFAULT' => 'By default every permission is <samp>NO</samp> (unset). So the permission can be overwritten by other settings.',
+ 'TRACE_DEFAULT' => 'By default every permission is <strong>NO</strong> (unset). So the permission can be overwritten by other settings.',
'TRACE_FOR' => 'Trace for',
'TRACE_GLOBAL_SETTING' => '%s (global)',
- 'TRACE_GROUP_NEVER_TOTAL_NEVER' => 'This group’s permission is set to <samp>NEVER</samp> like the total result so the old result is kept.',
- 'TRACE_GROUP_NEVER_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> like the total result so the old result is kept.',
- 'TRACE_GROUP_NEVER_TOTAL_NO' => 'This group’s permission is set to <samp>NEVER</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).',
- 'TRACE_GROUP_NEVER_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).',
- 'TRACE_GROUP_NEVER_TOTAL_YES' => 'This group’s permission is set to <samp>NEVER</samp> which overwrites the total <samp>YES</samp> to a <samp>NEVER</samp> for this user.',
- 'TRACE_GROUP_NEVER_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> which overwrites the total <samp>YES</samp> to a <samp>NEVER</samp> for this user.',
- 'TRACE_GROUP_NO' => 'The permission is <samp>NO</samp> for this group so the old total value is kept.',
- 'TRACE_GROUP_NO_LOCAL' => 'The permission is <samp>NO</samp> for this group within this forum so the old total value is kept.',
- 'TRACE_GROUP_YES_TOTAL_NEVER' => 'This group’s permission is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.',
- 'TRACE_GROUP_YES_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.',
- 'TRACE_GROUP_YES_TOTAL_NO' => 'This group’s permission is set to <samp>YES</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).',
- 'TRACE_GROUP_YES_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).',
- 'TRACE_GROUP_YES_TOTAL_YES' => 'This group’s permission is set to <samp>YES</samp> and the total permission is already set to <samp>YES</samp>, so the total result is kept.',
- 'TRACE_GROUP_YES_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> and the total permission is already set to <samp>YES</samp>, so the total result is kept.',
+ 'TRACE_GROUP_NEVER_TOTAL_NEVER' => 'This group’s permission is set to <strong>NEVER</strong> like the total result so the old result is kept.',
+ 'TRACE_GROUP_NEVER_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> like the total result so the old result is kept.',
+ 'TRACE_GROUP_NEVER_TOTAL_NO' => 'This group’s permission is set to <strong>NEVER</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).',
+ 'TRACE_GROUP_NEVER_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).',
+ 'TRACE_GROUP_NEVER_TOTAL_YES' => 'This group’s permission is set to <strong>NEVER</strong> which overwrites the total <strong>YES</strong> to a <strong>NEVER</strong> for this user.',
+ 'TRACE_GROUP_NEVER_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> which overwrites the total <strong>YES</strong> to a <strong>NEVER</strong> for this user.',
+ 'TRACE_GROUP_NO' => 'The permission is <strong>NO</strong> for this group so the old total value is kept.',
+ 'TRACE_GROUP_NO_LOCAL' => 'The permission is <strong>NO</strong> for this group within this forum so the old total value is kept.',
+ 'TRACE_GROUP_YES_TOTAL_NEVER' => 'This group’s permission is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.',
+ 'TRACE_GROUP_YES_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.',
+ 'TRACE_GROUP_YES_TOTAL_NO' => 'This group’s permission is set to <strong>YES</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).',
+ 'TRACE_GROUP_YES_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).',
+ 'TRACE_GROUP_YES_TOTAL_YES' => 'This group’s permission is set to <strong>YES</strong> and the total permission is already set to <strong>YES</strong>, so the total result is kept.',
+ 'TRACE_GROUP_YES_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> and the total permission is already set to <strong>YES</strong>, so the total result is kept.',
'TRACE_PERMISSION' => 'Trace permission - %s',
'TRACE_RESULT' => 'Trace result',
'TRACE_SETTING' => 'Trace setting',
- 'TRACE_USER_GLOBAL_YES_TOTAL_YES' => 'The forum independent user permission evaluates to <samp>YES</samp> but the total permission is already set to <samp>YES</samp>, so the total result is kept. %sTrace global permission%s',
- 'TRACE_USER_GLOBAL_YES_TOTAL_NEVER' => 'The forum independent user permission evaluates to <samp>YES</samp> which overwrites the current local result <samp>NEVER</samp>. %sTrace global permission%s',
- 'TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT' => 'The forum independent user permission evaluates to <samp>NEVER</samp> which doesn’t influence the local permission. %sTrace global permission%s',
-
- 'TRACE_USER_FOUNDER' => 'The user is a founder, therefore admin permissions are always set to <samp>YES</samp>.',
- 'TRACE_USER_KEPT' => 'The user’s permission is <samp>NO</samp> so the old total value is kept.',
- 'TRACE_USER_KEPT_LOCAL' => 'The user’s permission for this forum is <samp>NO</samp> so the old total value is kept.',
- 'TRACE_USER_NEVER_TOTAL_NEVER' => 'The user’s permission is set to <samp>NEVER</samp> and the total value is set to <samp>NEVER</samp>, so nothing is changed.',
- 'TRACE_USER_NEVER_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> and the total value is set to <samp>NEVER</samp>, so nothing is changed.',
- 'TRACE_USER_NEVER_TOTAL_NO' => 'The user’s permission is set to <samp>NEVER</samp> which becomes the total value because it was set to NO.',
- 'TRACE_USER_NEVER_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> which becomes the total value because it was set to NO.',
- 'TRACE_USER_NEVER_TOTAL_YES' => 'The user’s permission is set to <samp>NEVER</samp> and overwrites the previous <samp>YES</samp>.',
- 'TRACE_USER_NEVER_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> and overwrites the previous <samp>YES</samp>.',
- 'TRACE_USER_NO_TOTAL_NO' => 'The user’s permission is <samp>NO</samp> and the total value was set to NO so it defaults to <samp>NEVER</samp>.',
- 'TRACE_USER_NO_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is <samp>NO</samp> and the total value was set to NO so it defaults to <samp>NEVER</samp>.',
- 'TRACE_USER_YES_TOTAL_NEVER' => 'The user’s permission is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.',
- 'TRACE_USER_YES_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.',
- 'TRACE_USER_YES_TOTAL_NO' => 'The user’s permission is set to <samp>YES</samp> which becomes the total value because it was set to <samp>NO</samp>.',
- 'TRACE_USER_YES_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> which becomes the total value because it was set to <samp>NO</samp>.',
- 'TRACE_USER_YES_TOTAL_YES' => 'The user’s permission is set to <samp>YES</samp> and the total value is set to <samp>YES</samp>, so nothing is changed.',
- 'TRACE_USER_YES_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> and the total value is set to <samp>YES</samp>, so nothing is changed.',
+ 'TRACE_USER_GLOBAL_YES_TOTAL_YES' => 'The forum independent user permission evaluates to <strong>YES</strong> but the total permission is already set to <strong>YES</strong>, so the total result is kept. %sTrace global permission%s',
+ 'TRACE_USER_GLOBAL_YES_TOTAL_NEVER' => 'The forum independent user permission evaluates to <strong>YES</strong> which overwrites the current local result <strong>NEVER</strong>. %sTrace global permission%s',
+ 'TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT' => 'The forum independent user permission evaluates to <strong>NEVER</strong> which doesn’t influence the local permission. %sTrace global permission%s',
+
+ 'TRACE_USER_FOUNDER' => 'The user is a founder, therefore admin permissions are always set to <strong>YES</strong>.',
+ 'TRACE_USER_KEPT' => 'The user’s permission is <strong>NO</strong> so the old total value is kept.',
+ 'TRACE_USER_KEPT_LOCAL' => 'The user’s permission for this forum is <strong>NO</strong> so the old total value is kept.',
+ 'TRACE_USER_NEVER_TOTAL_NEVER' => 'The user’s permission is set to <strong>NEVER</strong> and the total value is set to <strong>NEVER</strong>, so nothing is changed.',
+ 'TRACE_USER_NEVER_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> and the total value is set to <strong>NEVER</strong>, so nothing is changed.',
+ 'TRACE_USER_NEVER_TOTAL_NO' => 'The user’s permission is set to <strong>NEVER</strong> which becomes the total value because it was set to NO.',
+ 'TRACE_USER_NEVER_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> which becomes the total value because it was set to NO.',
+ 'TRACE_USER_NEVER_TOTAL_YES' => 'The user’s permission is set to <strong>NEVER</strong> and overwrites the previous <strong>YES</strong>.',
+ 'TRACE_USER_NEVER_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> and overwrites the previous <strong>YES</strong>.',
+ 'TRACE_USER_NO_TOTAL_NO' => 'The user’s permission is <strong>NO</strong> and the total value was set to NO so it defaults to <strong>NEVER</strong>.',
+ 'TRACE_USER_NO_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is <strong>NO</strong> and the total value was set to NO so it defaults to <strong>NEVER</strong>.',
+ 'TRACE_USER_YES_TOTAL_NEVER' => 'The user’s permission is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.',
+ 'TRACE_USER_YES_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.',
+ 'TRACE_USER_YES_TOTAL_NO' => 'The user’s permission is set to <strong>YES</strong> which becomes the total value because it was set to <strong>NO</strong>.',
+ 'TRACE_USER_YES_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> which becomes the total value because it was set to <strong>NO</strong>.',
+ 'TRACE_USER_YES_TOTAL_YES' => 'The user’s permission is set to <strong>YES</strong> and the total value is set to <strong>YES</strong>, so nothing is changed.',
+ 'TRACE_USER_YES_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> and the total value is set to <strong>YES</strong>, so nothing is changed.',
'TRACE_WHO' => 'Who',
'TRACE_TOTAL' => 'Total',
diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php
index 865a2a0371..9faf1d0de9 100644
--- a/phpBB/language/en/acp/users.php
+++ b/phpBB/language/en/acp/users.php
@@ -51,6 +51,7 @@ $lang = array_merge($lang, array(
'CANNOT_FORCE_REACT_FOUNDER' => 'You are not allowed to force reactivation on founder accounts.',
'CANNOT_FORCE_REACT_YOURSELF' => 'You are not allowed to force reactivation of your own account.',
'CANNOT_REMOVE_ANONYMOUS' => 'You are not able to remove the guest user account.',
+ 'CANNOT_REMOVE_FOUNDER' => 'You are not allowed to remove founder accounts.',
'CANNOT_REMOVE_YOURSELF' => 'You are not allowed to remove your own user account.',
'CANNOT_SET_FOUNDER_IGNORED' => 'You are not able to promote ignored users to be founders.',
'CANNOT_SET_FOUNDER_INACTIVE' => 'You need to activate users before you promote them to founders, only activated users are able to be promoted.',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 1550271a3e..360d6be1e0 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -404,7 +404,7 @@ $lang = array_merge($lang, array(
'MODERATORS' => 'Moderators',
'MODULE_NOT_ACCESS' => 'Module not accessible',
'MODULE_NOT_FIND' => 'Cannot find module %s',
- 'MODULE_FILE_RIGHT_CLASS' => 'Module file %s does not contain correct class [%s]',
+ 'MODULE_FILE_INCORRECT_CLASS' => 'Module file %s does not contain correct class [%s]',
'MONTH' => 'Month',
'MOVE' => 'Move',
@@ -600,7 +600,8 @@ $lang = array_merge($lang, array(
'RETURN_FORUM' => '%sReturn to the forum last visited%s',
'RETURN_PAGE' => '%sReturn to the previous page%s',
'RETURN_TOPIC' => '%sReturn to the topic last visited%s',
- 'RETURN_TO' => 'Return to',
+ 'RETURN_TO' => 'Return to “%s”',
+ 'RETURN_TO_INDEX' => 'Return to Board Index',
'FEED' => 'Feed',
'FEED_NEWS' => 'News',
'FEED_TOPICS_ACTIVE' => 'Active Topics',
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index 58bb1d4b3a..40c8bd9f8e 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -476,7 +476,11 @@ $lang = array_merge($lang, array(
'TIMEZONE' => 'Timezone',
'TIMEZONE_DATE_SUGGESTION' => 'Suggestion: %s',
'TIMEZONE_INVALID' => 'The timezone you selected is invalid.',
- 'TO' => 'To',
+ 'TO' => 'Recipient',
+ 'TO_MASS' => 'Recipients',
+ 'TO_ADD' => 'Add recipient',
+ 'TO_ADD_MASS' => 'Add recipients',
+ 'TO_ADD_GROUPS' => 'Add groups',
'TOO_MANY_RECIPIENTS' => 'You tried to send a private message to too many recipients.',
'TOO_MANY_REGISTERS' => 'You have exceeded the maximum number of registration attempts for this session. Please try again later.',
diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
new file mode 100644
index 0000000000..c9255d88ee
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
@@ -0,0 +1,128 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+/**
+ * Migration to convert the Soft Delete MOD for 3.0
+ *
+ * https://www.phpbb.com/customise/db/mod/soft_delete/
+ */
+class soft_delete_mod_convert extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\alpha3',
+ );
+ }
+
+ public function effectively_installed()
+ {
+ return !$this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_deleted');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('permission.remove', array('m_harddelete', true)),
+ array('permission.remove', array('m_harddelete', false)),
+
+ array('custom', array(array($this, 'convert_posts'))),
+ array('custom', array(array($this, 'convert_topics'))),
+ );
+ }
+
+ public function convert_posts($start)
+ {
+ $content_visibility = $this->get_content_visibility();
+
+ $limit = 250;
+ $i = 0;
+
+ $sql = 'SELECT p.*, t.topic_first_post_id, t.topic_last_post_id
+ FROM ' . $this->table_prefix . 'posts p, ' . $this->table_prefix . 'topics t
+ WHERE p.post_deleted > 0
+ AND t.topic_id = p.topic_id';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $content_visibility->set_post_visibility(
+ ITEM_DELETED,
+ $row['post_id'],
+ $row['topic_id'],
+ $row['forum_id'],
+ $row['post_deleted'],
+ $row['post_deleted_time'],
+ '',
+ ($row['post_id'] == $row['topic_first_post_id']) ? true : false,
+ ($row['post_id'] == $row['topic_last_post_id']) ? true : false
+ );
+
+ $i++;
+ }
+
+ $this->db->sql_freeresult($result);
+
+ if ($i == $limit)
+ {
+ return $start + $i;
+ }
+ }
+
+ public function convert_topics($start)
+ {
+ $content_visibility = $this->get_content_visibility();
+
+ $limit = 100;
+ $i = 0;
+
+ $sql = 'SELECT *
+ FROM ' . $this->table_prefix . 'topics
+ WHERE topic_deleted > 0';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $content_visibility->set_topic_visibility(
+ ITEM_DELETED,
+ $row['topic_id'],
+ $row['forum_id'],
+ $row['topic_deleted'],
+ $row['topic_deleted_time'],
+ ''
+ );
+
+ $i++;
+ }
+
+ $this->db->sql_freeresult($result);
+
+ if ($i == $limit)
+ {
+ return $start + $i;
+ }
+ }
+
+ protected function get_content_visibility()
+ {
+ return new \phpbb\content_visibility(
+ new \phpbb\auth\auth(),
+ $this->db,
+ new \phpbb\user(),
+ $this->phpbb_root_path,
+ $this->php_ext,
+ $this->table_prefix . 'forums',
+ $this->table_prefix . 'posts',
+ $this->table_prefix . 'topics',
+ $this->table_prefix . 'users'
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php
new file mode 100644
index 0000000000..ab4be269e6
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php
@@ -0,0 +1,62 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+/**
+ * Migration to convert the Soft Delete MOD for 3.0
+ *
+ * https://www.phpbb.com/customise/db/mod/soft_delete/
+ */
+class soft_delete_mod_convert2 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\soft_delete_mod_convert',
+ );
+ }
+
+ public function effectively_installed()
+ {
+ return !$this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_deleted');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'drop_columns' => array(
+ $this->table_prefix . 'forums' => array('forum_deleted_topic_count', 'forum_deleted_reply_count'),
+ $this->table_prefix . 'posts' => array('post_deleted', 'post_deleted_time'),
+ $this->table_prefix . 'topics' => array('topic_deleted', 'topic_deleted_time', 'topic_deleted_reply_count'),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'add_columns' => array(
+ $this->table_prefix . 'forums' => array(
+ 'forum_deleted_topic_count' => array('UINT', 0),
+ 'forum_deleted_reply_count' => array('UINT', 0),
+ ),
+ $this->table_prefix . 'posts' => array(
+ 'post_deleted' => array('UINT', 0),
+ 'post_deleted_time' => array('TIMESTAMP', 0),
+ ),
+ $this->table_prefix . 'topics' => array(
+ 'topic_deleted' => array('UINT', 0),
+ 'topic_deleted_time' => array('TIMESTAMP', 0),
+ 'topic_deleted_reply_count' => array('UINT', 0),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php
index 8026824ab7..85ecb60f7e 100644
--- a/phpBB/phpbb/feed/forum.php
+++ b/phpBB/phpbb/feed/forum.php
@@ -109,7 +109,7 @@ class forum extends \phpbb\feed\post_base
}
$this->sql = array(
- 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/helper.php b/phpBB/phpbb/feed/helper.php
index 3f2759b85e..12acf997ac 100644
--- a/phpBB/phpbb/feed/helper.php
+++ b/phpBB/phpbb/feed/helper.php
@@ -24,6 +24,9 @@ class helper
/** @var string */
protected $phpbb_root_path;
+ /** @var string */
+ protected $phpEx;
+
/**
* Constructor
*
@@ -32,11 +35,12 @@ class helper
* @param string $phpbb_root_path Root path
* @return null
*/
- public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path)
+ public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path, $phpEx)
{
$this->config = $config;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
+ $this->phpEx = $phpEx;
}
/**
@@ -81,8 +85,16 @@ class helper
/**
* Generate text content
+ *
+ * @param string $content is feed text content
+ * @param string $uid is bbcode_uid
+ * @param string $bitfield is bbcode bitfield
+ * @param int $options bbcode flag options
+ * @param int $forum_id is the forum id
+ * @param array $post_attachments is an array containing the attachments and their respective info
+ * @return string the html content to be printed for the feed
*/
- public function generate_content($content, $uid, $bitfield, $options)
+ public function generate_content($content, $uid, $bitfield, $options, $forum_id, $post_attachments)
{
if (empty($content))
{
@@ -129,8 +141,21 @@ class helper
// Remove some specials html tag, because somewhere there are a mod to allow html tags ;)
$content = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' <strong>$1</strong> ', $content);
+ // Parse inline images to display with the feed
+ if (!empty($post_attachments))
+ {
+ $update_count = array();
+ parse_attachments($forum_id, $content, $post_attachments, $update_count);
+ $post_attachments = implode('<br />', $post_attachments);
+
+ // Convert attachments' relative path to absolute path
+ $post_attachments = str_replace($this->phpbb_root_path . 'download/file.' . $this->phpEx, $this->get_board_url() . '/download/file.' . $this->phpEx, $post_attachments);
+
+ $content .= $post_attachments;
+ }
+
// Remove Comments from inline attachments [ia]
- $content = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content);
+ $content = preg_replace('#<dd>(.*?)</dd>#','',$content);
// Replace some entities with their unicode counterpart
$entities = array(
diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php
index 7888e73239..1b7c452a92 100644
--- a/phpBB/phpbb/feed/news.php
+++ b/phpBB/phpbb/feed/news.php
@@ -85,7 +85,7 @@ class news extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php
index 4545ba5c64..d99200475e 100644
--- a/phpBB/phpbb/feed/overall.php
+++ b/phpBB/phpbb/feed/overall.php
@@ -53,7 +53,7 @@ class overall extends \phpbb\feed\post_base
// Get the actual data
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name, ' .
- 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
USERS_TABLE => 'u',
diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php
index 42c5eea9e3..c797d6a8ca 100644
--- a/phpBB/phpbb/feed/post_base.php
+++ b/phpBB/phpbb/feed/post_base.php
@@ -17,6 +17,7 @@ namespace phpbb\feed;
abstract class post_base extends \phpbb\feed\base
{
var $num_items = 'feed_limit_post';
+ var $attachments = array();
function set_keys()
{
@@ -48,4 +49,41 @@ abstract class post_base extends \phpbb\feed\base
. (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
}
}
+
+ function fetch_attachments()
+ {
+ $sql_array = array(
+ 'SELECT' => 'a.*',
+ 'FROM' => array(
+ ATTACHMENTS_TABLE => 'a'
+ ),
+ 'WHERE' => 'a.in_message = 0 ',
+ 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
+ );
+
+ if (isset($this->topic_id))
+ {
+ $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
+ }
+ else if (isset($this->forum_id))
+ {
+ $sql_array['LEFT_JOIN'] = array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't'),
+ 'ON' => 'a.topic_id = t.topic_id',
+ )
+ );
+ $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
+ }
+
+ $sql = $this->db->sql_build_query('SELECT', $sql_array);
+ $result = $this->db->sql_query($sql);
+
+ // Set attachments in feed items
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $this->attachments[$row['post_msg_id']][] = $row;
+ }
+ $this->db->sql_freeresult($result);
+ }
}
diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php
index 09f377dd10..a7acfb502f 100644
--- a/phpBB/phpbb/feed/topic.php
+++ b/phpBB/phpbb/feed/topic.php
@@ -88,7 +88,7 @@ class topic extends \phpbb\feed\post_base
function get_sql()
{
$this->sql = array(
- 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
'FROM' => array(
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php
index bdc858e947..e8b9f6de6c 100644
--- a/phpBB/phpbb/feed/topics.php
+++ b/phpBB/phpbb/feed/topics.php
@@ -57,7 +57,7 @@ class topics extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index cc0adac2eb..809a536c2a 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -74,7 +74,7 @@ class topics_active extends \phpbb\feed\topic_base
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views,
t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index fb3726c957..60180f1728 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -326,6 +326,12 @@ class fulltext_native extends \phpbb\search\base
$this->db->sql_freeresult($result);
}
+ // Handle +, - without preceeding whitespace character
+ $match = array('#(\S)\+#', '#(\S)-#');
+ $replace = array('$1 +', '$1 +');
+
+ $keywords = preg_replace($match, $replace, $keywords);
+
// now analyse the search query, first split it using the spaces
$query = explode(' ', $keywords);
diff --git a/phpBB/search.php b/phpBB/search.php
index d03cef5e14..4756a941f5 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -1020,6 +1020,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
{
$template->assign_vars(array(
'SEARCH_TOPIC' => $topic_title,
+ 'L_RETURN_TO_TOPIC' => $user->lang('RETURN_TO', $topic_title),
'U_SEARCH_TOPIC' => $view_topic_url
));
}
diff --git a/phpBB/styles/prosilver/template/jumpbox.html b/phpBB/styles/prosilver/template/jumpbox.html
index 201b2dece2..47d322407d 100644
--- a/phpBB/styles/prosilver/template/jumpbox.html
+++ b/phpBB/styles/prosilver/template/jumpbox.html
@@ -1,10 +1,10 @@
<!-- IF S_VIEWTOPIC -->
- <p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO} {FORUM_NAME}</a></p>
+ <p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_FORUM}</a></p>
<!-- ELSEIF S_VIEWFORUM -->
- <p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO} {L_INDEX}</a></p>
+ <p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_INDEX}</a></p>
<!-- ELSEIF SEARCH_TOPIC -->
- <p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO}{L_COLON} {SEARCH_TOPIC}</a></p>
+ <p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO_TOPIC}</a></p>
<!-- ELSEIF S_SEARCH_ACTION -->
<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_RETURN_TO_SEARCH_ADV}</a></p>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html
index 2ae224bc3a..e311b85cbe 100644
--- a/phpBB/styles/prosilver/template/posting_editor.html
+++ b/phpBB/styles/prosilver/template/posting_editor.html
@@ -1,73 +1,5 @@
<fieldset class="fields1">
- <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF -->
-
- <!-- IF S_PRIVMSGS and not S_SHOW_DRAFTS -->
-
- <div class="column1">
- <!-- IF S_ALLOW_MASS_PM -->
- <!-- IF .to_recipient -->
- <dl>
- <dt><label>{L_TO}{L_COLON}</label></dt>
- <dd>
- <!-- BEGIN to_recipient -->
- <!-- IF not to_recipient.S_FIRST_ROW and to_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF -->
- <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->&nbsp;
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" />&nbsp;<!-- ENDIF -->
- <!-- END to_recipient -->
- </dd>
- </dl>
- <!-- ENDIF -->
- <!-- IF .bcc_recipient -->
- <dl>
- <dt><label>{L_BCC}{L_COLON}</label></dt>
- <dd>
- <!-- BEGIN bcc_recipient -->
- <!-- IF not bcc_recipient.S_FIRST_ROW and bcc_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF -->
- <!-- IF bcc_recipient.IS_GROUP --><a href="{bcc_recipient.U_VIEW}"><strong>{bcc_recipient.NAME}</strong></a><!-- ELSE -->{bcc_recipient.NAME_FULL}<!-- ENDIF -->&nbsp;
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" />&nbsp;<!-- ENDIF -->
- <!-- END bcc_recipient -->
- </dd>
- </dl>
- <!-- ENDIF -->
- <!-- IF not S_EDIT_POST -->
- <dl class="pmlist">
- <dt><label>{L_TO}{L_COLON}<textarea id="username_list" name="username_list" class="inputbox" cols="50" rows="2" tabindex="1"></textarea></label></dt>
- <dd><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a></span></dd>
- <dd><input type="submit" name="add_to" value="{L_ADD}" class="button2" tabindex="1" /></dd>
- <dd><input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button2" tabindex="1" /></dd>
- </dl>
- <!-- ENDIF -->
- <!-- ELSE -->
- <dl>
- <dt><label for="username_list">{L_TO}{L_COLON}</label><!-- IF not S_EDIT_POST --><br /><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false">{L_FIND_USERNAME}</a></span><!-- ENDIF --></dt>
- <!-- IF .to_recipient -->
- <dd>
- <!-- BEGIN to_recipient -->
- <!-- IF not to_recipient.S_FIRST_ROW and to_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF -->
- <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->&nbsp;
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" />&nbsp;<!-- ENDIF -->
- <!-- END to_recipient -->
- </dd>
- <!-- ENDIF -->
-
- <!-- IF not S_EDIT_POST -->
- <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button2" /></dd>
- <!-- ENDIF -->
- </dl>
- <!-- ENDIF -->
-
- </div>
-
- <!-- IF S_GROUP_OPTIONS -->
- <div class="column2">
- <dl>
- <dd><label for="group_list">{L_USERGROUPS}{L_COLON}</label> <select name="group_list[]" id="group_list" multiple="multiple" size="4" class="inputbox">{S_GROUP_OPTIONS}</select></dd>
- </dl>
- </div>
- <!-- ENDIF -->
-
- <div class="clear"></div>
- <!-- ENDIF -->
+<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF -->
<!-- IF S_SHOW_TOPIC_ICONS or S_SHOW_PM_ICONS -->
<dl>
@@ -140,7 +72,7 @@
</div>
<!-- EVENT posting_editor_message_after -->
-</fieldset>
+ </fieldset>
<!-- IF $EXTRA_POSTING_OPTIONS eq 1 -->
diff --git a/phpBB/styles/prosilver/template/posting_pm_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html
new file mode 100644
index 0000000000..114b361e9a
--- /dev/null
+++ b/phpBB/styles/prosilver/template/posting_pm_header.html
@@ -0,0 +1,82 @@
+<fieldset class="fields1">
+ <!-- IF not S_SHOW_DRAFTS -->
+
+ <!-- IF S_GROUP_OPTIONS -->
+ <div class="column2">
+ <label for="group_list"><strong>{L_TO_ADD_GROUPS}{L_COLON}</strong></label><br />
+ <select name="group_list[]" id="group_list" multiple="multiple" size="3" class="inputbox">{S_GROUP_OPTIONS}</select><br />
+ </div>
+ <!-- ENDIF -->
+ <!-- IF S_ALLOW_MASS_PM -->
+ <div class="column1">
+ <!-- IF not S_EDIT_POST -->
+ <dl class="pmlist">
+ <dt><label><strong>{L_TO_ADD_MASS}{L_COLON}</strong><textarea id="username_list" name="username_list" class="inputbox" cols="50" rows="2" tabindex="1"></textarea></label></dt>
+ <dd class="recipients">
+ <input type="submit" name="add_to" value="{L_ADD}" class="button2" tabindex="1" />
+ <input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button2" tabindex="1" />
+ <span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a></span>
+ </dd>
+ </dl>
+ <!-- ENDIF -->
+ </div>
+ <!-- IF .to_recipient or .bcc_recipient --><hr /><!-- ENDIF -->
+ <div class="column1">
+ <!-- IF .to_recipient -->
+ <dl>
+ <dt><label>{L_TO_MASS}{L_COLON}</label></dt>
+ <dd class="recipients">
+ <ul class="recipients">
+ <!-- BEGIN to_recipient -->
+ <li>
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->
+ </li>
+ <!-- END to_recipient -->
+ </ul>
+ </dd>
+ </dl>
+ <!-- ENDIF -->
+ </div>
+ <!-- IF .bcc_recipient -->
+ <div class="column2">
+ <dl>
+ <dt><label>{L_BCC}{L_COLON}</label></dt>
+ <dd class="recipients">
+ <ul class="recipients">
+ <!-- BEGIN bcc_recipient -->
+ <li>
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ <!-- IF bcc_recipient.IS_GROUP --><a href="{bcc_recipient.U_VIEW}"><strong>{bcc_recipient.NAME}</strong></a><!-- ELSE -->{bcc_recipient.NAME_FULL}<!-- ENDIF -->
+ </li>
+ <!-- END bcc_recipient -->
+ </ul>
+ </dd>
+ </dl>
+ </div>
+ <!-- ENDIF -->
+ <!-- ELSE -->
+ <div class="column1">
+ <dl>
+ <dt><label for="username_list">{L_TO_ADD}{L_COLON}</label><!-- IF not S_EDIT_POST --><br /><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false">{L_FIND_USERNAME}</a></span><!-- ENDIF --></dt>
+ <!-- IF not S_EDIT_POST -->
+ <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button2" /></dd>
+ <!-- ENDIF -->
+ <!-- IF .to_recipient -->
+ <dd class="recipients">
+ <ul class="recipients">
+ <!-- BEGIN to_recipient -->
+ <li>
+ <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->&nbsp;
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ </li>
+ <!-- END to_recipient -->
+ </dd>
+ <!-- ENDIF -->
+ </dl>
+ </div>
+ <!-- ENDIF -->
+
+ <div class="clear"></div>
+ <!-- ENDIF -->
+ </fieldset>
diff --git a/phpBB/styles/prosilver/template/posting_pm_layout.html b/phpBB/styles/prosilver/template/posting_pm_layout.html
index 5421cc2cbd..c9b4a915ae 100644
--- a/phpBB/styles/prosilver/template/posting_pm_layout.html
+++ b/phpBB/styles/prosilver/template/posting_pm_layout.html
@@ -17,6 +17,12 @@
<h2>{L_TITLE}</h2>
+<div class="panel" id="pmheader-postingbox">
+ <div class="inner">
+ <!-- INCLUDE posting_pm_header.html -->
+ </div>
+</div>
+
<div class="panel" id="postingbox">
<div class="inner">
diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html
index 1a83484235..da73a7eef9 100644
--- a/phpBB/styles/prosilver/template/search_results.html
+++ b/phpBB/styles/prosilver/template/search_results.html
@@ -6,7 +6,7 @@
<!-- IF PHRASE_SEARCH_DISABLED --> <p><strong>{L_PHRASE_SEARCH_DISABLED}</strong></p><!-- ENDIF -->
<!-- IF SEARCH_TOPIC -->
- <p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}">{L_RETURN_TO}{L_COLON} {SEARCH_TOPIC}</a></p>
+ <p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}">{L_RETURN_TO_TOPIC}</a></p>
<!-- ELSE -->
<p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}">{L_RETURN_TO_SEARCH_ADV}</a></p>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
index 7a80f72348..a6ef3fc7dd 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
@@ -18,7 +18,7 @@
<!-- IF TOTAL_MESSAGES or S_VIEW_MESSAGE -->
<ul class="linklist">
<li class="rightside pagination">
- <!-- IF S_VIEW_MESSAGE --><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_CURRENT_FOLDER}">{L_RETURN_TO} {CUR_FOLDER_NAME}</a><!-- ENDIF -->
+ <!-- IF S_VIEW_MESSAGE --><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_CURRENT_FOLDER}">{L_RETURN_TO_FOLDER}</a><!-- ENDIF -->
<!-- IF FOLDER_CUR_MESSAGES neq 0 -->
<!-- IF TOTAL_MESSAGES -->{TOTAL_MESSAGES} &bull; <!-- ENDIF -->
<!-- IF .pagination -->
diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css
index 4e71dc4de4..0c52e12fdc 100644
--- a/phpBB/styles/prosilver/theme/bidi.css
+++ b/phpBB/styles/prosilver/theme/bidi.css
@@ -550,7 +550,7 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a {
---------------------------------------- */
.rtl .small-icon {
background-position: 100% 50%;
- padding: 1px 19px 0 0;
+ padding: 0 19px 0 0;
}
.rtl ul.linklist li.small-icon {
diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css
index 68d827b974..93c325e416 100644
--- a/phpBB/styles/prosilver/theme/buttons.css
+++ b/phpBB/styles/prosilver/theme/buttons.css
@@ -128,7 +128,7 @@ a.sendemail {
background-position: 0 50%;
background-repeat: no-repeat;
background-image: none;
- padding: 1px 0 0 17px;
+ padding: 0 0 0 17px;
}
ul.linklist li.small-icon {
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index d19b967771..1b4bdfcc6a 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -331,6 +331,7 @@ ul.linklist li {
margin-right: 5px;
font-size: 1.1em;
line-height: 2.2em;
+ padding-top: 1px;
}
ul.linklist li.rightside, p.rightside {
@@ -750,6 +751,31 @@ dl.details dd {
overflow: hidden;
}
+fieldset.fields1 ul.recipients {
+ list-style-type: none;
+ line-height: 1.8;
+ max-height: 150px;
+ overflow-y: auto;
+}
+
+fieldset.fields1 dd.recipients {
+ clear: left;
+ margin-left: 1em;
+}
+
+fieldset.fields1 ul.recipients input.button2{
+ font-size: 0.8em;
+ margin-right: 0;
+ padding: 0;
+}
+
+fieldset.fields1 dl.pmlist > dt {
+ width: auto !important;
+}
+
+fieldset.fields1 dl.pmlist dd.recipients {
+ margin-left: 0 !important;
+}
/* Pagination
---------------------------------------- */
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 755ce4a19d..64d2df2d1a 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -256,6 +256,7 @@ fieldset.submit-buttons input {
min-width: 100%;
max-width: 100%;
font-size: 1.2em;
+ resize: vertical;
}
/* Emoticons panel */
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index ab72b34487..596272636a 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -634,6 +634,7 @@ $template->assign_vars(array(
'S_TOPIC_ACTION' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id" . (($start == 0) ? '' : "&amp;start=$start")),
'S_MOD_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&amp;t=$topic_id" . (($start == 0) ? '' : "&amp;start=$start") . "&amp;quickmod=1&amp;redirect=" . urlencode(str_replace('&amp;', '&', $viewtopic_url)), true, $user->session_id),
+ 'L_RETURN_TO_FORUM' => $user->lang('RETURN_TO', $topic_data['forum_name']),
'S_VIEWTOPIC' => true,
'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false,
'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"),
diff --git a/tests/functional/acp_users_test.php b/tests/functional/acp_users_test.php
new file mode 100644
index 0000000000..50d9a67dc1
--- /dev/null
+++ b/tests/functional/acp_users_test.php
@@ -0,0 +1,45 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @group functional
+*/
+class phpbb_functional_acp_users_test extends phpbb_functional_test_case
+{
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->login();
+ $this->admin_login();
+ $this->add_lang('acp/users');
+ }
+
+ public function test_founder_deletion()
+ {
+ $username = 'founder-account';
+ $user_id = $this->create_user($username);
+ $this->make_founder($user_id);
+
+ $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}");
+ $form = $crawler->filter('#user_delete')->selectButton($this->lang('SUBMIT'))->form();
+ $crawler = self::submit($form);
+ $this->assertContains($this->lang('CANNOT_REMOVE_FOUNDER'), $this->get_content());
+ }
+
+ protected function make_founder($user_id)
+ {
+ $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}");
+ $form = $crawler->filter('#user_overview')->selectButton($this->lang('SUBMIT'))->form();
+ $data = array('user_founder' => '1');
+ $form->setValues($data);
+ $crawler = self::submit($form);
+ $this->assertContains($this->lang('USER_OVERVIEW_UPDATED'), $this->get_content());
+ }
+}
diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php
index 4725301141..57b0f56bee 100644
--- a/tests/functional/extension_controller_test.php
+++ b/tests/functional/extension_controller_test.php
@@ -113,11 +113,32 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c
}
/**
+ * Check the redirect after using the login_box() form
+ */
+ public function test_login_redirect()
+ {
+ $this->markTestIncomplete('Session table contains incorrect data for controllers on travis,'
+ . 'therefor the redirect fails.');
+
+ $this->phpbb_extension_manager->enable('foo/bar');
+ $crawler = self::request('GET', 'app.php/foo/login_redirect');
+ $this->assertContainsLang('LOGIN', $crawler->filter('h2')->text());
+ $form = $crawler->selectButton('login')->form(array(
+ 'username' => 'admin',
+ 'password' => 'adminadmin',
+ ));
+ $this->assertStringStartsWith('./app.php/foo/login_redirect', $form->get('redirect')->getValue());
+
+ $crawler = self::submit($form);
+ $this->assertContains("I am a variable", $crawler->filter('#content')->text(), 'Unsuccessful redirect after using login_box()');
+ $this->phpbb_extension_manager->purge('foo/bar');
+ }
+
+ /**
* Check the output of a controller using the template system
*/
public function test_redirect()
{
- $filesystem = new \phpbb\filesystem();
$this->phpbb_extension_manager->enable('foo/bar');
$crawler = self::request('GET', 'app.php/foo/redirect');
diff --git a/tests/functional/fixtures/ext/foo/bar/config/routing.yml b/tests/functional/fixtures/ext/foo/bar/config/routing.yml
index d4d256c293..08bc73038f 100644
--- a/tests/functional/fixtures/ext/foo/bar/config/routing.yml
+++ b/tests/functional/fixtures/ext/foo/bar/config/routing.yml
@@ -14,6 +14,10 @@ foo_exception_controller:
pattern: /foo/exception
defaults: { _controller: foo_bar.controller:exception }
+foo_login_redirect_controller:
+ pattern: /foo/login_redirect
+ defaults: { _controller: foo_bar.controller:login_redirect }
+
foo_redirect_controller:
pattern: /foo/redirect
defaults: { _controller: foo_bar.controller:redirect }
diff --git a/tests/functional/fixtures/ext/foo/bar/config/services.yml b/tests/functional/fixtures/ext/foo/bar/config/services.yml
index cec69f7807..d35be7955a 100644
--- a/tests/functional/fixtures/ext/foo/bar/config/services.yml
+++ b/tests/functional/fixtures/ext/foo/bar/config/services.yml
@@ -6,6 +6,7 @@ services:
- @path_helper
- @template
- @config
+ - @user
- %core.root_path%
- %core.php_ext%
diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php
index 45246f8a97..47d856a5df 100644
--- a/tests/functional/fixtures/ext/foo/bar/controller/controller.php
+++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php
@@ -10,13 +10,15 @@ class controller
protected $helper;
protected $path_helper;
protected $config;
+ protected $user;
- public function __construct(\phpbb\controller\helper $helper, \phpbb\path_helper $path_helper, \phpbb\template\template $template, \phpbb\config\config $config, $root_path, $php_ext)
+ public function __construct(\phpbb\controller\helper $helper, \phpbb\path_helper $path_helper, \phpbb\template\template $template, \phpbb\config\config $config, \phpbb\user $user, $root_path, $php_ext)
{
$this->template = $template;
$this->helper = $helper;
$this->path_helper = $path_helper;
$this->config = $config;
+ $this->user = $user;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
}
@@ -43,6 +45,18 @@ class controller
throw new \phpbb\controller\exception('Exception thrown from foo/exception route');
}
+ public function login_redirect()
+ {
+ if (!$this->user->data['is_registered'])
+ {
+ login_box();
+ }
+
+ $this->template->assign_var('A_VARIABLE', 'I am a variable');
+
+ return $this->helper->render('foo_bar_body.html');
+ }
+
public function redirect()
{
$url_root = generate_board_url();
diff --git a/tests/functional/ucp_pm_test.php b/tests/functional/ucp_pm_test.php
new file mode 100644
index 0000000000..09521cc9f4
--- /dev/null
+++ b/tests/functional/ucp_pm_test.php
@@ -0,0 +1,48 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @group functional
+*/
+class phpbb_functional_ucp_pm_test extends phpbb_functional_test_case
+{
+ public function setUp()
+ {
+ parent::setUp();
+ $this->login();
+ $this->admin_login();
+ }
+
+ public function test_pm_enabled()
+ {
+ $crawler = self::request('GET', 'ucp.php');
+ $this->assertContainsLang('PRIVATE_MESSAGES', $crawler->filter('html')->text());
+ }
+
+ public function test_pm_disabled()
+ {
+ $this->set_allow_pm(0);
+ $crawler = self::request('GET', 'ucp.php');
+ $this->assertNotContainsLang('PRIVATE_MESSAGES', $crawler->filter('html')->text());
+ $this->set_allow_pm(1);
+ }
+
+ protected function set_allow_pm($enable_pm)
+ {
+ $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=message');
+
+ $form = $crawler->selectButton('Submit')->form();
+ $values = $form->getValues();
+
+ $values["config[allow_privmsg]"] = $enable_pm;
+ $form->setValues($values);
+ $crawler = self::submit($form);
+ $this->assertGreaterThan(0, $crawler->filter('.successbox')->count());
+ }
+}
diff --git a/tests/search/native_test.php b/tests/search/native_test.php
index 4911160cc0..e860a4f89a 100644
--- a/tests/search/native_test.php
+++ b/tests/search/native_test.php
@@ -119,6 +119,55 @@ class phpbb_search_native_test extends phpbb_search_test_case
array(1, 2),
array(),
),
+ array(
+ 'foo -foo',
+ 'all',
+ true,
+ array(1),
+ array(1),
+ array(),
+ ),
+ array(
+ '-foo foo',
+ 'all',
+ true,
+ array(1),
+ array(1),
+ array(),
+ ),
+ // some creative edge cases
+ array(
+ 'foo foo-',
+ 'all',
+ true,
+ array(1),
+ array(),
+ array(),
+ ),
+ array(
+ 'foo- foo',
+ 'all',
+ true,
+ array(1),
+ array(),
+ array(),
+ ),
+ array(
+ 'foo-bar',
+ 'all',
+ true,
+ array(1, 2),
+ array(),
+ array(),
+ ),
+ array(
+ 'foo-bar-foo',
+ 'all',
+ true,
+ array(1, 2),
+ array(),
+ array(),
+ ),
// all common
array(
'commonword',
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index e40efdec03..a1a4ed73e2 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -192,7 +192,7 @@ class phpbb_functional_test_case extends phpbb_test_case
$db_tools,
self::$config['table_prefix'] . 'migrations',
$phpbb_root_path,
- $php_ext,
+ $phpEx,
self::$config['table_prefix'],
array(),
new \phpbb\db\migration\helper()
@@ -207,7 +207,7 @@ class phpbb_functional_test_case extends phpbb_test_case
new phpbb\filesystem(),
self::$config['table_prefix'] . 'ext',
dirname(__FILE__) . '/',
- $php_ext,
+ $phpEx,
$this->get_cache_driver()
);
@@ -473,6 +473,16 @@ class phpbb_functional_test_case extends phpbb_test_case
global $config;
$config = new \phpbb\config\config(array());
+
+ /*
+ * Add required config entries to the config array to prevent
+ * set_config() sending an INSERT query for already existing entries,
+ * resulting in a SQL error.
+ * This is because set_config() first sends an UPDATE query, then checks
+ * sql_affectedrows() which can be 0 (e.g. on MySQL) when the new
+ * data is already there.
+ */
+ $config['newest_user_colour'] = '';
$config['rand_seed'] = '';
$config['rand_seed_last_update'] = time() + 600;
@@ -716,15 +726,27 @@ class phpbb_functional_test_case extends phpbb_test_case
/**
* assertContains for language strings
*
- * @param string $needle Search string
- * @param string $haystack Search this
- * @param string $message Optional failure message
+ * @param string $needle Search string
+ * @param string $haystack Search this
+ * @param string $message Optional failure message
*/
public function assertContainsLang($needle, $haystack, $message = null)
{
$this->assertContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message);
}
+ /**
+ * assertNotContains for language strings
+ *
+ * @param string $needle Search string
+ * @param string $haystack Search this
+ * @param string $message Optional failure message
+ */
+ public function assertNotContainsLang($needle, $haystack, $message = null)
+ {
+ $this->assertNotContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message);
+ }
+
/*
* Perform some basic assertions for the page
*