diff options
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 --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /> <!-- 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 --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" /> <!-- 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 --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /> <!-- 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 --> + <!-- 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} • <!-- 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&t=$topic_id" . (($start == 0) ? '' : "&start=$start")), 'S_MOD_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . "&quickmod=1&redirect=" . urlencode(str_replace('&', '&', $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 * |