From ed40846590ea3b80af35aa845dba7e05da88c223 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 12:16:45 +0200 Subject: [PATCH 01/20] [ticket/12371] Do not group "quote" notifications Grouping these notification makes no sense, as the user will not find the posts he is quoted in, when they are spread over multiple pages PHPBB3-12371 --- phpBB/phpbb/notification/type/quote.php | 31 +++++++------------------ 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 745430e114..f4b4d763eb 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -113,29 +113,6 @@ class quote extends \phpbb\notification\type\post $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications - $update_notifications = array(); - $sql = 'SELECT n.* - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt - WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' - AND n.notification_read = 0 - AND nt.notification_type_id = n.notification_type_id - AND nt.notification_type_enabled = 1'; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Do not create a new notification - unset($notify_users[$row['user_id']]); - - $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); - } - $this->db->sql_freeresult($result); - return $notify_users; } @@ -190,6 +167,14 @@ class quote extends \phpbb\notification\type\post return true; } + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + /** * Get email template * From e0fadfb4d675df71b359b5d64b614051dda4017e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 12:19:04 +0200 Subject: [PATCH 02/20] [ticket/12371] Allow notification types to redirect to a different url This way we can redirect the post and bookmark notification to the first unread post in the topic PHPBB3-12371 --- phpBB/index.php | 2 +- phpBB/phpbb/notification/type/base.php | 8 ++++++++ phpBB/phpbb/notification/type/post.php | 8 ++++++++ phpBB/phpbb/notification/type/type_interface.php | 7 +++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/phpBB/index.php b/phpBB/index.php index 32bc118e8c..6927705f91 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -63,7 +63,7 @@ if (($mark_notification = $request->variable('mark_notification', 0))) redirect(append_sid($phpbb_root_path . $redirect)); } - redirect($notification->get_url()); + redirect($notification->get_redirect_url()); } } } diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 0719540bdb..7d08521d40 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -275,6 +275,14 @@ abstract class base implements \phpbb\notification\type\type_interface return $this->mark(true, $return); } + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + /** * Prepare to output the notification to the template * diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index f973becc3b..7d4bc06879 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -269,6 +269,14 @@ class post extends \phpbb\notification\type\base return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->item_id}#p{$this->item_id}"); } + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&view=unread#unread"); + } + /** * Users needed to query before this notification can be displayed * diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index e3e6898172..2f465aae2b 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -98,6 +98,13 @@ interface type_interface */ public function get_url(); + /** + * Get the url to redirect after the item has been marked as read + * + * @return string URL + */ + public function get_redirect_url(); + /** * URL to unsubscribe to this notification * From 92db22c8827abfad8615b0537fdc6fd89ab4203f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 12:28:14 +0200 Subject: [PATCH 03/20] [ticket/12371] Do not delete post related notifications when a post is deleted When a post is marked edited and therefor marked as softdeleted/unapproved, we should not delete the notifications, just like we can't delete the emails. Links are out there anyway and just keeping the notification is fail save. If we keep the notification we can just continue to update it when more posts are added. Also when we delete a post, we don't have to go though the table and find all related notifications to be able to delete them or even update them, when they have responders set. PHPBB3-12371 --- phpBB/includes/functions_admin.php | 2 -- phpBB/includes/functions_posting.php | 25 ++----------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index d72f89b6ac..01cba10b40 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -736,8 +736,6 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = // Notifications types to delete $delete_notifications_types = array( 'quote', - 'bookmark', - 'post', 'approve_post', 'post_in_queue', ); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 51bbcb8bae..ebd2d77887 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2272,16 +2272,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'edit_first_post': case 'edit': case 'edit_last_post': - if ($data['topic_visibility'] != ITEM_APPROVED) - { - $phpbb_notifications->delete_notifications('topic', $data['topic_id']); - } - - $phpbb_notifications->delete_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $data['post_id']); + // Nothing to do here break; } } @@ -2292,23 +2283,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'post': case 'reply': case 'quote': - // Nothing to do here - break; - case 'edit_topic': case 'edit_first_post': case 'edit': case 'edit_last_post': - if ($data['topic_visibility'] != ITEM_APPROVED) - { - $phpbb_notifications->delete_notifications('topic', $data['topic_id']); - } - - $phpbb_notifications->delete_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $data['post_id']); + // Nothing to do here break; } } From 418747ed341f0c4d2f1d1c1b5ea177fadde9ce7e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 12:44:31 +0200 Subject: [PATCH 04/20] [ticket/12371] Do not update the notification entry unneccessarily When the data did not change, we also don't have to run the query at all. PHPBB3-12371 --- phpBB/phpbb/notification/type/bookmark.php | 12 ++++++++---- phpBB/phpbb/notification/type/post.php | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 003998677d..c981695f74 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -110,10 +110,14 @@ class bookmark extends \phpbb\notification\type\post unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 7d4bc06879..987651887f 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -152,10 +152,14 @@ class post extends \phpbb\notification\type\base unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); @@ -392,7 +396,7 @@ class post extends \phpbb\notification\type\base // Do not add them as a responder if they were the original poster that created the notification if ($this->get_data('poster_id') == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } $responders = $this->get_data('responders'); @@ -404,7 +408,7 @@ class post extends \phpbb\notification\type\base // Do not add them as a responder multiple times if ($responder['poster_id'] == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } } @@ -415,6 +419,7 @@ class post extends \phpbb\notification\type\base $this->set_data('responders', $responders); - return array('notification_data' => serialize($this->get_data(false))); + $serialized_data = serialize($this->get_data(false)); + return array('notification_data' => $serialized_data); } } From 37751b51f95a3f05ea9a40f74978989edd2af69e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 12:50:29 +0200 Subject: [PATCH 05/20] [ticket/12371] Do not add unlimited users as responders We run into the risc that the data is longer then the character limit of the table column. However as we trim the users list anyway, we can also just stop adding them and display "many others" instead of "x others" PHPBB3-12371 --- phpBB/language/en/common.php | 7 +++++-- phpBB/phpbb/notification/type/post.php | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 677b228cc6..956b593476 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -422,14 +422,16 @@ $lang = array_merge($lang, array( 'NOT_WATCHING_FORUM' => 'You are no longer subscribed to updates on this forum.', 'NOT_WATCHING_TOPIC' => 'You are no longer subscribed to this topic.', 'NOTIFICATIONS' => 'Notifications', - // This applies for NOTIFICATION_BOOKMARK, NOTIFICATION_POST, and NOTIFICATION_QUOTE. + // This applies for NOTIFICATION_BOOKMARK and NOTIFICATION_POST. // %1$s will return a list of users that's concatenated using "," and "and" - see STRING_LIST // Once the user count reaches 5 users or more, the list is trimmed using NOTIFICATION_X_OTHERS + // Once the user count reaches 20 users or more, the list is trimmed using NOTIFICATION_MANY_OTHERS // Examples: // A replied... // A and B replied... // A, B and C replied... // A, B, C and 2 others replied... + // A, B, C and many others replied... 'NOTIFICATION_BOOKMARK' => array( 1 => '%1$s replied to the topic “%2$s” you have bookmarked.', ), @@ -454,7 +456,8 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.', 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', 'NOTIFICATION_ADMIN_ACTIVATE_USER' => 'The user “%1$s” is newly registered and requires activation.', - // Used in conjuction with NOTIFICATION_BOOKMARK, NOTIFICATION_POST, and NOTIFICATION_QUOTE. + // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. + 'NOTIFICATION_MANY_OTHERS' => 'many others', 'NOTIFICATION_X_OTHERS' => array( 2 => '%d others', ), diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 987651887f..826be0c992 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -210,7 +210,11 @@ class post extends \phpbb\notification\type\base } } - if ($trimmed_responders_cnt) + if ($trimmed_responders_cnt > 20) + { + $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS'); + } + else if ($trimmed_responders_cnt) { $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt); } @@ -403,6 +407,14 @@ class post extends \phpbb\notification\type\base $responders = ($responders === null) ? array() : $responders; + // Do not add more then 25 responder, + // we trim the username list to "a, b, c and x others" anyway + // so there is no use to add all of them anyway. + if (sizeof($responders) > 25) + { + return array(); + } + foreach ($responders as $responder) { // Do not add them as a responder multiple times @@ -420,6 +432,15 @@ class post extends \phpbb\notification\type\base $this->set_data('responders', $responders); $serialized_data = serialize($this->get_data(false)); + + // If the data is longer then 4000 characters, it would cause a SQL error + // so we just don't add the username to the list, when this would be the + // case. + if (utf8_strlen($serialized_data) >= 4000) + { + return array(); + } + return array('notification_data' => $serialized_data); } } From dac01e8ca534b4d145d99e49a6aee173b85925f5 Mon Sep 17 00:00:00 2001 From: Cesar G Date: Thu, 19 Dec 2013 14:01:07 -0800 Subject: [PATCH 06/20] [ticket/12052] Add support for ITEM_UNAPPROVED to set_post_visibility method PHPBB3-12052 --- phpBB/phpbb/content_visibility.php | 63 +++++++++++------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index f3db37e478..165a2c3a56 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -215,7 +215,7 @@ class content_visibility /** * Change visibility status of one post or all posts of a topic * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED} * @param $post_id mixed Post ID or array of post IDs to act on, * if it is empty, all posts of topic_id will be modified * @param $topic_id int Topic where $post_id is found @@ -231,7 +231,7 @@ class content_visibility */ public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) { return array(); } @@ -326,7 +326,7 @@ class content_visibility // Update users postcounts foreach ($postcounts as $num_posts => $poster_ids) { - if ($visibility == ITEM_DELETED) + if (in_array($visibility, array(ITEM_UNAPPROVED, ITEM_DELETED))) { $sql = 'UPDATE ' . $this->users_table . ' SET user_posts = 0 @@ -387,54 +387,35 @@ class content_visibility // Update the topic's reply count and the forum's post count if ($update_topic_postcount) { - $cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0; + $field_alias = array( + ITEM_APPROVED => 'posts_approved', + ITEM_UNAPPROVED => 'posts_unapproved', + ITEM_DELETED => 'posts_softdeleted', + ); + $cur_posts = array_fill_keys($field_alias, 0); + foreach ($postcount_visibility as $post_visibility => $visibility_posts) { - // We need to substract the posts from the counters ... - if ($post_visibility == ITEM_APPROVED) - { - $cur_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_UNAPPROVED) - { - $cur_unapproved_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_DELETED) - { - $cur_softdeleted_posts += $visibility_posts; - } + $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts; } $sql_ary = array(); - if ($visibility == ITEM_DELETED) + $recipient_field = $field_alias[$visibility]; + + foreach ($cur_posts as $field => $count) { - if ($cur_posts) + // Decrease the count for the old statuses. + if ($count && $field != $recipient_field) { - $sql_ary['posts_approved'] = ' - ' . $cur_posts; - } - if ($cur_unapproved_posts) - { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_posts + $cur_unapproved_posts) - { - $sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts); + $sql_ary[$field] = " - $count"; } } - else + // Add up the count from all statuses excluding the recipient status. + $count_increase = array_sum(array_diff($cur_posts, array($recipient_field))); + + if ($count_increase) { - if ($cur_unapproved_posts) - { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_softdeleted_posts) - { - $sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts; - } - if ($cur_softdeleted_posts + $cur_unapproved_posts) - { - $sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts); - } + $sql_ary[$recipient_field] = " + $count_increase"; } if (sizeof($sql_ary)) From 2ec9c08a2bce2cb83c68339d2d07039cabc44d68 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 14:10:58 +0200 Subject: [PATCH 07/20] [ticket/12052] Use different visibility when post was edited ... and needs to be reapproved. PHPBB3-12052 --- phpBB/includes/acp/acp_prune.php | 2 +- phpBB/includes/acp/acp_users.php | 3 ++- phpBB/includes/constants.php | 1 + phpBB/includes/functions_admin.php | 8 +++--- phpBB/includes/functions_posting.php | 39 +++++++++++++++++++++++++--- phpBB/includes/mcp/mcp_forum.php | 2 +- phpBB/includes/mcp/mcp_front.php | 4 +-- phpBB/includes/mcp/mcp_main.php | 4 ++- phpBB/includes/mcp/mcp_post.php | 2 +- phpBB/includes/mcp/mcp_queue.php | 12 ++++----- phpBB/includes/mcp/mcp_reports.php | 2 +- phpBB/includes/mcp/mcp_topic.php | 6 ++--- phpBB/mcp.php | 7 ++--- phpBB/memberlist.php | 2 +- phpBB/phpbb/content_visibility.php | 17 ++++++------ phpBB/search.php | 2 +- phpBB/viewforum.php | 2 +- phpBB/viewtopic.php | 6 ++--- 18 files changed, 79 insertions(+), 42 deletions(-) diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index d0e5dfb5f4..542f2502dd 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -533,7 +533,7 @@ class acp_prune WHERE u.user_id <> ' . ANONYMOUS . ' AND u.user_type <> ' . USER_FOUNDER . ((!empty($user_ids)) ? 'AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . ' - AND p.post_visibility = ' . ITEM_UNAPPROVED . ' + AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . ' AND u.user_id = p.poster_id GROUP BY p.poster_id HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index a720334ed2..3cd5e990cf 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -657,6 +657,7 @@ class acp_users { if ($topic_id_ary[$row['topic_id']][ITEM_APPROVED] == $row['topic_posts_approved'] && $topic_id_ary[$row['topic_id']][ITEM_UNAPPROVED] == $row['topic_posts_unapproved'] + && $topic_id_ary[$row['topic_id']][ITEM_REAPPROVE] == $row['topic_posts_unapproved'] && $topic_id_ary[$row['topic_id']][ITEM_DELETED] == $row['topic_posts_softdeleted']) { $move_topic_ary[] = $row['topic_id']; @@ -1050,7 +1051,7 @@ class acp_users $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND post_visibility = ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 11bbcd4154..a59b4a8add 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -91,6 +91,7 @@ define('ITEM_MOVED', 2); define('ITEM_UNAPPROVED', 0); // => has not yet been approved define('ITEM_APPROVED', 1); // => has been approved, and has not been soft deleted define('ITEM_DELETED', 2); // => has been soft deleted +define('ITEM_REAPPROVE', 3); // => has been edited and needs to be re-approved // Forum Flags define('FORUM_FLAG_LINK_TRACK', 1); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 01cba10b40..fdf40c8564 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -1487,7 +1487,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, ITEM_DELETED => (!empty($topics_softdeleted)) ? ' WHERE ' . $db->sql_in_set('topic_id', $topics_softdeleted) : '', ); - foreach ($topic_visiblities as $visibility => $sql_where) + foreach ($update_ary as $visibility => $sql_where) { if ($sql_where) { @@ -1776,7 +1776,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $forum_data[$forum_id]['topics_approved'] = $row['total_topics']; } - else if ($row['topic_visibility'] == ITEM_UNAPPROVED) + else if ($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) { $forum_data[$forum_id]['topics_unapproved'] = $row['total_topics']; } @@ -1999,7 +1999,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $topic_data[$topic_id]['posts_approved'] = $row['total_posts']; } - else if ($row['post_visibility'] == ITEM_UNAPPROVED) + else if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $topic_data[$topic_id]['posts_unapproved'] = $row['total_posts']; } @@ -2021,7 +2021,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $topic_data[$topic_id]['first_post_id'] = (!empty($topic_data[$topic_id]['first_post_id'])) ? min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']) : $row['first_post_id']; $topic_data[$topic_id]['last_post_id'] = max($topic_data[$topic_id]['last_post_id'], $row['last_post_id']); - if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED) + if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED || $topic_data[$topic_id]['visibility'] == ITEM_REAPPROVE) { // Soft delete status is stronger than unapproved. $topic_data[$topic_id]['visibility'] = $row['post_visibility']; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index ebd2d77887..887c73f7de 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1296,7 +1296,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; } - else if ($data['topic_visibility'] == ITEM_UNAPPROVED) + else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; } @@ -1403,7 +1403,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data); } - else if ($data['post_visibility'] == ITEM_UNAPPROVED) + else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1'; $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1'; @@ -1555,16 +1555,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u { // Post not approved, but in queue $post_visibility = ITEM_UNAPPROVED; + switch ($post_mode) + { + case 'edit_first_post': + case 'edit': + case 'edit_last_post': + case 'edit_topic': + $post_visibility = ITEM_REAPPROVE; + break; + } } // MODs/Extensions are able to force any visibility on posts if (isset($data['force_approved_state'])) { - $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_approved_state'] : $post_visibility; + $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_approved_state'] : $post_visibility; } if (isset($data['force_visibility'])) { - $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_visibility'] : $post_visibility; + $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_visibility'] : $post_visibility; } // Start the transaction here @@ -2032,6 +2041,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $first_post_has_topic_info = ($post_mode == 'edit_first_post' && (($post_visibility == ITEM_DELETED && $data['topic_posts_softdeleted'] == 1) || ($post_visibility == ITEM_UNAPPROVED && $data['topic_posts_unapproved'] == 1) || + ($post_visibility == ITEM_REAPPROVE && $data['topic_posts_unapproved'] == 1) || ($post_visibility == ITEM_APPROVED && $data['topic_posts_approved'] == 1))); // Fix the post's and topic's visibility and first/last post information, when the post is edited if (($post_mode != 'post' && $post_mode != 'reply') && $data['post_visibility'] != $post_visibility) @@ -2276,6 +2286,27 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u break; } } + else if ($post_visibility == ITEM_REAPPROVE) + { + switch ($mode) + { + case 'edit_topic': + case 'edit_first_post': + $phpbb_notifications->add_notifications('topic_in_queue', $notification_data); + break; + + case 'edit': + case 'edit_last_post': + $phpbb_notifications->add_notifications('post_in_queue', $notification_data); + break; + + case 'post': + case 'reply': + case 'quote': + // Nothing to do here + break; + } + } else if ($post_visibility == ITEM_DELETED) { switch ($mode) diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 7c1c61dae7..60b508990d 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -224,7 +224,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $topic_title = censor_text($row['topic_title']); - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? $url . '&i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . '&t=' . $row['topic_id'] : ''; diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index 44cab5d910..aee43c471d 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -39,7 +39,7 @@ function mcp_front_view($id, $mode, $action) $sql = 'SELECT COUNT(post_id) AS total FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $total = (int) $db->sql_fetchfield('total'); $db->sql_freeresult($result); @@ -60,7 +60,7 @@ function mcp_front_view($id, $mode, $action) $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND post_visibility = ' . ITEM_UNAPPROVED . ' + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . ' ORDER BY post_time DESC'; $result = $db->sql_query_limit($sql, 5); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 55440bf192..6b2e9266b3 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -493,7 +493,7 @@ function mcp_move_topic($topic_ids) { $topics_moved++; } - elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED) + elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED || $topic_info['topic_visibility'] == ITEM_REAPPROVE) { $topics_moved_unapproved++; } @@ -1230,6 +1230,7 @@ function mcp_fork_topic($topic_ids) $total_topics++; break; case ITEM_UNAPPROVED: + case ITEM_REAPPROVE: $total_topics_unapproved++; break; case ITEM_DELETED: @@ -1316,6 +1317,7 @@ function mcp_fork_topic($topic_ids) $total_posts++; break; case ITEM_UNAPPROVED: + case ITEM_REAPPROVE: $total_posts_unapproved++; break; case ITEM_DELETED: diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index e2d6cd15c9..5925575577 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -203,7 +203,7 @@ function mcp_post_details($id, $mode, $action) 'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']), 'S_POST_REPORTED' => ($post_info['post_reported']) ? true : false, - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED) ? true : false, + 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE) ? true : false, 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED) ? true : false, 'S_POST_LOCKED' => ($post_info['post_edit_locked']) ? true : false, 'S_USER_NOTES' => true, diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 8d998919e5..3b1081c5c7 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -115,10 +115,10 @@ class mcp_queue if (!empty($topic_id_list)) { - $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : ITEM_UNAPPROVED; + $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : array(ITEM_UNAPPROVED, ITEM_REAPPROVE); $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' - WHERE post_visibility = ' . $post_visibility . ' + WHERE ' . $db->sql_in_set('post_visibility', $post_visibility) . ' AND ' . $db->sql_in_set('topic_id', $topic_id_list); $result = $db->sql_query($sql); @@ -281,7 +281,7 @@ class mcp_queue 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id&f=$forum_id"), 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), 'S_POST_REPORTED' => $post_info['post_reported'], - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), + 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE, 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_USER_NOTES' => true, 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED), @@ -331,7 +331,7 @@ class mcp_queue $m_perm = 'm_approve'; $is_topics = ($mode == 'unapproved_topics' || $mode == 'deleted_topics') ? true : false; $is_restore = ($mode == 'deleted_posts' || $mode == 'deleted_topics') ? true : false; - $visibility_const = (!$is_restore) ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = (!$is_restore) ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $user->add_lang(array('viewtopic', 'viewforum')); @@ -419,7 +419,7 @@ class mcp_queue $sql = 'SELECT p.post_id FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t' . (($sort_order_sql[0] == 'u') ? ', ' . USERS_TABLE . ' u' : '') . ' WHERE ' . $db->sql_in_set('p.forum_id', $forum_list) . ' - AND p.post_visibility = ' . $visibility_const . ' + AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) . ' ' . (($sort_order_sql[0] == 'u') ? 'AND u.user_id = p.poster_id' : '') . ' ' . (($topic_id) ? 'AND p.topic_id = ' . $topic_id : '') . " AND t.topic_id = p.topic_id @@ -472,7 +472,7 @@ class mcp_queue $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_attachment AS post_attachment, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND topic_visibility = ' . $visibility_const . " + AND ' . $db->sql_in_set('topic_visibility', $visibility_const) . " AND topic_delete_user <> 0 $limit_time_sql ORDER BY $sort_order_sql"; diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 8026e071cd..d4c0c368cb 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -187,7 +187,7 @@ class mcp_reports 'S_CLOSE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&f=' . $post_info['forum_id'] . '&p=' . $post_id), 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), 'S_POST_REPORTED' => $post_info['post_reported'], - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), + 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE, 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_REPORT_CLOSED' => $report['report_closed'], 'S_USER_NOTES' => true, diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index cdb88bf2bf..48efa330d4 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -212,7 +212,7 @@ function mcp_topic_view($id, $mode, $action) parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count); } - if ($row['post_visibility'] == ITEM_UNAPPROVED) + if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $has_unapproved_posts = true; } @@ -239,7 +239,7 @@ function mcp_topic_view($id, $mode, $action) 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), 'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $topic_info['forum_id'])), - 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $topic_info['forum_id'])), + 'S_POST_UNAPPROVED' => (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $topic_info['forum_id'])), 'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED && $auth->acl_get('m_approve', $topic_info['forum_id'])), 'S_CHECKED' => (($submitted_id_list && !in_array(intval($row['post_id']), $submitted_id_list)) || in_array(intval($row['post_id']), $checked_ids)) ? true : false, 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, @@ -462,7 +462,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) while ($row = $db->sql_fetchrow($result)) { // If split from selected post (split_beyond), we split the unapproved items too. - if ($row['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) + if (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $row['forum_id'])) { // continue; } diff --git a/phpBB/mcp.php b/phpBB/mcp.php index 1449346deb..d77dfbd227 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -677,7 +677,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, case 'unapproved_posts': case 'deleted_posts': - $visibility_const = ($mode == 'unapproved_posts') ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = ($mode == 'unapproved_posts') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $type = 'posts'; $default_key = 't'; $default_dir = 'd'; @@ -687,6 +687,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t $where_sql " . $db->sql_in_set('p.forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . ' AND p.post_visibility = ' . $visibility_const . ' + AND ' . $db->sql_in_set('topic_visibility', $visibility_const) .' AND t.topic_id = p.topic_id AND t.topic_visibility <> p.post_visibility'; @@ -698,7 +699,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, case 'unapproved_topics': case 'deleted_topics': - $visibility_const = ($mode == 'unapproved_topics') ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = ($mode == 'unapproved_topics') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $type = 'topics'; $default_key = 't'; $default_dir = 'd'; @@ -706,7 +707,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, $sql = 'SELECT COUNT(topic_id) AS total FROM ' . TOPICS_TABLE . " $where_sql " . $db->sql_in_set('forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . ' - AND topic_visibility = ' . $visibility_const; + AND ' . $db->sql_in_set('topic_visibility', $visibility_const); if ($min_time) { diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 8fceb4ac5b..1e59c2abde 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -624,7 +624,7 @@ switch ($mode) $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $member['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index 165a2c3a56..881a8f2c54 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -215,23 +215,23 @@ class content_visibility /** * Change visibility status of one post or all posts of a topic * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $post_id mixed Post ID or array of post IDs to act on, * if it is empty, all posts of topic_id will be modified * @param $topic_id int Topic where $post_id is found * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action * @param $time int Timestamp when the action is performed - * @param $reason string Reason why the visibilty was changed. + * @param $reason string Reason why the visibility was changed. * @param $is_starter bool Is this the first post of the topic changed? * @param $is_latest bool Is this the last post of the topic changed? * @param $limit_visibility mixed Limit updating per topic_id to a certain visibility * @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time - * @return array Changed post data, empty array if an error occured. + * @return array Changed post data, empty array if an error occurred. */ public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -326,7 +326,7 @@ class content_visibility // Update users postcounts foreach ($postcounts as $num_posts => $poster_ids) { - if (in_array($visibility, array(ITEM_UNAPPROVED, ITEM_DELETED))) + if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) { $sql = 'UPDATE ' . $this->users_table . ' SET user_posts = 0 @@ -391,6 +391,7 @@ class content_visibility ITEM_APPROVED => 'posts_approved', ITEM_UNAPPROVED => 'posts_unapproved', ITEM_DELETED => 'posts_softdeleted', + ITEM_REAPPROVE => 'posts_unapproved', ); $cur_posts = array_fill_keys($field_alias, 0); @@ -456,7 +457,7 @@ class content_visibility * as soft deleted. * If you want to update all posts, use the force option. * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $topic_id mixed Topic ID to act on * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action @@ -467,7 +468,7 @@ class content_visibility */ public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -513,7 +514,7 @@ class content_visibility } else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED) { - // If we're soft deleting a topic we only approved posts are soft deleted. + // If we're soft deleting a topic we only mark approved posts as soft deleted. $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); } else diff --git a/phpBB/search.php b/phpBB/search.php index fbb4e93089..778e985bce 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -879,7 +879,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) $unread_topic = (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false; - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $forum_id)) ? true : false; + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false; $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false; $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&t=$result_topic_id", true, $user->session_id) : ''; diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index a7396f9c72..4345f4236e 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -749,7 +749,7 @@ if (sizeof($topic_list)) $view_topic_url_params = 'f=' . $row['forum_id'] . '&t=' . $topic_id; $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id'])); + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])); $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])); $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 9dc965240f..87ba09f66b 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -266,7 +266,7 @@ if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_appro if ($post_id) { // are we where we are supposed to be? - if ($topic_data['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $topic_data['forum_id'])) + if (($topic_data['post_visibility'] == ITEM_UNAPPROVED || $topic_data['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $topic_data['forum_id'])) { // If post_id was submitted, we try at least to display the topic as a last resort... if ($topic_id) @@ -1028,7 +1028,7 @@ while ($row = $db->sql_fetchrow($result)) { $attach_list[] = (int) $row['post_id']; - if ($row['post_visibility'] == ITEM_UNAPPROVED) + if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $has_attachments = true; } @@ -1642,7 +1642,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, 'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && sizeof($attachments[$row['post_id']]) > 1, - 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED) ? true : false, + 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false, 'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED) ? true : false, 'L_POST_DELETED_MESSAGE' => $l_deleted_message, 'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $forum_id)) ? true : false, From 5512e62c3c436215de6db0b45c693308e1b6dfed Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 14:26:55 +0200 Subject: [PATCH 08/20] [ticket/11772] Do not send out new topic/post notifications when reapproving Only add notifications, if we are not reapproving post When the topic was already approved, but was edited and now needs re-approval, we don't want to notify the users again. PHPBB3-11772 --- phpBB/includes/mcp/mcp_queue.php | 33 +++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 3b1081c5c7..2cbb0b03f6 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -660,11 +660,18 @@ class mcp_queue } $phpbb_notifications->delete_notifications('post_in_queue', $post_id); - $phpbb_notifications->add_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $post_data); + // Only add notifications, if we are not reapproving post + // When the topic was already approved, but was edited and + // now needs re-approval, we don't want to notify the users + // again. + if ($post_data['post_visibility'] == ITEM_UNAPPROVED) + { + $phpbb_notifications->add_notifications(array( + 'quote', + 'bookmark', + 'post', + ), $post_data); + } $phpbb_notifications->mark_notifications_read(array( 'quote', @@ -832,10 +839,18 @@ class mcp_queue )); $phpbb_notifications->delete_notifications('topic_in_queue', $topic_id); - $phpbb_notifications->add_notifications(array( - 'quote', - 'topic', - ), $topic_data); + + // Only add notifications, if we are not reapproving post + // When the topic was already approved, but was edited and + // now needs re-approval, we don't want to notify the users + // again. + if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED) + { + $phpbb_notifications->add_notifications(array( + 'quote', + 'topic', + ), $topic_data); + } $phpbb_notifications->mark_notifications_read('quote', $topic_data['post_id'], $user->data['user_id']); $phpbb_notifications->mark_notifications_read('topic', $topic_id, $user->data['user_id']); From 8375c3f78909f8926ca48bb9649aa3e1f95bd117 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Apr 2014 14:40:03 +0200 Subject: [PATCH 09/20] [ticket/12371] Fix SQL query PHPBB3-12371 --- phpBB/includes/acp/acp_users.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 3cd5e990cf..a139dad052 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1051,7 +1051,7 @@ class acp_users $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_visibility = ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); From 84a77d07be48fcb63f22e7dadefbb4ed0e4e0658 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 12 Apr 2014 09:56:57 +0200 Subject: [PATCH 10/20] [ticket/12371] We do not group quote notifications anymore PHPBB3-12371 --- tests/notification/submit_post_type_quote_test.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index a849cb7b1b..9956f3b58e 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -55,7 +55,7 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ * 2 => Poster, should NOT receive a notification * 3 => Quoted, should receive a notification * 4 => Quoted, but unauthed to read, should NOT receive a notification - * 5 => Quoted, but already notified, should NOT receive a new notification + * 5 => Quoted, but already notified, should STILL receive a new notification * 6 => Quoted, but option disabled, should NOT receive a notification * 7 => Quoted, option set to default, should receive a notification */ @@ -78,6 +78,7 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ array( array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), ), ), From 1d61fcf3c9cb9a92a6c9124cc15e4fd6d61fff6e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 13 Apr 2014 20:45:09 +0200 Subject: [PATCH 11/20] [ticket/12371] Rename disapprove and softdelete tests PHPBB3-12371 --- .../{disapprove_test.php => visibility_disapprove_test.php} | 2 +- .../{softdelete_test.php => visibility_softdelete_test.php} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/functional/{disapprove_test.php => visibility_disapprove_test.php} (99%) rename tests/functional/{softdelete_test.php => visibility_softdelete_test.php} (99%) diff --git a/tests/functional/disapprove_test.php b/tests/functional/visibility_disapprove_test.php similarity index 99% rename from tests/functional/disapprove_test.php rename to tests/functional/visibility_disapprove_test.php index ea594b1062..ca6f6f5f37 100644 --- a/tests/functional/disapprove_test.php +++ b/tests/functional/visibility_disapprove_test.php @@ -10,7 +10,7 @@ /** * @group functional */ -class phpbb_functional_disapprove_test extends phpbb_functional_test_case +class phpbb_functional_visibility_disapprove_test extends phpbb_functional_test_case { protected $data = array(); diff --git a/tests/functional/softdelete_test.php b/tests/functional/visibility_softdelete_test.php similarity index 99% rename from tests/functional/softdelete_test.php rename to tests/functional/visibility_softdelete_test.php index 1c86d00b9b..f8ada9687c 100644 --- a/tests/functional/softdelete_test.php +++ b/tests/functional/visibility_softdelete_test.php @@ -10,7 +10,7 @@ /** * @group functional */ -class phpbb_functional_softdelete_test extends phpbb_functional_test_case +class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_case { protected $data = array(); From 70f5686efb668f656310c168f1d43be483f1dd60 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 13 Apr 2014 20:45:29 +0200 Subject: [PATCH 12/20] [ticket/12371] Fix query in mcp_sorting() PHPBB3-12371 --- phpBB/mcp.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/mcp.php b/phpBB/mcp.php index d77dfbd227..3c6953b37c 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -686,8 +686,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, $sql = 'SELECT COUNT(p.post_id) AS total FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t $where_sql " . $db->sql_in_set('p.forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . ' - AND p.post_visibility = ' . $visibility_const . ' - AND ' . $db->sql_in_set('topic_visibility', $visibility_const) .' + AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) .' AND t.topic_id = p.topic_id AND t.topic_visibility <> p.post_visibility'; From 793680478bb751a4541aadd6ab4c973f24f5d8f2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 13 Apr 2014 20:46:27 +0200 Subject: [PATCH 13/20] [ticket/12371] Add functional tests for reapproving PHPBB3-12371 --- .../functional/visibility_reapprove_test.php | 406 ++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 tests/functional/visibility_reapprove_test.php diff --git a/tests/functional/visibility_reapprove_test.php b/tests/functional/visibility_reapprove_test.php new file mode 100644 index 0000000000..ae97c7e785 --- /dev/null +++ b/tests/functional/visibility_reapprove_test.php @@ -0,0 +1,406 @@ +login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Reapprove Test #1', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + + // Set flood interval to 0 + $this->set_flood_interval(0); + } + + public function test_create_posts() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => 0, + ), 'initial comparison'); + + // Test creating topic #1 + $post = $this->create_topic($this->data['forums']['Reapprove Test #1'], 'Reapprove Test Topic #1', 'This is a test topic posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->data['topics']['Reapprove Test Topic #1'] = (int) $post['topic_id']; + $this->data['posts']['Reapprove Test Topic #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after creating topic #1'); + + $this->logout(); + $this->create_user('reapprove_testuser'); + $this->add_user_group('NEWLY_REGISTERED', array('reapprove_testuser')); + $this->login('reapprove_testuser'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Reapprove Test #1'], $post['topic_id'], 'Re: Reapprove Test Topic #1-#2', 'This is a test post posted by the testing framework.', array(), 'POST_STORED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertNotContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after replying'); + + // Test creating topic #2 + $post = $this->create_topic($this->data['forums']['Reapprove Test #1'], 'Reapprove Test Topic #2', 'This is a test topic posted by the testing framework.', array(), 'POST_STORED_MOD'); + $crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Reapprove Test #1']}&sid={$this->sid}"); + + $this->assertNotContains('Reapprove Test Topic #2', $crawler->filter('html')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after creating topic #2'); + + $this->logout(); + } + + public function test_approve_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'before approving post'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + + $form = $crawler->selectButton($this->lang('APPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_APPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Re: Reapprove Test Topic #1-#2'], + ), 'after approving post'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewtopic.php?f=' . $this->data['forums']['Reapprove Test #1'] . '&t=' . $this->data['topics']['Reapprove Test Topic #1'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + } + + public function test_approve_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Re: Reapprove Test Topic #1-#2'], + ), 'before approving topic'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #2', $crawler->filter('h2')->text()); + + $form = $crawler->selectButton($this->lang('APPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + //@todo $this->assertContainsLang('TOPIC_APPROVED_SUCCESS', $crawler->text()); + $this->assertContainsLang('POST_APPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 3, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'after approving topic'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewtopic.php?f=' . $this->data['topic']['Reapprove Test Topic #2'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #2', $crawler->filter('h2')->text()); + } + + public function test_edit_posts() + { + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + $this->add_lang('posting'); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 3, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'before editing post'); + + $this->login('reapprove_testuser'); + $this->add_user_group('NEWLY_REGISTERED', array('reapprove_testuser')); + + // Test editing a post + $posting_url = "posting.php?mode=edit&f={$this->data['forums']['Reapprove Test #1']}&p={$this->data['posts']['Re: Reapprove Test Topic #1-#2']}&sid={$this->sid}"; + $form_data = array( + 'message' => 'Post edited by testing framework', + 'subject' => 'Re: Reapprove Test Topic #1-#2', + 'post' => true, + ); + $this->submit_post($posting_url, 'EDIT_POST', $form_data, 'POST_EDITED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertNotContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + $this->assertNotContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'after editing post'); + + // Test editing a topic + $posting_url = "posting.php?mode=edit&f={$this->data['forums']['Reapprove Test #1']}&p={$this->data['posts']['Reapprove Test Topic #2']}&sid={$this->sid}"; + $form_data = array( + 'message' => 'Post edited by testing framework', + 'subject' => 'Reapprove Test Topic #2', + 'post' => true, + ); + $this->submit_post($posting_url, 'EDIT_POST', $form_data, 'POST_EDITED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}", array(), false); + self::assert_response_html(404); + $this->assertNotContains('Reapprove Test Topic #2', $crawler->filter('#page-body')->text()); + $this->assertNotContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after editing topic'); + + $this->logout(); + $this->login(); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + $this->assertContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + } + + public function test_reset_flood_interval() + { + $this->login(); + $this->admin_login(); + + // Set flood interval back to 15 + $this->set_flood_interval(15); + } + + protected function assert_forum_details($forum_id, $details, $additional_error_message = '') + { + $this->db = $this->get_db(); + + $sql = 'SELECT ' . implode(', ', array_keys($details)) . ' + FROM phpbb_forums + WHERE forum_id = ' . (int) $forum_id; + $result = $this->db->sql_query($sql); + $data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); + } + + protected function set_flood_interval($flood_interval) + { + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[flood_interval]"] = $flood_interval; + $form->setValues($values); + $crawler = self::submit($form); + $this->assertGreaterThan(0, $crawler->filter('.successbox')->count()); + } + + protected function load_ids($data) + { + $this->db = $this->get_db(); + + if (!empty($data['forums'])) + { + $sql = 'SELECT * + FROM phpbb_forums + WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['forum_name'], $data['forums'])) + { + $this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['topics'])) + { + $sql = 'SELECT * + FROM phpbb_topics + WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['topic_title'], $data['topics'])) + { + $this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['posts'])) + { + $sql = 'SELECT * + FROM phpbb_posts + WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['post_subject'], $data['posts'])) + { + $this->data['posts'][$row['post_subject']] = (int) $row['post_id']; + } + } + $this->db->sql_freeresult($result); + } + } +} From ddbb521e57e0a6e3accb8fc3aeebe938aacf9000 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 13 Apr 2014 21:09:07 +0200 Subject: [PATCH 14/20] [ticket/12371] Correctly set is_starter when editing first post of the topic PHPBB3-12371 --- phpBB/includes/functions_posting.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 887c73f7de..73e95ae89a 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2049,7 +2049,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // If the post was not approved, it could also be the starter, // so we sync the starter after approving/restoring, to ensure that the stats are correct // Same applies for the last post - $is_starter = ($post_mode == 'edit_first_post' || $data['post_visibility'] != ITEM_APPROVED); + $is_starter = ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED); $is_latest = ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED); $phpbb_content_visibility = $phpbb_container->get('content.visibility'); From 16329c7ad90299a620855252902b3ef4d6959019 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 13 Apr 2014 21:15:08 +0200 Subject: [PATCH 15/20] [ticket/12371] Reapprove the post and topic again in tests PHPBB3-12371 --- tests/functional/visibility_reapprove_test.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/functional/visibility_reapprove_test.php b/tests/functional/visibility_reapprove_test.php index ae97c7e785..70134ef724 100644 --- a/tests/functional/visibility_reapprove_test.php +++ b/tests/functional/visibility_reapprove_test.php @@ -315,6 +315,16 @@ class phpbb_functional_visibility_reapprove_test extends phpbb_functional_test_c $this->assertContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); } + public function test_approve_post_again() + { + $this->test_approve_post(); + } + + public function test_approve_topic_again() + { + $this->test_approve_topic(); + } + public function test_reset_flood_interval() { $this->login(); From 465aa9c346f3d710d6d7e86de1667719d63364a7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 16 Apr 2014 19:47:37 +0200 Subject: [PATCH 16/20] [ticket/12371] Fix language in comment PHPBB3-12371 --- phpBB/phpbb/notification/type/post.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 826be0c992..bb5f3dfc5e 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -433,9 +433,8 @@ class post extends \phpbb\notification\type\base $serialized_data = serialize($this->get_data(false)); - // If the data is longer then 4000 characters, it would cause a SQL error - // so we just don't add the username to the list, when this would be the - // case. + // If the data is longer then 4000 characters, it would cause a SQL error. + // We don't add the username to the list if this is the case. if (utf8_strlen($serialized_data) >= 4000) { return array(); From 40d91a5d6ee26fceed430856532c6786f5dcf954 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 19 Apr 2014 11:14:01 +0200 Subject: [PATCH 17/20] [ticket/12371] Delete the approve_post notification when editing a post We need to delete the initial approve notification, so we can notify the user again, when his post got reapproved. PHPBB3-12371 --- phpBB/includes/functions_posting.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 73e95ae89a..32eb2505f8 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2293,11 +2293,19 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'edit_topic': case 'edit_first_post': $phpbb_notifications->add_notifications('topic_in_queue', $notification_data); + + // Delete the approve_post notification so we can notify the user again, + // when his post got reapproved + $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']); break; case 'edit': case 'edit_last_post': $phpbb_notifications->add_notifications('post_in_queue', $notification_data); + + // Delete the approve_post notification so we can notify the user again, + // when his post got reapproved + $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']); break; case 'post': From 7324cb051f4c655bd8027ab8078a1f5d42b60154 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 19 Apr 2014 11:22:46 +0200 Subject: [PATCH 18/20] [ticket/12371] Fix redirect link for approve_post and post_in_queue PHPBB3-12371 --- phpBB/phpbb/notification/type/approve_post.php | 8 ++++++++ phpBB/phpbb/notification/type/post_in_queue.php | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index e51ff12b3e..5912ad62b4 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -138,4 +138,12 @@ class approve_post extends \phpbb\notification\type\post { return 'post_approved'; } + + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } } diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index db16763583..56dfcce588 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -118,6 +118,14 @@ class post_in_queue extends \phpbb\notification\type\post return append_sid($this->phpbb_root_path . 'mcp.' . $this->php_ext, "i=queue&mode=approve_details&f={$this->get_data('forum_id')}&p={$this->item_id}"); } + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return parent::get_url(); + } + /** * Function for preparing the data for insertion in an SQL query * (The service handles insertion) From 2bb12d0d6f326dcee6e6fe44a99ce3f0dcfd1c23 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 2 May 2014 11:51:20 +0200 Subject: [PATCH 19/20] [ticket/12371] Fix typos in comment PHPBB3-12371 --- phpBB/phpbb/notification/type/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index bb5f3dfc5e..93fbcbde22 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -407,7 +407,7 @@ class post extends \phpbb\notification\type\base $responders = ($responders === null) ? array() : $responders; - // Do not add more then 25 responder, + // Do not add more than 25 responders, // we trim the username list to "a, b, c and x others" anyway // so there is no use to add all of them anyway. if (sizeof($responders) > 25) From 5c7199f3dd1e0dd99c173f90ada615c68d486f51 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 2 May 2014 11:51:40 +0200 Subject: [PATCH 20/20] [ticket/12371] Fix language string PHPBB3-12371 --- phpBB/language/en/common.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 956b593476..356316f35f 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -431,7 +431,7 @@ $lang = array_merge($lang, array( // A and B replied... // A, B and C replied... // A, B, C and 2 others replied... - // A, B, C and many others replied... + // A, B, C and others replied... 'NOTIFICATION_BOOKMARK' => array( 1 => '%1$s replied to the topic “%2$s” you have bookmarked.', ), @@ -457,7 +457,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', 'NOTIFICATION_ADMIN_ACTIVATE_USER' => 'The user “%1$s” is newly registered and requires activation.', // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. - 'NOTIFICATION_MANY_OTHERS' => 'many others', + 'NOTIFICATION_MANY_OTHERS' => 'others', 'NOTIFICATION_X_OTHERS' => array( 2 => '%d others', ),