diff options
107 files changed, 5918 insertions, 1481 deletions
diff --git a/phpBB/config/feed.yml b/phpBB/config/feed.yml index 59eeafd458..5a4cdae815 100644 --- a/phpBB/config/feed.yml +++ b/phpBB/config/feed.yml @@ -23,6 +23,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.forums: @@ -35,6 +36,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.news: @@ -47,6 +49,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.overall: @@ -59,6 +62,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.topic: @@ -71,6 +75,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.topics: @@ -83,6 +88,7 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% feed.topics_active: @@ -95,4 +101,5 @@ services: - @cache.driver - @user - @auth + - @content.visibility - %core.php_ext% diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index e228b3d83f..25fff79de3 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -66,6 +66,19 @@ services: - @dbal.conn - %tables.config_text% + content.visibility: + class: phpbb_content_visibility + arguments: + - @auth + - @dbal.conn + - @user + - %core.root_path% + - %core.php_ext% + - %tables.forums% + - %tables.posts% + - %tables.topics% + - %tables.users% + controller.helper: class: phpbb_controller_helper arguments: diff --git a/phpBB/config/tables.yml b/phpBB/config/tables.yml index ec5fec23ad..fdb448f4e0 100644 --- a/phpBB/config/tables.yml +++ b/phpBB/config/tables.yml @@ -2,10 +2,13 @@ parameters: tables.config: %core.table_prefix%config tables.config_text: %core.table_prefix%config_text tables.ext: %core.table_prefix%ext + tables.forums: %core.table_prefix%forums tables.log: %core.table_prefix%log tables.migrations: %core.table_prefix%migrations tables.modules: %core.table_prefix%modules tables.notification_types: %core.table_prefix%notification_types tables.notifications: %core.table_prefix%notifications + tables.posts: %core.table_prefix%posts + tables.topics: %core.table_prefix%topics tables.user_notifications: %core.table_prefix%user_notifications tables.users: %core.table_prefix%users diff --git a/phpBB/develop/benchmark.php b/phpBB/develop/benchmark.php index c867b9262e..c653fdaa24 100644 --- a/phpBB/develop/benchmark.php +++ b/phpBB/develop/benchmark.php @@ -192,13 +192,13 @@ function get_topic_count($forum_id) { global $db; - $sql = "SELECT forum_topics + $sql = "SELECT forum_topics_approved FROM " . FORUMS_TABLE . " WHERE (forum_id = $forum_id)"; if($result = $db->sql_query($sql)) { $row = $db->sql_fetchrow($result); - $topic_count = $row['forum_topics']; + $topic_count = $row['forum_topics_approved']; unset($result); unset($row); @@ -263,7 +263,7 @@ function make_post($new_topic_id, $forum_id, $user_id, $post_username, $text, $m $post_message = prepare_message($text, $html_on, $bbcode_on, $smilies_on, $bbcode_uid); - $sql = "INSERT INTO " . POSTS_TABLE . " (topic_id, forum_id, poster_id, attach_id, icon_id, post_username, post_time, poster_ip, post_approved, bbcode_uid, enable_bbcode, enable_html, enable_smilies, enable_sig, post_subject, post_text) + $sql = "INSERT INTO " . POSTS_TABLE . " (topic_id, forum_id, poster_id, attach_id, icon_id, post_username, post_time, poster_ip, post_visibility, bbcode_uid, enable_bbcode, enable_html, enable_smilies, enable_sig, post_subject, post_text) VALUES ($new_topic_id, $forum_id, $user_id, 0, 0, '$post_username', $current_time, '$user_ip', 1, '$bbcode_uid', $bbcode_on, $html_on, $smilies_on, $attach_sig, '$post_subject', '$post_message')"; $result = $db->sql_query($sql); @@ -282,10 +282,10 @@ function make_post($new_topic_id, $forum_id, $user_id, $post_username, $text, $m if($db->sql_query($sql)) { $sql = "UPDATE " . FORUMS_TABLE . " - SET forum_last_post_id = $new_post_id, forum_posts = forum_posts + 1"; + SET forum_last_post_id = $new_post_id, forum_posts_approved = forum_posts_approved + 1"; if($mode == "newtopic") { - $sql .= ", forum_topics = forum_topics + 1"; + $sql .= ", forum_topics_approved = forum_topics_approved + 1"; } $sql .= " WHERE forum_id = $forum_id"; diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 0fd1a722ca..316fbe19e6 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1104,9 +1104,12 @@ function get_schema_struct() 'forum_topics_per_page' => array('TINT:4', 0), 'forum_type' => array('TINT:4', 0), 'forum_status' => array('TINT:4', 0), - 'forum_posts' => array('UINT', 0), - 'forum_topics' => array('UINT', 0), - 'forum_topics_real' => array('UINT', 0), + 'forum_posts_approved' => array('UINT', 0), + 'forum_posts_unapproved' => array('UINT', 0), + 'forum_posts_softdeleted' => array('UINT', 0), + 'forum_topics_approved' => array('UINT', 0), + 'forum_topics_unapproved' => array('UINT', 0), + 'forum_topics_softdeleted' => array('UINT', 0), 'forum_last_post_id' => array('UINT', 0), 'forum_last_poster_id' => array('UINT', 0), 'forum_last_post_subject' => array('STEXT_UNI', ''), @@ -1381,7 +1384,7 @@ function get_schema_struct() 'icon_id' => array('UINT', 0), 'poster_ip' => array('VCHAR:40', ''), 'post_time' => array('TIMESTAMP', 0), - 'post_approved' => array('BOOL', 1), + 'post_visibility' => array('TINT:3', 0), 'post_reported' => array('BOOL', 0), 'enable_bbcode' => array('BOOL', 1), 'enable_smilies' => array('BOOL', 1), @@ -1400,6 +1403,9 @@ function get_schema_struct() 'post_edit_user' => array('UINT', 0), 'post_edit_count' => array('USINT', 0), 'post_edit_locked' => array('BOOL', 0), + 'post_delete_time' => array('TIMESTAMP', 0), + 'post_delete_reason' => array('STEXT_UNI', ''), + 'post_delete_user' => array('UINT', 0), ), 'PRIMARY_KEY' => 'post_id', 'KEYS' => array( @@ -1407,7 +1413,7 @@ function get_schema_struct() 'topic_id' => array('INDEX', 'topic_id'), 'poster_ip' => array('INDEX', 'poster_ip'), 'poster_id' => array('INDEX', 'poster_id'), - 'post_approved' => array('INDEX', 'post_approved'), + 'post_visibility' => array('INDEX', 'post_visibility'), 'post_username' => array('INDEX', 'post_username'), 'tid_post_time' => array('INDEX', array('topic_id', 'post_time')), ), @@ -1739,15 +1745,16 @@ function get_schema_struct() 'forum_id' => array('UINT', 0), 'icon_id' => array('UINT', 0), 'topic_attachment' => array('BOOL', 0), - 'topic_approved' => array('BOOL', 1), + 'topic_visibility' => array('TINT:3', 0), 'topic_reported' => array('BOOL', 0), 'topic_title' => array('STEXT_UNI', '', 'true_sort'), 'topic_poster' => array('UINT', 0), 'topic_time' => array('TIMESTAMP', 0), 'topic_time_limit' => array('TIMESTAMP', 0), 'topic_views' => array('UINT', 0), - 'topic_replies' => array('UINT', 0), - 'topic_replies_real' => array('UINT', 0), + 'topic_posts_approved' => array('UINT', 0), + 'topic_posts_unapproved' => array('UINT', 0), + 'topic_posts_softdeleted' => array('UINT', 0), 'topic_status' => array('TINT:3', 0), 'topic_type' => array('TINT:3', 0), 'topic_first_post_id' => array('UINT', 0), @@ -1769,14 +1776,17 @@ function get_schema_struct() 'poll_max_options' => array('TINT:4', 1), 'poll_last_vote' => array('TIMESTAMP', 0), 'poll_vote_change' => array('BOOL', 0), + 'topic_delete_time' => array('TIMESTAMP', 0), + 'topic_delete_reason' => array('STEXT_UNI', ''), + 'topic_delete_user' => array('UINT', 0), ), 'PRIMARY_KEY' => 'topic_id', 'KEYS' => array( 'forum_id' => array('INDEX', 'forum_id'), 'forum_id_type' => array('INDEX', array('forum_id', 'topic_type')), 'last_post_time' => array('INDEX', 'topic_last_post_time'), - 'topic_approved' => array('INDEX', 'topic_approved'), - 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_approved', 'topic_last_post_id')), + 'topic_visibility' => array('INDEX', 'topic_visibility'), + 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_visibility', 'topic_last_post_id')), 'fid_time_moved' => array('INDEX', array('forum_id', 'topic_last_post_time', 'topic_moved_id')), ), ); diff --git a/phpBB/develop/fill.php b/phpBB/develop/fill.php index e3b986e163..696b1e31c0 100644 --- a/phpBB/develop/fill.php +++ b/phpBB/develop/fill.php @@ -86,7 +86,7 @@ switch ($mode) $topic_rows[] = "($topic_id, $forum_id, '$forum_id-$topic_id', " . (($topic_id % 34) ? '0' : '1') . ')'; - $sql = 'INSERT IGNORE INTO ' . POSTS_TABLE . ' (topic_id, forum_id, poster_id, post_subject, post_text, post_username, post_approved, post_time, post_reported) + $sql = 'INSERT IGNORE INTO ' . POSTS_TABLE . ' (topic_id, forum_id, poster_id, post_subject, post_text, post_username, post_visibility, post_time, post_reported) VALUES '; $rows = array(); diff --git a/phpBB/develop/merge_post_tables.php b/phpBB/develop/merge_post_tables.php index 8edc330a0a..d687a292f2 100644 --- a/phpBB/develop/merge_post_tables.php +++ b/phpBB/develop/merge_post_tables.php @@ -50,7 +50,7 @@ switch ($db->sql_layer) ADD PRIMARY KEY (post_id), ADD INDEX topic_id (topic_id), ADD INDEX poster_ip (poster_ip), - ADD INDEX post_approved (post_approved), + ADD INDEX post_visibility (post_visibility), MODIFY COLUMN post_id mediumint(8) UNSIGNED NOT NULL auto_increment, ADD COLUMN post_encoding varchar(11) DEFAULT \'iso-8859-15\' NOT NULL'; break; @@ -162,7 +162,7 @@ while ($row = $db->sql_fetchrow($result)) $forum_id = $row['forum_id']; $sql_ary[] = "UPDATE " . $table_prefix . "forums - SET forum_last_poster_id = " . ((!empty($row['user_id']) && $row['user_id'] != ANONYMOUS) ? $row['user_id'] : ANONYMOUS) . ", forum_last_poster_name = '" . ((!empty($row['user_id']) && $row['user_id'] != ANONYMOUS) ? addslashes($row['username']) : addslashes($row['post_username'])) . "', forum_last_post_time = " . $row['post_time'] . ", forum_posts = " . (($post_count[$forum_id]) ? $post_count[$forum_id] : 0) . ", forum_topics = " . (($topic_count[$forum_id]) ? $topic_count[$forum_id] : 0) . " + SET forum_last_poster_id = " . ((!empty($row['user_id']) && $row['user_id'] != ANONYMOUS) ? $row['user_id'] : ANONYMOUS) . ", forum_last_poster_name = '" . ((!empty($row['user_id']) && $row['user_id'] != ANONYMOUS) ? addslashes($row['username']) : addslashes($row['post_username'])) . "', forum_last_post_time = " . $row['post_time'] . ", forum_posts_approved = " . (($post_count[$forum_id]) ? $post_count[$forum_id] : 0) . ", forum_topics_approved = " . (($topic_count[$forum_id]) ? $topic_count[$forum_id] : 0) . " WHERE forum_id = $forum_id"; $sql = "SELECT t.topic_id, u.username, u.user_id, u2.username as user2, u2.user_id as id2, p.post_username, p2.post_username AS post_username2, p2.post_time diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 7f82ebfeab..597dd5e932 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -552,9 +552,12 @@ function get_schema_struct() 'forum_topics_per_page' => array('TINT:4', 0), 'forum_type' => array('TINT:4', 0), 'forum_status' => array('TINT:4', 0), - 'forum_posts' => array('UINT', 0), - 'forum_topics' => array('UINT', 0), - 'forum_topics_real' => array('UINT', 0), + 'forum_posts_approved' => array('UINT', 0), + 'forum_posts_unapproved' => array('UINT', 0), + 'forum_posts_softdeleted' => array('UINT', 0), + 'forum_topics_approved' => array('UINT', 0), + 'forum_topics_unapproved' => array('UINT', 0), + 'forum_topics_softdeleted' => array('UINT', 0), 'forum_last_post_id' => array('UINT', 0), 'forum_last_poster_id' => array('UINT', 0), 'forum_last_post_subject' => array('STEXT_UNI', ''), @@ -768,7 +771,7 @@ function get_schema_struct() 'icon_id' => array('UINT', 0), 'poster_ip' => array('VCHAR:40', ''), 'post_time' => array('TIMESTAMP', 0), - 'post_approved' => array('BOOL', 1), + 'post_visibility' => array('TINT:3', 0), 'post_reported' => array('BOOL', 0), 'enable_bbcode' => array('BOOL', 1), 'enable_smilies' => array('BOOL', 1), @@ -794,7 +797,7 @@ function get_schema_struct() 'topic_id' => array('INDEX', 'topic_id'), 'poster_ip' => array('INDEX', 'poster_ip'), 'poster_id' => array('INDEX', 'poster_id'), - 'post_approved' => array('INDEX', 'post_approved'), + 'post_visibility' => array('INDEX', 'post_visibility'), 'post_username' => array('INDEX', 'post_username'), 'tid_post_time' => array('INDEX', array('topic_id', 'post_time')), ), @@ -1107,15 +1110,16 @@ function get_schema_struct() 'forum_id' => array('UINT', 0), 'icon_id' => array('UINT', 0), 'topic_attachment' => array('BOOL', 0), - 'topic_approved' => array('BOOL', 1), + 'topic_visibility' => array('TINT:3', 0), 'topic_reported' => array('BOOL', 0), 'topic_title' => array('STEXT_UNI', '', 'true_sort'), 'topic_poster' => array('UINT', 0), 'topic_time' => array('TIMESTAMP', 0), 'topic_time_limit' => array('TIMESTAMP', 0), 'topic_views' => array('UINT', 0), - 'topic_replies' => array('UINT', 0), - 'topic_replies_real' => array('UINT', 0), + 'topic_posts_approved' => array('UINT', 0), + 'topic_posts_unapproved' => array('UINT', 0), + 'topic_posts_softdeleted' => array('UINT', 0), 'topic_status' => array('TINT:3', 0), 'topic_type' => array('TINT:3', 0), 'topic_first_post_id' => array('UINT', 0), @@ -1143,8 +1147,8 @@ function get_schema_struct() 'forum_id' => array('INDEX', 'forum_id'), 'forum_id_type' => array('INDEX', array('forum_id', 'topic_type')), 'last_post_time' => array('INDEX', 'topic_last_post_time'), - 'topic_approved' => array('INDEX', 'topic_approved'), - 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_approved', 'topic_last_post_id')), + 'topic_visibility' => array('INDEX', 'topic_visibility'), + 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_visibility', 'topic_last_post_id')), 'fid_time_moved' => array('INDEX', array('forum_id', 'topic_last_post_time', 'topic_moved_id')), ), ); diff --git a/phpBB/docs/sphinx.sample.conf b/phpBB/docs/sphinx.sample.conf index d1b98d6cbc..620ec25761 100644 --- a/phpBB/docs/sphinx.sample.conf +++ b/phpBB/docs/sphinx.sample.conf @@ -15,6 +15,7 @@ source source_phpbb_{SPHINX_ID}_main p.forum_id, \ p.topic_id, \ p.poster_id, \ + p.post_visibility, \ CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \ p.post_time, \ p.post_subject, \ @@ -32,6 +33,7 @@ source source_phpbb_{SPHINX_ID}_main sql_attr_uint = forum_id sql_attr_uint = topic_id sql_attr_uint = poster_id + sql_attr_uint = post_visibility sql_attr_bool = topic_first_post sql_attr_bool = deleted sql_attr_timestamp = post_time @@ -48,6 +50,7 @@ source source_phpbb_{SPHINX_ID}_delta : source_phpbb_{SPHINX_ID}_main p.forum_id, \ p.topic_id, \ p.poster_id, \ + p.post_visibility, \ CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \ p.post_time, \ p.post_subject, \ diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 7e8d5d8388..970b033995 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -283,7 +283,7 @@ class acp_forums @set_time_limit(0); - $sql = 'SELECT forum_name, forum_topics_real + $sql = 'SELECT forum_name, (forum_topics_approved + forum_topics_unapproved + forum_topics_softdeleted) AS total_topics FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql); @@ -295,7 +295,7 @@ class acp_forums trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } - if ($row['forum_topics_real']) + if ($row['total_topics']) { $sql = 'SELECT MIN(topic_id) as min_topic_id, MAX(topic_id) as max_topic_id FROM ' . TOPICS_TABLE . ' @@ -314,7 +314,6 @@ class acp_forums $end = $start + $batch_size; // Sync all topics in batch mode... - sync('topic_approved', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, false); sync('topic', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, true); if ($end < $row2['max_topic_id']) @@ -330,15 +329,15 @@ class acp_forums $start += $batch_size; - $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync&start=$start&topics_done=$topics_done&total={$row['forum_topics_real']}"; + $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync&start=$start&topics_done=$topics_done&total={$row['total_topics']}"; meta_refresh(0, $url); $template->assign_vars(array( - 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$topics_done&total={$row['forum_topics_real']}", - 'UA_PROGRESS_BAR' => addslashes($this->u_action . "&action=progress_bar&start=$topics_done&total={$row['forum_topics_real']}"), + 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}", + 'UA_PROGRESS_BAR' => addslashes($this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}"), 'S_CONTINUE_SYNC' => true, - 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['forum_topics_real'])) + 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['total_topics'])) ); return; @@ -352,7 +351,7 @@ class acp_forums 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar', 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'), 'S_CONTINUE_SYNC' => true, - 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], 0, $row['forum_topics_real'])) + 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], 0, $row['total_topics'])) ); return; @@ -857,8 +856,8 @@ class acp_forums 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', 'FORUM_NAME' => $row['forum_name'], 'FORUM_DESCRIPTION' => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']), - 'FORUM_TOPICS' => $row['forum_topics'], - 'FORUM_POSTS' => $row['forum_posts'], + 'FORUM_TOPICS' => $row['forum_topics_approved'], + 'FORUM_POSTS' => $row['forum_posts_approved'], 'S_FORUM_LINK' => ($forum_type == FORUM_LINK) ? true : false, 'S_FORUM_POST' => ($forum_type == FORUM_POST) ? true : false, @@ -1144,7 +1143,8 @@ class acp_forums return array($user->lang['NO_FORUM_ACTION']); } - $forum_data_sql['forum_posts'] = $forum_data_sql['forum_topics'] = $forum_data_sql['forum_topics_real'] = $forum_data_sql['forum_last_post_id'] = $forum_data_sql['forum_last_poster_id'] = $forum_data_sql['forum_last_post_time'] = 0; + $forum_data_sql['forum_posts_approved'] = $forum_data_sql['forum_posts_unapproved'] = $forum_data_sql['forum_posts_softdeleted'] = $forum_data_sql['forum_topics_approved'] = $forum_data_sql['forum_topics_unapproved'] = $forum_data_sql['forum_topics_softdeleted'] = 0; + $forum_data_sql['forum_last_post_id'] = $forum_data_sql['forum_last_poster_id'] = $forum_data_sql['forum_last_post_time'] = 0; $forum_data_sql['forum_last_poster_name'] = $forum_data_sql['forum_last_poster_colour'] = ''; } else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_LINK) @@ -1264,9 +1264,12 @@ class acp_forums else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_POST) { // Changing a category to a forum? Reset the data (you can't post directly in a cat, you must use a forum) - $forum_data_sql['forum_posts'] = 0; - $forum_data_sql['forum_topics'] = 0; - $forum_data_sql['forum_topics_real'] = 0; + $forum_data_sql['forum_posts_approved'] = 0; + $forum_data_sql['forum_posts_unapproved'] = 0; + $forum_data_sql['forum_posts_softdeleted'] = 0; + $forum_data_sql['forum_topics_approved'] = 0; + $forum_data_sql['forum_topics_unapproved'] = 0; + $forum_data_sql['forum_topics_softdeleted'] = 0; $forum_data_sql['forum_last_post_id'] = 0; $forum_data_sql['forum_last_post_subject'] = ''; $forum_data_sql['forum_last_post_time'] = 0; @@ -1793,7 +1796,7 @@ class acp_forums FROM ' . POSTS_TABLE . ' WHERE forum_id = ' . $forum_id . ' AND post_postcount = 1 - AND post_approved = 1'; + AND post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $post_counts = array(); @@ -1931,7 +1934,7 @@ class acp_forums // Make sure the overall post/topic count is correct... $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' - WHERE post_approved = 1'; + WHERE post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -1940,7 +1943,7 @@ class acp_forums $sql = 'SELECT COUNT(topic_id) AS stat FROM ' . TOPICS_TABLE . ' - WHERE topic_approved = 1'; + WHERE topic_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index c44bc1b8a6..64c2b338fd 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -144,14 +144,14 @@ class acp_main $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' - WHERE post_approved = 1'; + WHERE post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); set_config('num_posts', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); $sql = 'SELECT COUNT(topic_id) AS stat FROM ' . TOPICS_TABLE . ' - WHERE topic_approved = 1'; + WHERE topic_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); set_config('num_topics', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); @@ -232,7 +232,7 @@ class acp_main $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id FROM ' . POSTS_TABLE . ' WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' - AND post_postcount = 1 AND post_approved = 1 + AND post_postcount = 1 AND post_visibility = ' . ITEM_APPROVED . ' GROUP BY poster_id'; $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index c8542ddbe7..cbfd578d87 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -624,29 +624,31 @@ class acp_users $topic_id_ary = $move_topic_ary = $move_post_ary = $new_topic_id_ary = array(); $forum_id_ary = array($new_forum_id); - $sql = 'SELECT topic_id, COUNT(post_id) AS total_posts + $sql = 'SELECT topic_id, post_visibility, COUNT(post_id) AS total_posts FROM ' . POSTS_TABLE . " WHERE poster_id = $user_id AND forum_id <> $new_forum_id - GROUP BY topic_id"; + GROUP BY topic_id, post_visibility"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $topic_id_ary[$row['topic_id']] = $row['total_posts']; + $topic_id_ary[$row['topic_id']][$row['post_visibility']] = $row['total_posts']; } $db->sql_freeresult($result); if (sizeof($topic_id_ary)) { - $sql = 'SELECT topic_id, forum_id, topic_title, topic_replies, topic_replies_real, topic_attachment + $sql = 'SELECT topic_id, forum_id, topic_title, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_attachment FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', array_keys($topic_id_ary)); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']]) + 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_DELETED] == $row['topic_posts_softdeleted']) { $move_topic_ary[] = $row['topic_id']; } @@ -679,7 +681,7 @@ class acp_users 'topic_time' => time(), 'forum_id' => $new_forum_id, 'icon_id' => 0, - 'topic_approved' => 1, + 'topic_visibility' => ITEM_APPROVED, 'topic_title' => $post_ary['title'], 'topic_first_poster_name' => $user_row['username'], 'topic_type' => POST_NORMAL, @@ -1036,7 +1038,7 @@ class acp_users $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_approved = 0'; + AND post_visibility = ' . ITEM_UNAPPROVED; $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 96011f4ec5..c1f4c6ac0e 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -87,6 +87,10 @@ define('ITEM_UNLOCKED', 0); define('ITEM_LOCKED', 1); 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 + // Forum Flags define('FORUM_FLAG_LINK_TRACK', 1); define('FORUM_FLAG_PRUNE_POLL', 2); diff --git a/phpBB/includes/content_visibility.php b/phpBB/includes/content_visibility.php new file mode 100644 index 0000000000..4ad5f6793e --- /dev/null +++ b/phpBB/includes/content_visibility.php @@ -0,0 +1,651 @@ +<?php +/** +* +* @package phpbb +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* phpbb_visibility +* Handle fetching and setting the visibility for topics and posts +* @package phpbb +*/ +class phpbb_content_visibility +{ + /** + * Database object + * @var phpbb_db_driver + */ + protected $db; + + /** + * User object + * @var phpbb_user + */ + protected $user; + + /** + * Auth object + * @var phpbb_auth + */ + protected $auth; + + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP Extension + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param phpbb_auth $auth Auth object + * @param phpbb_db_driver $db Database object + * @param phpbb_user $user User object + * @param string $phpbb_root_path Root path + * @param string $php_ext PHP Extension + * @return null + */ + public function __construct(phpbb_auth $auth, phpbb_db_driver $db, phpbb_user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) + { + $this->auth = $auth; + $this->db = $db; + $this->user = $user; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->forums_table = $forums_table; + $this->posts_table = $posts_table; + $this->topics_table = $topics_table; + $this->users_table = $users_table; + } + + /** + * Can the current logged-in user soft-delete posts? + * + * @param $forum_id int Forum ID whose permissions to check + * @param $poster_id int Poster ID of the post in question + * @param $post_locked bool Is the post locked? + * @return bool + */ + public function can_soft_delete($forum_id, $poster_id, $post_locked) + { + if ($this->auth->acl_get('m_softdelete', $forum_id)) + { + return true; + } + else if ($this->auth->acl_get('f_softdelete', $forum_id) && $poster_id == $this->user->data['user_id'] && !$post_locked) + { + return true; + } + + return false; + } + + /** + * Get the topics post count or the forums post/topic count based on permissions + * + * @param $mode string One of topic_posts, forum_posts or forum_topics + * @param $data array Array with the topic/forum data to calculate from + * @param $forum_id int The forum id is used for permission checks + * @return int Number of posts/topics the user can see in the topic/forum + */ + public function get_count($mode, $data, $forum_id) + { + if (!$this->auth->acl_get('m_approve', $forum_id)) + { + return (int) $data[$mode . '_approved']; + } + + return (int) $data[$mode . '_approved'] + (int) $data[$mode . '_unapproved'] + (int) $data[$mode . '_softdeleted']; + } + + /** + * Create topic/post visibility SQL for a given forum ID + * + * Note: Read permissions are not checked. + * + * @param $mode string Either "topic" or "post" + * @param $forum_id int The forum id is used for permission checks + * @param $table_alias string Table alias to prefix in SQL queries + * @return string The appropriate combination SQL logic for topic/post_visibility + */ + public function get_visibility_sql($mode, $forum_id, $table_alias = '') + { + if ($this->auth->acl_get('m_approve', $forum_id)) + { + return '1 = 1'; + } + + return $table_alias . $mode . '_visibility = ' . ITEM_APPROVED; + } + + /** + * Create topic/post visibility SQL for a set of forums + * + * Note: Read permissions are not checked. Forums without read permissions + * should not be in $forum_ids + * + * @param $mode string Either "topic" or "post" + * @param $forum_ids array Array of forum ids which the posts/topics are limited to + * @param $table_alias string Table alias to prefix in SQL queries + * @return string The appropriate combination SQL logic for topic/post_visibility + */ + public function get_forums_visibility_sql($mode, $forum_ids = array(), $table_alias = '') + { + $where_sql = '('; + + $approve_forums = array_intersect($forum_ids, array_keys($this->auth->acl_getf('m_approve', true))); + + if (sizeof($approve_forums)) + { + // Remove moderator forums from the rest + $forum_ids = array_diff($forum_ids, $approve_forums); + + if (!sizeof($forum_ids)) + { + // The user can see all posts/topics in all specified forums + return $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums); + } + else + { + // Moderator can view all posts/topics in some forums + $where_sql .= $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums) . ' OR '; + } + } + else + { + // The user is just a normal user + return $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ' + AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids, false, true); + } + + $where_sql .= '(' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ' + AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids) . '))'; + + return $where_sql; + } + + /** + * Create topic/post visibility SQL for all forums on the board + * + * Note: Read permissions are not checked. Forums without read permissions + * should be in $exclude_forum_ids + * + * @param $mode string Either "topic" or "post" + * @param $exclude_forum_ids array Array of forum ids which are excluded + * @param $table_alias string Table alias to prefix in SQL queries + * @return string The appropriate combination SQL logic for topic/post_visibility + */ + public function get_global_visibility_sql($mode, $exclude_forum_ids = array(), $table_alias = '') + { + $where_sqls = array(); + + $approve_forums = array_diff(array_keys($this->auth->acl_getf('m_approve', true)), $exclude_forum_ids); + + if (sizeof($exclude_forum_ids)) + { + $where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true) . ' + AND ' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ')'; + } + else + { + $where_sqls[] = $table_alias . $mode . '_visibility = ' . ITEM_APPROVED; + } + + if (sizeof($approve_forums)) + { + $where_sqls[] = $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums); + return '(' . implode(' OR ', $where_sqls) . ')'; + } + + // There is only one element, so we just return that one + return $where_sqls[0]; + } + + /** + * Change visibility status of one post or all posts of a topic + * + * @param $visibility int Element of {ITEM_APPROVED, 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 + * @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 $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. + */ + 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))) + { + return array(); + } + + if ($post_id) + { + if (is_array($post_id)) + { + $where_sql = $this->db->sql_in_set('post_id', array_map('intval', $post_id)); + } + else + { + $where_sql = 'post_id = ' . (int) $post_id; + } + $where_sql .= ' AND topic_id = ' . (int) $topic_id; + } + else + { + $where_sql = 'topic_id = ' . (int) $topic_id; + + // Limit the posts to a certain visibility and deletion time + // This allows us to only restore posts, that were approved + // when the topic got soft deleted. So previous soft deleted + // and unapproved posts are still soft deleted/unapproved + if ($limit_visibility !== false) + { + $where_sql .= ' AND post_visibility = ' . (int) $limit_visibility; + } + + if ($limit_delete_time !== false) + { + $where_sql .= ' AND post_delete_time = ' . (int) $limit_delete_time; + } + } + + $sql = 'SELECT poster_id, post_id, post_postcount, post_visibility + FROM ' . $this->posts_table . ' + WHERE ' . $where_sql; + $result = $this->db->sql_query($sql); + + $post_ids = $poster_postcounts = $postcounts = $postcount_visibility = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $post_ids[] = (int) $row['post_id']; + + if ($row['post_visibility'] != $visibility) + { + if ($row['post_postcount'] && !isset($poster_postcounts[(int) $row['poster_id']])) + { + $poster_postcounts[(int) $row['poster_id']] = 1; + } + else if ($row['post_postcount']) + { + $poster_postcounts[(int) $row['poster_id']]++; + } + + if (!isset($postcount_visibility[$row['post_visibility']])) + { + $postcount_visibility[$row['post_visibility']] = 1; + } + else + { + $postcount_visibility[$row['post_visibility']]++; + } + } + } + $this->db->sql_freeresult($result); + + if (empty($post_ids)) + { + return array(); + } + + $data = array( + 'post_visibility' => (int) $visibility, + 'post_delete_user' => (int) $user_id, + 'post_delete_time' => ((int) $time) ?: time(), + 'post_delete_reason' => truncate_string($reason, 255, 255, false), + ); + + $sql = 'UPDATE ' . $this->posts_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $data) . ' + WHERE ' . $this->db->sql_in_set('post_id', $post_ids); + $this->db->sql_query($sql); + + // Group the authors by post count, to reduce the number of queries + foreach ($poster_postcounts as $poster_id => $num_posts) + { + $postcounts[$num_posts][] = $poster_id; + } + + // Update users postcounts + foreach ($postcounts as $num_posts => $poster_ids) + { + if ($visibility == ITEM_DELETED) + { + $sql = 'UPDATE ' . $this->users_table . ' + SET user_posts = 0 + WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . ' + AND user_posts < ' . $num_posts; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . $this->users_table . ' + SET user_posts = user_posts - ' . $num_posts . ' + WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . ' + AND user_posts >= ' . $num_posts; + $this->db->sql_query($sql); + } + else + { + $sql = 'UPDATE ' . $this->users_table . ' + SET user_posts = user_posts + ' . $num_posts . ' + WHERE ' . $this->db->sql_in_set('user_id', $poster_ids); + $this->db->sql_query($sql); + } + } + + $update_topic_postcount = true; + + // Sync the first/last topic information if needed + if (!$is_starter && $is_latest) + { + // update_post_information can only update the last post info ... + if ($topic_id) + { + update_post_information('topic', $topic_id, false); + } + if ($forum_id) + { + update_post_information('forum', $forum_id, false); + } + } + else if ($is_starter && $topic_id) + { + if (!function_exists('sync')) + { + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); + } + + // ... so we need to use sync, if the first post is changed. + // The forum is resynced recursive by sync() itself. + sync('topic', 'topic_id', $topic_id, true); + + // sync recalculates the topic replies and forum posts by itself, so we don't do that. + $update_topic_postcount = false; + } + + // 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; + 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; + } + } + + $sql_ary = array(); + if ($visibility == ITEM_DELETED) + { + if ($cur_posts) + { + $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); + } + } + else + { + 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); + } + } + + if (sizeof($sql_ary)) + { + $topic_sql = $forum_sql = array(); + + foreach ($sql_ary as $field => $value_change) + { + $topic_sql[] = 'topic_' . $field . ' = topic_' . $field . $value_change; + $forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change; + } + + // Update the number for replies and posts + $sql = 'UPDATE ' . $this->topics_table . ' + SET ' . implode(', ', $topic_sql) . ' + WHERE topic_id = ' . (int) $topic_id; + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . $this->forums_table . ' + SET ' . implode(', ', $forum_sql) . ' + WHERE forum_id = ' . (int) $forum_id; + $this->db->sql_query($sql); + } + } + + return $data; + } + + /** + * Set topic visibility + * + * Allows approving (which is akin to undeleting/restore) or soft deleting an entire topic. + * Calls set_post_visibility as needed. + * + * Note: By default, when a soft deleted topic is restored. Only posts that + * were approved at the time of soft deleting, are being restored. + * Same applies to soft deleting. Only approved posts will be marked + * as soft deleted. + * If you want to update all posts, use the force option. + * + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @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 + * @param $time int Timestamp when the action is performed + * @param $reason string Reason why the visibilty was changed. + * @param $force_update_all bool Force to update all posts within the topic + * @return array Changed topic data, empty array if an error occured. + */ + 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))) + { + return array(); + } + + if (!$force_update_all) + { + $sql = 'SELECT topic_visibility, topic_delete_time + FROM ' . $this->topics_table . ' + WHERE topic_id = ' . (int) $topic_id; + $result = $this->db->sql_query($sql); + $original_topic_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$original_topic_data) + { + // The topic does not exist... + return array(); + } + } + + // Note, we do not set a reason for the posts, just for the topic + $data = array( + 'topic_visibility' => (int) $visibility, + 'topic_delete_user' => (int) $user_id, + 'topic_delete_time' => ((int) $time) ?: time(), + 'topic_delete_reason' => truncate_string($reason, 255, 255, false), + ); + + $sql = 'UPDATE ' . $this->topics_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $data) . ' + WHERE topic_id = ' . (int) $topic_id; + $this->db->sql_query($sql); + + if (!$this->db->sql_affectedrows()) + { + return array(); + } + + if (!$force_update_all && $original_topic_data['topic_delete_time'] && $original_topic_data['topic_visibility'] == ITEM_DELETED && $visibility == ITEM_APPROVED) + { + // If we're restoring a topic we only restore posts, that were soft deleted through the topic soft deletion. + self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility'], $original_topic_data['topic_delete_time']); + } + 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. + self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); + } + else + { + self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true); + } + + return $data; + } + + /** + * Add post to topic and forum statistics + * + * @param $data array Contains information from the topics table about given topic + * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @return void + */ + public function add_post_to_statistic($data, &$sql_data) + { + $sql_data[$this->topics_table] = (($sql_data[$this->topics_table]) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved + 1'; + + $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved + 1'; + + if ($data['post_postcount']) + { + $sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1'; + } + + set_config_count('num_posts', 1, true); + } + + /** + * Remove post from topic and forum statistics + * + * @param $data array Contains information from the topics table about given topic + * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @return void + */ + public function remove_post_from_statistic($data, &$sql_data) + { + $sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1'; + $sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1'; + + if ($data['post_postcount']) + { + $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; + } + + set_config_count('num_posts', -1, true); + } + + /** + * Remove topic from forum statistics + * + * @param $topic_id int The topic to act on + * @param $forum_id int Forum where the topic is found + * @param $topic_row array Contains information from the topic, may be empty at call time + * @param $sql_data array Populated with the SQL changes, may be empty at call time + * @return void + */ + public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data) + { + // Do we need to grab some topic informations? + if (!sizeof($topic_row)) + { + $sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility + FROM ' . $this->topics_table . ' + WHERE topic_id = ' . (int) $topic_id; + $result = $this->db->sql_query($sql); + $topic_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + } + + // If this is an edited topic or the first post the topic gets completely disapproved later on... + $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1'; + $sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved']; + $sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved']; + $sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted']; + + set_config_count('num_topics', -1, true); + set_config_count('num_posts', $topic_row['topic_posts_approved'] * (-1), true); + + // Get user post count information + $sql = 'SELECT poster_id, COUNT(post_id) AS num_posts + FROM ' . $this->posts_table . ' + WHERE topic_id = ' . (int) $topic_id . ' + AND post_postcount = 1 + AND post_visibility = ' . ITEM_APPROVED . ' + GROUP BY poster_id'; + $result = $this->db->sql_query($sql); + + $postcounts = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $postcounts[(int) $row['num_posts']][] = (int) $row['poster_id']; + } + $this->db->sql_freeresult($result); + + // Decrement users post count + foreach ($postcounts as $num_posts => $poster_ids) + { + $sql = 'UPDATE ' . $this->users_table . ' + SET user_posts = 0 + WHERE user_posts < ' . $num_posts . ' + AND ' . $this->db->sql_in_set('user_id', $poster_ids); + $this->db->sql_query($sql); + + $sql = 'UPDATE ' . $this->users_table . ' + SET user_posts = user_posts - ' . $num_posts . ' + WHERE user_posts >= ' . $num_posts . ' + AND ' . $this->db->sql_in_set('user_id', $poster_ids); + $this->db->sql_query($sql); + } + } +} diff --git a/phpBB/includes/db/migration/data/310/softdelete_p1.php b/phpBB/includes/db/migration/data/310/softdelete_p1.php new file mode 100644 index 0000000000..84f8eebd4a --- /dev/null +++ b/phpBB/includes/db/migration/data/310/softdelete_p1.php @@ -0,0 +1,171 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +class phpbb_db_migration_data_310_softdelete_p1 extends phpbb_db_migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_visibility'); + } + + static public function depends_on() + { + return array('phpbb_db_migration_data_310_dev'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'forums' => array( + 'forum_posts_approved' => array('UINT', 0), + 'forum_posts_unapproved' => array('UINT', 0), + 'forum_posts_softdeleted' => array('UINT', 0), + 'forum_topics_approved' => array('UINT', 0), + 'forum_topics_unapproved' => array('UINT', 0), + 'forum_topics_softdeleted' => array('UINT', 0), + ), + $this->table_prefix . 'posts' => array( + 'post_visibility' => array('TINT:3', 0), + 'post_delete_time' => array('TIMESTAMP', 0), + 'post_delete_reason' => array('STEXT_UNI', ''), + 'post_delete_user' => array('UINT', 0), + ), + $this->table_prefix . 'topics' => array( + 'topic_visibility' => array('TINT:3', 0), + 'topic_delete_time' => array('TIMESTAMP', 0), + 'topic_delete_reason' => array('STEXT_UNI', ''), + 'topic_delete_user' => array('UINT', 0), + 'topic_posts_approved' => array('UINT', 0), + 'topic_posts_unapproved' => array('UINT', 0), + 'topic_posts_softdeleted' => array('UINT', 0), + ), + ), + 'add_index' => array( + $this->table_prefix . 'posts' => array( + 'post_visibility' => array('post_visibility'), + ), + $this->table_prefix . 'topics' => array( + 'topic_visibility' => array('topic_visibility'), + 'forum_vis_last' => array('forum_id', 'topic_visibility', 'topic_last_post_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'forums' => array( + 'forum_posts_approved', + 'forum_posts_unapproved', + 'forum_posts_softdeleted', + 'forum_topics_approved', + 'forum_topics_unapproved', + 'forum_topics_softdeleted', + ), + $this->table_prefix . 'posts' => array( + 'post_visibility', + 'post_delete_time', + 'post_delete_reason', + 'post_delete_user', + ), + $this->table_prefix . 'topics' => array( + 'topic_visibility', + 'topic_delete_time', + 'topic_delete_reason', + 'topic_delete_user', + 'topic_posts_approved', + 'topic_posts_unapproved', + 'topic_posts_softdeleted', + ), + ), + 'drop_keys' => array( + $this->table_prefix . 'posts' => array('post_visibility'), + $this->table_prefix . 'topics' => array('topic_visibility', 'forum_vis_last'), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_post_visibility'))), + array('custom', array(array($this, 'update_topic_visibility'))), + array('custom', array(array($this, 'update_topic_forum_counts'))), + + array('permission.add', array('f_softdelete', false)), + array('permission.add', array('m_softdelete', false)), + ); + } + + public function update_post_visibility() + { + $sql = 'UPDATE ' . $this->table_prefix . 'posts + SET post_visibility = post_approved'; + $this->sql_query($sql); + } + + public function update_topic_visibility() + { + $sql = 'UPDATE ' . $this->table_prefix . 'topics + SET topic_visibility = topic_approved'; + $this->sql_query($sql); + } + + public function update_topic_forum_counts() + { + $sql = 'UPDATE ' . $this->table_prefix . 'topics + SET topic_posts_approved = topic_replies + 1, + topic_posts_unapproved = topic_replies_real - topic_replies + WHERE topic_visibility = ' . ITEM_APPROVED; + $this->sql_query($sql); + + $sql = 'UPDATE ' . $this->table_prefix . 'topics + SET topic_posts_approved = 0, + topic_posts_unapproved = (topic_replies_real - topic_replies) + 1 + WHERE topic_visibility = ' . ITEM_UNAPPROVED; + $this->sql_query($sql); + + $sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS sum_topics, SUM(topic_posts_approved) AS sum_posts_approved, SUM(topic_posts_unapproved) AS sum_posts_unapproved + FROM ' . $this->table_prefix . 'topics + GROUP BY forum_id, topic_visibility'; + $result = $this->db->sql_query($sql); + + $update_forums = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $forum_id = (int) $row['forum_id']; + if (!isset($update_forums[$forum_id])) + { + $update_forums[$forum_id] = array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + ); + } + + $update_forums[$forum_id]['forum_posts_approved'] += (int) $row['sum_posts_approved']; + $update_forums[$forum_id]['forum_posts_unapproved'] += (int) $row['sum_posts_unapproved']; + + $update_forums[$forum_id][(($row['topic_visibility'] == ITEM_APPROVED) ? 'forum_topics_approved' : 'forum_topics_unapproved')] += (int) $row['sum_topics']; + } + $this->db->sql_freeresult($result); + + foreach ($update_forums as $forum_id => $forum_data) + { + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $forum_data) . ' + WHERE forum_id = ' . $forum_id; + $this->sql_query($sql); + } + } +} diff --git a/phpBB/includes/db/migration/data/310/softdelete_p2.php b/phpBB/includes/db/migration/data/310/softdelete_p2.php new file mode 100644 index 0000000000..7320a2c2bf --- /dev/null +++ b/phpBB/includes/db/migration/data/310/softdelete_p2.php @@ -0,0 +1,68 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +class phpbb_db_migration_data_310_softdelete_p2 extends phpbb_db_migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_approved'); + } + + static public function depends_on() + { + return array( + 'phpbb_db_migration_data_310_dev', + 'phpbb_db_migration_data_310_softdelete_p1', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'forums' => array('forum_posts', 'forum_topics', 'forum_topics_real'), + $this->table_prefix . 'posts' => array('post_approved'), + $this->table_prefix . 'topics' => array('topic_approved', 'topic_replies', 'topic_replies_real'), + ), + 'drop_keys' => array( + $this->table_prefix . 'posts' => array('post_approved'), + $this->table_prefix . 'topics' => array('forum_appr_last'), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'forums' => array( + 'forum_posts' => array('UINT', 0), + 'forum_topics' => array('UINT', 0), + 'forum_topics_real' => array('UINT', 0), + ), + $this->table_prefix . 'posts' => array( + 'post_approved' => array('BOOL', 1), + ), + $this->table_prefix . 'topics' => array( + 'topic_approved' => array('BOOL', 1), + 'topic_replies' => array('UINT', 0), + 'topic_replies_real' => array('UINT', 0), + ), + ), + 'add_index' => array( + $this->table_prefix . 'posts' => array( + 'post_approved' => array('post_approved'), + ), + $this->table_prefix . 'topics' => array( + 'forum_appr_last' => array('forum_id', 'topic_approved', 'topic_last_post_id'), + ), + ), + ); + } +} diff --git a/phpBB/includes/feed/base.php b/phpBB/includes/feed/base.php index af28ee8dc8..296d830932 100644 --- a/phpBB/includes/feed/base.php +++ b/phpBB/includes/feed/base.php @@ -80,10 +80,11 @@ abstract class phpbb_feed_base * @param phpbb_cache_driver_interface $cache Cache object * @param phpbb_user $user User object * @param phpbb_auth $auth Auth object + * @param phpbb_content_visibility $content_visibility Auth object * @param string $phpEx php file extension * @return null */ - function __construct(phpbb_feed_helper $helper, phpbb_config $config, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, phpbb_user $user, phpbb_auth $auth, $phpEx) + function __construct(phpbb_feed_helper $helper, phpbb_config $config, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, phpbb_user $user, phpbb_auth $auth, phpbb_content_visibility $content_visibility, $phpEx) { $this->config = $config; $this->helper = $helper; @@ -91,6 +92,7 @@ abstract class phpbb_feed_base $this->cache = $cache; $this->user = $user; $this->auth = $auth; + $this->content_visibility = $content_visibility; $this->phpEx = $phpEx; $this->set_keys(); diff --git a/phpBB/includes/feed/forum.php b/phpBB/includes/feed/forum.php index 7670fbeaaa..b5f0dd0f8f 100644 --- a/phpBB/includes/feed/forum.php +++ b/phpBB/includes/feed/forum.php @@ -90,14 +90,12 @@ class phpbb_feed_forum extends phpbb_feed_post_base function get_sql() { - $m_approve = ($this->auth->acl_get('m_approve', $this->forum_id)) ? true : false; - // Determine topics with recent activity $sql = 'SELECT topic_id, topic_last_post_time FROM ' . TOPICS_TABLE . ' WHERE forum_id = ' . $this->forum_id . ' AND topic_moved_id = 0 - ' . ((!$m_approve) ? 'AND topic_approved = 1' : '') . ' + AND ' . $this->content_visibility->get_visibility_sql('topic', $this->forum_id) . ' ORDER BY topic_last_post_time DESC'; $result = $this->db->sql_query_limit($sql, $this->num_items); @@ -117,14 +115,14 @@ class phpbb_feed_forum extends phpbb_feed_post_base } $this->sql = array( - 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . 'u.username, u.user_id', 'FROM' => array( POSTS_TABLE => 'p', USERS_TABLE => 'u', ), 'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . ' - ' . ((!$m_approve) ? 'AND p.post_approved = 1' : '') . ' + AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . ' AND p.post_time >= ' . $min_post_time . ' AND p.poster_id = u.user_id', 'ORDER_BY' => 'p.post_time DESC', diff --git a/phpBB/includes/feed/forums.php b/phpBB/includes/feed/forums.php index 72f786aa6a..409097a9f3 100644 --- a/phpBB/includes/feed/forums.php +++ b/phpBB/includes/feed/forums.php @@ -49,7 +49,7 @@ class phpbb_feed_forums extends phpbb_feed_base $this->sql = array( 'SELECT' => 'f.forum_id, f.left_id, f.forum_name, f.forum_last_post_time, f.forum_desc, f.forum_desc_bitfield, f.forum_desc_uid, f.forum_desc_options, - f.forum_topics, f.forum_posts', + f.forum_topics_approved, f.forum_posts_approved', 'FROM' => array(FORUMS_TABLE => 'f'), 'WHERE' => 'f.forum_type = ' . FORUM_POST . ' AND ' . $this->db->sql_in_set('f.forum_id', $in_fid_ary), @@ -65,8 +65,8 @@ class phpbb_feed_forums extends phpbb_feed_base if ($this->config['feed_item_statistics']) { - $item_row['statistics'] = $this->user->lang('TOTAL_TOPICS', (int) $row['forum_topics']) - . ' ' . $this->separator_stats . ' ' . $this->user->lang('TOTAL_POSTS_COUNT', (int) $row['forum_posts']); + $item_row['statistics'] = $this->user->lang('TOTAL_TOPICS', (int) $row['forum_topics_approved']) + . ' ' . $this->separator_stats . ' ' . $this->user->lang('TOTAL_POSTS_COUNT', (int) $row['forum_posts_approved']); } } } diff --git a/phpBB/includes/feed/news.php b/phpBB/includes/feed/news.php index 92cc18a3ab..f2d45b5165 100644 --- a/phpBB/includes/feed/news.php +++ b/phpBB/includes/feed/news.php @@ -72,7 +72,7 @@ class phpbb_feed_news extends phpbb_feed_topic_base FROM ' . TOPICS_TABLE . ' WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . ' AND topic_moved_id = 0 - AND topic_approved = 1 + AND topic_visibility = ' . ITEM_APPROVED . ' ORDER BY topic_time DESC'; $result = $this->db->sql_query_limit($sql, $this->num_items); @@ -90,7 +90,7 @@ class phpbb_feed_news extends phpbb_feed_topic_base $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, - t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time, + 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', 'FROM' => array( TOPICS_TABLE => 't', diff --git a/phpBB/includes/feed/overall.php b/phpBB/includes/feed/overall.php index 5fb922f6bb..869df7cde0 100644 --- a/phpBB/includes/feed/overall.php +++ b/phpBB/includes/feed/overall.php @@ -33,17 +33,11 @@ class phpbb_feed_overall extends phpbb_feed_post_base return false; } - // m_approve forums - $fid_m_approve = $this->get_moderator_approve_forums(); - $sql_m_approve = (!empty($fid_m_approve)) ? 'OR ' . $this->db->sql_in_set('forum_id', $fid_m_approve) : ''; - // Determine topics with recent activity $sql = 'SELECT topic_id, topic_last_post_time FROM ' . TOPICS_TABLE . ' - WHERE ' . $this->db->sql_in_set('forum_id', $forum_ids) . ' - AND topic_moved_id = 0 - AND (topic_approved = 1 - ' . $sql_m_approve . ') + WHERE topic_moved_id = 0 + AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $forum_ids) . ' ORDER BY topic_last_post_time DESC'; $result = $this->db->sql_query_limit($sql, $this->num_items); @@ -65,7 +59,7 @@ class phpbb_feed_overall extends phpbb_feed_post_base // Get the actual data $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, ' . - 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . 'u.username, u.user_id', 'FROM' => array( USERS_TABLE => 'u', @@ -78,8 +72,7 @@ class phpbb_feed_overall extends phpbb_feed_post_base ), ), 'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . ' - AND (p.post_approved = 1 - ' . str_replace('forum_id', 'p.forum_id', $sql_m_approve) . ') + AND ' . $this->content_visibility->get_visibility_sql('post', array(), 'p.') . ' AND p.post_time >= ' . $min_post_time . ' AND u.user_id = p.poster_id', 'ORDER_BY' => 'p.post_time DESC', diff --git a/phpBB/includes/feed/post_base.php b/phpBB/includes/feed/post_base.php index a25ed50263..1f4cb4b5ef 100644 --- a/phpBB/includes/feed/post_base.php +++ b/phpBB/includes/feed/post_base.php @@ -51,7 +51,7 @@ abstract class phpbb_feed_post_base extends phpbb_feed_base { $item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row) . ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')]) - . (($this->is_moderator_approve_forum($row['forum_id']) && !$row['post_approved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : ''); + . (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : ''); } } } diff --git a/phpBB/includes/feed/topic.php b/phpBB/includes/feed/topic.php index 7d9a344982..36f958ac60 100644 --- a/phpBB/includes/feed/topic.php +++ b/phpBB/includes/feed/topic.php @@ -43,7 +43,7 @@ class phpbb_feed_topic extends phpbb_feed_post_base function open() { - $sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_approved, t.topic_title, t.topic_time, t.topic_views, t.topic_replies, t.topic_type + $sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_visibility, t.topic_title, t.topic_time, t.topic_views, t.topic_replies, t.topic_type FROM ' . TOPICS_TABLE . ' t LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id) @@ -94,14 +94,14 @@ class phpbb_feed_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_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . 'u.username, u.user_id', 'FROM' => array( POSTS_TABLE => 'p', USERS_TABLE => 'u', ), 'WHERE' => 'p.topic_id = ' . $this->topic_id . ' - ' . ($this->forum_id && !$this->auth->acl_get('m_approve', $this->forum_id) ? 'AND p.post_approved = 1' : '') . ' + AND ' . $this->content_visibility->get_visibility_sql('post', $this->forum_id, 'p.') . ' AND p.poster_id = u.user_id', 'ORDER_BY' => 'p.post_time DESC', ); diff --git a/phpBB/includes/feed/topic_base.php b/phpBB/includes/feed/topic_base.php index e6a47b4c86..b104a46631 100644 --- a/phpBB/includes/feed/topic_base.php +++ b/phpBB/includes/feed/topic_base.php @@ -51,9 +51,9 @@ abstract class phpbb_feed_topic_base extends phpbb_feed_base { $item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row) . ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')]) - . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . (($this->is_moderator_approve_forum($row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies']) + . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . $this->content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1 . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views'] - . (($this->is_moderator_approve_forum($row['forum_id']) && ($row['topic_replies_real'] != $row['topic_replies'])) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : ''); + . (($this->is_moderator_approve_forum($row['forum_id']) && $row['topic_posts_unapproved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : ''); } } } diff --git a/phpBB/includes/feed/topics.php b/phpBB/includes/feed/topics.php index c8761d7176..31f5177773 100644 --- a/phpBB/includes/feed/topics.php +++ b/phpBB/includes/feed/topics.php @@ -44,7 +44,7 @@ class phpbb_feed_topics extends phpbb_feed_topic_base FROM ' . TOPICS_TABLE . ' WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . ' AND topic_moved_id = 0 - AND topic_approved = 1 + AND topic_visibility = ' . ITEM_APPROVED . ' ORDER BY topic_time DESC'; $result = $this->db->sql_query_limit($sql, $this->num_items); @@ -62,7 +62,7 @@ class phpbb_feed_topics extends phpbb_feed_topic_base $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, - t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time, + 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', 'FROM' => array( TOPICS_TABLE => 't', diff --git a/phpBB/includes/feed/topics_active.php b/phpBB/includes/feed/topics_active.php index d1c920c136..249dd1d66a 100644 --- a/phpBB/includes/feed/topics_active.php +++ b/phpBB/includes/feed/topics_active.php @@ -59,7 +59,7 @@ class phpbb_feed_topics_active extends phpbb_feed_topic_base FROM ' . TOPICS_TABLE . ' WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . ' AND topic_moved_id = 0 - AND topic_approved = 1 + AND topic_visibility = ' . ITEM_APPROVED . ' ' . $last_post_time_sql . ' ORDER BY topic_last_post_time DESC'; $result = $this->db->sql_query_limit($sql, $this->num_items); @@ -78,7 +78,7 @@ class phpbb_feed_topics_active extends phpbb_feed_topic_base $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, - t.topic_id, t.topic_title, t.topic_replies, t.topic_replies_real, t.topic_views, + t.topic_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', 'FROM' => array( diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 6a1b3fd4f8..93ad723eda 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1974,7 +1974,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s */ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time = false, $mark_time_forum = false) { - global $db, $tracking_topics, $user, $config, $auth, $request; + global $db, $tracking_topics, $user, $config, $auth, $request, $phpbb_container; // Determine the users last forum mark time if not given. if ($mark_time_forum === false) @@ -1999,7 +1999,7 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti // Handle update of unapproved topics info. // Only update for moderators having m_approve permission for the forum. - $sql_update_unapproved = ($auth->acl_get('m_approve', $forum_id)) ? '': 'AND t.topic_approved = 1'; + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); // Check the forum for any left unread topics. // If there are none, we mark the forum as read. @@ -2019,8 +2019,8 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti AND tt.user_id = ' . $user->data['user_id'] . ') WHERE t.forum_id = ' . $forum_id . ' AND t.topic_last_post_time > ' . $mark_time_forum . ' - AND t.topic_moved_id = 0 ' . - $sql_update_unapproved . ' + AND t.topic_moved_id = 0 + AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.') . ' AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time)'; $result = $db->sql_query_limit($sql, 1); @@ -2044,8 +2044,8 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti FROM ' . TOPICS_TABLE . ' t WHERE t.forum_id = ' . $forum_id . ' AND t.topic_last_post_time > ' . $mark_time_forum . ' - AND t.topic_moved_id = 0 ' . - $sql_update_unapproved; + AND t.topic_moved_id = 0 + AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'); $result = $db->sql_query($sql); $check_forum = $tracking_topics['tf'][$forum_id]; diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 21662eb493..fc29492ac1 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -644,7 +644,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s 'posts' => ($call_delete_posts) ? delete_posts($where_type, $where_ids, false, true, $post_count_sync, false) : 0, ); - $sql = 'SELECT topic_id, forum_id, topic_approved, topic_moved_id + $sql = 'SELECT topic_id, forum_id, topic_visibility, topic_moved_id FROM ' . TOPICS_TABLE . ' WHERE ' . $where_clause; $result = $db->sql_query($sql); @@ -654,7 +654,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s $forum_ids[] = $row['forum_id']; $topic_ids[] = $row['topic_id']; - if ($row['topic_approved'] && !$row['topic_moved_id']) + if ($row['topic_visibility'] == ITEM_APPROVED && !$row['topic_moved_id']) { $approved_topics++; } @@ -775,7 +775,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = $approved_posts = 0; $post_ids = $topic_ids = $forum_ids = $post_counts = $remove_topics = array(); - $sql = 'SELECT post_id, poster_id, post_approved, post_postcount, topic_id, forum_id + $sql = 'SELECT post_id, poster_id, post_visibility, post_postcount, topic_id, forum_id FROM ' . POSTS_TABLE . ' WHERE ' . $where_clause; $result = $db->sql_query($sql); @@ -787,12 +787,12 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = $topic_ids[] = (int) $row['topic_id']; $forum_ids[] = (int) $row['forum_id']; - if ($row['post_postcount'] && $post_count_sync && $row['post_approved']) + if ($row['post_postcount'] && $post_count_sync && $row['post_visibility'] == ITEM_APPROVED) { $post_counts[$row['poster_id']] = (!empty($post_counts[$row['poster_id']])) ? $post_counts[$row['poster_id']] + 1 : 1; } - if ($row['post_approved']) + if ($row['post_visibility'] == ITEM_APPROVED) { $approved_posts++; } @@ -889,7 +889,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = sync('forum', 'forum_id', $forum_ids, true, true); } - if ($approved_posts) + if ($approved_posts && $post_count_sync) { set_config_count('num_posts', $approved_posts * (-1), true); } @@ -1292,7 +1292,7 @@ function phpbb_unlink($filename, $mode = 'file', $entry_removed = false) * - forum Resync complete forum * - topic Resync topics * - topic_moved Removes topic shadows that would be in the same forum as the topic they link to -* - topic_approved Resyncs the topic_approved flag according to the status of the first post +* - topic_visibility Resyncs the topic_visibility flag according to the status of the first post * - post_reported Resyncs the post_reported flag, relying on actual reports * - topic_reported Resyncs the topic_reported flag, relying on post_reported flags * - post_attachement Same as post_reported, but with attachment flags @@ -1312,7 +1312,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $where_ids = ($where_ids) ? array((int) $where_ids) : array(); } - if ($mode == 'forum' || $mode == 'topic' || $mode == 'topic_approved' || $mode == 'topic_reported' || $mode == 'post_reported') + if ($mode == 'forum' || $mode == 'topic' || $mode == 'topic_visibility' || $mode == 'topic_reported' || $mode == 'post_reported') { if (!$where_type) { @@ -1398,43 +1398,55 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $db->sql_transaction('commit'); break; - case 'topic_approved': + case 'topic_visibility': $db->sql_transaction('begin'); - switch ($db->sql_layer) + + $sql = 'SELECT t.topic_id, p.post_visibility + FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p + $where_sql_and p.topic_id = t.topic_id + AND p.post_visibility = " . ITEM_APPROVED; + $result = $db->sql_query($sql); + + $topics_approved = array(); + while ($row = $db->sql_fetchrow($result)) { - case 'mysql4': - case 'mysqli': - $sql = 'UPDATE ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p - SET t.topic_approved = p.post_approved - $where_sql_and t.topic_first_post_id = p.post_id"; - $db->sql_query($sql); - break; + $topics_approved[] = (int) $row['topic_id']; + } + $db->sql_freeresult($result); - default: - $sql = 'SELECT t.topic_id, p.post_approved - FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p - $where_sql_and p.post_id = t.topic_first_post_id - AND p.post_approved <> t.topic_approved"; - $result = $db->sql_query($sql); + $sql = 'SELECT t.topic_id, p.post_visibility + FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p + $where_sql_and " . $db->sql_in_set('t.topic_id', $topics_approved, true, true) . ' + AND p.topic_id = t.topic_id + AND p.post_visibility = ' . ITEM_DELETED; + $result = $db->sql_query($sql); - $topic_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $topic_ids[] = $row['topic_id']; - } - $db->sql_freeresult($result); + $topics_softdeleted = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topics_softdeleted[] = (int) $row['topic_id']; + } + $db->sql_freeresult($result); - if (!sizeof($topic_ids)) - { - return; - } + $topics_softdeleted = array_diff($topics_softdeleted, $topics_approved); + $topics_not_unapproved = array_merge($topics_softdeleted, $topics_approved); + + $update_ary = array( + ITEM_UNAPPROVED => (!empty($topics_not_unapproved)) ? $where_sql_and . ' ' . $db->sql_in_set('topic_id', $topics_not_unapproved, true) : '', + ITEM_APPROVED => (!empty($topics_approved)) ? ' WHERE ' . $db->sql_in_set('topic_id', $topics_approved) : '', + ITEM_DELETED => (!empty($topics_softdeleted)) ? ' WHERE ' . $db->sql_in_set('topic_id', $topics_softdeleted) : '', + ); + foreach ($topic_visiblities as $visibility => $sql_where) + { + if ($sql_where) + { $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_approved = 1 - topic_approved - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + SET topic_visibility = ' . $visibility . ' + ' . $sql_where; $db->sql_query($sql); - break; + } } $db->sql_transaction('commit'); @@ -1675,9 +1687,12 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $forum_data[$forum_id] = $row; if ($sync_extra) { - $forum_data[$forum_id]['posts'] = 0; - $forum_data[$forum_id]['topics'] = 0; - $forum_data[$forum_id]['topics_real'] = 0; + $forum_data[$forum_id]['posts_approved'] = 0; + $forum_data[$forum_id]['posts_unapproved'] = 0; + $forum_data[$forum_id]['posts_softdeleted'] = 0; + $forum_data[$forum_id]['topics_approved'] = 0; + $forum_data[$forum_id]['topics_unapproved'] = 0; + $forum_data[$forum_id]['topics_softdeleted'] = 0; } $forum_data[$forum_id]['last_post_id'] = 0; $forum_data[$forum_id]['last_post_subject'] = ''; @@ -1698,20 +1713,27 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, // 2: Get topic counts for each forum (optional) if ($sync_extra) { - $sql = 'SELECT forum_id, topic_approved, COUNT(topic_id) AS forum_topics + $sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS total_topics FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids) . ' - GROUP BY forum_id, topic_approved'; + GROUP BY forum_id, topic_visibility'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $forum_id = (int) $row['forum_id']; - $forum_data[$forum_id]['topics_real'] += $row['forum_topics']; - if ($row['topic_approved']) + if ($row['topic_visibility'] == ITEM_APPROVED) { - $forum_data[$forum_id]['topics'] = $row['forum_topics']; + $forum_data[$forum_id]['topics_approved'] = $row['total_topics']; + } + else if ($row['topic_visibility'] == ITEM_UNAPPROVED) + { + $forum_data[$forum_id]['topics_unapproved'] = $row['total_topics']; + } + else if ($row['topic_visibility'] == ITEM_DELETED) + { + $forum_data[$forum_id]['topics_softdeleted'] = $row['total_topics']; } } $db->sql_freeresult($result); @@ -1722,18 +1744,16 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { if (sizeof($forum_ids) == 1) { - $sql = 'SELECT SUM(t.topic_replies + 1) AS forum_posts + $sql = 'SELECT SUM(t.topic_posts_approved) AS forum_posts_approved, SUM(t.topic_posts_unapproved) AS forum_posts_unapproved, SUM(t.topic_posts_softdeleted) AS forum_posts_softdeleted FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . ' - AND t.topic_approved = 1 AND t.topic_status <> ' . ITEM_MOVED; } else { - $sql = 'SELECT t.forum_id, SUM(t.topic_replies + 1) AS forum_posts + $sql = 'SELECT t.forum_id, SUM(t.topic_posts_approved) AS forum_posts_approved, SUM(t.topic_posts_unapproved) AS forum_posts_unapproved, SUM(t.topic_posts_softdeleted) AS forum_posts_softdeleted FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . ' - AND t.topic_approved = 1 AND t.topic_status <> ' . ITEM_MOVED . ' GROUP BY t.forum_id'; } @@ -1744,7 +1764,9 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $forum_id = (sizeof($forum_ids) == 1) ? (int) $forum_ids[0] : (int) $row['forum_id']; - $forum_data[$forum_id]['posts'] = (int) $row['forum_posts']; + $forum_data[$forum_id]['posts_approved'] = (int) $row['forum_posts_approved']; + $forum_data[$forum_id]['posts_unapproved'] = (int) $row['forum_posts_unapproved']; + $forum_data[$forum_id]['posts_softdeleted'] = (int) $row['forum_posts_softdeleted']; } $db->sql_freeresult($result); } @@ -1755,14 +1777,14 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $sql = 'SELECT MAX(t.topic_last_post_id) as last_post_id FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . ' - AND t.topic_approved = 1'; + AND t.topic_visibility = ' . ITEM_APPROVED; } else { $sql = 'SELECT t.forum_id, MAX(t.topic_last_post_id) as last_post_id FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('t.forum_id', $forum_ids) . ' - AND t.topic_approved = 1 + AND t.topic_visibility = ' . ITEM_APPROVED . ' GROUP BY t.forum_id'; } @@ -1825,7 +1847,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, if ($sync_extra) { - array_push($fieldnames, 'posts', 'topics', 'topics_real'); + array_push($fieldnames, 'posts_approved', 'posts_unapproved', 'posts_softdeleted', 'topics_approved', 'topics_unapproved', 'topics_softdeleted'); } foreach ($forum_data as $forum_id => $row) @@ -1860,11 +1882,11 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, break; case 'topic': - $topic_data = $post_ids = $approved_unapproved_ids = $resync_forums = $delete_topics = $delete_posts = $moved_topics = array(); + $topic_data = $post_ids = $resync_forums = $delete_topics = $delete_posts = $moved_topics = array(); $db->sql_transaction('begin'); - $sql = 'SELECT t.topic_id, t.forum_id, t.topic_moved_id, t.topic_approved, ' . (($sync_extra) ? 't.topic_attachment, t.topic_reported, ' : '') . 't.topic_poster, t.topic_time, t.topic_replies, t.topic_replies_real, t.topic_first_post_id, t.topic_first_poster_name, t.topic_first_poster_colour, t.topic_last_post_id, t.topic_last_post_subject, t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_poster_colour, t.topic_last_post_time + $sql = 'SELECT t.topic_id, t.forum_id, t.topic_moved_id, t.topic_visibility, ' . (($sync_extra) ? 't.topic_attachment, t.topic_reported, ' : '') . 't.topic_poster, t.topic_time, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_first_post_id, t.topic_first_poster_name, t.topic_first_poster_colour, t.topic_last_post_id, t.topic_last_post_subject, t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_poster_colour, t.topic_last_post_time FROM ' . TOPICS_TABLE . " t $where_sql"; $result = $db->sql_query($sql); @@ -1879,8 +1901,10 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $topic_id = (int) $row['topic_id']; $topic_data[$topic_id] = $row; - $topic_data[$topic_id]['replies_real'] = -1; - $topic_data[$topic_id]['replies'] = 0; + $topic_data[$topic_id]['visibility'] = ITEM_UNAPPROVED; + $topic_data[$topic_id]['posts_approved'] = 0; + $topic_data[$topic_id]['posts_unapproved'] = 0; + $topic_data[$topic_id]['posts_softdeleted'] = 0; $topic_data[$topic_id]['first_post_id'] = 0; $topic_data[$topic_id]['last_post_id'] = 0; unset($topic_data[$topic_id]['topic_id']); @@ -1897,11 +1921,11 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $db->sql_freeresult($result); // Use "t" as table alias because of the $where_sql clause - // NOTE: 't.post_approved' in the GROUP BY is causing a major slowdown. - $sql = 'SELECT t.topic_id, t.post_approved, COUNT(t.post_id) AS total_posts, MIN(t.post_id) AS first_post_id, MAX(t.post_id) AS last_post_id + // NOTE: 't.post_visibility' in the GROUP BY is causing a major slowdown. + $sql = 'SELECT t.topic_id, t.post_visibility, COUNT(t.post_id) AS total_posts, MIN(t.post_id) AS first_post_id, MAX(t.post_id) AS last_post_id FROM ' . POSTS_TABLE . " t $where_sql - GROUP BY t.topic_id, t.post_approved"; + GROUP BY t.topic_id, t.post_visibility"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) @@ -1922,14 +1946,38 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, // When we'll be done, only topics with no posts will remain unset($delete_topics[$topic_id]); - $topic_data[$topic_id]['replies_real'] += $row['total_posts']; - $topic_data[$topic_id]['first_post_id'] = (!$topic_data[$topic_id]['first_post_id']) ? $row['first_post_id'] : min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']); + if ($row['post_visibility'] == ITEM_APPROVED) + { + $topic_data[$topic_id]['posts_approved'] = $row['total_posts']; + } + else if ($row['post_visibility'] == ITEM_UNAPPROVED) + { + $topic_data[$topic_id]['posts_unapproved'] = $row['total_posts']; + } + else if ($row['post_visibility'] == ITEM_DELETED) + { + $topic_data[$topic_id]['posts_softdeleted'] = $row['total_posts']; + } - if ($row['post_approved'] || !$topic_data[$topic_id]['last_post_id']) + if ($row['post_visibility'] == ITEM_APPROVED) { - $topic_data[$topic_id]['replies'] = $row['total_posts'] - 1; + $topic_data[$topic_id]['visibility'] = ITEM_APPROVED; + $topic_data[$topic_id]['first_post_id'] = $row['first_post_id']; $topic_data[$topic_id]['last_post_id'] = $row['last_post_id']; } + else if ($topic_data[$topic_id]['visibility'] != ITEM_APPROVED) + { + // If there is no approved post, we take the min/max of the other visibilities + // for the last and first post info, because it is only visible to moderators anyway + $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) + { + // Soft delete status is stronger than unapproved. + $topic_data[$topic_id]['visibility'] = $row['post_visibility']; + } + } } } $db->sql_freeresult($result); @@ -1970,7 +2018,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, unset($delete_topics, $delete_topic_ids); } - $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour + $sql = 'SELECT p.post_id, p.topic_id, p.post_visibility, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . ' AND u.user_id = p.poster_id'; @@ -1983,10 +2031,6 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, if ($row['post_id'] == $topic_data[$topic_id]['first_post_id']) { - if ($topic_data[$topic_id]['topic_approved'] != $row['post_approved']) - { - $approved_unapproved_ids[] = $topic_id; - } $topic_data[$topic_id]['time'] = $row['post_time']; $topic_data[$topic_id]['poster'] = $row['poster_id']; $topic_data[$topic_id]['first_poster_name'] = ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']; @@ -2047,7 +2091,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $sync_shadow_topics = array(); if (sizeof($post_ids)) { - $sql = 'SELECT p.post_id, p.topic_id, p.post_approved, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour + $sql = 'SELECT p.post_id, p.topic_id, p.post_visibility, p.poster_id, p.post_subject, p.post_username, p.post_time, u.username, u.user_colour FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . ' AND u.user_id = p.poster_id'; @@ -2114,18 +2158,8 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, unset($sync_shadow_topics, $shadow_topic_data); } - // approved becomes unapproved, and vice-versa - if (sizeof($approved_unapproved_ids)) - { - $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_approved = 1 - topic_approved - WHERE ' . $db->sql_in_set('topic_id', $approved_unapproved_ids); - $db->sql_query($sql); - } - unset($approved_unapproved_ids); - // These are fields that will be synchronised - $fieldnames = array('time', 'replies', 'replies_real', 'poster', 'first_post_id', 'first_poster_name', 'first_poster_colour', 'last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour'); + $fieldnames = array('time', 'visibility', 'posts_approved', 'posts_unapproved', 'posts_softdeleted', 'poster', 'first_post_id', 'first_poster_name', 'first_poster_colour', 'last_post_id', 'last_post_subject', 'last_post_time', 'last_poster_id', 'last_poster_name', 'last_poster_colour'); if ($sync_extra) { diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index ac791e0d9b..a34a193f60 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -1768,7 +1768,7 @@ function sync_post_count($offset, $limit) $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id FROM ' . POSTS_TABLE . ' WHERE post_postcount = 1 - AND post_approved = 1 + AND post_visibility = ' . ITEM_APPROVED . ' GROUP BY poster_id ORDER BY poster_id'; $result = $db->sql_query_limit($sql, $limit, $offset); @@ -1941,7 +1941,7 @@ function update_dynamic_config() $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' - WHERE post_approved = 1'; + WHERE post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -1950,7 +1950,7 @@ function update_dynamic_config() $sql = 'SELECT COUNT(topic_id) AS stat FROM ' . TOPICS_TABLE . ' - WHERE topic_approved = 1'; + WHERE topic_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 9854cd6d70..143813e4ed 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -22,7 +22,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod { global $db, $auth, $user, $template; global $phpbb_root_path, $phpEx, $config; - global $request, $phpbb_dispatcher; + global $request, $phpbb_dispatcher, $phpbb_container; $forum_rows = $subforums = $forum_ids = $forum_ids_moderator = $forum_moderators = $active_forum_ary = array(); $parent_id = $visible_forums = 0; @@ -149,6 +149,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $forum_tracking_info = array(); $branch_root_id = $root_data['forum_id']; + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + while ($row = $db->sql_fetchrow($result)) { /** @@ -214,8 +216,9 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod } // Count the difference of real to public topics, so we can display an information to moderators - $row['forum_id_unapproved_topics'] = ($auth->acl_get('m_approve', $forum_id) && ($row['forum_topics_real'] != $row['forum_topics'])) ? $forum_id : 0; - $row['forum_topics'] = ($auth->acl_get('m_approve', $forum_id)) ? $row['forum_topics_real'] : $row['forum_topics']; + $row['forum_id_unapproved_topics'] = ($auth->acl_get('m_approve', $forum_id) && $row['forum_topics_unapproved']) ? $forum_id : 0; + $row['forum_posts'] = $phpbb_content_visibility->get_count('forum_posts', $row, $forum_id); + $row['forum_topics'] = $phpbb_content_visibility->get_count('forum_topics', $row, $forum_id); // Display active topics from this forum? if ($show_active && $row['forum_type'] == FORUM_POST && $auth->acl_get('f_read', $forum_id) && ($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) @@ -815,7 +818,7 @@ function gen_forum_auth_level($mode, $forum_id, $forum_status) ($auth->acl_get('f_post', $forum_id) && !$locked) ? $user->lang['RULES_POST_CAN'] : $user->lang['RULES_POST_CANNOT'], ($auth->acl_get('f_reply', $forum_id) && !$locked) ? $user->lang['RULES_REPLY_CAN'] : $user->lang['RULES_REPLY_CANNOT'], ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id) && !$locked) ? $user->lang['RULES_EDIT_CAN'] : $user->lang['RULES_EDIT_CANNOT'], - ($user->data['is_registered'] && $auth->acl_gets('f_delete', 'm_delete', $forum_id) && !$locked) ? $user->lang['RULES_DELETE_CAN'] : $user->lang['RULES_DELETE_CANNOT'], + ($user->data['is_registered'] && ($auth->acl_gets('f_delete', 'm_delete', $forum_id) || $auth->acl_gets('f_softdelete', 'm_softdelete', $forum_id)) && !$locked) ? $user->lang['RULES_DELETE_CAN'] : $user->lang['RULES_DELETE_CANNOT'], ); if ($config['allow_attachments']) @@ -1005,7 +1008,7 @@ function display_reasons($reason_id = 0) function display_user_activity(&$userdata) { global $auth, $template, $db, $user; - global $phpbb_root_path, $phpEx; + global $phpbb_root_path, $phpEx, $phpbb_container; // Do not display user activity for users having more than 5000 posts... if ($userdata['user_posts'] > 5000) @@ -1015,73 +1018,65 @@ function display_user_activity(&$userdata) $forum_ary = array(); - // Do not include those forums the user is not having read access to... - $forum_read_ary = $auth->acl_getf('!f_read'); - - foreach ($forum_read_ary as $forum_id => $not_allowed) + $forum_read_ary = $auth->acl_getf('f_read'); + foreach ($forum_read_ary as $forum_id => $allowed) { - if ($not_allowed['f_read']) + if ($allowed['f_read']) { $forum_ary[] = (int) $forum_id; } } - $forum_ary = array_unique($forum_ary); - $forum_sql = (sizeof($forum_ary)) ? 'AND ' . $db->sql_in_set('forum_id', $forum_ary, true) : ''; - - $fid_m_approve = $auth->acl_getf('m_approve', true); - $sql_m_approve = (!empty($fid_m_approve)) ? 'OR ' . $db->sql_in_set('forum_id', array_keys($fid_m_approve)) : ''; - - // Obtain active forum - $sql = 'SELECT forum_id, COUNT(post_id) AS num_posts - FROM ' . POSTS_TABLE . ' - WHERE poster_id = ' . $userdata['user_id'] . " - AND post_postcount = 1 - AND (post_approved = 1 - $sql_m_approve) - $forum_sql - GROUP BY forum_id - ORDER BY num_posts DESC"; - $result = $db->sql_query_limit($sql, 1); - $active_f_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $forum_ary = array_diff($forum_ary, $user->get_passworded_forums()); - if (!empty($active_f_row)) + $active_f_row = $active_t_row = array(); + if (!empty($forum_ary)) { - $sql = 'SELECT forum_name - FROM ' . FORUMS_TABLE . ' - WHERE forum_id = ' . $active_f_row['forum_id']; - $result = $db->sql_query($sql, 3600); - $active_f_row['forum_name'] = (string) $db->sql_fetchfield('forum_name'); + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + + // Obtain active forum + $sql = 'SELECT forum_id, COUNT(post_id) AS num_posts + FROM ' . POSTS_TABLE . ' + WHERE poster_id = ' . $userdata['user_id'] . ' + AND post_postcount = 1 + AND ' . $phpbb_content_visibility->get_forums_visibility_sql('post', $forum_ary) . ' + GROUP BY forum_id + ORDER BY num_posts DESC'; + $result = $db->sql_query_limit($sql, 1); + $active_f_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - } - // Obtain active topic - // We need to exclude passworded forums here so we do not leak the topic title - $forum_ary_topic = array_unique(array_merge($forum_ary, $user->get_passworded_forums())); - $forum_sql_topic = (!empty($forum_ary_topic)) ? 'AND ' . $db->sql_in_set('forum_id', $forum_ary_topic, true) : ''; - - $sql = 'SELECT topic_id, COUNT(post_id) AS num_posts - FROM ' . POSTS_TABLE . ' - WHERE poster_id = ' . $userdata['user_id'] . " - AND post_postcount = 1 - AND (post_approved = 1 - $sql_m_approve) - $forum_sql_topic - GROUP BY topic_id - ORDER BY num_posts DESC"; - $result = $db->sql_query_limit($sql, 1); - $active_t_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + if (!empty($active_f_row)) + { + $sql = 'SELECT forum_name + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $active_f_row['forum_id']; + $result = $db->sql_query($sql, 3600); + $active_f_row['forum_name'] = (string) $db->sql_fetchfield('forum_name'); + $db->sql_freeresult($result); + } - if (!empty($active_t_row)) - { - $sql = 'SELECT topic_title - FROM ' . TOPICS_TABLE . ' - WHERE topic_id = ' . $active_t_row['topic_id']; - $result = $db->sql_query($sql); - $active_t_row['topic_title'] = (string) $db->sql_fetchfield('topic_title'); + // Obtain active topic + $sql = 'SELECT topic_id, COUNT(post_id) AS num_posts + FROM ' . POSTS_TABLE . ' + WHERE poster_id = ' . $userdata['user_id'] . ' + AND post_postcount = 1 + AND ' . $phpbb_content_visibility->get_forums_visibility_sql('post', $forum_ary) . ' + GROUP BY topic_id + ORDER BY num_posts DESC'; + $result = $db->sql_query_limit($sql, 1); + $active_t_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); + + if (!empty($active_t_row)) + { + $sql = 'SELECT topic_title + FROM ' . TOPICS_TABLE . ' + WHERE topic_id = ' . $active_t_row['topic_id']; + $result = $db->sql_query($sql); + $active_t_row['topic_title'] = (string) $db->sql_fetchfield('topic_title'); + $db->sql_freeresult($result); + } } $userdata['active_t_row'] = $active_t_row; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index b9b518ad32..03565c27bb 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -176,7 +176,7 @@ function update_post_information($type, $ids, $return_update_sql = false) if ($type != 'topic') { $topic_join = ', ' . TOPICS_TABLE . ' t'; - $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_approved = 1'; + $topic_condition = 'AND t.topic_id = p.topic_id AND t.topic_visibility = ' . ITEM_APPROVED; } else { @@ -190,7 +190,7 @@ function update_post_information($type, $ids, $return_update_sql = false) FROM ' . POSTS_TABLE . " p $topic_join WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . " $topic_condition - AND p.post_approved = 1"; + AND p.post_visibility = " . ITEM_APPROVED; } else { @@ -198,7 +198,7 @@ function update_post_information($type, $ids, $return_update_sql = false) FROM ' . POSTS_TABLE . " p $topic_join WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . " $topic_condition - AND p.post_approved = 1 + AND p.post_visibility = " . ITEM_APPROVED . " GROUP BY p.{$type}_id"; } $result = $db->sql_query($sql); @@ -982,13 +982,15 @@ function load_drafts($topic_id = 0, $forum_id = 0, $id = 0, $pm_action = '', $ms function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id = 0, $show_quote_button = true) { global $user, $auth, $db, $template, $bbcode, $cache; - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $phpbb_container; + + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); // Go ahead and pull all data for this topic $sql = 'SELECT p.post_id FROM ' . POSTS_TABLE . ' p' . " WHERE p.topic_id = $topic_id - " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . ' + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.') . ' ' . (($mode == 'post_review') ? " AND p.post_id > $cur_post_id" : '') . ' ' . (($mode == 'post_review_edit') ? " AND p.post_id = $cur_post_id" : '') . ' ORDER BY p.post_time '; @@ -1175,14 +1177,14 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id /** * Delete Post */ -function delete_post($forum_id, $topic_id, $post_id, &$data) +function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $softdelete_reason = '') { - global $db, $user, $auth; + global $db, $user, $auth, $phpbb_container; global $config, $phpEx, $phpbb_root_path; // Specify our post mode $post_mode = 'delete'; - if (($data['topic_first_post_id'] === $data['topic_last_post_id']) && $data['topic_replies_real'] == 0) + if (($data['topic_first_post_id'] === $data['topic_last_post_id']) && ($data['topic_posts_approved'] + $data['topic_posts_unapproved'] + $data['topic_posts_softdeleted'] == 1)) { $post_mode = 'delete_topic'; } @@ -1224,20 +1226,30 @@ function delete_post($forum_id, $topic_id, $post_id, &$data) $db->sql_freeresult($result); } - if (!delete_posts('post_id', array($post_id), false, false)) + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + + // (Soft) delete the post + if ($is_soft && ($post_mode != 'delete_topic')) + { + $phpbb_content_visibility->set_post_visibility(ITEM_DELETED, $post_id, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason, ($data['topic_first_post_id'] == $post_id), ($data['topic_last_post_id'] == $post_id)); + } + else if (!$is_soft) { - // Try to delete topic, we may had an previous error causing inconsistency - if ($post_mode == 'delete_topic') + if (!delete_posts('post_id', array($post_id), false, false, false)) { - delete_topics('topic_id', array($topic_id), false); + // Try to delete topic, we may had an previous error causing inconsistency + if ($post_mode == 'delete_topic') + { + delete_topics('topic_id', array($topic_id), false); + } + trigger_error('ALREADY_DELETED'); } - trigger_error('ALREADY_DELETED'); } $db->sql_transaction('commit'); // Collect the necessary information for updating the tables - $sql_data[FORUMS_TABLE] = ''; + $sql_data[FORUMS_TABLE] = $sql_data[TOPICS_TABLE] = ''; switch ($post_mode) { case 'delete_topic': @@ -1246,21 +1258,43 @@ function delete_post($forum_id, $topic_id, $post_id, &$data) { // counting is fun! we only have to do sizeof($forum_ids) number of queries, // even if the topic is moved back to where its shadow lives (we count how many times it is in a forum) - $db->sql_query('UPDATE ' . FORUMS_TABLE . ' SET forum_topics_real = forum_topics_real - ' . $topic_count . ', forum_topics = forum_topics - ' . $topic_count . ' WHERE forum_id = ' . $updated_forum); + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET forum_topics_approved = forum_topics_approved - ' . $topic_count . ' + WHERE forum_id = ' . $updated_forum; + $db->sql_query($sql); update_post_information('forum', $updated_forum); } - delete_topics('topic_id', array($topic_id), false); + if ($is_soft) + { + $topic_row = array(); + $phpbb_content_visibility->set_topic_visibility(ITEM_DELETED, $topic_id, $forum_id, $user->data['user_id'], time(), $softdelete_reason); + } + else + { + delete_topics('topic_id', array($topic_id), false); - $sql_data[FORUMS_TABLE] .= 'forum_topics_real = forum_topics_real - 1'; - $sql_data[FORUMS_TABLE] .= ($data['topic_approved']) ? ', forum_posts = forum_posts - 1, forum_topics = forum_topics - 1' : ''; + if ($data['topic_visibility'] == ITEM_APPROVED) + { + $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) + { + $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; + } + else if ($data['topic_visibility'] == ITEM_DELETED) + { + $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1'; + } - $update_sql = update_post_information('forum', $forum_id, true); - if (sizeof($update_sql)) - { - $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : ''; - $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]); + $update_sql = update_post_information('forum', $forum_id, true); + if (sizeof($update_sql)) + { + $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : ''; + $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]); + } } + break; case 'delete_first_post': @@ -1268,73 +1302,101 @@ function delete_post($forum_id, $topic_id, $post_id, &$data) FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u WHERE p.topic_id = $topic_id AND p.poster_id = u.user_id - ORDER BY p.post_time ASC"; + AND p.post_visibility = " . ITEM_APPROVED . ' + ORDER BY p.post_time ASC'; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; - - $sql_data[TOPICS_TABLE] = 'topic_poster = ' . intval($row['poster_id']) . ', topic_first_post_id = ' . intval($row['post_id']) . ", topic_first_poster_colour = '" . $db->sql_escape($row['user_colour']) . "', topic_first_poster_name = '" . (($row['poster_id'] == ANONYMOUS) ? $db->sql_escape($row['post_username']) : $db->sql_escape($row['username'])) . "', topic_time = " . (int) $row['post_time']; - - // Decrementing topic_replies here is fine because this case only happens if there is more than one post within the topic - basically removing one "reply" - $sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : ''); + if (!$row) + { + // No approved post, so the first is a not-approved post (unapproved or soft deleted) + $sql = 'SELECT p.post_id, p.poster_id, p.post_time, p.post_username, u.username, u.user_colour + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u + WHERE p.topic_id = $topic_id + AND p.poster_id = u.user_id + ORDER BY p.post_time ASC"; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + } $next_post_id = (int) $row['post_id']; + + $sql_data[TOPICS_TABLE] = $db->sql_build_array('UPDATE', array( + 'topic_poster' => (int) $row['poster_id'], + 'topic_first_post_id' => (int) $row['post_id'], + 'topic_first_poster_colour' => $row['user_colour'], + 'topic_first_poster_name' => ($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username'], + 'topic_time' => (int) $row['post_time'], + )); break; case 'delete_last_post': - $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; - - $update_sql = update_post_information('forum', $forum_id, true); - if (sizeof($update_sql)) + if (!$is_soft) { - $sql_data[FORUMS_TABLE] .= ($sql_data[FORUMS_TABLE]) ? ', ' : ''; - $sql_data[FORUMS_TABLE] .= implode(', ', $update_sql[$forum_id]); - } + // Update last post information when hard deleting. Soft delete already did that by itself. + $update_sql = update_post_information('forum', $forum_id, true); + if (sizeof($update_sql)) + { + $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . implode(', ', $update_sql[$forum_id]); + } - $sql_data[TOPICS_TABLE] = 'topic_bumped = 0, topic_bumper = 0, topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : ''); + $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_bumped = 0, topic_bumper = 0'; - $update_sql = update_post_information('topic', $topic_id, true); - if (sizeof($update_sql)) - { - $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]); - $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]); + $update_sql = update_post_information('topic', $topic_id, true); + if (!empty($update_sql)) + { + $sql_data[TOPICS_TABLE] .= ', ' . implode(', ', $update_sql[$topic_id]); + $next_post_id = (int) str_replace('topic_last_post_id = ', '', $update_sql[$topic_id][0]); + } } - else + + if (!$next_post_id) { $sql = 'SELECT MAX(post_id) as last_post_id FROM ' . POSTS_TABLE . " - WHERE topic_id = $topic_id " . - ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : ''); + WHERE topic_id = $topic_id + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id); $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); + $next_post_id = (int) $db->sql_fetchfield('last_post_id'); $db->sql_freeresult($result); - - $next_post_id = (int) $row['last_post_id']; } break; case 'delete': $sql = 'SELECT post_id FROM ' . POSTS_TABLE . " - WHERE topic_id = $topic_id " . - ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND post_approved = 1' : '') . ' + WHERE topic_id = $topic_id + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . ' AND post_time > ' . $data['post_time'] . ' ORDER BY post_time ASC'; $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); + $next_post_id = (int) $db->sql_fetchfield('post_id'); $db->sql_freeresult($result); - - $sql_data[FORUMS_TABLE] = ($data['post_approved']) ? 'forum_posts = forum_posts - 1' : ''; - - $sql_data[TOPICS_TABLE] = 'topic_replies_real = topic_replies_real - 1' . (($data['post_approved']) ? ', topic_replies = topic_replies - 1' : ''); - $next_post_id = (int) $row['post_id']; break; } if (($post_mode == 'delete') || ($post_mode == 'delete_last_post') || ($post_mode == 'delete_first_post')) { + if (!$is_soft) + { + if ($data['post_visibility'] == ITEM_APPROVED) + { + $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data); + } + else if ($data['post_visibility'] == ITEM_UNAPPROVED) + { + $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'; + } + else if ($data['post_visibility'] == ITEM_DELETED) + { + $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_softdeleted = forum_posts_softdeleted - 1'; + $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_softdeleted = topic_posts_softdeleted - 1'; + } + } + $sql = 'SELECT 1 AS has_attachments FROM ' . ATTACHMENTS_TABLE . ' WHERE topic_id = ' . $topic_id; @@ -1344,18 +1406,16 @@ function delete_post($forum_id, $topic_id, $post_id, &$data) if (!$has_attachments) { - $sql_data[TOPICS_TABLE] .= ', topic_attachment = 0'; + $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_attachment = 0'; } } -// $sql_data[USERS_TABLE] = ($data['post_postcount']) ? 'user_posts = user_posts - 1' : ''; - $db->sql_transaction('begin'); $where_sql = array( FORUMS_TABLE => "forum_id = $forum_id", TOPICS_TABLE => "topic_id = $topic_id", - USERS_TABLE => 'user_id = ' . $data['poster_id'] + USERS_TABLE => 'user_id = ' . $data['poster_id'], ); foreach ($sql_data as $table => $update_sql) @@ -1425,7 +1485,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u } else if ($mode == 'edit') { - $post_mode = ($data['topic_replies_real'] == 0) ? 'edit_topic' : (($data['topic_first_post_id'] == $data['post_id']) ? 'edit_first_post' : (($data['topic_last_post_id'] == $data['post_id']) ? 'edit_last_post' : 'edit')); + $post_mode = ($data['topic_posts_approved'] + $data['topic_posts_unapproved'] + $data['topic_posts_softdeleted'] == 1) ? 'edit_topic' : (($data['topic_first_post_id'] == $data['post_id']) ? 'edit_first_post' : (($data['topic_last_post_id'] == $data['post_id']) ? 'edit_last_post' : 'edit')); } // First of all make sure the subject and topic title are having the correct length. @@ -1438,9 +1498,9 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id']; // Retrieve some additional information if not present - if ($mode == 'edit' && (!isset($data['post_approved']) || !isset($data['topic_approved']) || $data['post_approved'] === false || $data['topic_approved'] === false)) + if ($mode == 'edit' && (!isset($data['post_visibility']) || !isset($data['topic_visibility']) || $data['post_visibility'] === false || $data['topic_visibility'] === false)) { - $sql = 'SELECT p.post_approved, t.topic_type, t.topic_replies, t.topic_replies_real, t.topic_approved + $sql = 'SELECT p.post_visibility, t.topic_type, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_visibility FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p WHERE t.topic_id = p.topic_id AND p.post_id = ' . $data['post_id']; @@ -1448,26 +1508,29 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $topic_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - $data['topic_approved'] = $topic_row['topic_approved']; - $data['post_approved'] = $topic_row['post_approved']; + $data['topic_visibility'] = $topic_row['topic_visibility']; + $data['post_visibility'] = $topic_row['post_visibility']; } - // This variable indicates if the user is able to post or put into the queue - it is used later for all code decisions regarding approval - // The variable name should be $post_approved, because it indicates if the post is approved or not - $post_approval = 1; + // This variable indicates if the user is able to post or put into the queue + $post_visibility = ITEM_APPROVED; // Check the permissions for post approval. // Moderators must go through post approval like ordinary users. if (!$auth->acl_get('f_noapprove', $data['forum_id'])) { // Post not approved, but in queue - $post_approval = 0; + $post_visibility = ITEM_UNAPPROVED; } - // Mods are able to force approved/unapproved posts. True means the post is approved, false the post is unapproved + // MODs/Extensions are able to force any visibility on posts if (isset($data['force_approved_state'])) { - $post_approval = ($data['force_approved_state']) ? 1 : 0; + $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (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; } // Start the transaction here @@ -1484,7 +1547,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u 'icon_id' => $data['icon_id'], 'poster_ip' => $user->ip, 'post_time' => $current_time, - 'post_approved' => $post_approval, + 'post_visibility' => $post_visibility, 'enable_bbcode' => $data['enable_bbcode'], 'enable_smilies' => $data['enable_smilies'], 'enable_magic_url' => $data['enable_urls'], @@ -1550,7 +1613,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u 'forum_id' => $data['forum_id'], 'poster_id' => $data['poster_id'], 'icon_id' => $data['icon_id'], - 'post_approved' => (!$post_approval) ? 0 : $data['post_approved'], + // We will change the visibility later + //'post_visibility' => $post_visibility, 'enable_bbcode' => $data['enable_bbcode'], 'enable_smilies' => $data['enable_smilies'], 'enable_magic_url' => $data['enable_urls'], @@ -1571,8 +1635,6 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u break; } - - $post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved']; $topic_row = array(); // And the topic ladies and gentlemen @@ -1585,7 +1647,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u 'topic_last_view_time' => $current_time, 'forum_id' => $data['forum_id'], 'icon_id' => $data['icon_id'], - 'topic_approved' => $post_approval, + 'topic_posts_approved' => ($post_visibility == ITEM_APPROVED) ? 1 : 0, + 'topic_posts_softdeleted' => ($post_visibility == ITEM_DELETED) ? 1 : 0, + 'topic_posts_unapproved' => ($post_visibility == ITEM_UNAPPROVED) ? 1 : 0, + 'topic_visibility' => $post_visibility, + 'topic_delete_user' => ($post_visibility != ITEM_APPROVED) ? (int) $user->data['user_id'] : 0, 'topic_title' => $subject, 'topic_first_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''), 'topic_first_poster_colour' => $user->data['user_colour'], @@ -1617,28 +1683,47 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u ); } - $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : ''); + $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_visibility == ITEM_APPROVED) ? ', user_posts = user_posts + 1' : ''); - if ($post_approval) + if ($post_visibility == ITEM_APPROVED) { - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1'; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_approved = forum_topics_approved + 1'; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_approved = forum_posts_approved + 1'; + } + else if ($post_visibility == ITEM_UNAPPROVED) + { + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_unapproved = forum_topics_unapproved + 1'; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_unapproved = forum_posts_unapproved + 1'; + } + else if ($post_visibility == ITEM_DELETED) + { + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_softdeleted = forum_topics_softdeleted + 1'; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_softdeleted = forum_posts_softdeleted + 1'; } - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($post_approval) ? ', forum_topics = forum_topics + 1' : ''); break; case 'reply': $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_view_time = ' . $current_time . ', - topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0' . - (($post_approval) ? ', topic_replies = topic_replies + 1' : '') . + (($post_visibility == ITEM_APPROVED) ? ', topic_posts_approved = topic_posts_approved + 1' : '') . + (($post_visibility == ITEM_UNAPPROVED) ? ', topic_posts_unapproved = topic_posts_unapproved + 1' : '') . + (($post_visibility == ITEM_DELETED) ? ', topic_posts_softdeleted = topic_posts_softdeleted + 1' : '') . ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : ''); - $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : ''); + $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_visibility == ITEM_APPROVED) ? ', user_posts = user_posts + 1' : ''); - if ($post_approval) + if ($post_visibility == ITEM_APPROVED) + { + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_approved = forum_posts_approved + 1'; + } + else if ($post_visibility == ITEM_UNAPPROVED) { - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1'; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_unapproved = forum_posts_unapproved + 1'; + } + else if ($post_visibility == ITEM_DELETED) + { + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts_softdeleted = forum_posts_softdeleted + 1'; } break; @@ -1662,7 +1747,6 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $sql_data[TOPICS_TABLE]['sql'] = array( 'forum_id' => $data['forum_id'], 'icon_id' => $data['icon_id'], - 'topic_approved' => (!$post_approval) ? 0 : $data['topic_approved'], 'topic_title' => $subject, 'topic_first_poster_name' => $username, 'topic_type' => $topic_type, @@ -1677,56 +1761,6 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u 'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0), ); - // Correctly set back the topic replies and forum posts... only if the topic was approved before and now gets disapproved - if (!$post_approval && $data['topic_approved']) - { - // Do we need to grab some topic informations? - if (!sizeof($topic_row)) - { - $sql = 'SELECT topic_type, topic_replies, topic_replies_real, topic_approved - FROM ' . TOPICS_TABLE . ' - WHERE topic_id = ' . $data['topic_id']; - $result = $db->sql_query($sql); - $topic_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - } - - // If this is the only post remaining we do not need to decrement topic_replies. - // Also do not decrement if first post - then the topic_replies will not be adjusted if approving the topic again. - - // If this is an edited topic or the first post the topic gets completely disapproved later on... - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1'; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1); - - set_config_count('num_topics', -1, true); - set_config_count('num_posts', ($topic_row['topic_replies'] + 1) * (-1), true); - - // Only decrement this post, since this is the one non-approved now - if ($auth->acl_get('f_postcount', $data['forum_id'])) - { - $sql_data[USERS_TABLE]['stat'][] = 'user_posts = user_posts - 1'; - } - } - - break; - - case 'edit': - case 'edit_last_post': - - // Correctly set back the topic replies and forum posts... but only if the post was approved before. - if (!$post_approval && $data['post_approved']) - { - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1, topic_last_view_time = ' . $current_time; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1'; - - set_config_count('num_posts', -1, true); - - if ($auth->acl_get('f_postcount', $data['forum_id'])) - { - $sql_data[USERS_TABLE]['stat'][] = 'user_posts = user_posts - 1'; - } - } - break; } @@ -1751,27 +1785,48 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if ($post_mode == 'reply') { $sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array( - 'topic_id' => $data['topic_id']) - ); + 'topic_id' => $data['topic_id'], + )); } $sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']); $db->sql_query($sql); $data['post_id'] = $db->sql_nextid(); - if ($post_mode == 'post') + if ($post_mode == 'post' || $post_visibility == ITEM_APPROVED) { $sql_data[TOPICS_TABLE]['sql'] = array( - 'topic_first_post_id' => $data['post_id'], 'topic_last_post_id' => $data['post_id'], 'topic_last_post_time' => $current_time, - 'topic_last_poster_id' => (int) $user->data['user_id'], - 'topic_last_poster_name' => (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''), + 'topic_last_poster_id' => $sql_data[POSTS_TABLE]['sql']['poster_id'], + 'topic_last_poster_name' => ($user->data['user_id'] == ANONYMOUS) ? $sql_data[POSTS_TABLE]['sql']['post_username'] : $user->data['username'], 'topic_last_poster_colour' => $user->data['user_colour'], 'topic_last_post_subject' => (string) $subject, ); } + if ($post_mode == 'post') + { + $sql_data[TOPICS_TABLE]['sql']['topic_first_post_id'] = $data['post_id']; + } + + // Update total post count and forum information + if ($post_visibility == ITEM_APPROVED) + { + if ($post_mode == 'post') + { + set_config_count('num_topics', 1, true); + } + set_config_count('num_posts', 1, true); + + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id']; + $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'"; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time; + $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id']; + $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'"; + $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'"; + } + unset($sql_data[POSTS_TABLE]['sql']); } @@ -1782,6 +1837,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . ' WHERE topic_id = ' . $data['topic_id']; $db->sql_query($sql); + + unset($sql_data[TOPICS_TABLE]['sql']); } // Update the posts table @@ -1791,6 +1848,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . ' WHERE post_id = ' . $data['post_id']; $db->sql_query($sql); + + unset($sql_data[POSTS_TABLE]['sql']); } // Update Poll Tables @@ -1936,114 +1995,21 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u } } - // we need to update the last forum information - // only applicable if the topic is approved - if ($post_approved || !$data['post_approved']) + // 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) { - // the last post makes us update the forum table. This can happen if... - // We make a new topic - // We reply to a topic - // We edit the last post in a topic and this post is the latest in the forum (maybe) - // We edit the only post in the topic - // We edit the first post in the topic and all the other posts are not approved - if (($post_mode == 'post' || $post_mode == 'reply') && $post_approved) - { - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id']; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'"; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id']; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'"; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'"; - } - else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])) - { - // this does not _necessarily_ mean that we must update the info again, - // it just means that we might have to - $sql = 'SELECT forum_last_post_id, forum_last_post_subject - FROM ' . FORUMS_TABLE . ' - WHERE forum_id = ' . (int) $data['forum_id']; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + // 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_latest = ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED); - // this post is the latest post in the forum, better update - if ($row['forum_last_post_id'] == $data['post_id']) - { - // If post approved and subject changed, or poster is anonymous, we need to update the forum_last* rows - if ($post_approved && ($row['forum_last_post_subject'] !== $subject || $data['poster_id'] == ANONYMOUS)) - { - // the post's subject changed - if ($row['forum_last_post_subject'] !== $subject) - { - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_subject = \'' . $db->sql_escape($subject) . '\''; - } - - // Update the user name if poster is anonymous... just in case an admin changed it - if ($data['poster_id'] == ANONYMOUS) - { - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape($username) . "'"; - } - } - else if ($data['post_approved'] !== $post_approved) - { - // we need a fresh change of socks, everything has become invalidated - $sql = 'SELECT MAX(topic_last_post_id) as last_post_id - FROM ' . TOPICS_TABLE . ' - WHERE forum_id = ' . (int) $data['forum_id'] . ' - AND topic_approved = 1'; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - // any posts left in this forum? - if (!empty($row['last_post_id'])) - { - $sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour - FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u - WHERE p.poster_id = u.user_id - AND p.post_id = ' . (int) $row['last_post_id']; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - // salvation, a post is found! jam it into the forums table - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id']; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time']; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id']; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; - } - else - { - // just our luck, the last topic in the forum has just been turned unapproved... - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0'; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''"; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0'; - $sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0'; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''"; - $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''"; - } - } - } - } + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + $phpbb_content_visibility->set_post_visibility($post_visibility, $data['post_id'], $data['topic_id'], $data['forum_id'], $user->data['user_id'], time(), '', $is_starter, $is_latest); } - - // topic sync time! - // simply, we update if it is a reply or the last post is edited - if ($post_approved) + else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])) { - // reply requires the whole thing - if ($post_mode == 'reply') - { - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $data['post_id']; - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $user->data['user_id']; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'"; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . (($user->data['user_id'] != ANONYMOUS) ? $db->sql_escape($user->data['user_colour']) : '') . "'"; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'"; - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $current_time; - } - else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies'])) + if ($post_visibility == ITEM_APPROVED || $data['topic_visibility'] == $post_visibility) { // only the subject can be changed from edit $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($subject) . "'"; @@ -2053,57 +2019,44 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u { $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape($username) . "'"; } - } - } - else if (!$data['post_approved'] && ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))) - { - // like having the rug pulled from under us - $sql = 'SELECT MAX(post_id) as last_post_id - FROM ' . POSTS_TABLE . ' - WHERE topic_id = ' . (int) $data['topic_id'] . ' - AND post_approved = 1'; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - // any posts left in this forum? - if (!empty($row['last_post_id'])) - { - $sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour - FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u - WHERE p.poster_id = u.user_id - AND p.post_id = ' . (int) $row['last_post_id']; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - // salvation, a post is found! jam it into the topics table - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_id = ' . (int) $row['post_id']; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'"; - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_post_time = ' . (int) $row['post_time']; - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_poster_id = ' . (int) $row['poster_id']; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'"; - $sql_data[TOPICS_TABLE]['stat'][] = "topic_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'"; - } - } + if ($post_visibility == ITEM_APPROVED) + { + // this does not _necessarily_ mean that we must update the info again, + // it just means that we might have to + $sql = 'SELECT forum_last_post_id, forum_last_post_subject + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . (int) $data['forum_id']; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - // Update total post count, do not consider moderated posts/topics - if ($post_approval) - { - if ($post_mode == 'post') - { - set_config_count('num_topics', 1, true); - set_config_count('num_posts', 1, true); - } + // this post is the latest post in the forum, better update + if ($row['forum_last_post_id'] == $data['post_id'] && ($row['forum_last_post_subject'] !== $subject || $data['poster_id'] == ANONYMOUS)) + { + // the post's subject changed + if ($row['forum_last_post_subject'] !== $subject) + { + $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'"; + } - if ($post_mode == 'reply') - { - set_config_count('num_posts', 1, true); + // Update the user name if poster is anonymous... just in case a moderator changed it + if ($data['poster_id'] == ANONYMOUS) + { + $sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape($username) . "'"; + } + } + } } } // Update forum stats - $where_sql = array(POSTS_TABLE => 'post_id = ' . $data['post_id'], TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], FORUMS_TABLE => 'forum_id = ' . $data['forum_id'], USERS_TABLE => 'user_id = ' . $poster_id); + $where_sql = array( + POSTS_TABLE => 'post_id = ' . $data['post_id'], + TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], + FORUMS_TABLE => 'forum_id = ' . $data['forum_id'], + USERS_TABLE => 'user_id = ' . $poster_id + ); foreach ($sql_data as $table => $update_ary) { @@ -2226,7 +2179,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $phpbb_notifications = $phpbb_container->get('notification_manager'); - if ($post_approval) + if ($post_visibility == ITEM_APPROVED) { switch ($mode) { @@ -2259,7 +2212,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u break; } } - else + else if ($post_visibility == ITEM_UNAPPROVED) { switch ($mode) { @@ -2276,6 +2229,32 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'edit_first_post': case 'edit': case 'edit_last_post': + // @todo: Check whether these notification deletions are correct + $phpbb_notifications->delete_notifications('topic', $data['topic_id']); + + $phpbb_notifications->delete_notifications(array( + 'quote', + 'bookmark', + 'post', + ), $data['post_id']); + break; + } + } + else if ($post_visibility == ITEM_DELETED) + { + switch ($mode) + { + case 'post': + case 'reply': + case 'quote': + // Nothing to do here + break; + + case 'edit_topic': + case 'edit_first_post': + case 'edit': + case 'edit_last_post': + // @todo: Check whether these notification deletions are correct $phpbb_notifications->delete_notifications('topic', $data['topic_id']); $phpbb_notifications->delete_notifications(array( @@ -2289,7 +2268,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $params = $add_anchor = ''; - if ($post_approval) + if ($post_visibility == ITEM_APPROVED) { $params .= '&t=' . $data['topic_id']; diff --git a/phpBB/includes/mcp/info/mcp_queue.php b/phpBB/includes/mcp/info/mcp_queue.php index 7ad79f9781..68cac5abd2 100644 --- a/phpBB/includes/mcp/info/mcp_queue.php +++ b/phpBB/includes/mcp/info/mcp_queue.php @@ -21,6 +21,8 @@ class mcp_queue_info 'modes' => array( 'unapproved_topics' => array('title' => 'MCP_QUEUE_UNAPPROVED_TOPICS', 'auth' => 'aclf_m_approve', 'cat' => array('MCP_QUEUE')), 'unapproved_posts' => array('title' => 'MCP_QUEUE_UNAPPROVED_POSTS', 'auth' => 'aclf_m_approve', 'cat' => array('MCP_QUEUE')), + 'deleted_topics' => array('title' => 'MCP_QUEUE_DELETED_TOPICS', 'auth' => 'aclf_m_approve', 'cat' => array('MCP_QUEUE')), + 'deleted_posts' => array('title' => 'MCP_QUEUE_DELETED_POSTS', 'auth' => 'aclf_m_approve', 'cat' => array('MCP_QUEUE')), 'approve_details' => array('title' => 'MCP_QUEUE_APPROVE_DETAILS', 'auth' => 'acl_m_approve,$id || (!$id && aclf_m_approve)', 'cat' => array('MCP_QUEUE')), ), ); diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 0fad9e2a22..841a0afddb 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -22,7 +22,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) { global $template, $db, $user, $auth, $cache, $module; global $phpEx, $phpbb_root_path, $config; - global $request, $phpbb_dispatcher; + global $request, $phpbb_dispatcher, $phpbb_container; $user->add_lang(array('viewtopic', 'viewforum')); @@ -98,7 +98,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $sort_by_sql = $sort_order_sql = array(); mcp_sorting('viewforum', $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id); - $forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total; + $forum_topics = ($total == -1) ? $forum_info['forum_topics_approved'] : $total; $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); @@ -116,6 +116,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'S_CAN_REPORT' => $auth->acl_get('m_report', $forum_id), 'S_CAN_DELETE' => $auth->acl_get('m_delete', $forum_id), + 'S_CAN_RESTORE' => $auth->acl_get('m_approve', $forum_id), 'S_CAN_MERGE' => $auth->acl_get('m_merge', $forum_id), 'S_CAN_MOVE' => $auth->acl_get('m_move', $forum_id), 'S_CAN_FORK' => $auth->acl_get('m_', $forum_id), @@ -151,10 +152,12 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $read_tracking_join = $read_tracking_select = ''; } + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + $sql = 'SELECT t.topic_id FROM ' . TOPICS_TABLE . ' t WHERE t.forum_id = ' . $forum_id . ' - ' . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND t.topic_approved = 1') . " + AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.') . " $limit_time_sql ORDER BY t.topic_type DESC, $sort_order_sql"; $result = $db->sql_query_limit($sql, $topics_per_page, $start); @@ -203,7 +206,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $row = &$topic_rows[$topic_id]; - $replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; + $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1; if ($row['topic_status'] == ITEM_MOVED) { @@ -220,9 +223,11 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $topic_title = censor_text($row['topic_title']); - $topic_unapproved = (!$row['topic_approved'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; - $posts_unapproved = ($row['topic_approved'] && $row['topic_replies'] < $row['topic_replies_real'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; + $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $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'] : ''; + $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? $url . '&i=queue&mode=deleted_topics&t=' . $topic_id : $u_mcp_queue; $topic_row = array( 'ATTACH_ICON_IMG' => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['topic_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '', @@ -232,6 +237,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '', 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '', 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '', + 'DELETED_IMG' => ($topic_deleted) ? $user->img('icon_topic_deleted', 'POSTS_DELETED') : '', 'TOPIC_AUTHOR' => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), @@ -245,7 +251,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'TOPIC_TYPE' => $topic_type, 'TOPIC_TITLE' => $topic_title, - 'REPLIES' => ($auth->acl_get('m_approve', $row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies'], + 'REPLIES' => $phpbb_content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1, 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), 'FIRST_POST_TIME' => $user->format_date($row['topic_time']), 'LAST_POST_SUBJECT' => $row['topic_last_post_subject'], @@ -254,6 +260,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && empty($row['topic_moved_id']) && $auth->acl_get('m_report', $row['forum_id'])) ? true : false, 'S_TOPIC_UNAPPROVED' => $topic_unapproved, 'S_POSTS_UNAPPROVED' => $posts_unapproved, + 'S_TOPIC_DELETED' => $topic_deleted, 'S_UNREAD_TOPIC' => $unread_topic, ); diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index ba4b15895a..44cab5d910 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_approved = 0'; + AND post_visibility = ' . ITEM_UNAPPROVED; $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_approved = 0 + AND post_visibility = ' . ITEM_UNAPPROVED . ' 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 c28b466bcf..275edbe55a 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -33,7 +33,7 @@ class mcp_main function main($id, $mode) { global $auth, $db, $user, $template, $action; - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $request; $quickmod = ($mode == 'quickmod') ? true : false; @@ -108,27 +108,48 @@ class mcp_main case 'delete_topic': $user->add_lang('viewtopic'); - $topic_ids = (!$quickmod) ? request_var('topic_id_list', array(0)) : array(request_var('t', 0)); + // f parameter is not reliable for permission usage, however we just use it to decide + // which permission we will check later on. So if it is manipulated, we will still catch it later on. + $forum_id = $request->variable('f', 0); + $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0)); + $soft_delete = (($request->is_set_post('confirm') && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id)) ? true : false; if (!sizeof($topic_ids)) { trigger_error('NO_TOPIC_SELECTED'); } - mcp_delete_topic($topic_ids); + mcp_delete_topic($topic_ids, $soft_delete, ($soft_delete) ? $request->variable('delete_reason', '', true) : ''); break; case 'delete_post': $user->add_lang('posting'); - $post_ids = (!$quickmod) ? request_var('post_id_list', array(0)) : array(request_var('p', 0)); + // f parameter is not reliable for permission usage, however we just use it to decide + // which permission we will check later on. So if it is manipulated, we will still catch it later on. + $forum_id = $request->variable('f', 0); + $post_ids = (!$quickmod) ? $request->variable('post_id_list', array(0)) : array($request->variable('p', 0)); + $soft_delete = (($request->is_set_post('confirm') && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id)) ? true : false; if (!sizeof($post_ids)) { trigger_error('NO_POST_SELECTED'); } - mcp_delete_post($post_ids); + mcp_delete_post($post_ids, $soft_delete, ($soft_delete) ? $request->variable('delete_reason', '', true) : ''); + break; + + case 'restore_topic': + $user->add_lang('posting'); + + $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0)); + + if (!sizeof($topic_ids)) + { + trigger_error('NO_TOPIC_SELECTED'); + } + + mcp_restore_topic($topic_ids); break; } @@ -455,59 +476,30 @@ function mcp_move_topic($topic_ids) $forum_sync_data[$forum_id] = current($topic_data); $forum_sync_data[$to_forum_id] = $forum_data; - // Real topics added to target forum - $topics_moved = sizeof($topic_data); - - // Approved topics added to target forum - $topics_authed_moved = 0; - - // Posts (topic replies + topic post if approved) added to target forum - $topic_posts_added = 0; - - // Posts (topic replies + topic post if approved and not global announcement) removed from source forum - $topic_posts_removed = 0; - - // Real topics removed from source forum (all topics without global announcements) - $topics_removed = 0; - - // Approved topics removed from source forum (except global announcements) - $topics_authed_removed = 0; + $topics_moved = $topics_moved_unapproved = $topics_moved_softdeleted = 0; + $posts_moved = $posts_moved_unapproved = $posts_moved_softdeleted = 0; foreach ($topic_data as $topic_id => $topic_info) { - if ($topic_info['topic_approved']) + if ($topic_info['topic_visibility'] == ITEM_APPROVED) { - $topics_authed_moved++; - $topic_posts_added++; + $topics_moved++; } - - $topic_posts_added += $topic_info['topic_replies']; - - $topics_removed++; - $topic_posts_removed += $topic_info['topic_replies']; - - if ($topic_info['topic_approved']) + elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED) { - $topics_authed_removed++; - $topic_posts_removed++; + $topics_moved_unapproved++; + } + elseif ($topic_info['topic_visibility'] == ITEM_DELETED) + { + $topics_moved_softdeleted++; } - } - - $db->sql_transaction('begin'); - - $sync_sql = array(); - - if ($topic_posts_added) - { - $sync_sql[$to_forum_id][] = 'forum_posts = forum_posts + ' . $topic_posts_added; - } - if ($topics_authed_moved) - { - $sync_sql[$to_forum_id][] = 'forum_topics = forum_topics + ' . (int) $topics_authed_moved; + $posts_moved += $topic_info['topic_posts_approved']; + $posts_moved_unapproved += $topic_info['topic_posts_unapproved']; + $posts_moved_softdeleted += $topic_info['topic_posts_softdeleted']; } - $sync_sql[$to_forum_id][] = 'forum_topics_real = forum_topics_real + ' . (int) $topics_moved; + $db->sql_transaction('begin'); // Move topics, but do not resync yet move_topics($topic_ids, $to_forum_id, false); @@ -520,6 +512,7 @@ function mcp_move_topic($topic_ids) $db->sql_query($sql); } + $shadow_topics = 0; $forum_ids = array($to_forum_id); foreach ($topic_data as $topic_id => $row) { @@ -528,21 +521,22 @@ function mcp_move_topic($topic_ids) add_log('mod', $to_forum_id, $topic_id, 'LOG_MOVE', $row['forum_name'], $forum_data['forum_name']); // Leave a redirection if required and only if the topic is visible to users - if ($leave_shadow && $row['topic_approved'] && $row['topic_type'] != POST_GLOBAL) + if ($leave_shadow && $row['topic_visibility'] == ITEM_APPROVED && $row['topic_type'] != POST_GLOBAL) { $shadow = array( 'forum_id' => (int) $row['forum_id'], 'icon_id' => (int) $row['icon_id'], 'topic_attachment' => (int) $row['topic_attachment'], - 'topic_approved' => 1, // a shadow topic is always approved + 'topic_visibility' => ITEM_APPROVED, // a shadow topic is always approved 'topic_reported' => 0, // a shadow topic is never reported 'topic_title' => (string) $row['topic_title'], 'topic_poster' => (int) $row['topic_poster'], 'topic_time' => (int) $row['topic_time'], 'topic_time_limit' => (int) $row['topic_time_limit'], 'topic_views' => (int) $row['topic_views'], - 'topic_replies' => (int) $row['topic_replies'], - 'topic_replies_real' => (int) $row['topic_replies_real'], + 'topic_posts_approved' => (int) $row['topic_posts_approved'], + 'topic_posts_unapproved'=> (int) $row['topic_posts_unapproved'], + 'topic_posts_softdeleted'=> (int) $row['topic_posts_softdeleted'], 'topic_status' => ITEM_MOVED, 'topic_type' => POST_NORMAL, 'topic_first_post_id' => (int) $row['topic_first_post_id'], @@ -568,25 +562,45 @@ function mcp_move_topic($topic_ids) $db->sql_query('INSERT INTO ' . TOPICS_TABLE . $db->sql_build_array('INSERT', $shadow)); // Shadow topics only count on new "topics" and not posts... a shadow topic alone has 0 posts - $topics_removed--; - $topics_authed_removed--; + $shadow_topics++; } } unset($topic_data); - if ($topic_posts_removed) + $sync_sql = array(); + if ($posts_moved) { - $sync_sql[$forum_id][] = 'forum_posts = forum_posts - ' . $topic_posts_removed; + $sync_sql[$to_forum_id][] = 'forum_posts_approved = forum_posts_approved + ' . (int) $posts_moved; + $sync_sql[$forum_id][] = 'forum_posts_approved = forum_posts_approved - ' . (int) $posts_moved; } - - if ($topics_removed) + if ($posts_moved_unapproved) + { + $sync_sql[$to_forum_id][] = 'forum_posts_unapproved = forum_posts_unapproved + ' . (int) $posts_moved_unapproved; + $sync_sql[$forum_id][] = 'forum_posts_unapproved = forum_posts_unapproved - ' . (int) $posts_moved_unapproved; + } + if ($posts_moved_softdeleted) { - $sync_sql[$forum_id][] = 'forum_topics_real = forum_topics_real - ' . (int) $topics_removed; + $sync_sql[$to_forum_id][] = 'forum_posts_softdeleted = forum_posts_softdeleted + ' . (int) $posts_moved_softdeleted; + $sync_sql[$forum_id][] = 'forum_posts_softdeleted = forum_posts_softdeleted - ' . (int) $posts_moved_softdeleted; } - if ($topics_authed_removed) + if ($topics_moved) { - $sync_sql[$forum_id][] = 'forum_topics = forum_topics - ' . (int) $topics_authed_removed; + $sync_sql[$to_forum_id][] = 'forum_topics_approved = forum_topics_approved + ' . (int) $topics_moved; + if ($topics_moved - $shadow_topics > 0) + { + $sync_sql[$forum_id][] = 'forum_topics_approved = forum_topics_approved - ' . (int) ($topics_moved - $shadow_topics); + } + } + if ($topics_moved_unapproved) + { + $sync_sql[$to_forum_id][] = 'forum_topics_unapproved = forum_topics_unapproved + ' . (int) $topics_moved_unapproved; + $sync_sql[$forum_id][] = 'forum_topics_unapproved = forum_topics_unapproved - ' . (int) $topics_moved_unapproved; + } + if ($topics_moved_softdeleted) + { + $sync_sql[$to_forum_id][] = 'forum_topics_softdeleted = forum_topics_softdeleted + ' . (int) $topics_moved_softdeleted; + $sync_sql[$forum_id][] = 'forum_topics_softdeleted = forum_topics_softdeleted - ' . (int) $topics_moved_softdeleted; } $success_msg = (sizeof($topic_ids) == 1) ? 'TOPIC_MOVED_SUCCESS' : 'TOPICS_MOVED_SUCCESS'; @@ -636,25 +650,98 @@ function mcp_move_topic($topic_ids) } /** +* Restore Topics +*/ +function mcp_restore_topic($topic_ids) +{ + global $auth, $user, $db, $phpEx, $phpbb_root_path, $request, $phpbb_container; + + if (!check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_approve'))) + { + return; + } + + $redirect = $request->variable('redirect', build_url(array('action', 'quickmod'))); + $forum_id = $request->variable('f', 0); + + $s_hidden_fields = build_hidden_fields(array( + 'topic_id_list' => $topic_ids, + 'f' => $forum_id, + 'action' => 'restore_topic', + 'redirect' => $redirect, + )); + $success_msg = ''; + + if (confirm_box(true)) + { + $success_msg = (sizeof($topic_ids) == 1) ? 'TOPIC_RESTORED_SUCCESS' : 'TOPICS_RESTORED_SUCCESS'; + + $data = get_topic_data($topic_ids); + + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + foreach ($data as $topic_id => $row) + { + $return = $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $row['forum_id'], $user->data['user_id'], time(), ''); + if (!empty($return)) + { + add_log('mod', $row['forum_id'], $topic_id, 'LOG_RESTORE_TOPIC', $row['topic_title'], $row['topic_first_poster_name']); + } + } + } + else + { + confirm_box(false, (sizeof($topic_ids) == 1) ? 'RESTORE_TOPIC' : 'RESTORE_TOPICS', $s_hidden_fields); + } + + $topic_id = $request->variable('t', 0); + if (!$request->is_set('quickmod', phpbb_request_interface::REQUEST)) + { + $redirect = $request->variable('redirect', "index.$phpEx"); + $redirect = reapply_sid($redirect); + $redirect_message = 'PAGE'; + } + else if ($topic_id) + { + $redirect = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id); + $redirect_message = 'TOPIC'; + } + else + { + $redirect = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id); + $redirect_message = 'FORUM'; + } + + if (!$success_msg) + { + redirect($redirect); + } + else + { + meta_refresh(3, $redirect); + trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_' . $redirect_message], '<a href="' . $redirect . '">', '</a>')); + } +} + +/** * Delete Topics */ -function mcp_delete_topic($topic_ids) +function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = '', $action = 'delete_topic') { - global $auth, $user, $db, $phpEx, $phpbb_root_path; + global $auth, $user, $db, $phpEx, $phpbb_root_path, $request, $phpbb_container; if (!check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_delete'))) { return; } - $redirect = request_var('redirect', build_url(array('action', 'quickmod'))); - $forum_id = request_var('f', 0); + $redirect = $request->variable('redirect', build_url(array('action', 'quickmod'))); + $forum_id = $request->variable('f', 0); - $s_hidden_fields = build_hidden_fields(array( + $s_hidden_fields = array( 'topic_id_list' => $topic_ids, 'f' => $forum_id, - 'action' => 'delete_topic', - 'redirect' => $redirect) + 'action' => $action, + 'redirect' => $redirect, ); $success_msg = ''; @@ -672,23 +759,81 @@ function mcp_delete_topic($topic_ids) } else { - add_log('mod', $row['forum_id'], $topic_id, 'LOG_DELETE_TOPIC', $row['topic_title'], $row['topic_first_poster_name']); + // Only soft delete non-shadow topics + if ($is_soft) + { + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + $return = $phpbb_content_visibility->set_topic_visibility(ITEM_DELETED, $topic_id, $row['forum_id'], $user->data['user_id'], time(), $soft_delete_reason); + if (!empty($return)) + { + add_log('mod', $row['forum_id'], $topic_id, 'LOG_SOFTDELETE_TOPIC', $row['topic_title'], $row['topic_first_poster_name']); + } + } + else + { + add_log('mod', $row['forum_id'], $topic_id, 'LOG_DELETE_TOPIC', $row['topic_title'], $row['topic_first_poster_name']); + } } } - $return = delete_topics('topic_id', $topic_ids); + if (!$is_soft) + { + $return = delete_topics('topic_id', $topic_ids); + } } else { - confirm_box(false, (sizeof($topic_ids) == 1) ? 'DELETE_TOPIC' : 'DELETE_TOPICS', $s_hidden_fields); + global $template; + + $user->add_lang('posting'); + + $only_softdeleted = false; + if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id)) + { + // If there are only soft deleted topics, we display a message why the option is not available + $sql = 'SELECT topic_id + FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . ' + AND topic_visibility <> ' . ITEM_DELETED; + $result = $db->sql_query_limit($sql, 1); + $only_softdeleted = !$db->sql_fetchfield('topic_id'); + $db->sql_freeresult($result); + } + + $template->assign_vars(array( + 'S_SOFTDELETED' => $only_softdeleted, + 'S_TOPIC_MODE' => true, + 'S_ALLOWED_DELETE' => $auth->acl_get('m_delete', $forum_id), + 'S_ALLOWED_SOFTDELETE' => $auth->acl_get('m_softdelete', $forum_id), + 'S_DELETE_REASON' => $auth->acl_get('m_softdelete', $forum_id), + )); + + $l_confirm = (sizeof($topic_ids) == 1) ? 'DELETE_TOPIC' : 'DELETE_TOPICS'; + if ($only_softdeleted) + { + $l_confirm .= '_PERMANENTLY'; + $s_hidden_fields['delete_permanent'] = '1'; + } + else if (!$auth->acl_get('m_softdelete', $forum_id)) + { + $s_hidden_fields['delete_permanent'] = '1'; + } + + confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html'); } - if (!isset($_REQUEST['quickmod'])) + $topic_id = $request->variable('t', 0); + if (!$request->is_set('quickmod', phpbb_request_interface::REQUEST)) { - $redirect = request_var('redirect', "index.$phpEx"); + $redirect = $request->variable('redirect', "index.$phpEx"); $redirect = reapply_sid($redirect); $redirect_message = 'PAGE'; } + else if ($is_soft && $topic_id) + { + $redirect = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id); + $redirect_message = 'TOPIC'; + } else { $redirect = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id); @@ -709,27 +854,93 @@ function mcp_delete_topic($topic_ids) /** * Delete Posts */ -function mcp_delete_post($post_ids) +function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '', $action = 'delete_post') { - global $auth, $user, $db, $phpEx, $phpbb_root_path; + global $auth, $user, $db, $phpEx, $phpbb_root_path, $request, $phpbb_container; - if (!check_ids($post_ids, POSTS_TABLE, 'post_id', array('m_delete'))) + if (!check_ids($post_ids, POSTS_TABLE, 'post_id', array('m_softdelete'))) { return; } - $redirect = request_var('redirect', build_url(array('action', 'quickmod'))); - $forum_id = request_var('f', 0); + $redirect = $request->variable('redirect', build_url(array('action', 'quickmod'))); + $forum_id = $request->variable('f', 0); - $s_hidden_fields = build_hidden_fields(array( + $s_hidden_fields = array( 'post_id_list' => $post_ids, 'f' => $forum_id, - 'action' => 'delete_post', - 'redirect' => $redirect) + 'action' => $action, + 'redirect' => $redirect, ); $success_msg = ''; - if (confirm_box(true)) + if (confirm_box(true) && $is_soft) + { + $post_info = get_post_data($post_ids); + + $topic_info = $approve_log = array(); + + // Group the posts by topic_id + foreach ($post_info as $post_id => $post_data) + { + if ($post_data['post_visibility'] != ITEM_APPROVED) + { + continue; + } + $topic_id = (int) $post_data['topic_id']; + + $topic_info[$topic_id]['posts'][] = (int) $post_id; + $topic_info[$topic_id]['forum_id'] = (int) $post_data['forum_id']; + + if ($post_id == $post_data['topic_first_post_id']) + { + $topic_info[$topic_id]['first_post'] = true; + } + + if ($post_id == $post_data['topic_last_post_id']) + { + $topic_info[$topic_id]['last_post'] = true; + } + + $approve_log[] = array( + 'forum_id' => $post_data['forum_id'], + 'topic_id' => $post_data['topic_id'], + 'post_subject' => $post_data['post_subject'], + 'poster_id' => $post_data['poster_id'], + 'post_username' => $post_data['post_username'], + 'username' => $post_data['username'], + ); + } + + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + foreach ($topic_info as $topic_id => $topic_data) + { + $phpbb_content_visibility->set_post_visibility(ITEM_DELETED, $topic_data['posts'], $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), $soft_delete_reason, isset($topic_data['first_post']), isset($topic_data['last_post'])); + } + $affected_topics = sizeof($topic_info); + // None of the topics is really deleted, so a redirect won't hurt much. + $deleted_topics = 0; + + $success_msg = (sizeof($post_info) == 1) ? 'POST_DELETED_SUCCESS' : 'POSTS_DELETED_SUCCESS'; + + foreach ($approve_log as $row) + { + $post_username = ($row['poster_id'] == ANONYMOUS && !empty($row['post_username'])) ? $row['post_username'] : $row['username']; + add_log('mod', $row['forum_id'], $row['topic_id'], 'LOG_SOFTDELETE_POST', $row['post_subject'], $post_username); + } + + $topic_id = $request->variable('t', 0); + + // Return links + $return_link = array(); + if ($affected_topics == 1 && $topic_id) + { + $return_link[] = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id") . '">', '</a>'); + } + $return_link[] = sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); + + } + else if (confirm_box(true)) { if (!function_exists('delete_posts')) { @@ -772,7 +983,7 @@ function mcp_delete_post($post_ids) $deleted_topics = ($row = $db->sql_fetchrow($result)) ? ($affected_topics - $row['topics_left']) : $affected_topics; $db->sql_freeresult($result); - $topic_id = request_var('t', 0); + $topic_id = $request->variable('t', 0); // Return links $return_link = array(); @@ -810,10 +1021,45 @@ function mcp_delete_post($post_ids) } else { - confirm_box(false, (sizeof($post_ids) == 1) ? 'DELETE_POST' : 'DELETE_POSTS', $s_hidden_fields); + global $template; + + $user->add_lang('posting'); + + $only_softdeleted = false; + if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id)) + { + // If there are only soft deleted posts, we display a message why the option is not available + $sql = 'SELECT post_id + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('post_id', $post_ids) . ' + AND post_visibility <> ' . ITEM_DELETED; + $result = $db->sql_query_limit($sql, 1); + $only_softdeleted = !$db->sql_fetchfield('post_id'); + $db->sql_freeresult($result); + } + + $template->assign_vars(array( + 'S_SOFTDELETED' => $only_softdeleted, + 'S_ALLOWED_DELETE' => $auth->acl_get('m_delete', $forum_id), + 'S_ALLOWED_SOFTDELETE' => $auth->acl_get('m_softdelete', $forum_id), + 'S_DELETE_REASON' => $auth->acl_get('m_softdelete', $forum_id), + )); + + $l_confirm = (sizeof($post_ids) == 1) ? 'DELETE_POST' : 'DELETE_POSTS'; + if ($only_softdeleted) + { + $l_confirm .= '_PERMANENTLY'; + $s_hidden_fields['delete_permanent'] = '1'; + } + else if (!$auth->acl_get('m_softdelete', $forum_id)) + { + $s_hidden_fields['delete_permanent'] = '1'; + } + + confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html'); } - $redirect = request_var('redirect', "index.$phpEx"); + $redirect = $request->variable('redirect', "index.$phpEx"); $redirect = reapply_sid($redirect); if (!$success_msg) @@ -898,10 +1144,10 @@ function mcp_fork_topic($topic_ids) { $topic_data = get_topic_data($topic_ids, 'f_post'); - $total_posts = 0; + $total_topics = $total_topics_unapproved = $total_topics_softdeleted = 0; + $total_posts = $total_posts_unapproved = $total_posts_softdeleted = 0; $new_topic_id_list = array(); - foreach ($topic_data as $topic_id => $topic_row) { if (!isset($search_type) && $topic_row['enable_indexing']) @@ -932,13 +1178,14 @@ function mcp_fork_topic($topic_ids) 'forum_id' => (int) $to_forum_id, 'icon_id' => (int) $topic_row['icon_id'], 'topic_attachment' => (int) $topic_row['topic_attachment'], - 'topic_approved' => 1, + 'topic_visibility' => (int) $topic_row['topic_visibility'], 'topic_reported' => 0, 'topic_title' => (string) $topic_row['topic_title'], 'topic_poster' => (int) $topic_row['topic_poster'], 'topic_time' => (int) $topic_row['topic_time'], - 'topic_replies' => (int) $topic_row['topic_replies_real'], - 'topic_replies_real' => (int) $topic_row['topic_replies_real'], + 'topic_posts_approved' => (int) $topic_row['topic_posts_approved'], + 'topic_posts_unapproved' => (int) $topic_row['topic_posts_unapproved'], + 'topic_posts_softdeleted' => (int) $topic_row['topic_posts_softdeleted'], 'topic_status' => (int) $topic_row['topic_status'], 'topic_type' => (int) $topic_row['topic_type'], 'topic_first_poster_name' => (string) $topic_row['topic_first_poster_name'], @@ -959,6 +1206,19 @@ function mcp_fork_topic($topic_ids) $new_topic_id = $db->sql_nextid(); $new_topic_id_list[$topic_id] = $new_topic_id; + switch ($topic_row['topic_visibility']) + { + case ITEM_APPROVED: + $total_topics++; + break; + case ITEM_UNAPPROVED: + $total_topics_unapproved++; + break; + case ITEM_DELETED: + $total_topics_softdeleted++; + break; + } + if ($topic_row['poll_start']) { $poll_rows = array(); @@ -999,7 +1259,6 @@ function mcp_fork_topic($topic_ids) continue; } - $total_posts += sizeof($post_rows); foreach ($post_rows as $row) { $sql_ary = array( @@ -1009,7 +1268,7 @@ function mcp_fork_topic($topic_ids) 'icon_id' => (int) $row['icon_id'], 'poster_ip' => (string) $row['poster_ip'], 'post_time' => (int) $row['post_time'], - 'post_approved' => 1, + 'post_visibility' => (int) $row['post_visibility'], 'post_reported' => 0, 'enable_bbcode' => (int) $row['enable_bbcode'], 'enable_smilies' => (int) $row['enable_smilies'], @@ -1033,6 +1292,19 @@ function mcp_fork_topic($topic_ids) $db->sql_query('INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_post_id = $db->sql_nextid(); + switch ($row['post_visibility']) + { + case ITEM_APPROVED: + $total_posts++; + break; + case ITEM_UNAPPROVED: + $total_posts_unapproved++; + break; + case ITEM_DELETED: + $total_posts_softdeleted++; + break; + } + // Copy whether the topic is dotted markread('post', $to_forum_id, $new_topic_id, 0, $row['poster_id']); @@ -1125,23 +1397,19 @@ function mcp_fork_topic($topic_ids) } // Sync new topics, parent forums and board stats - sync('topic', 'topic_id', $new_topic_id_list); - - $sync_sql = array(); - - $sync_sql[$to_forum_id][] = 'forum_posts = forum_posts + ' . $total_posts; - $sync_sql[$to_forum_id][] = 'forum_topics = forum_topics + ' . sizeof($new_topic_id_list); - $sync_sql[$to_forum_id][] = 'forum_topics_real = forum_topics_real + ' . sizeof($new_topic_id_list); - - foreach ($sync_sql as $forum_id_key => $array) - { - $sql = 'UPDATE ' . FORUMS_TABLE . ' - SET ' . implode(', ', $array) . ' - WHERE forum_id = ' . $forum_id_key; - $db->sql_query($sql); - } + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET forum_posts_approved = forum_posts_approved + ' . $total_posts . ', + forum_posts_unapproved = forum_posts_unapproved + ' . $total_posts_unapproved . ', + forum_posts_softdeleted = forum_posts_softdeleted + ' . $total_posts_softdeleted . ', + forum_topics_approved = forum_topics_approved + ' . $total_topics . ', + forum_topics_unapproved = forum_topics_unapproved + ' . $total_topics_unapproved . ', + forum_topics_softdeleted = forum_topics_softdeleted + ' . $total_topics_softdeleted . ' + WHERE forum_id = ' . $to_forum_id; + $db->sql_query($sql); + sync('topic', 'topic_id', $new_topic_id_list); sync('forum', 'forum_id', $to_forum_id); + set_config_count('num_topics', sizeof($new_topic_id_list), true); set_config_count('num_posts', $total_posts, true); diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index 520c964228..734fa96a78 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -174,6 +174,33 @@ function mcp_post_details($id, $mode, $action) } } + // Deleting information + if ($post_info['post_visibility'] == ITEM_DELETED && $post_info['post_delete_user']) + { + // User having deleted the post also being the post author? + if (!$post_info['post_delete_user'] || $post_info['post_delete_user'] == $post_info['poster_id']) + { + $display_username = get_username_string('full', $post_info['poster_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']); + } + else + { + $sql = 'SELECT user_id, username, user_colour + FROM ' . USERS_TABLE . ' + WHERE user_id = ' . (int) $post_info['post_delete_user']; + $result = $db->sql_query($sql); + $user_delete_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + $display_username = get_username_string('full', $post_info['post_delete_user'], $user_delete_row['username'], $user_delete_row['user_colour']); + } + + $user->add_lang('viewtopic'); + $l_deleted_by = $user->lang('DELETED_INFORMATION', $display_username, $user->format_date($post_info['post_delete_time'], false, true)); + } + else + { + $l_deleted_by = ''; + } + $template->assign_vars(array( 'U_MCP_ACTION' => "$url&i=main&quickmod=1&mode=post_details", // Use this for mode paramaters 'U_POST_ACTION' => "$url&i=$id&mode=post_details", // Use this for action parameters @@ -185,10 +212,13 @@ 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_approved']) ? true : false, + 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED) ? 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, 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, + 'DELETED_MESSAGE' => $l_deleted_by, + 'DELETE_REASON' => $post_info['post_delete_reason'], 'U_EDIT' => ($auth->acl_get('m_edit', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f={$post_info['forum_id']}&p={$post_info['post_id']}") : '', 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_chgposter&field=username&select_single=true'), @@ -205,6 +235,7 @@ function mcp_post_details($id, $mode, $action) 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$post_info['forum_id']}&start={$start}") . '">', '</a>'), 'REPORTED_IMG' => $user->img('icon_topic_reported', $user->lang['POST_REPORTED']), 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', $user->lang['POST_UNAPPROVED']), + 'DELETED_IMG' => $user->img('icon_topic_deleted', $user->lang['POST_DELETED']), 'EDIT_IMG' => $user->img('icon_post_edit', $user->lang['EDIT_POST']), 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), @@ -415,7 +446,7 @@ function change_poster(&$post_info, $userdata) } // Adjust post counts... only if the post is approved (else, it was not added the users post count anyway) - if ($post_info['post_postcount'] && $post_info['post_approved']) + if ($post_info['post_postcount'] && $post_info['post_visibility'] == ITEM_APPROVED) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - 1 diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 24afa1f210..8a9390212f 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -25,14 +25,14 @@ class mcp_queue var $p_master; var $u_action; - function mcp_queue(&$p_master) + public function mcp_queue(&$p_master) { $this->p_master = &$p_master; } - function main($id, $mode) + public function main($id, $mode) { - global $auth, $db, $user, $template, $cache; + global $auth, $db, $user, $template, $cache, $request; global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container; include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); @@ -45,25 +45,99 @@ class mcp_queue switch ($action) { case 'approve': - case 'disapprove': + case 'restore': include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); - $post_id_list = request_var('post_id_list', array(0)); + $post_id_list = $request->variable('post_id_list', array(0)); + $topic_id_list = $request->variable('topic_id_list', array(0)); - if (!sizeof($post_id_list)) + if (!empty($post_id_list)) + { + self::approve_posts($action, $post_id_list, 'queue', $mode); + } + else if (!empty($topic_id_list)) + { + self::approve_topics($action, $topic_id_list, 'queue', $mode); + } + else { trigger_error('NO_POST_SELECTED'); } + break; + + case 'delete': + $post_id_list = $request->variable('post_id_list', array(0)); + $topic_id_list = $request->variable('topic_id_list', array(0)); - if ($action == 'approve') + if (!empty($post_id_list)) + { + if (!function_exists('mcp_delete_post')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx); + } + mcp_delete_post($post_id_list, false, '', $action); + } + else if (!empty($topic_id_list)) { - approve_post($post_id_list, 'queue', $mode); + if (!function_exists('mcp_delete_topic')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx); + } + mcp_delete_topic($topic_id_list, false, '', $action); } else { - disapprove_post($post_id_list, 'queue', $mode); + trigger_error('NO_POST_SELECTED'); } + break; + case 'disapprove': + $post_id_list = $request->variable('post_id_list', array(0)); + $topic_id_list = $request->variable('topic_id_list', array(0)); + + if (!empty($topic_id_list) && $mode == 'deleted_topics') + { + if (!function_exists('mcp_delete_topics')) + { + global $phpbb_root_path, $phpEx; + include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx); + } + mcp_delete_topic($topic_id_list, false, '', 'disapprove'); + return; + } + + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } + + if (!empty($topic_id_list)) + { + $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : ITEM_UNAPPROVED; + $sql = 'SELECT post_id + FROM ' . POSTS_TABLE . ' + WHERE post_visibility = ' . $post_visibility . ' + AND ' . $db->sql_in_set('topic_id', $topic_id_list); + $result = $db->sql_query($sql); + + $post_id_list = array(); + while ($row = $db->sql_fetchrow($result)) + { + $post_id_list[] = (int) $row['post_id']; + } + $db->sql_freeresult($result); + } + + if (!empty($post_id_list)) + { + self::disapprove_posts($post_id_list, 'queue', $mode); + } + else + { + trigger_error('NO_POST_SELECTED'); + } break; } @@ -111,8 +185,8 @@ class mcp_queue $template->assign_vars(array( 'S_TOPIC_REVIEW' => true, 'S_BBCODE_ALLOWED' => $post_info['enable_bbcode'], - 'TOPIC_TITLE' => $post_info['topic_title']) - ); + 'TOPIC_TITLE' => $post_info['topic_title'], + )); } $extensions = $attachments = $topic_tracking_info = array(); @@ -175,12 +249,39 @@ class mcp_queue foreach ($attachments as $attachment) { $template->assign_block_vars('attachment', array( - 'DISPLAY_ATTACHMENT' => $attachment) - ); + 'DISPLAY_ATTACHMENT' => $attachment, + )); } } } + // Deleting information + if ($post_info['post_visibility'] == ITEM_DELETED && $post_info['post_delete_user']) + { + // User having deleted the post also being the post author? + if (!$post_info['post_delete_user'] || $post_info['post_delete_user'] == $post_info['poster_id']) + { + $display_username = get_username_string('full', $post_info['poster_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']); + } + else + { + $sql = 'SELECT u.user_id, u.username, u.user_colour + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u + WHERE p.post_id = ' . $post_info['post_id'] . ' + AND p.post_delete_user = u.user_id'; + $result = $db->sql_query($sql); + $post_delete_userinfo = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + $display_username = get_username_string('full', $post_info['post_delete_user'], $post_delete_userinfo['username'], $post_delete_userinfo['user_colour']); + } + + $l_deleted_by = $user->lang('DELETED_INFORMATION', $display_username, $user->format_date($post_info['post_delete_time'], false, true)); + } + else + { + $l_deleted_by = ''; + } + $post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&p=' . $post_info['post_id'] . '#p' . $post_info['post_id']); $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']); @@ -189,9 +290,12 @@ 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_approved'], + 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_USER_NOTES' => true, + 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED), + 'DELETED_MESSAGE' => $l_deleted_by, + 'DELETE_REASON' => $post_info['post_delete_reason'], 'U_EDIT' => ($auth->acl_get('m_edit', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f={$post_info['forum_id']}&p={$post_info['post_id']}") : '', 'U_MCP_APPROVE' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&f=' . $post_info['forum_id'] . '&p=' . $post_id), @@ -203,7 +307,8 @@ class mcp_queue 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), - 'RETURN_QUEUE' => sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&mode=unapproved_topics' : '&mode=unapproved_posts')) . "&start=$start\">", '</a>'), + + 'RETURN_QUEUE' => sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&mode=unapproved_topics' : '&mode=unapproved_posts')) . '&start=' . $start . '">', '</a>'), 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'), 'RETURN_TOPIC_SIMPLE' => sprintf($user->lang['RETURN_TOPIC_SIMPLE'], '<a href="' . $topic_url . '">', '</a>'), 'REPORTED_IMG' => $user->img('icon_topic_reported', $user->lang['POST_REPORTED']), @@ -230,9 +335,16 @@ class mcp_queue case 'unapproved_topics': case 'unapproved_posts': + case 'deleted_topics': + case 'deleted_posts': + $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; + $user->add_lang(array('viewtopic', 'viewforum')); - $topic_id = request_var('t', 0); + $topic_id = $request->variable('t', 0); $forum_info = array(); if ($topic_id) @@ -248,7 +360,7 @@ class mcp_queue $forum_id = $topic_info['forum_id']; } - $forum_list_approve = get_forum_list('m_approve', false, true); + $forum_list_approve = get_forum_list($m_perm, false, true); $forum_list_read = array_flip(get_forum_list('f_read', true, true)); // Flipped so we can isset() the forum IDs // Remove forums we cannot read @@ -274,16 +386,16 @@ class mcp_queue trigger_error('NOT_MODERATOR'); } - $sql = 'SELECT SUM(forum_topics) as sum_forum_topics + $sql = 'SELECT SUM(forum_topics_approved) as sum_forum_topics FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list); $result = $db->sql_query($sql); - $forum_info['forum_topics'] = (int) $db->sql_fetchfield('sum_forum_topics'); + $forum_info['forum_topics_approved'] = (int) $db->sql_fetchfield('sum_forum_topics'); $db->sql_freeresult($result); } else { - $forum_info = get_forum_data(array($forum_id), 'm_approve'); + $forum_info = get_forum_data(array($forum_id), $m_perm); if (!sizeof($forum_info)) { @@ -305,21 +417,22 @@ class mcp_queue $sort_by_sql = $sort_order_sql = array(); mcp_sorting($mode, $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id, $topic_id); - $forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total; + $forum_topics = ($total == -1) ? $forum_info['forum_topics_approved'] : $total; $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; $forum_names = array(); - if ($mode == 'unapproved_posts') + if (!$is_topics) { $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_approved = 0 + AND 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 - AND t.topic_first_post_id <> p.post_id + AND (t.topic_visibility <> p.post_visibility + OR t.topic_delete_user = 0) $limit_time_sql ORDER BY $sort_order_sql"; $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); @@ -365,9 +478,10 @@ class mcp_queue else { $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_approved = 0 + FROM ' . TOPICS_TABLE . ' t + WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' + AND topic_visibility = ' . $visibility_const . " + AND topic_delete_user <> 0 $limit_time_sql ORDER BY $sort_order_sql"; $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); @@ -401,7 +515,7 @@ class mcp_queue { if (empty($row['post_username'])) { - $row['post_username'] = $user->lang['GUEST']; + $row['post_username'] = $row['username'] ?: $user->lang['GUEST']; } $template->assign_block_vars('postrow', array( @@ -416,6 +530,7 @@ class mcp_queue 'U_POST_AUTHOR' => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']), 'POST_ID' => $row['post_id'], + 'TOPIC_ID' => $row['topic_id'], 'FORUM_NAME' => $forum_names[$row['forum_id']], 'POST_SUBJECT' => ($row['post_subject'] != '') ? $row['post_subject'] : $user->lang['NO_SUBJECT'], 'TOPIC_TITLE' => $row['topic_title'], @@ -430,581 +545,693 @@ class mcp_queue // Now display the page $template->assign_vars(array( - 'L_DISPLAY_ITEMS' => ($mode == 'unapproved_posts') ? $user->lang['DISPLAY_POSTS'] : $user->lang['DISPLAY_TOPICS'], - 'L_EXPLAIN' => ($mode == 'unapproved_posts') ? $user->lang['MCP_QUEUE_UNAPPROVED_POSTS_EXPLAIN'] : $user->lang['MCP_QUEUE_UNAPPROVED_TOPICS_EXPLAIN'], - 'L_TITLE' => ($mode == 'unapproved_posts') ? $user->lang['MCP_QUEUE_UNAPPROVED_POSTS'] : $user->lang['MCP_QUEUE_UNAPPROVED_TOPICS'], + 'L_DISPLAY_ITEMS' => (!$is_topics) ? $user->lang['DISPLAY_POSTS'] : $user->lang['DISPLAY_TOPICS'], + 'L_EXPLAIN' => $user->lang['MCP_QUEUE_' . strtoupper($mode) . '_EXPLAIN'], + 'L_TITLE' => $user->lang['MCP_QUEUE_' . strtoupper($mode)], 'L_ONLY_TOPIC' => ($topic_id) ? sprintf($user->lang['ONLY_TOPIC'], $topic_info['topic_title']) : '', 'S_FORUM_OPTIONS' => $forum_options, 'S_MCP_ACTION' => build_url(array('t', 'f', 'sd', 'st', 'sk')), - 'S_TOPICS' => ($mode == 'unapproved_posts') ? false : true, + 'S_TOPICS' => $is_topics, + 'S_RESTORE' => $is_restore, 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOPIC_ID' => $topic_id, - 'TOTAL' => $user->lang((($mode == 'unapproved_posts') ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total), + 'TOTAL' => $user->lang(((!$is_topics) ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total), )); $this->tpl_name = 'mcp_queue'; break; } } -} - -/** -* Approve Post/Topic -*/ -function approve_post($post_id_list, $id, $mode) -{ - global $db, $template, $user, $config; - global $phpEx, $phpbb_root_path; - global $request, $phpbb_container; - if (!check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) + /** + * Approve/Restore posts + * + * @param $action string Action we perform on the posts ('approve' or 'restore') + * @param $post_id_list array IDs of the posts to approve/restore + * @param $id mixed Category of the current active module + * @param $mode string Active module + * @return null + */ + static public function approve_posts($action, $post_id_list, $id, $mode) { - trigger_error('NOT_AUTHORISED'); - } + global $db, $template, $user, $config, $request, $phpbb_container; + global $phpEx, $phpbb_root_path; - $redirect = request_var('redirect', build_url(array('quickmod'))); - $success_msg = ''; + if (!check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) + { + trigger_error('NOT_AUTHORISED'); + } - $s_hidden_fields = build_hidden_fields(array( - 'i' => $id, - 'mode' => $mode, - 'post_id_list' => $post_id_list, - 'action' => 'approve', - 'redirect' => $redirect) - ); + $redirect = $request->variable('redirect', build_url(array('quickmod'))); + $success_msg = $post_url = ''; + $approve_log = array(); - $post_info = get_post_data($post_id_list, 'm_approve'); + $s_hidden_fields = build_hidden_fields(array( + 'i' => $id, + 'mode' => $mode, + 'post_id_list' => $post_id_list, + 'action' => $action, + 'redirect' => $redirect, + )); - if (confirm_box(true)) - { - $notify_poster = (isset($_REQUEST['notify_poster'])) ? true : false; + $post_info = get_post_data($post_id_list, 'm_approve'); - // If Topic -> total_topics = total_topics+1, total_posts = total_posts+1, forum_topics = forum_topics+1, forum_posts = forum_posts+1 - // If Post -> total_posts = total_posts+1, forum_posts = forum_posts+1, topic_replies = topic_replies+1 + if (confirm_box(true)) + { + $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster'])); - $total_topics = $total_posts = 0; - $topic_approve_sql = $post_approve_sql = $topic_id_list = $forum_id_list = $approve_log = array(); - $user_posts_sql = $post_approved_list = array(); + $topic_info = array(); - foreach ($post_info as $post_id => $post_data) - { - if ($post_data['post_approved']) + // Group the posts by topic_id + foreach ($post_info as $post_id => $post_data) { - $post_approved_list[] = $post_id; - continue; - } + if ($post_data['post_visibility'] == ITEM_APPROVED) + { + continue; + } + $topic_id = (int) $post_data['topic_id']; - $topic_id_list[$post_data['topic_id']] = 1; - $forum_id_list[$post_data['forum_id']] = 1; + $topic_info[$topic_id]['posts'][] = (int) $post_id; + $topic_info[$topic_id]['forum_id'] = (int) $post_data['forum_id']; - // User post update (we do not care about topic or post, since user posts are strictly connected to posts) - // But we care about forums where post counts get not increased. ;) - if ($post_data['post_postcount']) - { - $user_posts_sql[$post_data['poster_id']] = (empty($user_posts_sql[$post_data['poster_id']])) ? 1 : $user_posts_sql[$post_data['poster_id']] + 1; - } + // Refresh the first post, if the time or id is older then the current one + if ($post_id <= $post_data['topic_first_post_id'] || $post_data['post_time'] <= $post_data['topic_time']) + { + $topic_info[$topic_id]['first_post'] = true; + } - // Topic or Post. ;) - if ($post_data['topic_first_post_id'] == $post_id) - { - $total_topics++; - $topic_approve_sql[] = $post_data['topic_id']; + // Refresh the last post, if the time or id is newer then the current one + if ($post_id >= $post_data['topic_last_post_id'] || $post_data['post_time'] >= $post_data['topic_last_post_time']) + { + $topic_info[$topic_id]['last_post'] = true; + } + + $post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$post_data['forum_id']}&t={$post_data['topic_id']}&p={$post_data['post_id']}") . '#p' . $post_data['post_id']; $approve_log[] = array( - 'type' => 'topic', - 'post_subject' => $post_data['post_subject'], 'forum_id' => $post_data['forum_id'], 'topic_id' => $post_data['topic_id'], + 'post_subject' => $post_data['post_subject'], ); } - else + + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + foreach ($topic_info as $topic_id => $topic_data) { - $approve_log[] = array( - 'type' => 'post', - 'post_subject' => $post_data['post_subject'], - 'forum_id' => $post_data['forum_id'], - 'topic_id' => $post_data['topic_id'], - ); + $phpbb_content_visibility->set_post_visibility(ITEM_APPROVED, $topic_data['posts'], $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), '', isset($topic_data['first_post']), isset($topic_data['last_post'])); } - $total_posts++; + if (sizeof($post_info) >= 1) + { + $success_msg = (sizeof($post_info) == 1) ? 'POST_' . strtoupper($action) . 'D_SUCCESS' : 'POSTS_' . strtoupper($action) . 'D_SUCCESS'; + } - // Increment by topic_replies if we approve a topic... - // This works because we do not adjust the topic_replies when re-approving a topic after an edit. - if ($post_data['topic_first_post_id'] == $post_id && $post_data['topic_replies']) + foreach ($approve_log as $log_data) { - $total_posts += $post_data['topic_replies']; + add_log('mod', $log_data['forum_id'], $log_data['topic_id'], 'LOG_POST_' . strtoupper($action) . 'D', $log_data['post_subject']); } - $post_approve_sql[] = $post_id; - } + // Only send out the mails, when the posts are being approved + if ($action == 'approve') + { + $phpbb_notifications = $phpbb_container->get('notification_manager'); - $post_id_list = array_values(array_diff($post_id_list, $post_approved_list)); - for ($i = 0, $size = sizeof($post_approved_list); $i < $size; $i++) - { - unset($post_info[$post_approved_list[$i]]); - } + // Handle notifications + foreach ($post_info as $post_id => $post_data) + { + $phpbb_notifications->delete_notifications('post_in_queue', $post_id); - if (sizeof($topic_approve_sql)) - { - $sql = 'UPDATE ' . TOPICS_TABLE . ' - SET topic_approved = 1 - WHERE ' . $db->sql_in_set('topic_id', $topic_approve_sql); - $db->sql_query($sql); - } + $phpbb_notifications->add_notifications(array( + 'quote', + 'bookmark', + 'post', + ), $post_data); + + $phpbb_notifications->mark_notifications_read(array( + 'quote', + 'bookmark', + 'post', + ), $post_data['post_id'], $user->data['user_id']); - if (sizeof($post_approve_sql)) + // Notify Poster? + if ($notify_poster) + { + if ($post_data['poster_id'] == ANONYMOUS) + { + continue; + } + + $phpbb_notifications->add_notifications('approve_post', $post_data); + } + } + } + } + else { - $sql = 'UPDATE ' . POSTS_TABLE . ' - SET post_approved = 1 - WHERE ' . $db->sql_in_set('post_id', $post_approve_sql); - $db->sql_query($sql); + $show_notify = false; + + if ($action == 'approve') + { + foreach ($post_info as $post_data) + { + if ($post_data['poster_id'] == ANONYMOUS) + { + continue; + } + else + { + $show_notify = true; + break; + } + } + } + + $template->assign_vars(array( + 'S_NOTIFY_POSTER' => $show_notify, + 'S_' . strtoupper($action) => true, + )); + + confirm_box(false, strtoupper($action) . '_POST' . ((sizeof($post_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); } - unset($topic_approve_sql, $post_approve_sql); + $redirect = $request->variable('redirect', "index.$phpEx"); + $redirect = reapply_sid($redirect); - foreach ($approve_log as $log_data) + if (!$success_msg) { - add_log('mod', $log_data['forum_id'], $log_data['topic_id'], ($log_data['type'] == 'topic') ? 'LOG_TOPIC_APPROVED' : 'LOG_POST_APPROVED', $log_data['post_subject']); + redirect($redirect); } - - if (sizeof($user_posts_sql)) + else { - // Try to minimize the query count by merging users with the same post count additions - $user_posts_update = array(); + meta_refresh(3, $redirect); - foreach ($user_posts_sql as $user_id => $user_posts) + // If approving one post, also give links back to post... + $add_message = ''; + if (sizeof($post_info) == 1 && $post_url) { - $user_posts_update[$user_posts][] = $user_id; + $add_message = '<br /><br />' . sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'); } - foreach ($user_posts_update as $user_posts => $user_id_ary) + $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . $add_message; + + if ($request->is_ajax()) { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_posts = user_posts + ' . $user_posts . ' - WHERE ' . $db->sql_in_set('user_id', $user_id_ary); - $db->sql_query($sql); + $json_response = new phpbb_json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => true, + )); } - } - if ($total_topics) - { - set_config_count('num_topics', $total_topics, true); + trigger_error($message); } + } + + /** + * Approve/Restore topics + * + * @param $action string Action we perform on the posts ('approve' or 'restore') + * @param $topic_id_list array IDs of the topics to approve/restore + * @param $id mixed Category of the current active module + * @param $mode string Active module + * @return null + */ + static public function approve_topics($action, $topic_id_list, $id, $mode) + { + global $db, $template, $user, $config; + global $phpEx, $phpbb_root_path, $request, $phpbb_container; - if ($total_posts) + if (!check_ids($topic_id_list, TOPICS_TABLE, 'topic_id', array('m_approve'))) { - set_config_count('num_posts', $total_posts, true); + trigger_error('NOT_AUTHORISED'); } - sync('topic', 'topic_id', array_keys($topic_id_list), true); - sync('forum', 'forum_id', array_keys($forum_id_list), true, true); - unset($topic_id_list, $forum_id_list); + $redirect = $request->variable('redirect', build_url(array('quickmod'))); + $success_msg = $topic_url = ''; + $approve_log = array(); - // Send out normal user notifications - $email_sig = str_replace('<br />', "\n", "-- \n" . $config['board_email_sig']); + $s_hidden_fields = build_hidden_fields(array( + 'i' => $id, + 'mode' => $mode, + 'topic_id_list' => $topic_id_list, + 'action' => $action, + 'redirect' => $redirect, + )); - $phpbb_notifications = $phpbb_container->get('notification_manager'); + $topic_info = get_topic_data($topic_id_list, 'm_approve'); - // Handle notifications - foreach ($post_info as $post_id => $post_data) + if (confirm_box(true)) { - if ($post_id == $post_data['topic_first_post_id'] && $post_id == $post_data['topic_last_post_id']) + $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster'])) ? true : false; + + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + foreach ($topic_info as $topic_id => $topic_data) { - $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), ''); - $phpbb_notifications->add_notifications(array( - 'quote', - 'topic', - ), $post_data); + $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_data['forum_id']}&t={$topic_id}"); - $phpbb_notifications->mark_notifications_read('quote', $post_data['post_id'], $user->data['user_id']); - $phpbb_notifications->mark_notifications_read('topic', $post_data['topic_id'], $user->data['user_id']); + $approve_log[] = array( + 'forum_id' => $topic_data['forum_id'], + 'topic_id' => $topic_data['topic_id'], + 'topic_title' => $topic_data['topic_title'], + ); + } - if ($notify_poster) - { - $phpbb_notifications->add_notifications('approve_topic', $post_data); - } + if (sizeof($topic_info) >= 1) + { + $success_msg = (sizeof($topic_info) == 1) ? 'TOPIC_' . strtoupper($action) . 'D_SUCCESS' : 'TOPICS_' . strtoupper($action) . 'D_SUCCESS'; } - else + + foreach ($approve_log as $log_data) { - $phpbb_notifications->delete_notifications('post_in_queue', $post_id); + add_log('mod', $log_data['forum_id'], $log_data['topic_id'], 'LOG_TOPIC_' . strtoupper($action) . 'D', $log_data['topic_title']); + } - $phpbb_notifications->add_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $post_data); - - $phpbb_notifications->mark_notifications_read(array( - 'quote', - 'bookmark', - 'post', - ),$post_data['post_id'], $user->data['user_id']); + // Only send out the mails, when the posts are being approved + if ($action == 'approve') + { + // Handle notifications + $phpbb_notifications = $phpbb_container->get('notification_manager'); - if ($notify_poster) + foreach ($topic_info as $topic_id => $topic_data) { - $phpbb_notifications->add_notifications('approve_post', $post_data); - } - } - } + $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + $phpbb_notifications->add_notifications(array( + 'quote', + 'topic', + ), $post_data); - if (sizeof($post_id_list) == 1) - { - $post_data = $post_info[$post_id_list[0]]; - $post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$post_data['forum_id']}&t={$post_data['topic_id']}&p={$post_data['post_id']}") . '#p' . $post_data['post_id']; - } - unset($post_info); + $phpbb_notifications->mark_notifications_read('quote', $post_data['post_id'], $user->data['user_id']); + $phpbb_notifications->mark_notifications_read('topic', $post_data['topic_id'], $user->data['user_id']); - if ($total_topics) - { - $success_msg = ($total_topics == 1) ? 'TOPIC_APPROVED_SUCCESS' : 'TOPICS_APPROVED_SUCCESS'; + if ($notify_poster) + { + $phpbb_notifications->add_notifications('approve_topic', $post_data); + } + } + } } else { - $success_msg = (sizeof($post_id_list) + sizeof($post_approved_list) == 1) ? 'POST_APPROVED_SUCCESS' : 'POSTS_APPROVED_SUCCESS'; - } - } - else - { - $show_notify = false; + $show_notify = false; - if ($config['email_enable'] || $config['jab_enable']) - { - foreach ($post_info as $post_data) + if ($action == 'approve') { - if ($post_data['poster_id'] == ANONYMOUS) - { - continue; - } - else + foreach ($topic_info as $topic_data) { - $show_notify = true; - break; + if ($topic_data['topic_poster'] == ANONYMOUS) + { + continue; + } + else + { + $show_notify = true; + break; + } } } - } - $template->assign_vars(array( - 'S_NOTIFY_POSTER' => $show_notify, - 'S_APPROVE' => true) - ); - - confirm_box(false, 'APPROVE_POST' . ((sizeof($post_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); - } + $template->assign_vars(array( + 'S_NOTIFY_POSTER' => $show_notify, + 'S_' . strtoupper($action) => true, + )); - $redirect = request_var('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); + confirm_box(false, strtoupper($action) . '_TOPIC' . ((sizeof($topic_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); + } - if (!$success_msg) - { - redirect($redirect); - } - else - { - meta_refresh(3, $redirect); + $redirect = $request->variable('redirect', "index.$phpEx"); + $redirect = reapply_sid($redirect); - // If approving one post, also give links back to post... - $add_message = ''; - if (sizeof($post_id_list) == 1 && !empty($post_url)) + if (!$success_msg) { - $add_message = '<br /><br />' . sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'); + redirect($redirect); } + else + { + meta_refresh(3, $redirect); - $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], "<a href=\"$redirect\">", '</a>') . $add_message; + // If approving one topic, also give links back to topic... + $add_message = ''; + if (sizeof($topic_info) == 1 && $topic_url) + { + $add_message = '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $topic_url . '">', '</a>'); + } - if ($request->is_ajax()) - { - $json_response = new phpbb_json_response; - $json_response->send(array( - 'MESSAGE_TITLE' => $user->lang['INFORMATION'], - 'MESSAGE_TEXT' => $message, - 'REFRESH_DATA' => null, - 'approved' => true - )); - } + $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . $add_message; - trigger_error($message); - } -} + if ($request->is_ajax()) + { + $json_response = new phpbb_json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => true, + )); + } -/** -* Disapprove Post/Topic -*/ -function disapprove_post($post_id_list, $id, $mode) -{ - global $db, $template, $user, $config; - global $phpEx, $phpbb_root_path; - global $request, $phpbb_container; + trigger_error($message); + } + } - if (!check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) + /** + * Disapprove Post + * + * @param $post_id_list array IDs of the posts to disapprove/delete + * @param $id mixed Category of the current active module + * @param $mode string Active module + * @return null + */ + static public function disapprove_posts($post_id_list, $id, $mode) { - trigger_error('NOT_AUTHORISED'); - } + global $db, $template, $user, $config, $phpbb_container; + global $phpEx, $phpbb_root_path, $request; - $redirect = request_var('redirect', build_url(array('t', 'mode', 'quickmod')) . "&mode=$mode"); - $reason = utf8_normalize_nfc(request_var('reason', '', true)); - $reason_id = request_var('reason_id', 0); - $success_msg = $additional_msg = ''; + if (!check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) + { + trigger_error('NOT_AUTHORISED'); + } - $s_hidden_fields = build_hidden_fields(array( - 'i' => $id, - 'mode' => $mode, - 'post_id_list' => $post_id_list, - 'action' => 'disapprove', - 'redirect' => $redirect) - ); + $redirect = $request->variable('redirect', build_url(array('t', 'mode', 'quickmod')) . "&mode=$mode"); + $reason = $request->variable('reason', '', true); + $reason_id = $request->variable('reason_id', 0); + $success_msg = $additional_msg = ''; - $notify_poster = (isset($_REQUEST['notify_poster'])) ? true : false; - $disapprove_reason = ''; + $s_hidden_fields = build_hidden_fields(array( + 'i' => $id, + 'mode' => $mode, + 'post_id_list' => $post_id_list, + 'action' => 'disapprove', + 'redirect' => $redirect, + )); - if ($reason_id) - { - $sql = 'SELECT reason_title, reason_description - FROM ' . REPORTS_REASONS_TABLE . " - WHERE reason_id = $reason_id"; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!$row || (!$reason && strtolower($row['reason_title']) == 'other')) - { - $additional_msg = $user->lang['NO_REASON_DISAPPROVAL']; + $notify_poster = $request->is_set('notify_poster'); + $disapprove_reason = ''; - $request->overwrite('confirm', null, phpbb_request_interface::POST); - $request->overwrite('confirm_key', null, phpbb_request_interface::POST); - $request->overwrite('confirm_key', null, phpbb_request_interface::REQUEST); - } - else + if ($reason_id) { - // If the reason is defined within the language file, we will use the localized version, else just use the database entry... - $disapprove_reason = (strtolower($row['reason_title']) != 'other') ? ((isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description']) : ''; - $disapprove_reason .= ($reason) ? "\n\n" . $reason : ''; - - if (isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) + $sql = 'SELECT reason_title, reason_description + FROM ' . REPORTS_REASONS_TABLE . " + WHERE reason_id = $reason_id"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$row || (!$reason && strtolower($row['reason_title']) == 'other')) { - $disapprove_reason_lang = strtoupper($row['reason_title']); + $additional_msg = $user->lang['NO_REASON_DISAPPROVAL']; + + $request->overwrite('confirm', null, phpbb_request_interface::POST); + $request->overwrite('confirm_key', null, phpbb_request_interface::POST); + $request->overwrite('confirm_key', null, phpbb_request_interface::REQUEST); } + else + { + // If the reason is defined within the language file, we will use the localized version, else just use the database entry... + $disapprove_reason = (strtolower($row['reason_title']) != 'other') ? ((isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description']) : ''; + $disapprove_reason .= ($reason) ? "\n\n" . $reason : ''; - $email_disapprove_reason = $disapprove_reason; + if (isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) + { + $disapprove_reason_lang = strtoupper($row['reason_title']); + } + } } - } - $post_info = get_post_data($post_id_list, 'm_approve'); + $post_info = get_post_data($post_id_list, 'm_approve'); - if (confirm_box(true)) - { - $disapprove_log = $disapprove_log_topics = $disapprove_log_posts = array(); - $topic_replies_real = $post_disapprove_list = array(); - - // Build a list of posts to be unapproved and get the related topics real replies count + $is_disapproving = false; foreach ($post_info as $post_id => $post_data) { - $post_disapprove_list[$post_id] = $post_data['topic_id']; - if (!isset($topic_replies_real[$post_data['topic_id']])) + if ($post_data['post_visibility'] == ITEM_DELETED) { - $topic_replies_real[$post_data['topic_id']] = $post_data['topic_replies_real']; + continue; } + + $is_disapproving = true; } - // Now we build the log array - foreach ($post_disapprove_list as $post_id => $topic_id) + if (confirm_box(true)) { - // If the count of disapproved posts for the topic is greater - // than topic's real replies count, the whole topic is disapproved/deleted - if (sizeof(array_keys($post_disapprove_list, $topic_id)) > $topic_replies_real[$topic_id]) + $disapprove_log = $disapprove_log_topics = $disapprove_log_posts = array(); + $topic_posts_unapproved = $post_disapprove_list = $topic_information = array(); + + // Build a list of posts to be disapproved and get the related topics real replies count + foreach ($post_info as $post_id => $post_data) { - // Don't write the log more than once for every topic - if (!isset($disapprove_log_topics[$topic_id])) + $post_disapprove_list[$post_id] = $post_data['topic_id']; + if (!isset($topic_posts_unapproved[$post_data['topic_id']])) { - // Build disapproved topics log - $disapprove_log_topics[$topic_id] = array( - 'type' => 'topic', - 'post_subject' => $post_info[$post_id]['topic_title'], - 'forum_id' => $post_info[$post_id]['forum_id'], - 'topic_id' => 0, // useless to log a topic id, as it will be deleted - ); + $topic_information[$post_data['topic_id']] = $post_data; + $topic_posts_unapproved[$post_data['topic_id']] = 0; } + $topic_posts_unapproved[$post_data['topic_id']]++; } - else + + // Now we build the log array + foreach ($post_disapprove_list as $post_id => $topic_id) { - // Build disapproved posts log - $disapprove_log_posts[] = array( - 'type' => 'post', - 'post_subject' => $post_info[$post_id]['post_subject'], - 'forum_id' => $post_info[$post_id]['forum_id'], - 'topic_id' => $post_info[$post_id]['topic_id'], - ); + // If the count of disapproved posts for the topic is equal + // to the number of unapproved posts in the topic, and there are no different + // posts, we disapprove the hole topic + if ($topic_information[$topic_id]['topic_posts_approved'] == 0 && + $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 && + $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id]) + { + // Don't write the log more than once for every topic + if (!isset($disapprove_log_topics[$topic_id])) + { + // Build disapproved topics log + $disapprove_log_topics[$topic_id] = array( + 'type' => 'topic', + 'post_subject' => $post_info[$post_id]['topic_title'], + 'forum_id' => $post_info[$post_id]['forum_id'], + 'topic_id' => 0, // useless to log a topic id, as it will be deleted + 'post_username' => ($post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username'])) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username'], + ); + } + } + else + { + // Build disapproved posts log + $disapprove_log_posts[] = array( + 'type' => 'post', + 'post_subject' => $post_info[$post_id]['post_subject'], + 'forum_id' => $post_info[$post_id]['forum_id'], + 'topic_id' => $post_info[$post_id]['topic_id'], + 'post_username' => ($post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username'])) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username'], + ); + } } - } - // Get disapproved posts/topics counts separately - $num_disapproved_topics = sizeof($disapprove_log_topics); - $num_disapproved_posts = sizeof($disapprove_log_posts); + // Get disapproved posts/topics counts separately + $num_disapproved_topics = sizeof($disapprove_log_topics); + $num_disapproved_posts = sizeof($disapprove_log_posts); - // Build the whole log - $disapprove_log = array_merge($disapprove_log_topics, $disapprove_log_posts); + // Build the whole log + $disapprove_log = array_merge($disapprove_log_topics, $disapprove_log_posts); - // Unset unneeded arrays - unset($post_data, $disapprove_log_topics, $disapprove_log_posts); + // Unset unneeded arrays + unset($post_data, $disapprove_log_topics, $disapprove_log_posts); - // Let's do the job - delete disapproved posts - if (sizeof($post_disapprove_list)) - { - if (!function_exists('delete_posts')) + // Let's do the job - delete disapproved posts + if (sizeof($post_disapprove_list)) { - include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx); - } + if (!function_exists('delete_posts')) + { + include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + } - // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts - // Note: function delete_posts triggers related forums/topics sync, - // so we don't need to call update_post_information later and to adjust real topic replies or forum topics count manually - delete_posts('post_id', array_keys($post_disapprove_list)); + // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts + // Note: function delete_posts triggers related forums/topics sync, + // so we don't need to call update_post_information later and to adjust real topic replies or forum topics count manually + delete_posts('post_id', array_keys($post_disapprove_list)); - foreach ($disapprove_log as $log_data) - { - add_log('mod', $log_data['forum_id'], $log_data['topic_id'], ($log_data['type'] == 'topic') ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED', $log_data['post_subject'], $disapprove_reason); + foreach ($disapprove_log as $log_data) + { + if ($is_disapproving) + { + $l_log_message = ($log_data['type'] == 'topic') ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED'; + add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason); + } + else + { + $l_log_message = ($log_data['type'] == 'topic') ? 'LOG_DELETE_TOPIC' : 'LOG_DELETE_POST'; + add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $log_data['post_username']); + } + } } - } - $phpbb_notifications = $phpbb_container->get('notification_manager'); + $phpbb_notifications = $phpbb_container->get('notification_manager'); - foreach ($post_info as $post_id => $post_data) - { - if ($post_id == $post_data['topic_first_post_id'] && $post_id == $post_data['topic_last_post_id']) - { - $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); - } - else - { - $phpbb_notifications->delete_notifications('post_in_queue', $post_id); - } - } - - // Notify Poster? - if ($notify_poster) - { $lang_reasons = array(); - // Handle notifications foreach ($post_info as $post_id => $post_data) { - $post_data['disapprove_reason'] = ''; - if (isset($disapprove_reason_lang)) + $disapprove_all_posts_in_topic = $topic_information[$topic_id]['topic_posts_approved'] == 0 && + $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 && + $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id]; + + $phpbb_notifications->delete_notifications('post_in_queue', $post_id); + + // Do we disapprove the whole topic? Remove potential notifications + if ($disapprove_all_posts_in_topic) { - // Okay we need to get the reason from the posters language - if (!isset($lang_reasons[$post_data['user_lang']])) + $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + } + + // Notify Poster? + if ($notify_poster) + { + if ($post_data['poster_id'] == ANONYMOUS) { - // Assign the current users translation as the default, this is not ideal but getting the board default adds another layer of complexity. - $lang_reasons[$post_data['user_lang']] = $user->lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; + continue; + } - // Only load up the language pack if the language is different to the current one - if ($post_data['user_lang'] != $user->lang_name && file_exists($phpbb_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx)) + $post_data['disapprove_reason'] = ''; + if (isset($disapprove_reason_lang)) + { + // Okay we need to get the reason from the posters language + if (!isset($lang_reasons[$post_data['user_lang']])) { - // Load up the language pack - $lang = array(); - @include($phpbb_root_path . '/language/' . basename($post_data['user_lang']) . '/mcp.' . $phpEx); + // Assign the current users translation as the default, this is not ideal but getting the board default adds another layer of complexity. + $lang_reasons[$post_data['user_lang']] = $user->lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; - // If we find the reason in this language pack use it - if (isset($lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang])) + // Only load up the language pack if the language is different to the current one + if ($post_data['user_lang'] != $user->lang_name && file_exists($phpbb_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx)) { - $lang_reasons[$post_data['user_lang']] = $lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; - } + // Load up the language pack + $lang = array(); + @include($phpbb_root_path . '/language/' . basename($post_data['user_lang']) . '/mcp.' . $phpEx); + + // If we find the reason in this language pack use it + if (isset($lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang])) + { + $lang_reasons[$post_data['user_lang']] = $lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; + } - unset($lang); // Free memory + unset($lang); // Free memory + } } + + $post_data['disapprove_reason'] = $lang_reasons[$post_data['user_lang']]; + $post_data['disapprove_reason'] .= ($reason) ? "\n\n" . $reason : ''; } - $post_data['disapprove_reason'] = $lang_reasons[$post_data['user_lang']]; - $post_data['disapprove_reason'] .= ($reason) ? "\n\n" . $reason : ''; - } - if ($post_id == $post_data['topic_first_post_id'] && $post_id == $post_data['topic_last_post_id']) - { - if ($notify_poster) + if ($disapprove_all_posts_in_topic && $topic_information[$topic_id]['topic_posts_unapproved'] == 1) { + // If there is only 1 post when disapproving the topic, + // we send the user a "disapprove topic" notification... $phpbb_notifications->add_notifications('disapprove_topic', $post_data); } - } - else - { - if ($notify_poster) + else { + // ... otherwise there are multiple unapproved posts and + // all of them are disapproved as posts. $phpbb_notifications->add_notifications('disapprove_post', $post_data); } } } - unset($lang_reasons); - } - unset($post_info, $disapprove_reason, $email_disapprove_reason, $disapprove_reason_lang); + unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang); - if ($num_disapproved_topics) - { - $success_msg = ($num_disapproved_topics == 1) ? 'TOPIC_DISAPPROVED_SUCCESS' : 'TOPICS_DISAPPROVED_SUCCESS'; + + if ($num_disapproved_topics) + { + $success_msg = ($num_disapproved_topics == 1) ? 'TOPIC' : 'TOPICS'; + } + else + { + $success_msg = ($num_disapproved_posts == 1) ? 'POST' : 'POSTS'; + } + + if ($is_disapproving) + { + $success_msg .= '_DISAPPROVED_SUCCESS'; + } + else + { + $success_msg .= '_DELETED_SUCCESS'; + } } else { - $success_msg = ($num_disapproved_posts == 1) ? 'POST_DISAPPROVED_SUCCESS' : 'POSTS_DISAPPROVED_SUCCESS'; - } - } - else - { - include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx); + if (!function_exists('display_reasons')) + { + include($phpbb_root_path . 'includes/functions_display.' . $phpEx); + } - display_reasons($reason_id); + $show_notify = false; - $show_notify = false; + foreach ($post_info as $post_data) + { + if ($post_data['poster_id'] == ANONYMOUS) + { + continue; + } + else + { + $show_notify = true; + break; + } + } - foreach ($post_info as $post_data) - { - if ($post_data['poster_id'] == ANONYMOUS) + $l_confirm_msg = 'DISAPPROVE_POST'; + $confirm_template = 'mcp_approve.html'; + if ($is_disapproving) { - continue; + display_reasons($reason_id); } else { - $show_notify = true; - break; + $user->add_lang('posting'); + + $l_confirm_msg = 'DELETE_POST_PERMANENTLY'; + $confirm_template = 'confirm_delete_body.html'; } - } + $l_confirm_msg .= ((sizeof($post_id_list) == 1) ? '' : 'S'); - $template->assign_vars(array( - 'S_NOTIFY_POSTER' => $show_notify, - 'S_APPROVE' => false, - 'REASON' => $reason, - 'ADDITIONAL_MSG' => $additional_msg) - ); + $template->assign_vars(array( + 'S_NOTIFY_POSTER' => $show_notify, + 'S_APPROVE' => false, + 'REASON' => ($is_disapproving) ? $reason : '', + 'ADDITIONAL_MSG' => $additional_msg, + )); - confirm_box(false, 'DISAPPROVE_POST' . ((sizeof($post_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); - } + confirm_box(false, $l_confirm_msg, $s_hidden_fields, $confirm_template); + } - $redirect = request_var('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); + $redirect = $request->variable('redirect', "index.$phpEx"); + $redirect = reapply_sid($redirect); - if (!$success_msg) - { - redirect($redirect); - } - else - { - $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], "<a href=\"$redirect\">", '</a>'); - - if ($request->is_ajax()) + if (!$success_msg) { - $json_response = new phpbb_json_response; - $json_response->send(array( - 'MESSAGE_TITLE' => $user->lang['INFORMATION'], - 'MESSAGE_TEXT' => $message, - 'REFRESH_DATA' => null, - 'approved' => false - )); + redirect($redirect); } + else + { + $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'); - meta_refresh(3, $redirect); - trigger_error($message); + if ($request->is_ajax()) + { + $json_response = new phpbb_json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => false, + )); + } + + meta_refresh(3, $redirect); + trigger_error($message); + } } } diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 0a600d7057..72400ce623 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_approved'], + 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == POST_UNAPPROVED), 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_USER_NOTES' => true, @@ -292,11 +292,11 @@ class mcp_reports $global_id = $forum_list[0]; - $sql = 'SELECT SUM(forum_topics) as sum_forum_topics + $sql = 'SELECT SUM(forum_topics_approved) as sum_forum_topics FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list); $result = $db->sql_query($sql); - $forum_info['forum_topics'] = (int) $db->sql_fetchfield('sum_forum_topics'); + $forum_info['forum_topics_approved'] = (int) $db->sql_fetchfield('sum_forum_topics'); $db->sql_freeresult($result); } else @@ -328,7 +328,7 @@ class mcp_reports $sort_by_sql = $sort_order_sql = array(); mcp_sorting($mode, $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id, $topic_id); - $forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total; + $forum_topics = ($total == -1) ? $forum_info['forum_topics_approved'] : $total; $limit_time_sql = ($sort_days) ? 'AND r.report_time >= ' . (time() - ($sort_days * 86400)) : ''; if ($mode == 'reports') diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index e3dd5a6b57..d0e4a2e057 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) function mcp_topic_view($id, $mode, $action) { global $phpEx, $phpbb_root_path, $config; - global $template, $db, $user, $auth, $cache; + global $template, $db, $user, $auth, $cache, $phpbb_container; $url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . extra_url()); @@ -84,8 +84,8 @@ function mcp_topic_view($id, $mode, $action) $subject = $topic_info['topic_title']; } - // Approve posts? - if ($action == 'approve' && $auth->acl_get('m_approve', $topic_info['forum_id'])) + // Restore or pprove posts? + if (($action == 'restore' || $action == 'approve') && $auth->acl_get('m_approve', $topic_info['forum_id'])) { include($phpbb_root_path . 'includes/mcp/mcp_queue.' . $phpEx); include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); @@ -98,7 +98,7 @@ function mcp_topic_view($id, $mode, $action) if (!$sort) { - approve_post($post_id_list, $id, $mode); + mcp_queue::approve_posts($action, $post_id_list, $id, $mode); } } @@ -112,17 +112,11 @@ function mcp_topic_view($id, $mode, $action) mcp_sorting('viewtopic', $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $topic_info['forum_id'], $topic_id, $where_sql); $limit_time_sql = ($sort_days) ? 'AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); if ($total == -1) { - if ($auth->acl_get('m_approve', $topic_info['forum_id'])) - { - $total = $topic_info['topic_replies_real'] + 1; - } - else - { - $total = $topic_info['topic_replies'] + 1; - } + $total = $phpbb_content_visibility->get_count('topic_posts', $topic_info, $topic_info['forum_id']); } $posts_per_page = max(0, request_var('posts_per_page', intval($config['posts_per_page']))); @@ -145,8 +139,8 @@ function mcp_topic_view($id, $mode, $action) $sql = 'SELECT u.username, u.username_clean, u.user_colour, p.* FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u WHERE ' . (($action == 'reports') ? 'p.post_reported = 1 AND ' : '') . ' - p.topic_id = ' . $topic_id . ' ' . - ((!$auth->acl_get('m_approve', $topic_info['forum_id'])) ? ' AND p.post_approved = 1 ' : '') . ' + p.topic_id = ' . $topic_id . ' + AND ' . $phpbb_content_visibility->get_visibility_sql('post', $topic_info['forum_id'], 'p.') . ' AND p.poster_id = u.user_id ' . $limit_time_sql . ' ORDER BY ' . $sort_order_sql; @@ -182,7 +176,7 @@ function mcp_topic_view($id, $mode, $action) $topic_tracking_info = get_complete_topic_tracking($topic_info['forum_id'], $topic_id); } - $has_unapproved_posts = false; + $has_unapproved_posts = $has_deleted_posts = false; // Grab extensions $extensions = $attachments = array(); @@ -227,11 +221,16 @@ function mcp_topic_view($id, $mode, $action) parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count); } - if (!$row['post_approved']) + if ($row['post_visibility'] == ITEM_UNAPPROVED) { $has_unapproved_posts = true; } + if ($row['post_visibility'] == ITEM_DELETED) + { + $has_deleted_posts = true; + } + $post_unread = (isset($topic_tracking_info[$topic_id]) && $row['post_time'] > $topic_tracking_info[$topic_id]) ? true : false; $template->assign_block_vars('postrow', array( @@ -249,7 +248,8 @@ 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_approved'] && $auth->acl_get('m_approve', $topic_info['forum_id'])), + 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED && $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, @@ -325,6 +325,7 @@ function mcp_topic_view($id, $mode, $action) 'REPORTED_IMG' => $user->img('icon_topic_reported', 'POST_REPORTED'), 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'POST_UNAPPROVED'), + 'DELETED_IMG' => $user->img('icon_topic_deleted', 'POST_DELETED_RESTORE'), 'INFO_IMG' => $user->img('icon_post_info', 'VIEW_INFO'), 'S_MCP_ACTION' => "$url&i=$id&mode=$mode&action=$action&start=$start", @@ -333,6 +334,7 @@ function mcp_topic_view($id, $mode, $action) 'S_CAN_MERGE' => ($auth->acl_get('m_merge', $topic_info['forum_id'])) ? true : false, 'S_CAN_DELETE' => ($auth->acl_get('m_delete', $topic_info['forum_id'])) ? true : false, 'S_CAN_APPROVE' => ($has_unapproved_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false, + 'S_CAN_RESTORE' => ($has_deleted_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false, 'S_CAN_LOCK' => ($auth->acl_get('m_lock', $topic_info['forum_id'])) ? true : false, 'S_CAN_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? true : false, 'S_CAN_SYNC' => $auth->acl_get('m_', $topic_info['forum_id']), @@ -448,7 +450,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) if ($sort_order_sql[0] == 'u') { - $sql = 'SELECT p.post_id, p.forum_id, p.post_approved + $sql = 'SELECT p.post_id, p.forum_id, p.post_visibility FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u WHERE p.topic_id = $topic_id AND p.poster_id = u.user_id @@ -457,7 +459,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) } else { - $sql = 'SELECT p.post_id, p.forum_id, p.post_approved + $sql = 'SELECT p.post_id, p.forum_id, p.post_visibility FROM ' . POSTS_TABLE . " p WHERE p.topic_id = $topic_id $limit_time_sql @@ -470,7 +472,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_approved'] && !$auth->acl_get('m_approve', $row['forum_id'])) + if ($row['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) { // continue; } @@ -497,10 +499,10 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) $icon_id = request_var('icon', 0); $sql_ary = array( - 'forum_id' => $to_forum_id, - 'topic_title' => $subject, - 'icon_id' => $icon_id, - 'topic_approved'=> 1 + 'forum_id' => $to_forum_id, + 'topic_title' => $subject, + 'icon_id' => $icon_id, + 'topic_visibility' => 1 ); $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index b16a7df606..7dc4da8ffe 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -351,7 +351,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -360,7 +360,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts if (!$this->search_query) @@ -378,7 +378,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary) ))); @@ -445,19 +445,6 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base break; } - if (!sizeof($m_approve_fid_ary)) - { - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } - else if ($m_approve_fid_ary === array(-1)) - { - $m_approve_fid_sql = ''; - } - else - { - $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } - $sql_select = (!$result_count) ? 'SQL_CALC_FOUND_ROWS ' : ''; $sql_select = ($type == 'posts') ? $sql_select . 'p.post_id' : 'DISTINCT ' . $sql_select . 't.topic_id'; $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; @@ -480,7 +467,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $sql_where_options .= ($topic_id) ? ' AND p.topic_id = ' . $topic_id : ''; $sql_where_options .= ($join_topic) ? ' AND t.topic_id = p.topic_id' : ''; $sql_where_options .= (sizeof($ex_fid_ary)) ? ' AND ' . $this->db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; - $sql_where_options .= $m_approve_fid_sql; + $sql_where_options .= ' AND ' . $post_visibility; $sql_where_options .= $sql_author; $sql_where_options .= ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; $sql_where_options .= $sql_match_where; @@ -546,7 +533,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -574,7 +561,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary), $author_name, ))); @@ -629,18 +616,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base break; } - if (!sizeof($m_approve_fid_ary)) - { - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } - else if ($m_approve_fid_ary == array(-1)) - { - $m_approve_fid_sql = ''; - } - else - { - $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } + $m_approve_fid_sql = ' AND ' . $post_visibility; // If the cache was completely empty count the results $calc_results = ($result_count) ? '' : 'SQL_CALC_FOUND_ROWS '; diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index b9c784ea67..730c3a6c2d 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -507,7 +507,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -516,7 +516,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts. if (empty($this->search_query)) @@ -544,7 +544,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary), $author_name, ))); @@ -721,14 +721,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base $sql_where[] = '(' . implode(' OR ', $is_null_joins) . ')'; } - if (!sizeof($m_approve_fid_ary)) - { - $sql_where[] = 'p.post_approved = 1'; - } - else if ($m_approve_fid_ary !== array(-1)) - { - $sql_where[] = '(p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } + $sql_where[] = $post_visibility; if ($topic_id) { @@ -911,7 +904,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -920,7 +913,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No author? No posts if (!sizeof($author_ary)) @@ -939,7 +932,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary), $author_name, ))); @@ -967,6 +960,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base $sql_time = ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; $sql_topic_id = ($topic_id) ? ' AND p.topic_id = ' . (int) $topic_id : ''; $sql_firstpost = ($firstpost_only) ? ' AND p.post_id = t.topic_first_post_id' : ''; + $post_visibility = ($post_visibility) ? ' AND ' . $post_visibility : ''; // Build sql strings for sorting $sql_sort = $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); @@ -989,19 +983,6 @@ class phpbb_search_fulltext_native extends phpbb_search_base break; } - if (!sizeof($m_approve_fid_ary)) - { - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } - else if ($m_approve_fid_ary == array(-1)) - { - $m_approve_fid_sql = ''; - } - else - { - $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } - $select = ($type == 'posts') ? 'p.post_id' : 't.topic_id'; $is_mysql = false; @@ -1024,7 +1005,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base WHERE $sql_author $sql_topic_id $sql_firstpost - $m_approve_fid_sql + $post_visibility $sql_fora $sql_time"; } @@ -1044,7 +1025,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base WHERE $sql_author $sql_topic_id $sql_firstpost - $m_approve_fid_sql + $post_visibility $sql_fora AND t.topic_id = p.topic_id $sql_time" . (($this->db->sql_layer == 'sqlite') ? ')' : ''); @@ -1070,7 +1051,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base WHERE $sql_author $sql_topic_id $sql_firstpost - $m_approve_fid_sql + $post_visibility $sql_fora $sql_sort_join $sql_time @@ -1084,7 +1065,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base WHERE $sql_author $sql_topic_id $sql_firstpost - $m_approve_fid_sql + $post_visibility $sql_fora AND t.topic_id = p.topic_id $sql_sort_join diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index 758c3ba061..6b4b310f2e 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -334,7 +334,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -343,7 +343,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts if (!$this->search_query) @@ -367,7 +367,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary) ))); @@ -434,19 +434,6 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base break; } - if (!sizeof($m_approve_fid_ary)) - { - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } - else if ($m_approve_fid_ary === array(-1)) - { - $m_approve_fid_sql = ''; - } - else - { - $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } - $sql_select = ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id'; $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; $field = ($type == 'posts') ? 'post_id' : 'topic_id'; @@ -470,7 +457,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $sql_where_options .= ($topic_id) ? ' AND p.topic_id = ' . $topic_id : ''; $sql_where_options .= ($join_topic) ? ' AND t.topic_id = p.topic_id' : ''; $sql_where_options .= (sizeof($ex_fid_ary)) ? ' AND ' . $this->db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; - $sql_where_options .= $m_approve_fid_sql; + $sql_where_options .= ' AND ' . $post_visibility; $sql_where_options .= $sql_author; $sql_where_options .= ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; $sql_where_options .= $sql_match_where; @@ -550,7 +537,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -559,7 +546,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No author? No posts if (!sizeof($author_ary)) @@ -578,7 +565,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base $sort_key, $topic_id, implode(',', $ex_fid_ary), - implode(',', $m_approve_fid_ary), + $post_visibility, implode(',', $author_ary), $author_name, ))); @@ -633,18 +620,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base break; } - if (!sizeof($m_approve_fid_ary)) - { - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } - else if ($m_approve_fid_ary == array(-1)) - { - $m_approve_fid_sql = ''; - } - else - { - $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $this->db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; - } + $m_approve_fid_sql = ' AND ' . $post_visibility; // Build the query for really selecting the post_ids if ($type == 'posts') diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php index 889324bbda..2f7b236c78 100644 --- a/phpBB/includes/search/fulltext_sphinx.php +++ b/phpBB/includes/search/fulltext_sphinx.php @@ -274,6 +274,7 @@ class phpbb_search_fulltext_sphinx p.forum_id, p.topic_id, p.poster_id, + p.post_visibility, CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, p.post_time, p.post_subject, @@ -291,6 +292,7 @@ class phpbb_search_fulltext_sphinx array('sql_attr_uint', 'forum_id'), array('sql_attr_uint', 'topic_id'), array('sql_attr_uint', 'poster_id'), + array('sql_attr_uint', 'post_visibility'), array('sql_attr_bool', 'topic_first_post'), array('sql_attr_bool', 'deleted'), array('sql_attr_timestamp' , 'post_time'), @@ -306,6 +308,7 @@ class phpbb_search_fulltext_sphinx p.forum_id, p.topic_id, p.poster_id, + p.post_visibility, CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, p.post_time, p.post_subject, @@ -445,7 +448,7 @@ class phpbb_search_fulltext_sphinx * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -454,7 +457,7 @@ class phpbb_search_fulltext_sphinx * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) + public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts. if (!strlen($this->search_query) && !sizeof($author_ary)) @@ -569,6 +572,11 @@ class phpbb_search_fulltext_sphinx $this->sphinx->SetFilter('poster_id', $author_ary); } + // As this is not simply possible at the moment, we limit the result to approved posts. + // This will make it impossible for moderators to search unapproved and softdeleted posts, + // but at least it will also cause the same for normal users. + $this->sphinx->SetFilter('post_visibility', array(ITEM_APPROVED)); + if (sizeof($ex_fid_ary)) { // All forums that a user is allowed to access @@ -663,7 +671,7 @@ class phpbb_search_fulltext_sphinx * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched - * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match @@ -672,14 +680,14 @@ class phpbb_search_fulltext_sphinx * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ - public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) + public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { $this->search_query = ''; $this->sphinx->SetMatchMode(SPH_MATCH_FULLSCAN); $fields = ($firstpost_only) ? 'firstpost' : 'all'; $terms = 'all'; - return $this->keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, $id_ary, $start, $per_page); + return $this->keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, $id_ary, $start, $per_page); } /** diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index 94fd59433b..615b567134 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -642,7 +642,7 @@ class ucp_main */ function assign_topiclist($mode = 'subscribed', $forbidden_forum_ary = array()) { - global $user, $db, $template, $config, $cache, $auth, $phpbb_root_path, $phpEx; + global $user, $db, $template, $config, $cache, $auth, $phpbb_root_path, $phpEx, $phpbb_container; $table = ($mode == 'subscribed') ? TOPICS_WATCH_TABLE : BOOKMARKS_TABLE; $start = request_var('start', 0); @@ -768,6 +768,8 @@ class ucp_main } } + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + foreach ($topic_list as $topic_id) { $row = &$rowset[$topic_id]; @@ -778,7 +780,7 @@ class ucp_main $unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false; // Replies - $replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; + $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1; if ($row['topic_status'] == ITEM_MOVED && !empty($row['topic_moved_id'])) { diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 5f30625980..4532ecb609 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -497,8 +497,9 @@ if (!$get_info) array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), array('topic_time', 'topics.topic_time', ''), array('topic_views', 'topics.topic_views', ''), - array('topic_replies', 'topics.topic_replies', ''), - array('topic_replies_real', 'topics.topic_replies', ''), + array('topic_posts_approved', 'topics.topic_replies + 1', ''), + array('topic_posts_unapproved', 0, ''), + array('topic_posts_softdeleted',0, ''), array('topic_last_post_id', 'topics.topic_last_post_id', ''), array('topic_status', 'topics.topic_status', 'is_topic_locked'), array('topic_moved_id', 0, ''), @@ -530,8 +531,9 @@ if (!$get_info) array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), array('topic_time', 'topics.topic_time', ''), array('topic_views', 'topics.topic_views', ''), - array('topic_replies', 'topics.topic_replies', ''), - array('topic_replies_real', 'topics.topic_replies', ''), + array('topic_posts_approved', 'topics.topic_replies + 1', ''), + array('topic_posts_unapproved', 0, ''), + array('topic_posts_softdeleted',0, ''), array('topic_last_post_id', 'topics.topic_last_post_id', ''), array('topic_status', ITEM_MOVED, ''), array('topic_moved_id', 'topics.topic_moved_id', ''), diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php index 0b6daeef47..a698f0ef13 100644 --- a/phpBB/install/convertors/functions_phpbb20.php +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -243,9 +243,12 @@ function phpbb_insert_forums() 'forum_rules_options' => 7, 'forum_rules_uid' => '', 'forum_topics_per_page' => 0, - 'forum_posts' => 0, - 'forum_topics' => 0, - 'forum_topics_real' => 0, + '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, 'forum_last_poster_id' => 0, 'forum_last_post_subject' => '', diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php index 6198efe4c7..8a8c440036 100644 --- a/phpBB/install/install_convert.php +++ b/phpBB/install/install_convert.php @@ -1464,7 +1464,6 @@ class install_convert extends module $end = ($sync_batch + $batch_size - 1); // Sync all topics in batch mode... - sync('topic_approved', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, false); sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true); $template->assign_block_vars('checks', array( diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index a64b8eeffc..ca68ea387d 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -372,9 +372,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page INTEGER DEFAULT 0 NOT NULL, forum_type INTEGER DEFAULT 0 NOT NULL, forum_status INTEGER DEFAULT 0 NOT NULL, - forum_posts INTEGER DEFAULT 0 NOT NULL, - forum_topics INTEGER DEFAULT 0 NOT NULL, - forum_topics_real INTEGER DEFAULT 0 NOT NULL, + forum_posts_approved INTEGER DEFAULT 0 NOT NULL, + forum_posts_unapproved INTEGER DEFAULT 0 NOT NULL, + forum_posts_softdeleted INTEGER DEFAULT 0 NOT NULL, + forum_topics_approved INTEGER DEFAULT 0 NOT NULL, + forum_topics_unapproved INTEGER DEFAULT 0 NOT NULL, + forum_topics_softdeleted INTEGER DEFAULT 0 NOT NULL, forum_last_post_id INTEGER DEFAULT 0 NOT NULL, forum_last_poster_id INTEGER DEFAULT 0 NOT NULL, forum_last_post_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, @@ -722,7 +725,7 @@ CREATE TABLE phpbb_posts ( icon_id INTEGER DEFAULT 0 NOT NULL, poster_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, post_time INTEGER DEFAULT 0 NOT NULL, - post_approved INTEGER DEFAULT 1 NOT NULL, + post_visibility INTEGER DEFAULT 0 NOT NULL, post_reported INTEGER DEFAULT 0 NOT NULL, enable_bbcode INTEGER DEFAULT 1 NOT NULL, enable_smilies INTEGER DEFAULT 1 NOT NULL, @@ -740,7 +743,10 @@ CREATE TABLE phpbb_posts ( post_edit_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, post_edit_user INTEGER DEFAULT 0 NOT NULL, post_edit_count INTEGER DEFAULT 0 NOT NULL, - post_edit_locked INTEGER DEFAULT 0 NOT NULL + post_edit_locked INTEGER DEFAULT 0 NOT NULL, + post_delete_time INTEGER DEFAULT 0 NOT NULL, + post_delete_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, + post_delete_user INTEGER DEFAULT 0 NOT NULL );; ALTER TABLE phpbb_posts ADD PRIMARY KEY (post_id);; @@ -749,7 +755,7 @@ CREATE INDEX phpbb_posts_forum_id ON phpbb_posts(forum_id);; CREATE INDEX phpbb_posts_topic_id ON phpbb_posts(topic_id);; CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts(poster_ip);; CREATE INDEX phpbb_posts_poster_id ON phpbb_posts(poster_id);; -CREATE INDEX phpbb_posts_post_approved ON phpbb_posts(post_approved);; +CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts(post_visibility);; CREATE INDEX phpbb_posts_post_username ON phpbb_posts(post_username);; CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts(topic_id, post_time);; @@ -1215,15 +1221,16 @@ CREATE TABLE phpbb_topics ( forum_id INTEGER DEFAULT 0 NOT NULL, icon_id INTEGER DEFAULT 0 NOT NULL, topic_attachment INTEGER DEFAULT 0 NOT NULL, - topic_approved INTEGER DEFAULT 1 NOT NULL, + topic_visibility INTEGER DEFAULT 0 NOT NULL, topic_reported INTEGER DEFAULT 0 NOT NULL, topic_title VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, topic_poster INTEGER DEFAULT 0 NOT NULL, topic_time INTEGER DEFAULT 0 NOT NULL, topic_time_limit INTEGER DEFAULT 0 NOT NULL, topic_views INTEGER DEFAULT 0 NOT NULL, - topic_replies INTEGER DEFAULT 0 NOT NULL, - topic_replies_real INTEGER DEFAULT 0 NOT NULL, + topic_posts_approved INTEGER DEFAULT 0 NOT NULL, + topic_posts_unapproved INTEGER DEFAULT 0 NOT NULL, + topic_posts_softdeleted INTEGER DEFAULT 0 NOT NULL, topic_status INTEGER DEFAULT 0 NOT NULL, topic_type INTEGER DEFAULT 0 NOT NULL, topic_first_post_id INTEGER DEFAULT 0 NOT NULL, @@ -1244,7 +1251,10 @@ CREATE TABLE phpbb_topics ( poll_length INTEGER DEFAULT 0 NOT NULL, poll_max_options INTEGER DEFAULT 1 NOT NULL, poll_last_vote INTEGER DEFAULT 0 NOT NULL, - poll_vote_change INTEGER DEFAULT 0 NOT NULL + poll_vote_change INTEGER DEFAULT 0 NOT NULL, + topic_delete_time INTEGER DEFAULT 0 NOT NULL, + topic_delete_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, + topic_delete_user INTEGER DEFAULT 0 NOT NULL );; ALTER TABLE phpbb_topics ADD PRIMARY KEY (topic_id);; @@ -1252,8 +1262,8 @@ ALTER TABLE phpbb_topics ADD PRIMARY KEY (topic_id);; CREATE INDEX phpbb_topics_forum_id ON phpbb_topics(forum_id);; CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics(forum_id, topic_type);; CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics(topic_last_post_time);; -CREATE INDEX phpbb_topics_topic_approved ON phpbb_topics(topic_approved);; -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics(forum_id, topic_approved, topic_last_post_id);; +CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics(topic_visibility);; +CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics(forum_id, topic_visibility, topic_last_post_id);; CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics(forum_id, topic_last_post_time, topic_moved_id);; CREATE GENERATOR phpbb_topics_gen;; diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 8465dc4d72..a2a6d2192c 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -459,9 +459,12 @@ CREATE TABLE [phpbb_forums] ( [forum_topics_per_page] [int] DEFAULT (0) NOT NULL , [forum_type] [int] DEFAULT (0) NOT NULL , [forum_status] [int] DEFAULT (0) NOT NULL , - [forum_posts] [int] DEFAULT (0) NOT NULL , - [forum_topics] [int] DEFAULT (0) NOT NULL , - [forum_topics_real] [int] DEFAULT (0) NOT NULL , + [forum_posts_approved] [int] DEFAULT (0) NOT NULL , + [forum_posts_unapproved] [int] DEFAULT (0) NOT NULL , + [forum_posts_softdeleted] [int] DEFAULT (0) NOT NULL , + [forum_topics_approved] [int] DEFAULT (0) NOT NULL , + [forum_topics_unapproved] [int] DEFAULT (0) NOT NULL , + [forum_topics_softdeleted] [int] DEFAULT (0) NOT NULL , [forum_last_post_id] [int] DEFAULT (0) NOT NULL , [forum_last_poster_id] [int] DEFAULT (0) NOT NULL , [forum_last_post_subject] [varchar] (255) DEFAULT ('') NOT NULL , @@ -889,7 +892,7 @@ CREATE TABLE [phpbb_posts] ( [icon_id] [int] DEFAULT (0) NOT NULL , [poster_ip] [varchar] (40) DEFAULT ('') NOT NULL , [post_time] [int] DEFAULT (0) NOT NULL , - [post_approved] [int] DEFAULT (1) NOT NULL , + [post_visibility] [int] DEFAULT (0) NOT NULL , [post_reported] [int] DEFAULT (0) NOT NULL , [enable_bbcode] [int] DEFAULT (1) NOT NULL , [enable_smilies] [int] DEFAULT (1) NOT NULL , @@ -907,7 +910,10 @@ CREATE TABLE [phpbb_posts] ( [post_edit_reason] [varchar] (255) DEFAULT ('') NOT NULL , [post_edit_user] [int] DEFAULT (0) NOT NULL , [post_edit_count] [int] DEFAULT (0) NOT NULL , - [post_edit_locked] [int] DEFAULT (0) NOT NULL + [post_edit_locked] [int] DEFAULT (0) NOT NULL , + [post_delete_time] [int] DEFAULT (0) NOT NULL , + [post_delete_reason] [varchar] (255) DEFAULT ('') NOT NULL , + [post_delete_user] [int] DEFAULT (0) NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO @@ -930,7 +936,7 @@ GO CREATE INDEX [poster_id] ON [phpbb_posts]([poster_id]) ON [PRIMARY] GO -CREATE INDEX [post_approved] ON [phpbb_posts]([post_approved]) ON [PRIMARY] +CREATE INDEX [post_visibility] ON [phpbb_posts]([post_visibility]) ON [PRIMARY] GO CREATE INDEX [post_username] ON [phpbb_posts]([post_username]) ON [PRIMARY] @@ -1463,15 +1469,16 @@ CREATE TABLE [phpbb_topics] ( [forum_id] [int] DEFAULT (0) NOT NULL , [icon_id] [int] DEFAULT (0) NOT NULL , [topic_attachment] [int] DEFAULT (0) NOT NULL , - [topic_approved] [int] DEFAULT (1) NOT NULL , + [topic_visibility] [int] DEFAULT (0) NOT NULL , [topic_reported] [int] DEFAULT (0) NOT NULL , [topic_title] [varchar] (255) DEFAULT ('') NOT NULL , [topic_poster] [int] DEFAULT (0) NOT NULL , [topic_time] [int] DEFAULT (0) NOT NULL , [topic_time_limit] [int] DEFAULT (0) NOT NULL , [topic_views] [int] DEFAULT (0) NOT NULL , - [topic_replies] [int] DEFAULT (0) NOT NULL , - [topic_replies_real] [int] DEFAULT (0) NOT NULL , + [topic_posts_approved] [int] DEFAULT (0) NOT NULL , + [topic_posts_unapproved] [int] DEFAULT (0) NOT NULL , + [topic_posts_softdeleted] [int] DEFAULT (0) NOT NULL , [topic_status] [int] DEFAULT (0) NOT NULL , [topic_type] [int] DEFAULT (0) NOT NULL , [topic_first_post_id] [int] DEFAULT (0) NOT NULL , @@ -1492,7 +1499,10 @@ CREATE TABLE [phpbb_topics] ( [poll_length] [int] DEFAULT (0) NOT NULL , [poll_max_options] [int] DEFAULT (1) NOT NULL , [poll_last_vote] [int] DEFAULT (0) NOT NULL , - [poll_vote_change] [int] DEFAULT (0) NOT NULL + [poll_vote_change] [int] DEFAULT (0) NOT NULL , + [topic_delete_time] [int] DEFAULT (0) NOT NULL , + [topic_delete_reason] [varchar] (255) DEFAULT ('') NOT NULL , + [topic_delete_user] [int] DEFAULT (0) NOT NULL ) ON [PRIMARY] GO @@ -1512,10 +1522,10 @@ GO CREATE INDEX [last_post_time] ON [phpbb_topics]([topic_last_post_time]) ON [PRIMARY] GO -CREATE INDEX [topic_approved] ON [phpbb_topics]([topic_approved]) ON [PRIMARY] +CREATE INDEX [topic_visibility] ON [phpbb_topics]([topic_visibility]) ON [PRIMARY] GO -CREATE INDEX [forum_appr_last] ON [phpbb_topics]([forum_id], [topic_approved], [topic_last_post_id]) ON [PRIMARY] +CREATE INDEX [forum_appr_last] ON [phpbb_topics]([forum_id], [topic_visibility], [topic_last_post_id]) ON [PRIMARY] GO CREATE INDEX [fid_time_moved] ON [phpbb_topics]([forum_id], [topic_last_post_time], [topic_moved_id]) ON [PRIMARY] diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 37e4e66ad7..2c5931bae4 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -257,9 +257,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page tinyint(4) DEFAULT '0' NOT NULL, forum_type tinyint(4) DEFAULT '0' NOT NULL, forum_status tinyint(4) DEFAULT '0' NOT NULL, - forum_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_real mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_post_subject blob NOT NULL, @@ -508,7 +511,7 @@ CREATE TABLE phpbb_posts ( icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, poster_ip varbinary(40) DEFAULT '' NOT NULL, post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_approved tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + post_visibility tinyint(3) DEFAULT '0' NOT NULL, post_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, @@ -527,12 +530,15 @@ CREATE TABLE phpbb_posts ( post_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, post_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, post_edit_locked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + post_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + post_delete_reason blob NOT NULL, + post_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (post_id), KEY forum_id (forum_id), KEY topic_id (topic_id), KEY poster_ip (poster_ip), KEY poster_id (poster_id), - KEY post_approved (post_approved), + KEY post_visibility (post_visibility), KEY post_username (post_username(255)), KEY tid_post_time (topic_id, post_time) ); @@ -839,15 +845,16 @@ CREATE TABLE phpbb_topics ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_approved tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + topic_visibility tinyint(3) DEFAULT '0' NOT NULL, topic_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, topic_title blob NOT NULL, topic_poster mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_time int(11) UNSIGNED DEFAULT '0' NOT NULL, topic_time_limit int(11) UNSIGNED DEFAULT '0' NOT NULL, topic_views mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_replies mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_replies_real mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_status tinyint(3) DEFAULT '0' NOT NULL, topic_type tinyint(3) DEFAULT '0' NOT NULL, topic_first_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -869,12 +876,15 @@ CREATE TABLE phpbb_topics ( poll_max_options tinyint(4) DEFAULT '1' NOT NULL, poll_last_vote int(11) UNSIGNED DEFAULT '0' NOT NULL, poll_vote_change tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + topic_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + topic_delete_reason blob NOT NULL, + topic_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (topic_id), KEY forum_id (forum_id), KEY forum_id_type (forum_id, topic_type), KEY last_post_time (topic_last_post_time), - KEY topic_approved (topic_approved), - KEY forum_appr_last (forum_id, topic_approved, topic_last_post_id), + KEY topic_visibility (topic_visibility), + KEY forum_appr_last (forum_id, topic_visibility, topic_last_post_id), KEY fid_time_moved (forum_id, topic_last_post_time, topic_moved_id) ); diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index ff0f315f93..7b7be3c462 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -257,9 +257,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page tinyint(4) DEFAULT '0' NOT NULL, forum_type tinyint(4) DEFAULT '0' NOT NULL, forum_status tinyint(4) DEFAULT '0' NOT NULL, - forum_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_real mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + forum_topics_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, forum_last_post_subject varchar(255) DEFAULT '' NOT NULL, @@ -508,7 +511,7 @@ CREATE TABLE phpbb_posts ( icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, poster_ip varchar(40) DEFAULT '' NOT NULL, post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_approved tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + post_visibility tinyint(3) DEFAULT '0' NOT NULL, post_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, @@ -527,12 +530,15 @@ CREATE TABLE phpbb_posts ( post_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, post_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, post_edit_locked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + post_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + post_delete_reason varchar(255) DEFAULT '' NOT NULL, + post_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (post_id), KEY forum_id (forum_id), KEY topic_id (topic_id), KEY poster_ip (poster_ip), KEY poster_id (poster_id), - KEY post_approved (post_approved), + KEY post_visibility (post_visibility), KEY post_username (post_username), KEY tid_post_time (topic_id, post_time) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; @@ -839,15 +845,16 @@ CREATE TABLE phpbb_topics ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_approved tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + topic_visibility tinyint(3) DEFAULT '0' NOT NULL, topic_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, topic_title varchar(255) DEFAULT '' NOT NULL COLLATE utf8_unicode_ci, topic_poster mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_time int(11) UNSIGNED DEFAULT '0' NOT NULL, topic_time_limit int(11) UNSIGNED DEFAULT '0' NOT NULL, topic_views mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_replies mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_replies_real mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + topic_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, topic_status tinyint(3) DEFAULT '0' NOT NULL, topic_type tinyint(3) DEFAULT '0' NOT NULL, topic_first_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -869,12 +876,15 @@ CREATE TABLE phpbb_topics ( poll_max_options tinyint(4) DEFAULT '1' NOT NULL, poll_last_vote int(11) UNSIGNED DEFAULT '0' NOT NULL, poll_vote_change tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + topic_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + topic_delete_reason varchar(255) DEFAULT '' NOT NULL, + topic_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (topic_id), KEY forum_id (forum_id), KEY forum_id_type (forum_id, topic_type), KEY last_post_time (topic_last_post_time), - KEY topic_approved (topic_approved), - KEY forum_appr_last (forum_id, topic_approved, topic_last_post_id), + KEY topic_visibility (topic_visibility), + KEY forum_appr_last (forum_id, topic_visibility, topic_last_post_id), KEY fid_time_moved (forum_id, topic_last_post_time, topic_moved_id) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 11f245869d..75c01446d8 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -520,9 +520,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page number(4) DEFAULT '0' NOT NULL, forum_type number(4) DEFAULT '0' NOT NULL, forum_status number(4) DEFAULT '0' NOT NULL, - forum_posts number(8) DEFAULT '0' NOT NULL, - forum_topics number(8) DEFAULT '0' NOT NULL, - forum_topics_real number(8) DEFAULT '0' NOT NULL, + forum_posts_approved number(8) DEFAULT '0' NOT NULL, + forum_posts_unapproved number(8) DEFAULT '0' NOT NULL, + forum_posts_softdeleted number(8) DEFAULT '0' NOT NULL, + forum_topics_approved number(8) DEFAULT '0' NOT NULL, + forum_topics_unapproved number(8) DEFAULT '0' NOT NULL, + forum_topics_softdeleted number(8) DEFAULT '0' NOT NULL, forum_last_post_id number(8) DEFAULT '0' NOT NULL, forum_last_poster_id number(8) DEFAULT '0' NOT NULL, forum_last_post_subject varchar2(765) DEFAULT '' , @@ -977,7 +980,7 @@ CREATE TABLE phpbb_posts ( icon_id number(8) DEFAULT '0' NOT NULL, poster_ip varchar2(40) DEFAULT '' , post_time number(11) DEFAULT '0' NOT NULL, - post_approved number(1) DEFAULT '1' NOT NULL, + post_visibility number(3) DEFAULT '0' NOT NULL, post_reported number(1) DEFAULT '0' NOT NULL, enable_bbcode number(1) DEFAULT '1' NOT NULL, enable_smilies number(1) DEFAULT '1' NOT NULL, @@ -996,6 +999,9 @@ CREATE TABLE phpbb_posts ( post_edit_user number(8) DEFAULT '0' NOT NULL, post_edit_count number(4) DEFAULT '0' NOT NULL, post_edit_locked number(1) DEFAULT '0' NOT NULL, + post_delete_time number(11) DEFAULT '0' NOT NULL, + post_delete_reason varchar2(765) DEFAULT '' , + post_delete_user number(8) DEFAULT '0' NOT NULL, CONSTRAINT pk_phpbb_posts PRIMARY KEY (post_id) ) / @@ -1008,7 +1014,7 @@ CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip) / CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id) / -CREATE INDEX phpbb_posts_post_approved ON phpbb_posts (post_approved) +CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility) / CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username) / @@ -1607,15 +1613,16 @@ CREATE TABLE phpbb_topics ( forum_id number(8) DEFAULT '0' NOT NULL, icon_id number(8) DEFAULT '0' NOT NULL, topic_attachment number(1) DEFAULT '0' NOT NULL, - topic_approved number(1) DEFAULT '1' NOT NULL, + topic_visibility number(3) DEFAULT '0' NOT NULL, topic_reported number(1) DEFAULT '0' NOT NULL, topic_title varchar2(765) DEFAULT '' , topic_poster number(8) DEFAULT '0' NOT NULL, topic_time number(11) DEFAULT '0' NOT NULL, topic_time_limit number(11) DEFAULT '0' NOT NULL, topic_views number(8) DEFAULT '0' NOT NULL, - topic_replies number(8) DEFAULT '0' NOT NULL, - topic_replies_real number(8) DEFAULT '0' NOT NULL, + topic_posts_approved number(8) DEFAULT '0' NOT NULL, + topic_posts_unapproved number(8) DEFAULT '0' NOT NULL, + topic_posts_softdeleted number(8) DEFAULT '0' NOT NULL, topic_status number(3) DEFAULT '0' NOT NULL, topic_type number(3) DEFAULT '0' NOT NULL, topic_first_post_id number(8) DEFAULT '0' NOT NULL, @@ -1637,6 +1644,9 @@ CREATE TABLE phpbb_topics ( poll_max_options number(4) DEFAULT '1' NOT NULL, poll_last_vote number(11) DEFAULT '0' NOT NULL, poll_vote_change number(1) DEFAULT '0' NOT NULL, + topic_delete_time number(11) DEFAULT '0' NOT NULL, + topic_delete_reason varchar2(765) DEFAULT '' , + topic_delete_user number(8) DEFAULT '0' NOT NULL, CONSTRAINT pk_phpbb_topics PRIMARY KEY (topic_id) ) / @@ -1647,9 +1657,9 @@ CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type) / CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time) / -CREATE INDEX phpbb_topics_topic_approved ON phpbb_topics (topic_approved) +CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility) / -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_approved, topic_last_post_id) +CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id) / CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id) / diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index fea5700167..c7fbe9a507 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -395,9 +395,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page INT2 DEFAULT '0' NOT NULL, forum_type INT2 DEFAULT '0' NOT NULL, forum_status INT2 DEFAULT '0' NOT NULL, - forum_posts INT4 DEFAULT '0' NOT NULL CHECK (forum_posts >= 0), - forum_topics INT4 DEFAULT '0' NOT NULL CHECK (forum_topics >= 0), - forum_topics_real INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_real >= 0), + forum_posts_approved INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_approved >= 0), + forum_posts_unapproved INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_unapproved >= 0), + forum_posts_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_softdeleted >= 0), + forum_topics_approved INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_approved >= 0), + forum_topics_unapproved INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_unapproved >= 0), + forum_topics_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_softdeleted >= 0), forum_last_post_id INT4 DEFAULT '0' NOT NULL CHECK (forum_last_post_id >= 0), forum_last_poster_id INT4 DEFAULT '0' NOT NULL CHECK (forum_last_poster_id >= 0), forum_last_post_subject varchar(255) DEFAULT '' NOT NULL, @@ -694,7 +697,7 @@ CREATE TABLE phpbb_posts ( icon_id INT4 DEFAULT '0' NOT NULL CHECK (icon_id >= 0), poster_ip varchar(40) DEFAULT '' NOT NULL, post_time INT4 DEFAULT '0' NOT NULL CHECK (post_time >= 0), - post_approved INT2 DEFAULT '1' NOT NULL CHECK (post_approved >= 0), + post_visibility INT2 DEFAULT '0' NOT NULL, post_reported INT2 DEFAULT '0' NOT NULL CHECK (post_reported >= 0), enable_bbcode INT2 DEFAULT '1' NOT NULL CHECK (enable_bbcode >= 0), enable_smilies INT2 DEFAULT '1' NOT NULL CHECK (enable_smilies >= 0), @@ -713,6 +716,9 @@ CREATE TABLE phpbb_posts ( post_edit_user INT4 DEFAULT '0' NOT NULL CHECK (post_edit_user >= 0), post_edit_count INT2 DEFAULT '0' NOT NULL CHECK (post_edit_count >= 0), post_edit_locked INT2 DEFAULT '0' NOT NULL CHECK (post_edit_locked >= 0), + post_delete_time INT4 DEFAULT '0' NOT NULL CHECK (post_delete_time >= 0), + post_delete_reason varchar(255) DEFAULT '' NOT NULL, + post_delete_user INT4 DEFAULT '0' NOT NULL CHECK (post_delete_user >= 0), PRIMARY KEY (post_id) ); @@ -720,7 +726,7 @@ CREATE INDEX phpbb_posts_forum_id ON phpbb_posts (forum_id); CREATE INDEX phpbb_posts_topic_id ON phpbb_posts (topic_id); CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip); CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id); -CREATE INDEX phpbb_posts_post_approved ON phpbb_posts (post_approved); +CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility); CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username); CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts (topic_id, post_time); @@ -1093,15 +1099,16 @@ CREATE TABLE phpbb_topics ( forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), icon_id INT4 DEFAULT '0' NOT NULL CHECK (icon_id >= 0), topic_attachment INT2 DEFAULT '0' NOT NULL CHECK (topic_attachment >= 0), - topic_approved INT2 DEFAULT '1' NOT NULL CHECK (topic_approved >= 0), + topic_visibility INT2 DEFAULT '0' NOT NULL, topic_reported INT2 DEFAULT '0' NOT NULL CHECK (topic_reported >= 0), topic_title varchar(255) DEFAULT '' NOT NULL, topic_poster INT4 DEFAULT '0' NOT NULL CHECK (topic_poster >= 0), topic_time INT4 DEFAULT '0' NOT NULL CHECK (topic_time >= 0), topic_time_limit INT4 DEFAULT '0' NOT NULL CHECK (topic_time_limit >= 0), topic_views INT4 DEFAULT '0' NOT NULL CHECK (topic_views >= 0), - topic_replies INT4 DEFAULT '0' NOT NULL CHECK (topic_replies >= 0), - topic_replies_real INT4 DEFAULT '0' NOT NULL CHECK (topic_replies_real >= 0), + topic_posts_approved INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_approved >= 0), + topic_posts_unapproved INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_unapproved >= 0), + topic_posts_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_softdeleted >= 0), topic_status INT2 DEFAULT '0' NOT NULL, topic_type INT2 DEFAULT '0' NOT NULL, topic_first_post_id INT4 DEFAULT '0' NOT NULL CHECK (topic_first_post_id >= 0), @@ -1123,14 +1130,17 @@ CREATE TABLE phpbb_topics ( poll_max_options INT2 DEFAULT '1' NOT NULL, poll_last_vote INT4 DEFAULT '0' NOT NULL CHECK (poll_last_vote >= 0), poll_vote_change INT2 DEFAULT '0' NOT NULL CHECK (poll_vote_change >= 0), + topic_delete_time INT4 DEFAULT '0' NOT NULL CHECK (topic_delete_time >= 0), + topic_delete_reason varchar(255) DEFAULT '' NOT NULL, + topic_delete_user INT4 DEFAULT '0' NOT NULL CHECK (topic_delete_user >= 0), PRIMARY KEY (topic_id) ); CREATE INDEX phpbb_topics_forum_id ON phpbb_topics (forum_id); CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type); CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time); -CREATE INDEX phpbb_topics_topic_approved ON phpbb_topics (topic_approved); -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_approved, topic_last_post_id); +CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility); +CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id); CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id); /* diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 355981721e..a159534bb2 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -320,6 +320,7 @@ INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_subscribe', 1); INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_user_lock', 1); INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_vote', 1); INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_votechg', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_softdelete', 1); # -- Moderator related auth options INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_', 1, 1); @@ -333,6 +334,7 @@ INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_merg INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_move', 1, 1); INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_report', 1, 1); INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_split', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_softdelete', 1, 1); # -- Global moderator auth option (not a local option) INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_ban', 0, 1); @@ -453,9 +455,9 @@ INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) INSERT INTO phpbb_styles (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, ''); # -- Forums -INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts, forum_topics, forum_topics_real, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents) VALUES ('{L_FORUMS_FIRST_CATEGORY}', '', 1, 4, 0, 0, 1, 1, 1, 1, 2, 'Admin', 'AA0000', 972086460, '', '', '', '', '', '', '', 0, 0, ''); +INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents) VALUES ('{L_FORUMS_FIRST_CATEGORY}', '', 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 'Admin', 'AA0000', 972086460, '', '', '', '', '', '', '', 0, 0, ''); -INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts, forum_topics, forum_topics_real, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 1, 1, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48); +INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48); # -- Users / Anonymous user INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0); @@ -523,7 +525,7 @@ INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 11, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option NOT IN ('m_ban', 'm_chgposter'); # Simple Moderator (m_) -INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 12, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_delete', 'm_edit', 'm_info', 'm_report'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 12, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_delete', 'm_softdelete', 'm_edit', 'm_info', 'm_report'); # Queue Moderator (m_) INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 13, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_approve', 'm_edit'); @@ -621,10 +623,10 @@ INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, # -- Demo Topic -INSERT INTO phpbb_topics (topic_title, topic_poster, topic_time, topic_views, topic_replies, topic_replies_real, forum_id, topic_status, topic_type, topic_first_post_id, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_subject, topic_last_post_time, topic_last_view_time, poll_title) VALUES ('{L_TOPICS_TOPIC_TITLE}', 2, 972086460, 0, 0, 0, 2, 0, 0, 1, 'Admin', 'AA0000', 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, 972086460, ''); +INSERT INTO phpbb_topics (topic_title, topic_poster, topic_time, topic_views, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, forum_id, topic_status, topic_type, topic_first_post_id, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_subject, topic_last_post_time, topic_last_view_time, poll_title, topic_visibility) VALUES ('{L_TOPICS_TOPIC_TITLE}', 2, 972086460, 0, 1, 0, 0, 2, 0, 0, 1, 'Admin', 'AA0000', 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, 972086460, '', 1); # -- Demo Post -INSERT INTO phpbb_posts (topic_id, forum_id, poster_id, icon_id, post_time, post_username, poster_ip, post_subject, post_text, post_checksum, bbcode_uid) VALUES (1, 2, 2, 0, 972086460, '', '127.0.0.1', '{L_TOPICS_TOPIC_TITLE}', '{L_DEFAULT_INSTALL_POST}', '5dd683b17f641daf84c040bfefc58ce9', ''); +INSERT INTO phpbb_posts (topic_id, forum_id, poster_id, icon_id, post_time, post_username, poster_ip, post_subject, post_text, post_checksum, bbcode_uid, post_visibility) VALUES (1, 2, 2, 0, 972086460, '', '127.0.0.1', '{L_TOPICS_TOPIC_TITLE}', '{L_DEFAULT_INSTALL_POST}', '5dd683b17f641daf84c040bfefc58ce9', '', 1); # -- Admin posted to the demo topic INSERT INTO phpbb_topics_posted (user_id, topic_id, topic_posted) VALUES (2, 1, 1); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 02ffb9a857..72b2b276da 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -250,9 +250,12 @@ CREATE TABLE phpbb_forums ( forum_topics_per_page tinyint(4) NOT NULL DEFAULT '0', forum_type tinyint(4) NOT NULL DEFAULT '0', forum_status tinyint(4) NOT NULL DEFAULT '0', - forum_posts INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_topics INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_topics_real INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_posts_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_posts_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_posts_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_topics_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_topics_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', + forum_topics_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', forum_last_post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', forum_last_poster_id INTEGER UNSIGNED NOT NULL DEFAULT '0', forum_last_post_subject text(65535) NOT NULL DEFAULT '', @@ -493,7 +496,7 @@ CREATE TABLE phpbb_posts ( icon_id INTEGER UNSIGNED NOT NULL DEFAULT '0', poster_ip varchar(40) NOT NULL DEFAULT '', post_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_approved INTEGER UNSIGNED NOT NULL DEFAULT '1', + post_visibility tinyint(3) NOT NULL DEFAULT '0', post_reported INTEGER UNSIGNED NOT NULL DEFAULT '0', enable_bbcode INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_smilies INTEGER UNSIGNED NOT NULL DEFAULT '1', @@ -511,14 +514,17 @@ CREATE TABLE phpbb_posts ( post_edit_reason text(65535) NOT NULL DEFAULT '', post_edit_user INTEGER UNSIGNED NOT NULL DEFAULT '0', post_edit_count INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_edit_locked INTEGER UNSIGNED NOT NULL DEFAULT '0' + post_edit_locked INTEGER UNSIGNED NOT NULL DEFAULT '0', + post_delete_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + post_delete_reason text(65535) NOT NULL DEFAULT '', + post_delete_user INTEGER UNSIGNED NOT NULL DEFAULT '0' ); CREATE INDEX phpbb_posts_forum_id ON phpbb_posts (forum_id); CREATE INDEX phpbb_posts_topic_id ON phpbb_posts (topic_id); CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip); CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id); -CREATE INDEX phpbb_posts_post_approved ON phpbb_posts (post_approved); +CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility); CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username); CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts (topic_id, post_time); @@ -811,15 +817,16 @@ CREATE TABLE phpbb_topics ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', icon_id INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_attachment INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_approved INTEGER UNSIGNED NOT NULL DEFAULT '1', + topic_visibility tinyint(3) NOT NULL DEFAULT '0', topic_reported INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_title text(65535) NOT NULL DEFAULT '', topic_poster INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_time INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_time_limit INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_views INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_replies INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_replies_real INTEGER UNSIGNED NOT NULL DEFAULT '0', + topic_posts_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', + topic_posts_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', + topic_posts_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', topic_status tinyint(3) NOT NULL DEFAULT '0', topic_type tinyint(3) NOT NULL DEFAULT '0', topic_first_post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -840,14 +847,17 @@ CREATE TABLE phpbb_topics ( poll_length INTEGER UNSIGNED NOT NULL DEFAULT '0', poll_max_options tinyint(4) NOT NULL DEFAULT '1', poll_last_vote INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_vote_change INTEGER UNSIGNED NOT NULL DEFAULT '0' + poll_vote_change INTEGER UNSIGNED NOT NULL DEFAULT '0', + topic_delete_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + topic_delete_reason text(65535) NOT NULL DEFAULT '', + topic_delete_user INTEGER UNSIGNED NOT NULL DEFAULT '0' ); CREATE INDEX phpbb_topics_forum_id ON phpbb_topics (forum_id); CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type); CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time); -CREATE INDEX phpbb_topics_topic_approved ON phpbb_topics (topic_approved); -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_approved, topic_last_post_id); +CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility); +CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id); CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id); # Table: 'phpbb_topics_track' diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 4c2002754f..d128caca63 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -559,12 +559,17 @@ $lang = array_merge($lang, array( 'LOG_POST_APPROVED' => '<strong>Approved post</strong><br />» %s', 'LOG_POST_DISAPPROVED' => '<strong>Disapproved post “%1$s” with the following reason</strong><br />» %2$s', 'LOG_POST_EDITED' => '<strong>Edited post “%1$s” written by</strong><br />» %2$s', + 'LOG_POST_RESTORED' => '<strong>Restored post</strong><br />» %s', 'LOG_REPORT_CLOSED' => '<strong>Closed report</strong><br />» %s', 'LOG_REPORT_DELETED' => '<strong>Deleted report</strong><br />» %s', + 'LOG_RESTORE_TOPIC' => '<strong>Restored topic “%1$s” written by</strong><br />» %2$s', + 'LOG_SOFTDELETE_POST' => '<strong>Soft deleted post “%1$s” written by</strong><br />» %2$s', + 'LOG_SOFTDELETE_TOPIC' => '<strong>Soft deleted topic “%1$s” written by</strong><br />» %2$s', 'LOG_SPLIT_DESTINATION' => '<strong>Moved split posts</strong><br />» to %s', 'LOG_SPLIT_SOURCE' => '<strong>Split posts</strong><br />» from %s', 'LOG_TOPIC_APPROVED' => '<strong>Approved topic</strong><br />» %s', + 'LOG_TOPIC_RESTORED' => '<strong>Restored topic</strong><br />» %s', 'LOG_TOPIC_DISAPPROVED' => '<strong>Disapproved topic “%1$s” with the following reason</strong><br />%2$s', 'LOG_TOPIC_RESYNC' => '<strong>Resynchronised topic counters</strong><br />» %s', 'LOG_TOPIC_TYPE_CHANGED' => '<strong>Changed topic type</strong><br />» %s', diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php index 27ef714f8b..98679ad544 100644 --- a/phpBB/language/en/acp/permissions_phpbb.php +++ b/phpBB/language/en/acp/permissions_phpbb.php @@ -152,7 +152,8 @@ $lang = array_merge($lang, array( 'acl_f_announce' => array('lang' => 'Can post announcements', 'cat' => 'post'), 'acl_f_reply' => array('lang' => 'Can reply to topics', 'cat' => 'post'), 'acl_f_edit' => array('lang' => 'Can edit own posts', 'cat' => 'post'), - 'acl_f_delete' => array('lang' => 'Can delete own posts', 'cat' => 'post'), + 'acl_f_delete' => array('lang' => 'Can permanently delete own posts', 'cat' => 'post'), + 'acl_f_softdelete' => array('lang' => 'Can soft delete own posts<br /><em>Moderators, who have the approve posts permission, can restore soft deleted posts.</em>', 'cat' => 'post'), 'acl_f_ignoreflood' => array('lang' => 'Can ignore flood limit', 'cat' => 'post'), 'acl_f_postcount' => array('lang' => 'Increment post counter<br /><em>Please note that this setting only affects new posts.</em>', 'cat' => 'post'), 'acl_f_noapprove' => array('lang' => 'Can post without approval', 'cat' => 'post'), @@ -173,8 +174,9 @@ $lang = array_merge($lang, array( // Moderator Permissions $lang = array_merge($lang, array( 'acl_m_edit' => array('lang' => 'Can edit posts', 'cat' => 'post_actions'), - 'acl_m_delete' => array('lang' => 'Can delete posts', 'cat' => 'post_actions'), - 'acl_m_approve' => array('lang' => 'Can approve posts', 'cat' => 'post_actions'), + 'acl_m_delete' => array('lang' => 'Can permanently delete posts', 'cat' => 'post_actions'), + 'acl_m_softdelete' => array('lang' => 'Can soft delete posts<br /><em>Moderators, who have the approve posts permission, can restore soft deleted posts.</em>', 'cat' => 'post_actions'), + 'acl_m_approve' => array('lang' => 'Can approve and restore posts', 'cat' => 'post_actions'), 'acl_m_report' => array('lang' => 'Can close and delete reports', 'cat' => 'post_actions'), 'acl_m_chgposter' => array('lang' => 'Can change post author', 'cat' => 'post_actions'), diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 7c7afd83f4..b188d90f3a 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -519,8 +519,12 @@ $lang = array_merge($lang, array( 'POSTS' => 'Posts', 'POSTS_UNAPPROVED' => 'At least one post in this topic has not been approved.', 'POST_BY_AUTHOR' => 'by', - 'POST_BY_FOE' => 'This post was made by <strong>%1$s</strong> who is currently on your ignore list. %2$sDisplay this post%3$s.', + 'POST_BY_FOE' => '<strong>%1$s</strong>, who is currently on your ignore list, made this post.', + 'POST_DISPLAY' => '%1$sDisplay this post%2$s.', 'POST_DAY' => '%.2f posts per day', + 'POST_DELETED' => 'Deleted post:', + 'POST_DELETED_BY' => '<strong>%2$s</strong> deleted the post by <strong>%1$s</strong> on %3$s.', + 'POST_DELETED_BY_REASON'=> '<strong>%2$s</strong> deleted the post by <strong>%1$s</strong> on %3$s for the following reason: %4$s', 'POST_DETAILS' => 'Post details', 'POST_NEW_TOPIC' => 'Post new topic', 'POST_PCT' => '%.2f%% of all posts', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index 29f418183f..b75e0ea495 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -52,6 +52,10 @@ $lang = array_merge($lang, array( 'APPROVE_POST_CONFIRM' => 'Are you sure you want to approve this post?', 'APPROVE_POSTS' => 'Approve posts', 'APPROVE_POSTS_CONFIRM' => 'Are you sure you want to approve the selected posts?', + 'APPROVE_TOPIC' => 'Approve topic', + 'APPROVE_TOPIC_CONFIRM' => 'Are you sure you want to approve this topic?', + 'APPROVE_TOPICS' => 'Approve topics', + 'APPROVE_TOPICS_CONFIRM'=> 'Are you sure you want to approve the selected topics?', 'CANNOT_MOVE_SAME_FORUM'=> 'You cannot move a topic to the forum it’s already in.', 'CANNOT_WARN_ANONYMOUS' => 'You cannot warn unregistered guest users.', @@ -72,16 +76,12 @@ $lang = array_merge($lang, array( 'DELETE_PM_REPORTS' => 'Delete PM reports', 'DELETE_PM_REPORTS_CONFIRM' => 'Are you sure you want to delete the selected PM reports?', 'DELETE_POSTS' => 'Delete posts', - 'DELETE_POSTS_CONFIRM' => 'Are you sure you want to delete these posts?', - 'DELETE_POST_CONFIRM' => 'Are you sure you want to delete this post?', 'DELETE_REPORT' => 'Delete report', 'DELETE_REPORT_CONFIRM' => 'Are you sure you want to delete the selected report?', 'DELETE_REPORTS' => 'Delete reports', 'DELETE_REPORTS_CONFIRM' => 'Are you sure you want to delete the selected reports?', 'DELETE_SHADOW_TOPIC' => 'Delete shadow topic', 'DELETE_TOPICS' => 'Delete selected topics', - 'DELETE_TOPICS_CONFIRM' => 'Are you sure you want to delete these topics?', - 'DELETE_TOPIC_CONFIRM' => 'Are you sure you want to delete this topic?', 'DISAPPROVE' => 'Disapprove', 'DISAPPROVE_REASON' => 'Reason for disapproval', 'DISAPPROVE_POST' => 'Disapprove post', @@ -201,6 +201,10 @@ $lang = array_merge($lang, array( 'MCP_QUEUE_UNAPPROVED_POSTS_EXPLAIN' => 'This is a list of all posts which require approving before they will be visible to users.', 'MCP_QUEUE_UNAPPROVED_TOPICS' => 'Topics awaiting approval', 'MCP_QUEUE_UNAPPROVED_TOPICS_EXPLAIN' => 'This is a list of all topics which require approving before they will be visible to users.', + 'MCP_QUEUE_DELETED_POSTS' => 'Deleted posts', + 'MCP_QUEUE_DELETED_POSTS_EXPLAIN' => 'This is a list of all soft deleted posts. You can restore or permanently delete the posts from this screen.', + 'MCP_QUEUE_DELETED_TOPICS' => 'Deleted topics', + 'MCP_QUEUE_DELETED_TOPICS_EXPLAIN' => 'This is a list of all soft deleted topics. You can restore or permanently delete the topics from this screen.', 'MCP_VIEW_USER' => 'View warnings for a specific user', @@ -238,6 +242,7 @@ $lang = array_merge($lang, array( 'NO_POST' => 'You have to select a post in order to warn the user for a post.', 'NO_POST_REPORT' => 'This post was not reported.', 'NO_POST_SELECTED' => 'You must select at least one post to perform this action.', + 'NO_POSTS_DELETED' => 'There are no deleted posts.', 'NO_POSTS_QUEUE' => 'There are no posts waiting for approval.', 'NO_REASON_DISAPPROVAL' => 'Please give an appropriate reason for disapproval.', 'NO_REPORT' => 'No report found', @@ -245,6 +250,7 @@ $lang = array_merge($lang, array( 'NO_REPORT_SELECTED' => 'You must select at least one report to perform this action.', 'NO_TOPIC_ICON' => 'None', 'NO_TOPIC_SELECTED' => 'You must select at least one topic to perform this action.', + 'NO_TOPICS_DELETED' => 'There are no deleted topics.', 'NO_TOPICS_QUEUE' => 'There are no topics waiting for approval.', 'ONLY_TOPIC' => 'Only topic “%s”', @@ -269,15 +275,17 @@ $lang = array_merge($lang, array( 'POSTS_DISAPPROVED_SUCCESS' => 'The selected posts have been disapproved.', 'POSTS_LOCKED_SUCCESS' => 'The selected posts have been locked successfully.', 'POSTS_MERGED_SUCCESS' => 'The selected posts have been merged.', - 'POSTS_UNLOCKED_SUCCESS' => 'The selected posts have been unlocked successfully.', 'POSTS_PER_PAGE' => 'Posts per page', 'POSTS_PER_PAGE_EXPLAIN' => '(Set to 0 to view all posts.)', + 'POSTS_RESTORED_SUCCESS' => 'The selected posts have been restored successfully.', + 'POSTS_UNLOCKED_SUCCESS' => 'The selected posts have been unlocked successfully.', 'POST_APPROVED_SUCCESS' => 'The selected post has been approved.', 'POST_DELETED_SUCCESS' => 'The selected post has been successfully removed from the database.', 'POST_DISAPPROVED_SUCCESS' => 'The selected post has been disapproved.', 'POST_LOCKED_SUCCESS' => 'Post locked successfully.', 'POST_NOT_EXIST' => 'The post you requested does not exist.', 'POST_REPORTED_SUCCESS' => 'This post has been successfully reported.', + 'POST_RESTORED_SUCCESS' => 'This post has been restored successfully.', 'POST_UNLOCKED_SUCCESS' => 'Post unlocked successfully.', 'READ_USERNOTES' => 'User notes', @@ -304,6 +312,15 @@ $lang = array_merge($lang, array( 'REPORT_POST_EXPLAIN' => 'Use this form to report the selected post to the forum moderators and board administrators. Reporting should generally be used only if the post breaks forum rules.', 'REPORT_REASON' => 'Report reason', 'REPORT_TIME' => 'Report time', + 'RESTORE' => 'Restore', + 'RESTORE_POST' => 'Restore post', + 'RESTORE_POST_CONFIRM' => 'Are you sure you want to restore this post?', + 'RESTORE_POSTS' => 'Restore posts', + 'RESTORE_POSTS_CONFIRM' => 'Are you sure you want to restore the selected posts?', + 'RESTORE_TOPIC' => 'Restore topic', + 'RESTORE_TOPIC_CONFIRM' => 'Are you sure you want to restore this topic?', + 'RESTORE_TOPICS' => 'Restore topics', + 'RESTORE_TOPICS_CONFIRM' => 'Are you sure you want to restore the selected topics?', 'RESYNC' => 'Resync', 'RETURN_MESSAGE' => '%sReturn to the message%s', 'RETURN_NEW_FORUM' => '%sGo to the new forum%s', @@ -344,6 +361,7 @@ $lang = array_merge($lang, array( 'TOPICS_FORKED_SUCCESS' => 'The selected topics have been copied successfully.', 'TOPICS_LOCKED_SUCCESS' => 'The selected topics have been locked.', 'TOPICS_MOVED_SUCCESS' => 'The selected topics have been moved successfully.', + 'TOPICS_RESTORED_SUCCESS' => 'The selected topics have been restored successfully.', 'TOPICS_RESYNC_SUCCESS' => 'The selected topics have been resynchronised.', 'TOPICS_TYPE_CHANGED' => 'Topic types changed successfully.', 'TOPICS_UNLOCKED_SUCCESS' => 'The selected topics have been unlocked.', @@ -354,6 +372,7 @@ $lang = array_merge($lang, array( 'TOPIC_LOCKED_SUCCESS' => 'The selected topic has been locked.', 'TOPIC_MOVED_SUCCESS' => 'The selected topic has been moved successfully.', 'TOPIC_NOT_EXIST' => 'The topic you selected does not exist.', + 'TOPIC_RESTORED_SUCCESS' => 'The selected topic has been restored successfully.', 'TOPIC_RESYNC_SUCCESS' => 'The selected topic has been resynchronised.', 'TOPIC_SPLIT_SUCCESS' => 'The selected topic has been split successfully.', 'TOPIC_TIME' => 'Topic time', diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 7651ff2b63..0e8d59a92e 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -77,8 +77,20 @@ $lang = array_merge($lang, array( 'DELETE_MESSAGE' => 'Delete message', 'DELETE_MESSAGE_CONFIRM' => 'Are you sure you want to delete this message?', 'DELETE_OWN_POSTS' => 'Sorry but you can only delete your own posts.', + 'DELETE_PERMANENTLY' => 'Delete permanently', 'DELETE_POST_CONFIRM' => 'Are you sure you want to delete this post?', - 'DELETE_POST_WARN' => 'Once deleted the post cannot be recovered', + 'DELETE_POST_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete this post?', + 'DELETE_POST_PERMANENTLY' => 'Permanently delete this post so it can not be recovered', + 'DELETE_POSTS_CONFIRM' => 'Are you sure you want to delete these posts?', + 'DELETE_POSTS_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete these posts?', + 'DELETE_REASON' => 'Soft delete reason', + 'DELETE_REASON_EXPLAIN' => 'The specified reason for deletion will be visible to moderators.', + 'DELETE_POST_WARN' => 'Deleted this post', + 'DELETE_TOPIC_CONFIRM' => 'Are you sure you want to delete this topic?', + 'DELETE_TOPIC_PERMANENTLY' => 'Permanently delete this topic so it can not be recovered', + 'DELETE_TOPIC_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete this topic?', + 'DELETE_TOPICS_CONFIRM' => 'Are you sure you want to delete these topics?', + 'DELETE_TOPICS_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete these topics?', 'DISABLE_BBCODE' => 'Disable BBCode', 'DISABLE_MAGIC_URL' => 'Do not automatically parse URLs', 'DISABLE_SMILIES' => 'Disable smilies', diff --git a/phpBB/language/en/viewtopic.php b/phpBB/language/en/viewtopic.php index 278c064fe7..6f318c39f1 100644 --- a/phpBB/language/en/viewtopic.php +++ b/phpBB/language/en/viewtopic.php @@ -50,6 +50,7 @@ $lang = array_merge($lang, array( 'CODE' => 'Code', 'DELETE_TOPIC' => 'Delete topic', + 'DELETED_INFORMATION' => 'Deleted by %1$s on %2$s', 'DISAPPROVE' => 'Disapprove', 'DOWNLOAD_NOTICE' => 'You do not have the required permissions to view the files attached to this post.', @@ -89,6 +90,7 @@ $lang = array_merge($lang, array( 'POLL_ENDED_AT' => 'Poll ended at %s', 'POLL_RUN_TILL' => 'Poll runs till %s', 'POLL_VOTED_OPTION' => 'You voted for this option', + 'POST_DELETED_RESTORE' => 'This post has been deleted. It can be restored.', 'PRINT_TOPIC' => 'Print view', 'QUICK_MOD' => 'Quick-mod tools', @@ -96,6 +98,8 @@ $lang = array_merge($lang, array( 'QUOTE' => 'Quote', 'REPLY_TO_TOPIC' => 'Reply to topic', + 'RESTORE' => 'Restore', + 'RESTORE_TOPIC' => 'Restore topic', 'RETURN_POST' => '%sReturn to the post%s', 'SUBMIT_VOTE' => 'Submit vote', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index c36faad74b..5beea45c7d 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -158,6 +158,7 @@ if ($quickmod) case 'move': case 'delete_post': case 'delete_topic': + case 'restore_topic': $module->load('mcp', 'main', 'quickmod'); return; break; @@ -199,7 +200,7 @@ if (!$post_id) $module->set_display('warn', 'warn_post', false); } -if ($mode == '' || $mode == 'unapproved_topics' || $mode == 'unapproved_posts') +if ($mode == '' || $mode == 'unapproved_topics' || $mode == 'unapproved_posts' || $mode == 'deleted_topics' || $mode == 'deleted_posts') { $module->set_display('queue', 'approve_details', false); } @@ -483,7 +484,7 @@ function get_post_data($post_ids, $acl_list = false, $read_tracking = false) continue; } - if (!$row['post_approved'] && !$auth->acl_get('m_approve', $row['forum_id'])) + if ($row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) { // Moderators without the permission to approve post should at least not see them. ;) continue; @@ -501,7 +502,7 @@ function get_post_data($post_ids, $acl_list = false, $read_tracking = false) */ function get_forum_data($forum_id, $acl_list = 'f_list', $read_tracking = false) { - global $auth, $db, $user, $config; + global $auth, $db, $user, $config, $phpbb_container; $rowset = array(); @@ -531,6 +532,8 @@ function get_forum_data($forum_id, $acl_list = 'f_list', $read_tracking = false) WHERE " . $db->sql_in_set('f.forum_id', $forum_id); $result = $db->sql_query($sql); + $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + while ($row = $db->sql_fetchrow($result)) { if ($acl_list && !$auth->acl_gets($acl_list, $row['forum_id'])) @@ -538,10 +541,7 @@ function get_forum_data($forum_id, $acl_list = 'f_list', $read_tracking = false) continue; } - if ($auth->acl_get('m_approve', $row['forum_id'])) - { - $row['forum_topics'] = $row['forum_topics_real']; - } + $row['forum_topics_approved'] = $phpbb_content_visibility->get_count('forum_topics', $row, $row['forum_id']); $rowset[$row['forum_id']] = $row; } @@ -619,7 +619,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, if (!$auth->acl_get('m_approve', $forum_id)) { - $sql .= 'AND topic_approved = 1'; + $sql .= 'AND topic_visibility = ' . ITEM_APPROVED; } break; @@ -635,11 +635,13 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, if (!$auth->acl_get('m_approve', $forum_id)) { - $sql .= 'AND post_approved = 1'; + $sql .= 'AND post_visibility = ' . ITEM_APPROVED; } break; case 'unapproved_posts': + case 'deleted_posts': + $visibility_const = ($mode == 'unapproved_posts') ? ITEM_UNAPPROVED : ITEM_DELETED; $type = 'posts'; $default_key = 't'; $default_dir = 'd'; @@ -648,9 +650,9 @@ 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_approved = 0 + AND p.post_visibility = ' . $visibility_const . ' AND t.topic_id = p.topic_id - AND t.topic_first_post_id <> p.post_id'; + AND t.topic_visibility <> p.post_visibility'; if ($min_time) { @@ -659,6 +661,8 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, break; case 'unapproved_topics': + case 'deleted_topics': + $visibility_const = ($mode == 'unapproved_topics') ? ITEM_UNAPPROVED : ITEM_DELETED; $type = 'topics'; $default_key = 't'; $default_dir = 'd'; @@ -666,7 +670,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_approved = 0'; + AND topic_visibility = ' . $visibility_const; if ($min_time) { @@ -748,7 +752,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, $limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'tt' => $user->lang['TOPIC_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']); - $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_replies_real' : 't.topic_replies'), 's' => 't.topic_title', 'v' => 't.topic_views'); + $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'tt' => 't.topic_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views'); $limit_time_sql = ($min_time) ? "AND t.topic_last_post_time >= $min_time" : ''; break; @@ -796,7 +800,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, 'S_SELECT_SORT_DAYS' => $s_limit_days) ); - if (($sort_days && $mode != 'viewlogs') || in_array($mode, array('reports', 'unapproved_topics', 'unapproved_posts')) || $where_sql != 'WHERE') + if (($sort_days && $mode != 'viewlogs') || in_array($mode, array('reports', 'unapproved_topics', 'unapproved_posts', 'deleted_topics', 'deleted_posts')) || $where_sql != 'WHERE') { $result = $db->sql_query($sql); $total = (int) $db->sql_fetchfield('total'); diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 7ecf332720..46136dbdd4 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -638,7 +638,7 @@ switch ($mode) $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_approved = 0'; + AND post_visibility = ' . ITEM_UNAPPROVED; $result = $db->sql_query($sql); $member['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); diff --git a/phpBB/posting.php b/phpBB/posting.php index c6b9ff4cce..ac459197b3 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -35,11 +35,17 @@ $submit = (isset($_POST['post'])) ? true : false; $preview = (isset($_POST['preview'])) ? true : false; $save = (isset($_POST['save'])) ? true : false; $load = (isset($_POST['load'])) ? true : false; -$delete = (isset($_POST['delete'])) ? true : false; +$confirm = $request->is_set_post('confirm'); $cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false; -$refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($_POST['cancel_unglobalise']) || $save || $load || $preview) ? true : false; -$mode = ($delete && !$preview && !$refresh && $submit) ? 'delete' : request_var('mode', ''); +$refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($_POST['cancel_unglobalise']) || $save || $load || $preview); +$mode = request_var('mode', ''); + +// If the user is not allowed to delete the post, we try to soft delete it, so we overwrite the mode here. +if ($mode == 'delete' && (($confirm && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id))) +{ + $mode = 'soft_delete'; +} $error = $post_data = array(); $current_time = time(); @@ -92,6 +98,8 @@ if (in_array($mode, array('post', 'reply', 'quote', 'edit', 'delete')) && !$foru trigger_error('NO_FORUM'); } +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + // We need to know some basic information in all cases before we do anything. switch ($mode) { @@ -121,13 +129,14 @@ switch ($mode) $sql = 'SELECT f.*, t.* FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f WHERE t.topic_id = $topic_id - AND f.forum_id = t.forum_id" . - (($auth->acl_get('m_approve', $forum_id)) ? '' : ' AND t.topic_approved = 1'); + AND f.forum_id = t.forum_id + AND " . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'); break; case 'quote': case 'edit': case 'delete': + case 'soft_delete': if (!$post_id) { $user->setup('posting'); @@ -149,8 +158,8 @@ switch ($mode) WHERE p.post_id = $post_id AND t.topic_id = p.topic_id AND u.user_id = p.poster_id - AND f.forum_id = t.forum_id" . - (($auth->acl_get('m_approve', $forum_id)) ? '' : ' AND p.post_approved = 1'); + AND f.forum_id = t.forum_id + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.'); break; case 'smilies': @@ -198,7 +207,7 @@ if (!$post_data) // Not able to reply to unapproved posts/topics // TODO: add more descriptive language key -if ($auth->acl_get('m_approve', $forum_id) && ((($mode == 'reply' || $mode == 'bump') && !$post_data['topic_approved']) || ($mode == 'quote' && !$post_data['post_approved']))) +if ($auth->acl_get('m_approve', $forum_id) && ((($mode == 'reply' || $mode == 'bump') && $post_data['topic_visibility'] != ITEM_APPROVED) || ($mode == 'quote' && $post_data['post_visibility'] != ITEM_APPROVED))) { trigger_error(($mode == 'reply' || $mode == 'bump') ? 'TOPIC_UNAPPROVED' : 'POST_UNAPPROVED'); } @@ -290,10 +299,22 @@ switch ($mode) break; case 'delete': - if ($user->data['is_registered'] && $auth->acl_gets('f_delete', 'm_delete', $forum_id)) + if ($user->data['is_registered'] && ($auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)))) + { + $is_authed = true; + } + break; + + case 'soft_delete': + if ($user->data['is_registered'] && $phpbb_content_visibility->can_soft_delete($forum_id, $post_data['poster_id'], $post_data['post_edit_locked'])) { $is_authed = true; } + else + { + // Display the same error message for softdelete we use for delete + $mode = 'delete'; + } break; } @@ -342,9 +363,17 @@ if ($mode == 'edit' && !$auth->acl_get('m_edit', $forum_id)) } // Handle delete mode... -if ($mode == 'delete') +if ($mode == 'delete' || $mode == 'soft_delete') { - handle_post_delete($forum_id, $topic_id, $post_id, $post_data); + if ($mode == 'soft_delete' && $post_data['post_visibility'] == ITEM_DELETED) + { + $user->setup('posting'); + trigger_error('NO_POST'); + } + + $allow_reason = $auth->acl_get('m_softdelete', $forum_id) || ($auth->acl_gets('m_delete', 'f_delete', $forum_id) && $auth->acl_gets('m_softdelete', 'f_softdelete', $forum_id)); + $soft_delete_reason = ($mode == 'soft_delete' && $allow_reason) ? $request->variable('delete_reason', '', true) : ''; + handle_post_delete($forum_id, $topic_id, $post_id, $post_data, ($mode == 'soft_delete'), $soft_delete_reason); return; } @@ -900,6 +929,19 @@ if ($submit || $preview || $refresh) $error[] = $user->lang['FORM_INVALID']; } + if ($submit && $mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED && !isset($_POST['soft_delete']) && $auth->acl_get('m_approve', $forum_id)) + { + $is_first_post = ($post_id == $post_data['topic_first_post_id'] || !$post_data['topic_posts_approved']); + $is_last_post = ($post_id == $post_data['topic_last_post_id'] || !$post_data['topic_posts_approved']); + $updated_post_data = $phpbb_content_visibility->set_post_visibility(ITEM_APPROVED, $post_id, $post_data['topic_id'], $post_data['forum_id'], $user->data['user_id'], time(), '', $is_first_post, $is_last_post); + + if (!empty($updated_post_data)) + { + // Update the post_data, so we don't need to refetch it. + $post_data = array_merge($post_data, $updated_post_data); + } + } + // Parse subject if (!$preview && !$refresh && utf8_clean_string($post_data['post_subject']) === '' && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id))) { @@ -1099,14 +1141,15 @@ if ($submit || $preview || $refresh) 'attachment_data' => $message_parser->attachment_data, 'filename_data' => $message_parser->filename_data, - 'topic_approved' => (isset($post_data['topic_approved'])) ? $post_data['topic_approved'] : false, - 'post_approved' => (isset($post_data['post_approved'])) ? $post_data['post_approved'] : false, + 'topic_visibility' => (isset($post_data['topic_visibility'])) ? $post_data['topic_visibility'] : false, + 'post_visibility' => (isset($post_data['post_visibility'])) ? $post_data['post_visibility'] : false, ); if ($mode == 'edit') { - $data['topic_replies_real'] = $post_data['topic_replies_real']; - $data['topic_replies'] = $post_data['topic_replies']; + $data['topic_posts_approved'] = $post_data['topic_posts_approved']; + $data['topic_posts_unapproved'] = $post_data['topic_posts_unapproved']; + $data['topic_posts_softdeleted'] = $post_data['topic_posts_softdeleted']; } // The last parameter tells submit_post if search indexer has to be run @@ -1117,6 +1160,15 @@ if ($submit || $preview || $refresh) $captcha->reset(); } + // Handle delete mode... + if ($request->is_set_post('delete') || $request->is_set_post('delete_permanent')) + { + $allow_reason = $auth->acl_get('m_softdelete', $forum_id) || ($auth->acl_gets('m_delete', 'f_delete', $forum_id) && $auth->acl_gets('m_softdelete', 'f_softdelete', $forum_id)); + $soft_delete_reason = (!$request->is_set_post('delete_permanent') && $allow_reason) ? $request->variable('delete_reason', '', true) : ''; + handle_post_delete($forum_id, $topic_id, $post_id, $post_data, !$request->is_set_post('delete_permanent'), $soft_delete_reason); + return; + } + // Check the permissions for post approval. // Moderators must go through post approval like ordinary users. if ((!$auth->acl_get('f_noapprove', $data['forum_id']) && empty($data['force_approved_state'])) || (isset($data['force_approved_state']) && !$data['force_approved_state'])) @@ -1438,6 +1490,11 @@ $template->assign_vars(array( 'S_LOCK_TOPIC_CHECKED' => ($lock_topic_checked) ? ' checked="checked"' : '', 'S_LOCK_POST_ALLOWED' => ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false, 'S_LOCK_POST_CHECKED' => ($lock_post_checked) ? ' checked="checked"' : '', + 'S_SOFTDELETE_CHECKED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? ' checked="checked"' : '', + 'S_DELETE_REASON' => ($mode == 'edit' && $auth->acl_get('m_softdelete', $forum_id)) ? true : false, + 'S_SOFTDELETE_ALLOWED' => ($mode == 'edit' && $phpbb_content_visibility->can_soft_delete($forum_id, $post_data['poster_id'], $lock_post_checked)) ? true : false, + 'S_RESTORE_ALLOWED' => $auth->acl_get('m_approve', $forum_id), + 'S_IS_DELETED' => ($mode == 'edit' && $post_data['post_visibility'] == ITEM_DELETED) ? true : false, 'S_LINKS_ALLOWED' => $url_status, 'S_MAGIC_URL_CHECKED' => ($urls_checked) ? ' checked="checked"' : '', 'S_TYPE_TOGGLE' => $topic_type_toggle, @@ -1539,18 +1596,20 @@ function upload_popup($forum_style = 0) /** * Do the various checks required for removing posts as well as removing it */ -function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data) +function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $soft_delete_reason = '') { global $user, $db, $auth, $config; global $phpbb_root_path, $phpEx; + $perm_check = ($is_soft) ? 'softdelete' : 'delete'; + // If moderator removing post or user itself removing post, present a confirmation screen - if ($auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_delete', $forum_id) && $post_id == $post_data['topic_last_post_id'] && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']))) + if ($auth->acl_get("m_$perm_check", $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get("f_$perm_check", $forum_id) && $post_id == $post_data['topic_last_post_id'] && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']))) { - $s_hidden_fields = build_hidden_fields(array( + $s_hidden_fields = array( 'p' => $post_id, 'f' => $forum_id, - 'mode' => 'delete') + 'mode' => ($is_soft) ? 'soft_delete' : 'delete', ); if (confirm_box(true)) @@ -1558,29 +1617,31 @@ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data) $data = array( 'topic_first_post_id' => $post_data['topic_first_post_id'], 'topic_last_post_id' => $post_data['topic_last_post_id'], - 'topic_replies_real' => $post_data['topic_replies_real'], - 'topic_approved' => $post_data['topic_approved'], + 'topic_posts_approved' => $post_data['topic_posts_approved'], + 'topic_posts_unapproved' => $post_data['topic_posts_unapproved'], + 'topic_posts_softdeleted' => $post_data['topic_posts_softdeleted'], + 'topic_visibility' => $post_data['topic_visibility'], 'topic_type' => $post_data['topic_type'], - 'post_approved' => $post_data['post_approved'], + 'post_visibility' => $post_data['post_visibility'], 'post_reported' => $post_data['post_reported'], 'post_time' => $post_data['post_time'], 'poster_id' => $post_data['poster_id'], - 'post_postcount' => $post_data['post_postcount'] + 'post_postcount' => $post_data['post_postcount'], ); - $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data); + $next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $soft_delete_reason); $post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username']; if ($next_post_id === false) { - add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_TOPIC', $post_data['topic_title'], $post_username); + add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username); $meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"); $message = $user->lang['POST_DELETED']; } else { - add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_POST', $post_data['post_subject'], $post_username); + add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username); $meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p=$next_post_id") . "#p$next_post_id"; $message = $user->lang['POST_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>'); @@ -1592,7 +1653,32 @@ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data) } else { - confirm_box(false, 'DELETE_POST', $s_hidden_fields); + global $user, $template, $request; + + $can_delete = $auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_delete', $forum_id)); + $can_softdelete = $auth->acl_get('m_softdelete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_softdelete', $forum_id)); + $display_reason = $auth->acl_get('m_softdelete', $forum_id) || ($can_delete && $can_softdelete); + + $template->assign_vars(array( + 'S_SOFTDELETED' => $post_data['post_visibility'] == ITEM_DELETED, + 'S_CHECKED_PERMANENT' => $request->is_set_post('delete_permanent') ? ' checked="checked"' : '', + 'S_ALLOWED_DELETE' => $can_delete, + 'S_ALLOWED_SOFTDELETE' => $can_softdelete, + 'S_DELETE_REASON' => $display_reason, + )); + + $l_confirm = 'DELETE_POST'; + if ($post_data['post_visibility'] == ITEM_DELETED) + { + $l_confirm .= '_PERMANENTLY'; + $s_hidden_fields['delete_permanent'] = '1'; + } + else if (!$can_softdelete) + { + $s_hidden_fields['delete_permanent'] = '1'; + } + + confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html'); } } diff --git a/phpBB/search.php b/phpBB/search.php index 7d20d8d4a2..2429c81dae 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -119,6 +119,8 @@ $sort_by_text = array('a' => $user->lang['SORT_AUTHOR'], 't' => $user->lang['SOR $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + if ($keywords || $author || $author_id || $search_id || $submit) { // clear arrays @@ -249,22 +251,9 @@ if ($keywords || $author || $author_id || $search_id || $submit) } $db->sql_freeresult($result); - // find out in which forums the user is allowed to view approved posts - if ($auth->acl_get('m_approve')) - { - $m_approve_fid_ary = array(-1); - $m_approve_fid_sql = ''; - } - else if ($auth->acl_getf_global('m_approve')) - { - $m_approve_fid_ary = array_diff(array_keys($auth->acl_getf('!m_approve', true)), $ex_fid_ary); - $m_approve_fid_sql = ' AND (p.post_approved = 1' . ((sizeof($m_approve_fid_ary)) ? ' OR ' . $db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) : '') . ')'; - } - else - { - $m_approve_fid_ary = array(); - $m_approve_fid_sql = ' AND p.post_approved = 1'; - } + // find out in which forums the user is allowed to view posts + $m_approve_posts_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('post', $ex_fid_ary, 'p.'); + $m_approve_topics_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('topic', $ex_fid_ary, 't.'); if ($reset_search_forum) { @@ -342,7 +331,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) FROM ' . TOPICS_TABLE . " t WHERE t.topic_moved_id = 0 $last_post_time_sql - " . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . ' + AND " . $m_approve_topics_fid_sql . ' ' . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . ' ORDER BY t.topic_last_post_time DESC'; $field = 'topic_id'; @@ -380,7 +369,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) WHERE t.topic_replies = 0 AND p.topic_id = t.topic_id $last_post_time - $m_approve_fid_sql + AND $m_approve_posts_fid_sql " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " $sql_sort"; $field = 'post_id'; @@ -393,7 +382,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) AND t.topic_moved_id = 0 AND p.topic_id = t.topic_id $last_post_time - $m_approve_fid_sql + AND $m_approve_topics_fid_sql " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " $sql_sort"; $field = 'topic_id'; @@ -409,7 +398,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); $sql_where = 'AND t.topic_moved_id = 0 - ' . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . ' + AND ' . $m_approve_topics_fid_sql . ' ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : ''); gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); @@ -432,9 +421,9 @@ if ($keywords || $author || $author_id || $search_id || $submit) { $sql = 'SELECT p.post_id FROM ' . POSTS_TABLE . ' p - WHERE p.post_time > ' . $user->data['user_lastvisit'] . " - $m_approve_fid_sql - " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " + WHERE p.post_time > ' . $user->data['user_lastvisit'] . ' + AND ' . $m_approve_posts_fid_sql . ' + ' . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " $sql_sort"; $field = 'post_id'; } @@ -444,7 +433,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) FROM ' . TOPICS_TABLE . ' t WHERE t.topic_last_post_time > ' . $user->data['user_lastvisit'] . ' AND t.topic_moved_id = 0 - ' . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . ' + AND ' . $m_approve_topics_fid_sql . ' ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . " $sql_sort"; /* @@ -456,8 +445,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) WHERE p.post_time > ' . $user->data['user_lastvisit'] . ' AND t.topic_id = p.topic_id AND t.topic_moved_id = 0 - ' . $m_approve_fid_sql . ' - ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . " + AND ' . $m_approve_topics_fid_sql . " GROUP BY t.topic_id $sql_sort"; */ @@ -533,17 +521,16 @@ if ($keywords || $author || $author_id || $search_id || $submit) // make sure that some arrays are always in the same order sort($ex_fid_ary); - sort($m_approve_fid_ary); sort($author_id_ary); if ($search->get_search_query()) { - $total_match_count = $search->keyword_search($show_results, $search_fields, $search_terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page); + $total_match_count = $search->keyword_search($show_results, $search_fields, $search_terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_posts_fid_sql, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page); } else if (sizeof($author_id_ary)) { $firstpost_only = ($search_fields === 'firstpost' || $search_fields == 'titleonly') ? true : false; - $total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page); + $total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_posts_fid_sql, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page); } // For some searches we need to print out the "no results" page directly to allow re-sorting/refining the search options. @@ -558,7 +545,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) { $sql_where .= $db->sql_in_set(($show_results == 'posts') ? 'p.post_id' : 't.topic_id', $id_ary); $sql_where .= (sizeof($ex_fid_ary)) ? ' AND (' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ' OR f.forum_id IS NULL)' : ''; - $sql_where .= ($show_results == 'posts') ? $m_approve_fid_sql : str_replace(array('p.post_approved', 'p.forum_id'), array('t.topic_approved', 't.forum_id'), $m_approve_fid_sql); + $sql_where .= ' AND ' . (($show_results == 'posts') ? $m_approve_posts_fid_sql : $m_approve_topics_fid_sql); } if ($show_results == 'posts') @@ -638,6 +625,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'), 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'), 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'), + 'DELETED_IMG' => $user->img('icon_topic_deleted', 'TOPIC_DELETED'), 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'), 'U_SEARCH_WORDS' => $u_search, @@ -874,12 +862,11 @@ if ($keywords || $author || $author_id || $search_id || $submit) $forum_id = $row['forum_id']; $result_topic_id = $row['topic_id']; $topic_title = censor_text($row['topic_title']); + $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1; $view_topic_url_params = "f=$forum_id&t=$result_topic_id" . (($u_hilit) ? "&hilit=$u_hilit" : ''); $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); - $replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; - if ($show_results == 'topics') { if ($config['load_db_track'] && $author_id === $user->data['user_id']) @@ -892,9 +879,11 @@ 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_approved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false; - $posts_unapproved = ($row['topic_approved'] && $row['topic_replies'] < $row['topic_replies_real'] && $auth->acl_get('m_approve', $forum_id)) ? true : false; + $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $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) : ''; + $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&mode=deleted_topics&t=$result_topic_id", true, $user->session_id) : ''; $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['topic_title']); @@ -929,6 +918,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false, 'S_TOPIC_UNAPPROVED' => $topic_unapproved, 'S_POSTS_UNAPPROVED' => $posts_unapproved, + 'S_TOPIC_DELETED' => $topic_deleted, 'U_LAST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'], 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 2528b96ece..394aca749b 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -126,11 +126,19 @@ phpbb.addAjaxCallback('post_delete', function() { }); // This callback removes the approve / disapprove div or link. -phpbb.addAjaxCallback('post_approve', function(res) { - var remove = (res.approved) ? $(this) : $(this).parents('.post'); +phpbb.addAjaxCallback('post_visibility', function(res) { + var remove = (res.visible) ? $(this) : $(this).parents('.post'); $(remove).css('pointer-events', 'none').fadeOut(function() { $(this).remove(); }); + + if (res.visible) + { + // Remove the "Deleted by" message from the post on restoring. + remove.parents('.post').find('.post_deleted_msg').css('pointer-events', 'none').fadeOut(function() { + $(this).remove(); + }); + } }); // This removes the parent row of the link or form that fired the callback. @@ -178,6 +186,20 @@ $('#qr_full_editor').click(function() { }); +/** + * Make the display post links to use JS + */ +$('.display_post').click(function(e) { + // Do not follow the link + e.preventDefault(); + + var post_id = $(this).attr('data-post-id'); + $('#post_content' + post_id).show(); + $('#profile' + post_id).show(); + $('#post_hidden' + post_id).hide(); +}); + + /** * This AJAXifies the quick-mod tools. The reason it cannot be a standard @@ -208,6 +230,14 @@ $('#quick-mod-select').change(function () { $('#quickmodform').submit(); }); +$('#delete_permanent').click(function () { + if ($(this).attr('checked')) { + $('#delete_reason').hide(); + } else { + $('#delete_reason').show(); + } +}); + /** * Toggle the member search panel in memberlist.php. * diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html new file mode 100644 index 0000000000..759b6b46b2 --- /dev/null +++ b/phpBB/styles/prosilver/template/confirm_delete_body.html @@ -0,0 +1,72 @@ +<!-- IF S_AJAX_REQUEST --> + <p>{MESSAGE_TEXT}</p> + + <!-- IF not S_SOFTDELETED and (S_DELETE_REASON or (S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE)) --> + <!-- IF S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE --> + <label> + <strong>{L_DELETE_PERMANENTLY}{L_COLON}</strong> + <input id="delete_permanent" name="delete_permanent" type="checkbox" value="1" {S_CHECKED_PERMANENT} /> + <!-- IF S_TOPIC_MODE -->{L_DELETE_TOPIC_PERMANENTLY}<!-- ELSE -->{L_DELETE_POST_PERMANENTLY}<!-- ENDIF --> + </label> + <!-- ENDIF --> + + <!-- IF S_DELETE_REASON --> + <label for="delete_reason"> + <strong>{L_DELETE_REASON}{L_COLON}</strong><br /><span>{L_DELETE_REASON_EXPLAIN}</span><br /> + <input type="text" name="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /> + </label> + <!-- ENDIF --> + <!-- ENDIF --> + + <fieldset class="submit-buttons"> + <input type="button" name="confirm" value="{L_YES}" class="button1" /> + <input type="button" name="cancel" value="{L_NO}" class="button2" /> + </fieldset> + +<!-- ELSE --> + +<!-- INCLUDE overall_header.html --> + +<form id="confirm" action="{S_CONFIRM_ACTION}" method="post"> +<div class="panel"> + <div class="inner"> + + <h2>{MESSAGE_TITLE}</h2> + + <p>{MESSAGE_TEXT}</p> + + <!-- IF not S_SOFTDELETED and (S_DELETE_REASON or (S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE)) --> + <fieldset class="fields1"> + <!-- IF S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE --> + <dl> + <dt><label for="delete_permanent">{L_DELETE_PERMANENTLY}{L_COLON}</label></dt> + <dd> + <label for="delete_permanent"> + <input id="delete_permanent" name="delete_permanent" type="checkbox" value="1" {S_CHECKED_PERMANENT} /> + <!-- IF S_TOPIC_MODE -->{L_DELETE_TOPIC_PERMANENTLY}<!-- ELSE -->{L_DELETE_POST_PERMANENTLY}<!-- ENDIF --> + </label> + </dd> + </dl> + <!-- ENDIF --> + + <!-- IF S_DELETE_REASON --> + <dl> + <dt><label for="delete_reason">{L_DELETE_REASON}{L_COLON}</label><br /><span>{L_DELETE_REASON_EXPLAIN}</span></dt> + <dd><input type="text" name="delete_reason" id="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /></dd> + </dl> + <!-- ENDIF --> + </fieldset> + <!-- ENDIF --> + + <fieldset class="submit-buttons"> + {S_HIDDEN_FIELDS} + <input type="submit" name="confirm" value="{L_YES}" class="button1" /> + <input type="submit" name="cancel" value="{L_NO}" class="button2" /> + </fieldset> + + </div> +</div> +</form> + +<!-- INCLUDE overall_footer.html --> +<!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html index 6c8215c7c6..ab7f92e262 100644 --- a/phpBB/styles/prosilver/template/mcp_approve.html +++ b/phpBB/styles/prosilver/template/mcp_approve.html @@ -7,7 +7,7 @@ <label><input type="checkbox" name="notify_poster" checked="checked" /> <!-- IF S_APPROVE -->{L_NOTIFY_POSTER_APPROVAL}<!-- ELSE -->{L_NOTIFY_POSTER_DISAPPROVAL}<!-- ENDIF --></label> <!-- ENDIF --> - <!-- IF not S_APPROVE --> + <!-- IF not S_APPROVE and not S_RESTORE and .reason --> <label><strong>{L_DISAPPROVE_REASON}{L_COLON}</strong> <select name="reason_id"> <!-- BEGIN reason --><option value="{reason.ID}"<!-- IF reason.S_SELECTED --> selected="selected"<!-- ENDIF -->>{reason.DESCRIPTION}</option><!-- END reason --> @@ -45,7 +45,7 @@ </dl> <!-- ENDIF --> - <!-- IF not S_APPROVE --> + <!-- IF not S_APPROVE and not S_RESTORE and .reason --> <dl class="fields2 nobg"> <dt><label>{L_DISAPPROVE_REASON}{L_COLON}</label></dt> <dd><select name="reason_id"> diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index db5525fcd0..45e6c10d46 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -45,6 +45,7 @@ <!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a> <!-- ENDIF --> <a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF topicrow.S_TOPIC_DELETED or topicrow.S_POSTS_DELETED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.DELETED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --> <!-- IF topicrow.S_MOVED_TOPIC and S_CAN_DELETE --> <a href="{topicrow.U_DELETE_TOPIC}" class="topictitle">[ {L_DELETE_SHADOW_TOPIC} ]</a><!-- ENDIF --> <br /> @@ -128,6 +129,7 @@ <select name="action"> <option value="" selected="selected">{L_SELECT_ACTION}</option> <!-- IF S_CAN_DELETE --><option value="delete_topic">{L_DELETE}</option><!-- ENDIF --> + <!-- IF S_CAN_RESTORE --><option value="restore_topic">{L_RESTORE}</option><!-- ENDIF --> <!-- IF S_CAN_MERGE --><option value="merge_topics">{L_MERGE}</option><!-- ENDIF --> <!-- IF S_CAN_MOVE --><option value="move">{L_MOVE}</option><!-- ENDIF --> <!-- IF S_CAN_FORK --><option value="fork">{L_FORK}</option><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index 756a6eb114..4cdd62957c 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -79,6 +79,17 @@ {S_FORM_TOKEN} </p> </form> + <!-- ELSEIF S_POST_DELETED --> + <form method="post" id="mcp_approve" action="{U_APPROVE_ACTION}"> + + <p class="rules"> + <input class="button2" type="submit" value="{L_DELETE}" name="action[disapprove]" /> + <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" /> + <!-- IF not S_FIRST_POST --><input type="hidden" name="mode" value="unapproved_posts" /><!-- ENDIF --> + <input type="hidden" name="post_id_list[]" value="{POST_ID}" /> + {S_FORM_TOKEN} + </p> + </form> <!-- ENDIF --> <!-- IF S_MESSAGE_REPORTED --> @@ -100,6 +111,13 @@ </dl> <!-- ENDIF --> + <!-- IF DELETED_MESSAGE or DELETE_REASON --> + <div class="notice"> + {DELETED_MESSAGE} + <!-- IF DELETE_REASON --><br /><strong>{L_REASON}{L_COLON}</strong> <em>{DELETE_REASON}</em><!-- ENDIF --> + </div> + <!-- ENDIF --> + <!-- IF SIGNATURE --> <div id="sig{POST_ID}" class="signature">{SIGNATURE}</div> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index d630606175..c2d39eff98 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -59,7 +59,13 @@ </dd> - <dd class="mark"><input type="checkbox" name="post_id_list[]" value="{postrow.POST_ID}" /></dd> + <dd class="mark"> + <!-- IF S_TOPICS --> + <input type="checkbox" name="topic_id_list[]" value="{postrow.TOPIC_ID}" /> + <!-- ELSE --> + <input type="checkbox" name="post_id_list[]" value="{postrow.POST_ID}" /> + <!-- ENDIF --> + </dd> </dl> </li> <!-- ENDIF --> @@ -88,7 +94,13 @@ </li> </ul> <!-- ELSE --> - <p class="notopics"><strong><!-- IF S_TOPICS -->{L_NO_TOPICS_QUEUE}<!-- ELSE -->{L_NO_POSTS_QUEUE}<!-- ENDIF --></strong></p> + <p class="notopics"><strong> + <!-- IF S_RESTORE --> + <!-- IF S_TOPICS -->{L_NO_TOPICS_DELETED}<!-- ELSE -->{L_NO_POSTS_DELETED}<!-- ENDIF --> + <!-- ELSE --> + <!-- IF S_TOPICS -->{L_NO_TOPICS_QUEUE}<!-- ELSE -->{L_NO_POSTS_QUEUE}<!-- ENDIF --> + <!-- ENDIF --> + </strong></p> <!-- ENDIF --> </div> @@ -96,9 +108,20 @@ <!-- IF .postrow --> <fieldset class="display-actions"> + <!-- IF S_RESTORE --> + <input class="button2" type="submit" name="action[delete]" value="{L_DELETE}" /> + <input class="button1" type="submit" name="action[restore]" value="{L_RESTORE}" /> + <!-- ELSE --> <input class="button2" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" /> <input class="button1" type="submit" name="action[approve]" value="{L_APPROVE}" /> - <div><a href="#" onclick="marklist('mcp', 'post_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'post_id_list', false); return false;">{L_UNMARK_ALL}</a></div> + <!-- ENDIF --> + <div> + <!-- IF S_TOPICS --> + <a href="#" onclick="marklist('mcp', 'topic_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'topic_id_list', false); return false;">{L_UNMARK_ALL}</a> + <!-- ELSE --> + <a href="#" onclick="marklist('mcp', 'post_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'post_id_list', false); return false;">{L_UNMARK_ALL}</a> + <!-- ENDIF --> + </div> </fieldset> <!-- ENDIF --> </form> diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 8dfee55cbf..3975b6e513 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -110,9 +110,10 @@ onload_functions.push('subPanels()'); <h3><a href="{postrow.U_POST_DETAILS}">{postrow.POST_SUBJECT}</a></h3> <p class="author"><a href="#pr{postrow.POST_ID}">{postrow.MINI_POST_IMG}</a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong><!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --></p> - <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_REPORTED --> + <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_DELETED or postrow.S_POST_REPORTED --> <p class="rules"> <!-- IF postrow.S_POST_UNAPPROVED -->{UNAPPROVED_IMG} <a href="{postrow.U_MCP_APPROVE}"><strong>{L_POST_UNAPPROVED}</strong></a><br /><!-- ENDIF --> + <!-- IF postrow.S_POST_DELETED -->{DELETED_IMG} <a href="{postrow.U_MCP_APPROVE}"><strong>{L_POST_DELETED}</strong></a><br /><!-- ENDIF --> <!-- IF postrow.S_POST_REPORTED -->{REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}"><strong>{L_POST_REPORTED}</strong></a><!-- ENDIF --> </p> <!-- ENDIF --> @@ -159,6 +160,7 @@ onload_functions.push('subPanels()'); <!-- IF S_CAN_APPROVE --><option value="approve">{L_APPROVE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_LOCK --><option value="lock_post">{L_LOCK_POST_POSTS} [ {L_LOCK_POST_EXPLAIN} ]</option><option value="unlock_post">{L_UNLOCK_POST_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_DELETE --><option value="delete_post">{L_DELETE_POSTS}</option><!-- ENDIF --> + <!-- IF S_CAN_RESTORE --><option value="restore">{L_RESTORE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_MERGE --><option value="merge_posts"<!-- IF S_MERGE_VIEW --> selected="selected"<!-- ENDIF -->>{L_MERGE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_SPLIT --><option value="split_all"<!-- IF S_SPLIT_VIEW --> selected="selected"<!-- ENDIF -->>{L_SPLIT_POSTS}</option><option value="split_beyond">{L_SPLIT_AFTER}</option><!-- ENDIF --> <!-- IF S_CAN_SYNC --><option value="resync">{L_RESYNC}</option><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 3eac8fb03a..1907d0660f 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -67,14 +67,6 @@ <!-- ENDIF --> <div class="clear"></div> - - <!-- ENDIF --> - - <!-- IF S_DELETE_ALLOWED --> - <dl> - <dt><label for="delete">{L_DELETE_POST}{L_COLON}</label></dt> - <dd><label for="delete"><input type="checkbox" name="delete" id="delete" /> {L_DELETE_POST_WARN}</label></dd> - </dl> <!-- ENDIF --> <!-- IF S_SHOW_TOPIC_ICONS or S_SHOW_PM_ICONS --> @@ -249,6 +241,17 @@ </dl> <!-- ENDIF --> + <!-- IF S_SOFTDELETE_ALLOWED or S_DELETE_ALLOWED --> + <hr class="dashed" /> + <dl> + <dt><label for="delete">{L_DELETE_POST}{L_COLON}</label></dt> + <dd><label for="delete"><input type="checkbox" name="delete" id="delete" {S_SOFTDELETE_CHECKED} /> {L_DELETE_POST_WARN}</label></dd> + <!-- IF S_DELETE_ALLOWED and S_SOFTDELETE_ALLOWED --> + <dd><label for="delete_permanent"><input type="checkbox" name="delete_permanent" id="delete_permanent" /> {L_DELETE_POST_PERMANENTLY}</label></dd> + <!-- ENDIF --> + </dl> + <!-- ENDIF --> + <!-- IF S_EDIT_REASON --> <dl> <dt><label for="edit_reason">{L_EDIT_REASON}{L_COLON}</label></dt> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index e31c278a4b..f0424c45db 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -66,6 +66,7 @@ <!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --> <a href="{searchresults.U_VIEW_TOPIC}" class="topictitle">{searchresults.TOPIC_TITLE}</a> {searchresults.ATTACH_ICON_IMG} <!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --><a href="{searchresults.U_MCP_QUEUE}">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF searchresults.S_TOPIC_DELETED --><a href="{searchresults.U_MCP_QUEUE}">{DELETED_IMG}</a> <!-- ENDIF --> <!-- IF searchresults.S_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br /> <!-- IF .searchresults.pagination --> <div class="pagination"> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 9cbe7bc45a..69b0608a64 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -146,6 +146,7 @@ <div class="list-inner"> <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF topicrow.S_TOPIC_DELETED --><a href="{topicrow.U_MCP_QUEUE}">{DELETED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br /> <!-- IF .topicrow.pagination --> <div class="pagination"> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 9c0743d04d..a8bac42842 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -114,19 +114,30 @@ <!-- BEGIN postrow --> <!-- IF postrow.S_FIRST_UNREAD --><a id="unread"></a><!-- ENDIF --> - <div id="p{postrow.POST_ID}" class="post <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_IGNORE_POST --> online<!-- ENDIF -->"> + <div id="p{postrow.POST_ID}" class="post <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> online<!-- ENDIF -->"> <div class="inner"> <div class="postbody"> - <!-- IF postrow.S_IGNORE_POST --> - <div class="ignore">{postrow.L_IGNORE_POST}</div> - <!-- ELSE --> + <!-- IF postrow.S_POST_HIDDEN --> + <!-- IF postrow.S_POST_DELETED --> + <div class="ignore" id="post_hidden{postrow.POST_ID}"> + {postrow.L_POST_DELETED_MESSAGE}<br /> + {postrow.L_POST_DISPLAY} + </div> + <!-- ELSEIF postrow.S_IGNORE_POST --> + <div class="ignore" id="post_hidden{postrow.POST_ID}"> + {postrow.L_IGNORE_POST}<br /> + {postrow.L_POST_DISPLAY} + </div> + <!-- ENDIF --> + <!-- ENDIF --> + <div id="post_content{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> <!-- IF not S_IS_BOT --> <!-- IF postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE --> <ul class="profile-icons"> <!-- IF postrow.U_EDIT --><li class="edit-icon"><a href="{postrow.U_EDIT}" title="{L_EDIT_POST}"><span>{L_EDIT_POST}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_DELETE --><li class="delete-icon"><a href="{postrow.U_DELETE}" title="{L_DELETE_POST}" data-ajax="post_delete"<!-- IF postrow.POST_NUMBER == 1 --> data-refresh="true"<!-- ENDIF -->><span>{L_DELETE_POST}</span></a></li><!-- ENDIF --> + <!-- IF postrow.U_DELETE --><li class="delete-icon"><a href="{postrow.U_DELETE}" title="{L_DELETE_POST}"><span>{L_DELETE_POST}</span></a></li><!-- ENDIF --> <!-- IF postrow.U_REPORT --><li class="report-icon"><a href="{postrow.U_REPORT}" title="{L_REPORT_POST}"><span>{L_REPORT_POST}</span></a></li><!-- ENDIF --> <!-- IF postrow.U_WARN --><li class="warn-icon"><a href="{postrow.U_WARN}" title="{L_WARN_USER}"><span>{L_WARN_USER}</span></a></li><!-- ENDIF --> <!-- IF postrow.U_INFO --><li class="info-icon"><a href="{postrow.U_INFO}" title="{L_INFORMATION}"><span>{L_INFORMATION}</span></a></li><!-- ENDIF --> @@ -138,8 +149,8 @@ <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3> <p class="author"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF -->{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » {postrow.POST_DATE} </p> - <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_REPORTED --> - <form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}" data-ajax="post_approve"> + <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_DELETED or postrow.S_POST_REPORTED --> + <form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}"> <p class="rules"> <!-- IF postrow.S_POST_UNAPPROVED --> {UNAPPROVED_IMG} <strong>{L_POST_UNAPPROVED}</strong> @@ -147,8 +158,18 @@ <input class="button1" type="submit" value="{L_APPROVE}" name="action[approve]" /> <input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" /> {S_FORM_TOKEN} - <br /><!-- ENDIF --> - <!-- IF postrow.S_POST_REPORTED -->{REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}"><strong>{L_POST_REPORTED}</strong></a><!-- ENDIF --> + <br /> + <!-- ELSEIF postrow.S_POST_DELETED --> + {DELETED_IMG} <strong>{L_POST_DELETED}</strong> + <input class="button2" type="submit" value="{L_DELETE}" name="action[disapprove]" /> + <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" /> + <input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" /> + {S_FORM_TOKEN} + <br /> + <!-- ENDIF --> + <!-- IF postrow.S_POST_REPORTED --> + {REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}"><strong>{L_POST_REPORTED}</strong></a> + <!-- ENDIF --> </p> </form> <!-- ENDIF --> @@ -177,20 +198,25 @@ <!-- ENDIF --> <!-- IF postrow.S_DISPLAY_NOTICE --><div class="rules">{L_DOWNLOAD_NOTICE}</div><!-- ENDIF --> - <!-- IF postrow.EDITED_MESSAGE or postrow.EDIT_REASON --> - <div class="notice">{postrow.EDITED_MESSAGE} + <!-- IF postrow.DELETED_MESSAGE or postrow.DELETE_REASON --> + <div class="notice post_deleted_msg"> + {postrow.DELETED_MESSAGE} + <!-- IF postrow.DELETE_REASON --><br /><strong>{L_REASON}{L_COLON}</strong> <em>{postrow.DELETE_REASON}</em><!-- ENDIF --> + </div> + <!-- ELSEIF postrow.EDITED_MESSAGE or postrow.EDIT_REASON --> + <div class="notice"> + {postrow.EDITED_MESSAGE} <!-- IF postrow.EDIT_REASON --><br /><strong>{L_REASON}{L_COLON}</strong> <em>{postrow.EDIT_REASON}</em><!-- ENDIF --> </div> <!-- ENDIF --> <!-- IF postrow.BUMPED_MESSAGE --><div class="notice"><br /><br />{postrow.BUMPED_MESSAGE}</div><!-- ENDIF --> <!-- IF postrow.SIGNATURE --><div id="sig{postrow.POST_ID}" class="signature">{postrow.SIGNATURE}</div><!-- ENDIF --> - <!-- ENDIF --> + </div> </div> - <!-- IF not postrow.S_IGNORE_POST --> - <dl class="postprofile" id="profile{postrow.POST_ID}"> + <dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> <dt> <!-- IF postrow.POSTER_AVATAR --> <!-- IF postrow.U_POST_AUTHOR --><a href="{postrow.U_POST_AUTHOR}">{postrow.POSTER_AVATAR}</a><!-- ELSE -->{postrow.POSTER_AVATAR}<!-- ENDIF --><br /> @@ -233,7 +259,6 @@ <!-- ENDIF --> </dl> - <!-- ENDIF --> <div class="back2top"><a href="#wrap" class="top" title="{L_BACK_TO_TOP}">{L_BACK_TO_TOP}</a></div> diff --git a/phpBB/styles/prosilver/theme/images/icon_topic_deleted.png b/phpBB/styles/prosilver/theme/images/icon_topic_deleted.png Binary files differnew file mode 100644 index 0000000000..494b4fb563 --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_topic_deleted.png diff --git a/phpBB/styles/prosilver/theme/imageset.css b/phpBB/styles/prosilver/theme/imageset.css index cb99e9e715..296c617f17 100644 --- a/phpBB/styles/prosilver/theme/imageset.css +++ b/phpBB/styles/prosilver/theme/imageset.css @@ -340,6 +340,11 @@ span.imageset { padding-left: 16px; padding-top: 14px; } +.imageset.icon_topic_deleted { + background-image: url("./images/icon_topic_deleted.png"); + padding-left: 16px; + padding-top: 14px; +} .imageset.icon_topic_unapproved { background-image: url("./images/icon_topic_unapproved.gif"); padding-left: 16px; diff --git a/phpBB/styles/subsilver2/template/confirm_delete_body.html b/phpBB/styles/subsilver2/template/confirm_delete_body.html new file mode 100644 index 0000000000..9e416f5195 --- /dev/null +++ b/phpBB/styles/subsilver2/template/confirm_delete_body.html @@ -0,0 +1,56 @@ +<!-- INCLUDE overall_header.html --> + +<div id="pagecontent"> + + <form name="confirm" action="{S_CONFIRM_ACTION}" method="post"> + + <table class="tablebg" width="100%" cellspacing="1"> + <tr> + <th>{MESSAGE_TITLE}</th> + </tr> + <tr> + <td class="row1" align="center"> + <br /> + <p class="gen">{MESSAGE_TEXT}</p> + <br /> + + <!-- IF not S_SOFTDELETED and (S_DELETE_REASON or (S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE)) --> + <table border="0" width="90%" cellspacing="2" cellpadding="1"> + <!-- IF S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE --> + <tr> + <td class="row1" width="22%"><b class="gen">{L_DELETE_PERMANENTLY}{L_COLON}</b></td> + <td class="row1" width="78%"> + <input id="delete_permanent" name="delete_permanent" type="checkbox" value="1" {S_CHECKED_PERMANENT} /> + <!-- IF S_TOPIC_MODE -->{L_DELETE_TOPIC_PERMANENTLY}<!-- ELSE -->{L_DELETE_POST_PERMANENTLY}<!-- ENDIF --> + </td> + </tr> + <!-- ENDIF --> + <!-- IF S_DELETE_REASON --> + <tr> + <td class="row1" valign="top"><span class="gen"><b>{L_DELETE_REASON}{L_COLON}</b></span><br /><span class="gensmall">{L_DELETE_REASON_EXPLAIN}</span></td> + <td class="row1"><input type="text" name="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /></td> + </tr> + <!-- ENDIF --> + </table> + <br /> + <!-- ENDIF --> + {S_HIDDEN_FIELDS} + <input type="submit" name="confirm" value="{L_YES}" class="btnmain" /> + <input type="submit" name="cancel" value="{L_NO}" class="btnlite" /> + </td> + </tr> + </table> + + </form> + +</div> + +<br clear="all" /> + +<!-- INCLUDE breadcrumbs.html --> + +<br clear="all" /> + +<div align="{S_CONTENT_FLOW_END}"><!-- INCLUDE jumpbox.html --></div> + +<!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/subsilver2/template/mcp_approve.html b/phpBB/styles/subsilver2/template/mcp_approve.html index 5ad7d2f9b5..8c2ef0806b 100644 --- a/phpBB/styles/subsilver2/template/mcp_approve.html +++ b/phpBB/styles/subsilver2/template/mcp_approve.html @@ -16,7 +16,7 @@ <!-- IF S_NOTIFY_POSTER --> <input type="checkbox" class="radio" name="notify_poster" checked="checked" /><span class="gen"><!-- IF S_APPROVE -->{L_NOTIFY_POSTER_APPROVAL}<!-- ELSE -->{L_NOTIFY_POSTER_DISAPPROVAL}<!-- ENDIF --></span><br /> <!-- ENDIF --> - <!-- IF not S_APPROVE --> + <!-- IF not S_APPROVE and not S_RESTORE and .reason --> <br /> <table border="0" width="90%" cellspacing="2" cellpadding="1"> <tr> diff --git a/phpBB/styles/subsilver2/template/mcp_forum.html b/phpBB/styles/subsilver2/template/mcp_forum.html index 6972f14b79..b168bf3ac8 100644 --- a/phpBB/styles/subsilver2/template/mcp_forum.html +++ b/phpBB/styles/subsilver2/template/mcp_forum.html @@ -33,6 +33,9 @@ <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --> <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF topicrow.S_TOPIC_DELETED or topicrow.S_POSTS_DELETED --> + <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{topicrow.DELETED_IMG}</a> + <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED and topicrow.U_MCP_REPORT --> <a href="{topicrow.U_MCP_REPORT}" class="imageset">{REPORTED_IMG}</a> <!-- ENDIF --> @@ -58,6 +61,7 @@ <select name="action"> <option value="" selected="selected">{L_SELECT_ACTION}</option> <!-- IF S_CAN_DELETE --><option value="delete_topic">{L_DELETE}</option><!-- ENDIF --> + <!-- IF S_CAN_RESTORE --><option value="restore_topic">{L_RESTORE}</option><!-- ENDIF --> <!-- IF S_CAN_MERGE --><option value="merge_topics">{L_MERGE}</option><!-- ENDIF --> <!-- IF S_CAN_MOVE --><option value="move">{L_MOVE}</option><!-- ENDIF --> <!-- IF S_CAN_FORK --><option value="fork">{L_FORK}</option><!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/mcp_post.html b/phpBB/styles/subsilver2/template/mcp_post.html index 910accd09f..a3ebb00d06 100644 --- a/phpBB/styles/subsilver2/template/mcp_post.html +++ b/phpBB/styles/subsilver2/template/mcp_post.html @@ -50,7 +50,12 @@ </tr> <tr> <td class="row1"><b class="gen"><!-- IF S_PM -->{L_PM_SUBJECT}<!-- ELSE -->{L_POST_SUBJECT}<!-- ENDIF -->{L_COLON} </b></td> - <td class="row2"><span class="gen">{POST_SUBJECT}</span> <!-- IF S_POST_UNAPPROVED --><span class="postapprove">{UNAPPROVED_IMG} <a href="{U_MCP_APPROVE}">{L_POST_UNAPPROVED}</a></span> <!-- ENDIF --> <!-- IF S_POST_REPORTED and not S_MCP_REPORT --><span class="postreported">{REPORTED_IMG} <a href="{U_MCP_REPORT}">{L_POST_REPORTED}</a></span><!-- ENDIF --></td> + <td class="row2"> + <span class="gen">{POST_SUBJECT}</span> + <!-- IF S_POST_UNAPPROVED --><span class="postapprove">{UNAPPROVED_IMG} <a href="{U_MCP_APPROVE}">{L_POST_UNAPPROVED}</a></span> <!-- ENDIF --> + <!-- IF S_POST_DELETED --><span class="postapprove">{DELETED_IMG} <a href="{U_MCP_APPROVE}">{L_POST_DELETED}</a></span> <!-- ENDIF --> + <!-- IF S_POST_REPORTED and not S_MCP_REPORT --><span class="postreported">{REPORTED_IMG} <a href="{U_MCP_REPORT}">{L_POST_REPORTED}</a></span><!-- ENDIF --> + </td> </tr> <tr> <td class="row1" width="20%"><b class="gen"><!-- IF S_PM -->{L_PM_FROM}<!-- ELSE -->{L_POSTER}<!-- ENDIF -->{L_COLON} </b></td> diff --git a/phpBB/styles/subsilver2/template/mcp_queue.html b/phpBB/styles/subsilver2/template/mcp_queue.html index febde7e59c..7ca659b5da 100644 --- a/phpBB/styles/subsilver2/template/mcp_queue.html +++ b/phpBB/styles/subsilver2/template/mcp_queue.html @@ -23,15 +23,37 @@ <td style="padding: 4px;" align="{S_CONTENT_FLOW_BEGIN}" valign="top" nowrap="nowrap"><span class="gen">{postrow.POST_AUTHOR_FULL}</span><br /> <span class="gensmall">[ <a href="{postrow.U_VIEW_DETAILS}">{L_VIEW_DETAILS}</a> ]</span></td> <td class="postdetails" style="padding: 4px;" align="{S_CONTENT_FLOW_BEGIN}" valign="top" nowrap="nowrap">{postrow.POST_TIME}</td> - <td align="center"><input type="checkbox" class="radio" name="post_id_list[]" value="{postrow.POST_ID}" /></td> + <td align="center"> + <!-- IF S_TOPICS --> + <input type="checkbox" class="radio" name="topic_id_list[]" value="{postrow.TOPIC_ID}" /> + <!-- ELSE --> + <input type="checkbox" class="radio" name="post_id_list[]" value="{postrow.POST_ID}" /> + <!-- ENDIF --> + </td> </tr> <!-- BEGINELSE --> <tr> - <td class="row1" colspan="4" height="30" align="center" valign="middle"><span class="gen"><!-- IF S_TOPICS -->{L_NO_TOPICS_QUEUE}<!-- ELSE -->{L_NO_POSTS_QUEUE}<!-- ENDIF --></span></td> + <td class="row1" colspan="4" height="30" align="center" valign="middle"> + <span class="gen"> + <!-- IF S_RESTORE --> + <!-- IF S_TOPICS -->{L_NO_TOPICS_DELETED}<!-- ELSE -->{L_NO_POSTS_DELETED}<!-- ENDIF --> + <!-- ELSE --> + <!-- IF S_TOPICS -->{L_NO_TOPICS_QUEUE}<!-- ELSE -->{L_NO_POSTS_QUEUE}<!-- ENDIF --> + <!-- ENDIF --> + </span> + </td> </tr> <!-- END postrow --> <tr> - <td class="cat" colspan="4" align="center"><input class="btnmain" type="submit" name="action[approve]" value="{L_APPROVE}" /> <input class="btnlite" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" /></td> + <td class="cat" colspan="4" align="center"> + <!-- IF S_RESTORE --> + <input class="btnlite" type="submit" name="action[delete]" value="{L_DELETE}" /> + <input class="btnmain" type="submit" name="action[restore]" value="{L_RESTORE}" /> + <!-- ELSE --> + <input class="btnmain" type="submit" name="action[approve]" value="{L_APPROVE}" /> + <input class="btnlite" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" /> + <!-- ENDIF --> + </td> </tr> </table> {S_FORM_TOKEN} @@ -39,7 +61,15 @@ <table width="100%" cellspacing="2" cellpadding="2" border="0" align="center"> <tr> - <td align="{S_CONTENT_FLOW_END}" valign="top" nowrap="nowrap"><b class="gensmall"><a href="#" onclick="marklist('mcp', '', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', '', false); return false;">{L_UNMARK_ALL}</a></b></td> + <td align="{S_CONTENT_FLOW_END}" valign="top" nowrap="nowrap"> + <b class="gensmall"> + <!-- IF S_TOPICS --> + <a href="#" onclick="marklist('mcp', 'topic_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'topic_id_list', false); return false;">{L_UNMARK_ALL}</a> + <!-- ELSE --> + <a href="#" onclick="marklist('mcp', 'post_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'post_id_list', false); return false;">{L_UNMARK_ALL}</a> + <!-- ENDIF --> + </b> + </td> </tr> </table> diff --git a/phpBB/styles/subsilver2/template/mcp_topic.html b/phpBB/styles/subsilver2/template/mcp_topic.html index 014d8b9468..d3b4408243 100644 --- a/phpBB/styles/subsilver2/template/mcp_topic.html +++ b/phpBB/styles/subsilver2/template/mcp_topic.html @@ -112,6 +112,7 @@ <tr valign="middle"> <td width="100%"> <!-- IF postrow.S_POST_UNAPPROVED and postrow.U_MCP_APPROVE --><span class="postapprove">{UNAPPROVED_IMG} <a href="{postrow.U_MCP_APPROVE}">{L_POST_UNAPPROVED}</a></span><br /><!-- ENDIF --> + <!-- IF postrow.S_POST_DELETED and postrow.U_MCP_APPROVE --><span class="postapprove">{DELETED_IMG} <a href="{postrow.U_MCP_APPROVE}">{L_POST_DELETED}</a></span><br /><!-- ENDIF --> <!-- IF postrow.S_POST_REPORTED and postrow.U_MCP_REPORT --><span class="postreported">{REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}">{L_POST_REPORTED}</a></span><!-- ENDIF --> </td> <td width="10" nowrap="nowrap">{postrow.MINI_POST_IMG}</td> @@ -133,6 +134,7 @@ <!-- IF S_CAN_APPROVE --><option value="approve">{L_APPROVE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_LOCK --><option value="lock_post">{L_LOCK_POST_POSTS} [ {L_LOCK_POST_EXPLAIN} ]</option><option value="unlock_post">{L_UNLOCK_POST_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_DELETE --><option value="delete_post">{L_DELETE_POSTS}</option><!-- ENDIF --> + <!-- IF S_CAN_RESTORE --><option value="restore">{L_RESTORE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_MERGE --><option value="merge_posts"<!-- IF ACTION eq 'merge' --> selected="selected"<!-- ENDIF -->>{L_MERGE_POSTS}</option><!-- ENDIF --> <!-- IF S_CAN_SPLIT --><option value="split_all"<!-- IF ACTION eq 'split' --> selected="selected"<!-- ENDIF -->>{L_SPLIT_POSTS}</option><option value="split_beyond">{L_SPLIT_AFTER}</option><!-- ENDIF --> <!-- IF S_CAN_SYNC --><option value="resync">{L_RESYNC}</option><!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/posting_body.html b/phpBB/styles/subsilver2/template/posting_body.html index 4feb4e955a..635b05aaa0 100644 --- a/phpBB/styles/subsilver2/template/posting_body.html +++ b/phpBB/styles/subsilver2/template/posting_body.html @@ -114,13 +114,6 @@ </tr> <!-- ENDIF --> -<!-- IF S_DELETE_ALLOWED --> - <tr> - <td class="row1"><b class="genmed">{L_DELETE_POST}{L_COLON}</b></td> - <td class="row2"><input type="checkbox" class="radio" name="delete" /> <span class="gensmall">[ {L_DELETE_POST_WARN} ]</span></td> - </tr> -<!-- ENDIF --> - <!-- IF S_SHOW_TOPIC_ICONS or S_SHOW_PM_ICONS --> <tr> <td class="row1"><b class="genmed">{L_ICON}{L_COLON}</b></td> @@ -310,7 +303,7 @@ <!-- IF S_TYPE_TOGGLE --> <tr> - <td> </td> + <td></td> <td class="gen"><!-- IF S_EDIT_POST -->{L_CHANGE_TOPIC_TO}<!-- ELSE -->{L_POST_TOPIC_AS}<!-- ENDIF -->{L_COLON} <!-- BEGIN topic_type --><input type="radio" class="radio" name="topic_type" value="{topic_type.VALUE}"{topic_type.S_CHECKED} />{topic_type.L_TOPIC_TYPE} <!-- END topic_type --></td> </tr> <!-- ENDIF --> @@ -319,6 +312,26 @@ </td> </tr> +<!-- IF S_SOFTDELETE_ALLOWED or S_DELETE_ALLOWED --> + <tr> + <td class="row1" valign="top"><b class="genmed">{L_DELETE_POST}{L_COLON}</b></td> + <td class="row2"> + <table cellpadding="1"> + <tr> + <td><input type="checkbox" class="radio" name="delete" /></td> + <td class="gen">{L_DELETE_POST_WARN}</td> + </tr> + <!-- IF S_SOFTDELETE_ALLOWED and S_DELETE_ALLOWED --> + <tr> + <td><input type="checkbox" class="radio" name="delete_permanent" /></td> + <td class="gen">{L_DELETE_POST_PERMANENTLY}</td> + </tr> + <!-- ENDIF --> + </table> + </td> + </tr> +<!-- ENDIF --> + <!-- IF S_TOPIC_TYPE_ANNOUNCE or S_TOPIC_TYPE_STICKY --> <tr> <td class="row1"><b class="genmed">{L_STICK_TOPIC_FOR}{L_COLON}</b><br /><span class="gensmall">{L_STICKY_ANNOUNCE_TIME_LIMIT}</span></td> diff --git a/phpBB/styles/subsilver2/template/search_results.html b/phpBB/styles/subsilver2/template/search_results.html index 8ced5a5301..d98079de20 100644 --- a/phpBB/styles/subsilver2/template/search_results.html +++ b/phpBB/styles/subsilver2/template/search_results.html @@ -39,6 +39,9 @@ <!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --> <a href="{searchresults.U_MCP_QUEUE}" class="imageset">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF searchresults.S_TOPIC_DELETED --> + <a href="{searchresults.U_MCP_QUEUE}" class="imageset">{DELETED_IMG}</a> + <!-- ENDIF --> <!-- IF searchresults.S_TOPIC_REPORTED --> <a href="{searchresults.U_MCP_REPORT}" class="imageset">{REPORTED_IMG}</a> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/viewforum_body.html b/phpBB/styles/subsilver2/template/viewforum_body.html index 664a6a26c5..d07e9a1372 100644 --- a/phpBB/styles/subsilver2/template/viewforum_body.html +++ b/phpBB/styles/subsilver2/template/viewforum_body.html @@ -43,7 +43,10 @@ <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="imageset">{NEWEST_POST_IMG}</a><!-- ENDIF --> {topicrow.ATTACH_ICON_IMG} <!-- IF topicrow.S_HAS_POLL or topicrow.S_TOPIC_MOVED --><b>{topicrow.TOPIC_TYPE}</b> <!-- ENDIF --><a title="{L_POSTED}{L_COLON} {topicrow.FIRST_POST_TIME}" href="{topicrow.U_VIEW_TOPIC}"class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --> - <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{UNAPPROVED_IMG}</a> + <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{topicrow.UNAPPROVED_IMG}</a> + <!-- ENDIF --> + <!-- IF topicrow.S_TOPIC_DELETED --> + <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{DELETED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --> <a href="{topicrow.U_MCP_REPORT}" class="imageset">{REPORTED_IMG}</a> @@ -205,6 +208,9 @@ <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --> <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> + <!-- IF topicrow.S_TOPIC_DELETED --> + <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{DELETED_IMG}</a> + <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --> <a href="{topicrow.U_MCP_REPORT}" class="imageset">{REPORTED_IMG}</a> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index b561b99abd..299b8219eb 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -136,8 +136,19 @@ <!-- ENDIF --> <!-- IF postrow.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - <!-- IF postrow.S_IGNORE_POST --> - <td class="gensmall" colspan="2" height="25" align="center"><!-- IF postrow.S_FIRST_UNREAD --><a name="unread"></a><!-- ENDIF --><a name="p{postrow.POST_ID}"></a>{postrow.L_IGNORE_POST}</td> + <!-- IF postrow.S_POST_HIDDEN --> + <td class="gensmall" colspan="2" height="25" align="center"> + <!-- IF postrow.S_FIRST_UNREAD --><a name="unread"></a><!-- ENDIF --> + <a name="p{postrow.POST_ID}"></a> + <!-- IF postrow.S_POST_HIDDEN --> + <!-- IF postrow.S_POST_DELETED --> + {postrow.L_POST_DELETED_MESSAGE} + <!-- ELSEIF postrow.S_IGNORE_POST --> + {postrow.L_IGNORE_POST} + <!-- ENDIF --> + <br />{postrow.L_POST_DISPLAY} + <!-- ENDIF --> + </td> <!-- ELSE --> <td align="center" valign="middle"> @@ -207,10 +218,14 @@ <table width="100%" cellspacing="5"> <tr> <td> - <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_REPORTED --> + <!-- IF postrow.S_POST_UNAPPROVED or postrow.S_POST_DELETED or postrow.S_POST_REPORTED --> <table width="100%" cellspacing="0"> <tr> - <td class="gensmall"><!-- IF postrow.S_POST_UNAPPROVED --><span class="postapprove">{UNAPPROVED_IMG} <a href="{postrow.U_MCP_APPROVE}">{L_POST_UNAPPROVED}</a></span><br /> <!-- ENDIF --> <!-- IF postrow.S_POST_REPORTED --><span class="postreported">{REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}">{L_POST_REPORTED}</a></span><!-- ENDIF --></td> + <td class="gensmall"> + <!-- IF postrow.S_POST_UNAPPROVED --><span class="postapprove">{UNAPPROVED_IMG} <a href="{postrow.U_MCP_APPROVE}">{L_POST_UNAPPROVED}</a></span><br /> <!-- ENDIF --> + <!-- IF postrow.S_POST_DELETED --><span class="postapprove">{DELETED_IMG} <a href="{postrow.U_MCP_RESTORE}">{L_POST_DELETED}</a></span><br /> <!-- ENDIF --> + <!-- IF postrow.S_POST_REPORTED --><span class="postreported">{REPORTED_IMG} <a href="{postrow.U_MCP_REPORT}">{L_POST_REPORTED}</a></span><!-- ENDIF --> + </td> </tr> </table> @@ -241,7 +256,22 @@ <div class="postbody"><br />_________________<br />{postrow.SIGNATURE}</div> <!-- ENDIF --> - <!-- IF postrow.EDITED_MESSAGE or postrow.EDIT_REASON --> + <!-- IF postrow.DELETED_MESSAGE or postrow.DELETE_REASON --> + <!-- IF postrow.DELETE_REASON --> + <br /><br /> + <table class="tablebg" width="100%" cellspacing="1"> + <tr> + <td class="row3"><span class="gensmall">{postrow.DELETED_MESSAGE}</span></td> + </tr> + <tr> + <td class="row2"><span class="genmed">{postrow.DELETE_REASON}</span></td> + </tr> + </table> + <!-- ELSE --> + <br /><br /> + <span class="gensmall">{postrow.DELETED_MESSAGE}</span> + <!-- ENDIF --> + <!-- ELSEIF postrow.EDITED_MESSAGE or postrow.EDIT_REASON --> <!-- IF postrow.EDIT_REASON --> <br /><br /> <table class="tablebg" width="100%" cellspacing="1"> diff --git a/phpBB/styles/subsilver2/theme/images/icon_topic_deleted.png b/phpBB/styles/subsilver2/theme/images/icon_topic_deleted.png Binary files differnew file mode 100644 index 0000000000..494b4fb563 --- /dev/null +++ b/phpBB/styles/subsilver2/theme/images/icon_topic_deleted.png diff --git a/phpBB/styles/subsilver2/theme/stylesheet.css b/phpBB/styles/subsilver2/theme/stylesheet.css index df46c91d8d..bfb80a53b5 100644 --- a/phpBB/styles/subsilver2/theme/stylesheet.css +++ b/phpBB/styles/subsilver2/theme/stylesheet.css @@ -985,6 +985,11 @@ a.imageset { padding-left: 19px; padding-top: 18px; } +.imageset.icon_topic_deleted { + background-image: url("./images/icon_topic_deleted.png"); + padding-left: 14px; + padding-top: 14px; +} /* English images for fallback */ diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 5fed514a12..06af674ee6 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -241,14 +241,14 @@ gen_forum_auth_level('forum', $forum_id, $forum_data['forum_status']); $limit_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']); -$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => 't.topic_replies', 's' => 't.topic_title', 'v' => 't.topic_views'); +$sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 't.topic_title', 'v' => 't.topic_views'); $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir); +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + // Limit topics to certain time frame, obtain correct topic count -// global announcements must not be counted, normal announcements have to -// be counted, as forum_topics(_real) includes them if ($sort_days) { $min_post_time = time() - ($sort_days * 86400); @@ -259,7 +259,7 @@ if ($sort_days) AND (topic_last_post_time >= $min_post_time OR topic_type = " . POST_ANNOUNCE . ' OR topic_type = ' . POST_GLOBAL . ') - ' . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND topic_approved = 1'); + AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id); $result = $db->sql_query($sql); $topics_count = (int) $db->sql_fetchfield('num_topics'); $db->sql_freeresult($result); @@ -275,7 +275,7 @@ if ($sort_days) } else { - $topics_count = ($auth->acl_get('m_approve', $forum_id)) ? $forum_data['forum_topics_real'] : $forum_data['forum_topics']; + $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); $sql_limit_time = ''; } @@ -325,6 +325,7 @@ $template->assign_vars(array( 'FOLDER_MOVED_IMG' => $user->img('topic_moved', 'TOPIC_MOVED'), 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'), 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'), + 'DELETED_IMG' => $user->img('icon_topic_deleted', 'TOPIC_DELETED'), 'GOTO_PAGE_IMG' => $user->img('icon_post_target', 'GOTO_PAGE'), 'L_NO_TOPICS' => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['POST_FORUM_LOCKED'] : $user->lang['NO_TOPICS'], @@ -371,7 +372,7 @@ $sql_array = array( 'LEFT_JOIN' => array(), ); -$sql_approved = ($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND t.topic_approved = 1'; +$sql_approved = ' AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'); if ($user->data['is_registered']) { @@ -422,9 +423,9 @@ if ($forum_data['forum_type'] == FORUM_POST) while ($row = $db->sql_fetchrow($result)) { - if (!$row['topic_approved'] && !$auth->acl_get('m_approve', $row['forum_id'])) + if ($row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) { - // Do not display announcements that are waiting for approval. + // Do not display announcements that are waiting for approval or soft deleted. continue; } @@ -683,7 +684,7 @@ if (sizeof($topic_list)) $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; // Replies - $replies = ($auth->acl_get('m_approve', $topic_forum_id)) ? $row['topic_replies_real'] : $row['topic_replies']; + $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1; if ($row['topic_status'] == ITEM_MOVED) { @@ -703,9 +704,12 @@ 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_approved'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; - $posts_unapproved = ($row['topic_approved'] && $row['topic_replies'] < $row['topic_replies_real'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; + $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $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; + $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&t=$topic_id", true, $user->session_id) : ''; + $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=deleted_topics&t=' . $topic_id, true, $user->session_id) : $u_mcp_queue; // Send vars to template $topic_row = array( @@ -744,6 +748,7 @@ if (sizeof($topic_list)) 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $row['forum_id'])) ? true : false, 'S_TOPIC_UNAPPROVED' => $topic_unapproved, 'S_POSTS_UNAPPROVED' => $posts_unapproved, + 'S_TOPIC_DELETED' => $topic_deleted, 'S_HAS_POLL' => ($row['poll_start']) ? true : false, 'S_POST_ANNOUNCE' => ($row['topic_type'] == POST_ANNOUNCE) ? true : false, 'S_POST_GLOBAL' => ($row['topic_type'] == POST_GLOBAL) ? true : false, diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 4dd03202f1..1e444f47ad 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -55,6 +55,8 @@ if (!$topic_id && !$post_id) trigger_error('NO_TOPIC'); } +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + // Find topic id if user requested a newer or older topic if ($view && !$post_id) { @@ -77,13 +79,12 @@ if ($view && !$post_id) { // Get topic tracking info $topic_tracking_info = get_complete_topic_tracking($forum_id, $topic_id); - $topic_last_read = (isset($topic_tracking_info[$topic_id])) ? $topic_tracking_info[$topic_id] : 0; $sql = 'SELECT post_id, topic_id, forum_id FROM ' . POSTS_TABLE . " WHERE topic_id = $topic_id - " . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND post_approved = 1') . " + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id) . " AND post_time > $topic_last_read AND forum_id = $forum_id ORDER BY post_time ASC"; @@ -137,7 +138,7 @@ if ($view && !$post_id) WHERE forum_id = ' . $row['forum_id'] . " AND topic_moved_id = 0 AND topic_last_post_time $sql_condition {$row['topic_last_post_time']} - " . (($auth->acl_get('m_approve', $row['forum_id'])) ? '' : 'AND topic_approved = 1') . " + AND " . $phpbb_content_visibility->get_visibility_sql('topic', $row['forum_id']) . " ORDER BY topic_last_post_time $sql_ordering"; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); @@ -181,7 +182,7 @@ $sql_array = array( // The FROM-Order is quite important here, else t.* columns can not be correctly bound. if ($post_id) { - $sql_array['SELECT'] .= ', p.post_approved, p.post_time, p.post_id'; + $sql_array['SELECT'] .= ', p.post_visibility, p.post_time, p.post_id'; $sql_array['FROM'][POSTS_TABLE] = 'p'; } @@ -252,11 +253,18 @@ if (!$topic_data) } $forum_id = (int) $topic_data['forum_id']; + +// Now we know the forum_id and can check the permissions +if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) +{ + trigger_error('NO_TOPIC'); +} + // This is for determining where we are (page) if ($post_id) { // are we where we are supposed to be? - if (!$topic_data['post_approved'] && !$auth->acl_get('m_approve', $topic_data['forum_id'])) + if ($topic_data['post_visibility'] == ITEM_UNAPPROVED && !$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) @@ -272,7 +280,7 @@ if ($post_id) if ($sort_dir == $check_sort) { - $topic_data['prev_posts'] = ($auth->acl_get('m_approve', $forum_id)) ? $topic_data['topic_replies_real'] : $topic_data['topic_replies']; + $topic_data['prev_posts'] = $phpbb_content_visibility->get_count('topic_posts', $topic_data, $forum_id) - 1; } else { @@ -284,7 +292,7 @@ if ($post_id) $sql = 'SELECT COUNT(p.post_id) AS prev_posts FROM ' . POSTS_TABLE . " p WHERE p.topic_id = {$topic_data['topic_id']} - " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : ''); + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.'); if ($sort_dir == 'd') { @@ -304,8 +312,7 @@ if ($post_id) } $topic_id = (int) $topic_data['topic_id']; -// -$topic_replies = ($auth->acl_get('m_approve', $forum_id)) ? $topic_data['topic_replies_real'] : $topic_data['topic_replies']; +$topic_replies = $phpbb_content_visibility->get_count('topic_posts', $topic_data, $forum_id) - 1; // Check sticky/announcement time limit if (($topic_data['topic_type'] == POST_STICKY || $topic_data['topic_type'] == POST_ANNOUNCE) && $topic_data['topic_time_limit'] && ($topic_data['topic_time'] + $topic_data['topic_time_limit']) < time()) @@ -322,11 +329,6 @@ if (($topic_data['topic_type'] == POST_STICKY || $topic_data['topic_type'] == PO // Setup look and feel $user->setup('viewtopic', $topic_data['forum_style']); -if (!$topic_data['topic_approved'] && !$auth->acl_get('m_approve', $forum_id)) -{ - trigger_error('NO_TOPIC'); -} - // Start auth check if (!$auth->acl_get('f_read', $forum_id)) { @@ -409,7 +411,7 @@ if ($sort_days) FROM ' . POSTS_TABLE . " WHERE topic_id = $topic_id AND post_time >= $min_post_time - " . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND post_approved = 1'); + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id); $result = $db->sql_query($sql); $total_posts = (int) $db->sql_fetchfield('num_posts'); $db->sql_freeresult($result); @@ -531,7 +533,8 @@ $quickmod_array = array( 'lock' => array('LOCK_TOPIC', ($topic_data['topic_status'] == ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'] && $topic_data['topic_status'] == ITEM_UNLOCKED))), 'unlock' => array('UNLOCK_TOPIC', ($topic_data['topic_status'] != ITEM_UNLOCKED) && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'] && $topic_data['topic_status'] == ITEM_UNLOCKED))), - 'delete_topic' => array('DELETE_TOPIC', $auth->acl_get('m_delete', $forum_id)), + 'delete_topic' => array('DELETE_TOPIC', ($auth->acl_get('m_delete', $forum_id) || (($topic_data['topic_visibility'] != ITEM_DELETED) && $auth->acl_get('m_softdelete', $forum_id)))), + 'restore_topic' => array('RESTORE_TOPIC', (($topic_data['topic_visibility'] == ITEM_DELETED) && $auth->acl_get('m_approve', $forum_id))), 'move' => array('MOVE_TOPIC', $auth->acl_get('m_move', $forum_id) && $topic_data['topic_status'] != ITEM_MOVED), 'split' => array('SPLIT_TOPIC', $auth->acl_get('m_split', $forum_id)), 'merge' => array('MERGE_POSTS', $auth->acl_get('m_merge', $forum_id)), @@ -616,6 +619,7 @@ $template->assign_vars(array( 'REPLY_IMG' => ($topic_data['forum_status'] == ITEM_LOCKED || $topic_data['topic_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', 'TOPIC_LOCKED') : $user->img('button_topic_reply', 'REPLY_TO_TOPIC'), 'EDIT_IMG' => $user->img('icon_post_edit', 'EDIT_POST'), 'DELETE_IMG' => $user->img('icon_post_delete', 'DELETE_POST'), + 'DELETED_IMG' => $user->img('icon_topic_deleted', 'POST_DELETED_RESTORE'), 'INFO_IMG' => $user->img('icon_post_info', 'VIEW_INFO'), 'PROFILE_IMG' => $user->img('icon_user_profile', 'READ_PROFILE'), 'SEARCH_IMG' => $user->img('icon_user_search', 'SEARCH_USER_POSTS'), @@ -936,7 +940,7 @@ else } // Container for user details, only process once -$post_list = $user_cache = $id_cache = $attachments = $attach_list = $rowset = $update_count = $post_edit_list = array(); +$post_list = $user_cache = $id_cache = $attachments = $attach_list = $rowset = $update_count = $post_edit_list = $post_delete_list = array(); $has_attachments = $display_notice = false; $bbcode_bitfield = ''; $i = $i_total = 0; @@ -945,7 +949,7 @@ $i = $i_total = 0; $sql = 'SELECT p.post_id FROM ' . POSTS_TABLE . ' p' . (($join_user_sql[$sort_key]) ? ', ' . USERS_TABLE . ' u': '') . " WHERE p.topic_id = $topic_id - " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . " + AND " . $phpbb_content_visibility->get_visibility_sql('post', $forum_id, 'p.') . " " . (($join_user_sql[$sort_key]) ? 'AND u.user_id = p.poster_id': '') . " $limit_posts_time ORDER BY $sql_sort_order"; @@ -1027,14 +1031,14 @@ while ($row = $db->sql_fetchrow($result)) { $attach_list[] = (int) $row['post_id']; - if ($row['post_approved']) + if ($row['post_visibility'] == ITEM_UNAPPROVED) { $has_attachments = true; } } $rowset[$row['post_id']] = array( - 'hide_post' => ($row['foe'] && ($view != 'show' || $post_id != $row['post_id'])) ? true : false, + 'hide_post' => (($row['foe'] || $row['post_visibility'] == ITEM_DELETED) && ($view != 'show' || $post_id != $row['post_id'])) ? true : false, 'post_id' => $row['post_id'], 'post_time' => $row['post_time'], @@ -1049,11 +1053,14 @@ while ($row = $db->sql_fetchrow($result)) 'post_edit_reason' => $row['post_edit_reason'], 'post_edit_user' => $row['post_edit_user'], 'post_edit_locked' => $row['post_edit_locked'], + 'post_delete_time' => $row['post_delete_time'], + 'post_delete_reason'=> $row['post_delete_reason'], + 'post_delete_user' => $row['post_delete_user'], // Make sure the icon actually exists 'icon_id' => (isset($icons[$row['icon_id']]['img'], $icons[$row['icon_id']]['height'], $icons[$row['icon_id']]['width'])) ? $row['icon_id'] : 0, 'post_attachment' => $row['post_attachment'], - 'post_approved' => $row['post_approved'], + 'post_visibility' => $row['post_visibility'], 'post_reported' => $row['post_reported'], 'post_username' => $row['post_username'], 'post_text' => $row['post_text'], @@ -1320,8 +1327,8 @@ if (sizeof($attach_list)) $sql = 'SELECT a.post_msg_id as post_id FROM ' . ATTACHMENTS_TABLE . ' a, ' . POSTS_TABLE . " p WHERE p.topic_id = $topic_id - AND p.post_approved = 1 - AND p.topic_id = a.topic_id"; + AND p.post_visibility = " . ITEM_APPROVED . ' + AND p.topic_id = a.topic_id'; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -1502,6 +1509,62 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) $l_edited_by = ''; } + // Deleting information + if ($row['post_visibility'] == ITEM_DELETED && $row['post_delete_user']) + { + // Get usernames for all following posts if not already stored + if (!sizeof($post_delete_list) && ($row['post_delete_reason'] || ($row['post_delete_user'] && !isset($user_cache[$row['post_delete_user']])))) + { + // Remove all post_ids already parsed (we do not have to check them) + $post_storage_list = (!$store_reverse) ? array_slice($post_list, $i) : array_slice(array_reverse($post_list), $i); + + $sql = 'SELECT DISTINCT u.user_id, u.username, u.user_colour + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u + WHERE ' . $db->sql_in_set('p.post_id', $post_storage_list) . ' + AND p.post_delete_user <> 0 + AND p.post_delete_user = u.user_id'; + $result2 = $db->sql_query($sql); + while ($user_delete_row = $db->sql_fetchrow($result2)) + { + $post_delete_list[$user_delete_row['user_id']] = $user_delete_row; + } + $db->sql_freeresult($result2); + + unset($post_storage_list); + } + + if ($row['post_delete_user'] && !isset($user_cache[$row['post_delete_user']])) + { + $user_cache[$row['post_delete_user']] = $post_delete_list[$row['post_delete_user']]; + } + + $display_postername = get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']); + + // User having deleted the post also being the post author? + if (!$row['post_delete_user'] || $row['post_delete_user'] == $poster_id) + { + $display_username = $display_postername; + } + else + { + $display_username = get_username_string('full', $row['post_delete_user'], $user_cache[$row['post_delete_user']]['username'], $user_cache[$row['post_delete_user']]['user_colour']); + } + + if ($row['post_delete_reason']) + { + $l_deleted_message = $user->lang('POST_DELETED_BY_REASON', $display_postername, $display_username, $user->format_date($row['post_delete_time'], false, true), $row['post_delete_reason']); + } + else + { + $l_deleted_message = $user->lang('POST_DELETED_BY', $display_postername, $display_username, $user->format_date($row['post_delete_time'], false, true)); + } + $l_deleted_by = $user->lang('DELETED_INFORMATION', $display_username, $user->format_date($row['post_delete_time'], false, true)); + } + else + { + $l_deleted_by = $l_deleted_message = ''; + } + // Bump information if ($topic_data['topic_bumped'] && $row['post_id'] == $topic_data['topic_last_post_id'] && isset($user_cache[$topic_data['topic_bumper']]) ) { @@ -1538,9 +1601,9 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) ($row['post_time'] > time() - ($config['edit_time'] * 60) || !$config['edit_time']) ))); - $delete_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_delete', $forum_id) || ( + $delete_allowed = ($user->data['is_registered'] && (($auth->acl_get('m_delete', $forum_id) || ($auth->acl_get('m_softdelete', $forum_id) && $row['post_visibility'] != ITEM_DELETED)) || ( $user->data['user_id'] == $poster_id && - $auth->acl_get('f_delete', $forum_id) && + ($auth->acl_get('f_delete', $forum_id) || ($auth->acl_get('f_softdelete', $forum_id) && $row['post_visibility'] != ITEM_DELETED)) && $topic_data['topic_last_post_id'] == $row['post_id'] && ($row['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']) && // we do not want to allow removal of the last post if a moderator locked it! @@ -1570,6 +1633,8 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'SIGNATURE' => ($row['enable_sig']) ? $user_cache[$poster_id]['sig'] : '', 'EDITED_MESSAGE' => $l_edited_by, 'EDIT_REASON' => $row['post_edit_reason'], + 'DELETED_MESSAGE' => $l_deleted_by, + 'DELETE_REASON' => $row['post_delete_reason'], 'BUMPED_MESSAGE' => $l_bumped_by, 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), @@ -1596,10 +1661,11 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'U_YIM' => $user_cache[$poster_id]['yim'], 'U_JABBER' => $user_cache[$poster_id]['jabber'], - 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p={$row['post_id']}&f=$forum_id"), + 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p={$row['post_id']}&f=$forum_id&redirect=" . urlencode(str_replace('&', '&', $viewtopic_url . '&p=' . $row['post_id'] . '#p' . $row['post_id']))), 'U_REPORT' => ($auth->acl_get('f_report', $forum_id)) ? append_sid("{$phpbb_root_path}report.$phpEx", 'f=' . $forum_id . '&p=' . $row['post_id']) : '', 'U_MCP_REPORT' => ($auth->acl_get('m_report', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '', 'U_MCP_APPROVE' => ($auth->acl_get('m_approve', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '', + 'U_MCP_RESTORE' => ($auth->acl_get('m_approve', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_data['topic_visibility'] != ITEM_DELETED) ? 'deleted_posts' : 'deleted_topics') . '&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '', 'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'], 'U_NEXT_POST_ID' => ($i < $i_total && isset($rowset[$post_list[$i + 1]])) ? $rowset[$post_list[$i + 1]]['post_id'] : '', 'U_PREV_POST_ID' => $prev_post_id, @@ -1612,7 +1678,9 @@ 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_approved']) ? false : true, + 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED) ? 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, 'S_DISPLAY_NOTICE' => $display_notice && $row['post_attachment'], 'S_FRIEND' => ($row['friend']) ? true : false, @@ -1621,8 +1689,10 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'S_CUSTOM_FIELDS' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false, 'S_TOPIC_POSTER' => ($topic_data['topic_poster'] == $poster_id) ? true : false, - 'S_IGNORE_POST' => ($row['hide_post']) ? true : false, - 'L_IGNORE_POST' => ($row['hide_post']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), '<a href="' . $viewtopic_url . "&p={$row['post_id']}&view=show#p{$row['post_id']}" . '">', '</a>') : '', + 'S_IGNORE_POST' => ($row['foe']) ? true : false, + 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '', + 'S_POST_HIDDEN' => $row['hide_post'], + 'L_POST_DISPLAY' => ($row['hide_post']) ? $user->lang('POST_DISPLAY', '<a class="display_post" data-post-id="' . $row['post_id'] . '" href="' . $viewtopic_url . "&p={$row['post_id']}&view=show#p{$row['post_id']}" . '">', '</a>') : '', ); $user_poster_data = $user_cache[$poster_id]; diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php new file mode 100644 index 0000000000..6234aac9ad --- /dev/null +++ b/tests/content_visibility/delete_post_test.php @@ -0,0 +1,310 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; +require_once dirname(__FILE__) . '/../mock/search.php'; + +class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/delete_post.xml'); + } + + public function delete_post_data() + { + $info_data = array( + 'topic_first_post_id' => 1, + 'topic_last_post_id' => 3, + 'topic_posts_approved' => 3, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_visibility' => ITEM_APPROVED, + 'post_time' => 2, + 'post_visibility' => ITEM_APPROVED, + 'post_postcount' => true, + 'poster_id' => 1, + 'post_reported' => false, + ); + + return array( + array( + 1, 1, 2, + array_merge($info_data, array( + 'post_time' => 2, + )), + false, 'harddelete', + array( + array('post_id' => 1, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + //array('post_id' => 2, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 1, + 'topic_last_post_id' => 3, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), + ), + ), + array( + 1, 1, 1, + array_merge($info_data, array( + 'post_time' => 1, + )), + false, 'harddelete', + array( + //array('post_id' => 1, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 2, + 'topic_last_post_id' => 3, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), + ), + ), + array( + 1, 1, 3, + array_merge($info_data, array( + 'post_time' => 3, + )), + false, 'harddelete', + array( + array('post_id' => 1, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + //array('post_id' => 3, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 1, + 'topic_last_post_id' => 2, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2), + ), + ), + array( + 1, 1, 2, + array_merge($info_data, array( + 'post_time' => 2, + )), + true, 'soft delete', + array( + array('post_id' => 1, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => ITEM_DELETED, 'post_delete_reason' => 'soft delete'), + array('post_id' => 3, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 1, + 'topic_last_post_id' => 3, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 1, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), + ), + ), + array( + 1, 1, 1, + array_merge($info_data, array( + 'post_time' => 1, + )), + true, 'soft delete', + array( + array('post_id' => 1, 'post_visibility' => ITEM_DELETED, 'post_delete_reason' => 'soft delete'), + array('post_id' => 2, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 2, + 'topic_last_post_id' => 3, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 1, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3), + ), + ), + array( + 1, 1, 3, + array_merge($info_data, array( + 'post_time' => 3, + )), + true, 'soft delete', + array( + array('post_id' => 1, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => ITEM_APPROVED, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => ITEM_DELETED, 'post_delete_reason' => 'soft delete'), + ), + array( + array( + 'topic_visibility' => ITEM_APPROVED, + 'topic_first_post_id' => 1, + 'topic_last_post_id' => 2, + 'topic_posts_approved' => 2, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 1, + 'topic_delete_reason' => '', + ), + ), + array( + array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2), + ), + ), + + array( + 2, 2, 4, + array( + 'topic_first_post_id' => 4, + 'topic_last_post_id' => 4, + 'topic_posts_approved' => 1, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_visibility' => ITEM_APPROVED, + 'post_time' => 4, + 'post_visibility' => ITEM_APPROVED, + 'post_postcount' => true, + 'poster_id' => 1, + 'post_reported' => false, + ), + false, 'harddelete', + array( + ), + array( + ), + array( + 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), + ), + ), + + array( + 2, 2, 4, + array( + 'topic_first_post_id' => 4, + 'topic_last_post_id' => 4, + 'topic_posts_approved' => 1, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 0, + 'topic_visibility' => ITEM_APPROVED, + 'post_time' => 4, + 'post_visibility' => ITEM_APPROVED, + 'post_postcount' => true, + 'poster_id' => 1, + 'post_reported' => false, + ), + true, 'soft delete', + array( + array('post_id' => 4, 'post_visibility' => ITEM_DELETED, 'post_delete_reason' => ''), + ), + array( + array( + 'topic_visibility' => ITEM_DELETED, + 'topic_first_post_id' => 4, + 'topic_last_post_id' => 4, + 'topic_posts_approved' => 0, + 'topic_posts_unapproved' => 0, + 'topic_posts_softdeleted' => 1, + 'topic_delete_reason' => 'soft delete', + ), + ), + array( + array('forum_posts_approved' => 0, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 0, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 1, 'forum_last_post_id' => 0), + ), + ), + ); + } + + /** + * @dataProvider delete_post_data + */ + public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason, $expected_posts, $expected_topic, $expected_forum) + { + global $auth, $cache, $config, $db, $phpbb_container, $phpbb_root_path, $phpEx; + + $config['search_type'] = 'phpbb_mock_search'; + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + set_config_count(null, null, null, new phpbb_config(array('num_posts' => 3, 'num_topics' => 1))); + + // Create auth mock + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap(array( + array('m_approve', 1, true), + ))); + $user = $this->getMock('phpbb_user'); + + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); + $phpbb_container->set('content.visibility', new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); + + delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason); + + $result = $db->sql_query('SELECT post_id, post_visibility, post_delete_reason + FROM phpbb_posts + WHERE topic_id = ' . $topic_id . ' + ORDER BY post_id ASC'); + + $this->assertEquals($expected_posts, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + + $result = $db->sql_query('SELECT topic_visibility, topic_first_post_id, topic_last_post_id, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_delete_reason + FROM phpbb_topics + WHERE topic_id = ' . $topic_id); + + $this->assertEquals($expected_topic, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + + $result = $db->sql_query('SELECT forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id + FROM phpbb_forums + WHERE forum_id = ' . $forum_id); + + $this->assertEquals($expected_forum, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + } +} diff --git a/tests/content_visibility/fixtures/delete_post.xml b/tests/content_visibility/fixtures/delete_post.xml new file mode 100644 index 0000000000..deca9c74b6 --- /dev/null +++ b/tests/content_visibility/fixtures/delete_post.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_forums"> + <column>forum_id</column> + <column>forum_posts_approved</column> + <column>forum_posts_unapproved</column> + <column>forum_posts_softdeleted</column> + <column>forum_topics_approved</column> + <column>forum_topics_unapproved</column> + <column>forum_topics_softdeleted</column> + <column>forum_last_post_id</column> + <column>forum_parents</column> + <column>forum_desc</column> + <column>forum_rules</column> + + <row> + <value>1</value> + <value>3</value> + <value>0</value> + <value>0</value> + <value>1</value> + <value>0</value> + <value>0</value> + <value>3</value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>0</value> + <value>0</value> + <value>1</value> + <value>0</value> + <value>0</value> + <value>4</value> + <value></value> + <value></value> + <value></value> + </row> + </table> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <column>topic_visibility</column> + <column>topic_title</column> + <column>topic_first_post_id</column> + <column>topic_last_post_id</column> + <column>topic_delete_user</column> + <column>topic_delete_time</column> + <column>topic_delete_reason</column> + <column>topic_posts_approved</column> + <column>topic_posts_unapproved</column> + <column>topic_posts_softdeleted</column> + + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + <value>1</value> + <value>3</value> + <value>0</value> + <value>0</value> + <value></value> + <value>3</value> + <value>0</value> + <value>0</value> + </row> + <row> + <value>2</value> + <value>2</value> + <value>1</value> + <value>Approved</value> + <value>4</value> + <value>4</value> + <value>0</value> + <value>0</value> + <value></value> + <value>1</value> + <value>0</value> + <value>0</value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>poster_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_time</column> + <column>post_text</column> + <column>post_delete_user</column> + <column>post_delete_time</column> + <column>post_delete_reason</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>2</value> + <value>Approved</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + <row> + <value>3</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>3</value> + <value>Approved</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + + <row> + <value>4</value> + <value>1</value> + <value>2</value> + <value>2</value> + <value>1</value> + <value>4</value> + <value>Approved</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + </table> + <table name="phpbb_users"> + <column>user_id</column> + <column>user_posts</column> + <column>username</column> + <column>username_clean</column> + <column>user_permissions</column> + <column>user_sig</column> + <column>user_occ</column> + <column>user_interests</column> + <row> + <value>1</value> + <value>4</value> + <value>user 1</value> + <value>user 1</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/content_visibility/fixtures/get_forums_visibility_sql.xml b/tests/content_visibility/fixtures/get_forums_visibility_sql.xml new file mode 100644 index 0000000000..658d34398f --- /dev/null +++ b/tests/content_visibility/fixtures/get_forums_visibility_sql.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <column>topic_visibility</column> + <column>topic_title</column> + <row> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>3</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + <row> + <value>4</value> + <value>2</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>5</value> + <value>2</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>6</value> + <value>2</value> + <value>2</value> + <value>Softdeleted</value> + </row> + <row> + <value>7</value> + <value>3</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>8</value> + <value>3</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>9</value> + <value>3</value> + <value>2</value> + <value>Softdeleted</value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_text</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>3</value> + <value>3</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + <row> + <value>4</value> + <value>4</value> + <value>2</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>5</value> + <value>5</value> + <value>2</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>6</value> + <value>6</value> + <value>2</value> + <value>2</value> + <value>Softdeleted</value> + </row> + <row> + <value>7</value> + <value>7</value> + <value>3</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>8</value> + <value>8</value> + <value>3</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>9</value> + <value>9</value> + <value>3</value> + <value>2</value> + <value>Softdeleted</value> + </row> + </table> +</dataset> diff --git a/tests/content_visibility/fixtures/get_visibility_sql.xml b/tests/content_visibility/fixtures/get_visibility_sql.xml new file mode 100644 index 0000000000..146244263e --- /dev/null +++ b/tests/content_visibility/fixtures/get_visibility_sql.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <column>topic_visibility</column> + <column>topic_title</column> + <row> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>3</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_text</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>3</value> + <value>3</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + </table> +</dataset> diff --git a/tests/content_visibility/fixtures/set_post_visibility.xml b/tests/content_visibility/fixtures/set_post_visibility.xml new file mode 100644 index 0000000000..722525deaa --- /dev/null +++ b/tests/content_visibility/fixtures/set_post_visibility.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <column>topic_visibility</column> + <column>topic_title</column> + <column>topic_first_post_id</column> + <column>topic_last_post_id</column> + <column>topic_posts_approved</column> + <column>topic_posts_softdeleted</column> + <column>topic_posts_unapproved</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>1</value> + </row> + + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>2 Approved posts</value> + <value>5</value> + <value>6</value> + <value>1</value> + <value>1</value> + <value>1</value> + </row> + + <row> + <value>3</value> + <value>1</value> + <value>1</value> + <value>Only 1 Approved posts</value> + <value>8</value> + <value>8</value> + <value>1</value> + <value>0</value> + <value>0</value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>poster_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_text</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>3</value> + <value>3</value> + <value>1</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + + <row> + <value>4</value> + <value>1</value> + <value>2</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + </row> + <row> + <value>5</value> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + <row> + <value>6</value> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value>Approved 2</value> + </row> + <row> + <value>7</value> + <value>3</value> + <value>2</value> + <value>1</value> + <value>2</value> + <value>Softdeleted</value> + </row> + <row> + <value>8</value> + <value>1</value> + <value>3</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + </row> + </table> + <table name="phpbb_users"> + <column>user_id</column> + <column>user_posts</column> + <column>username</column> + <column>username_clean</column> + <column>user_permissions</column> + <column>user_sig</column> + <column>user_occ</column> + <column>user_interests</column> + <row> + <value>1</value> + <value>1</value> + <value>user 1</value> + <value>user 1</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>user 2</value> + <value>user 2</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>3</value> + <value>1</value> + <value>user 3</value> + <value>user 3</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/content_visibility/fixtures/set_topic_visibility.xml b/tests/content_visibility/fixtures/set_topic_visibility.xml new file mode 100644 index 0000000000..a875012d4f --- /dev/null +++ b/tests/content_visibility/fixtures/set_topic_visibility.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <column>topic_visibility</column> + <column>topic_title</column> + <column>topic_first_post_id</column> + <column>topic_last_post_id</column> + <column>topic_delete_user</column> + <column>topic_delete_time</column> + <column>topic_delete_reason</column> + + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + + <row> + <value>2</value> + <value>1</value> + <value>2</value> + <value>Soft deleted</value> + <value>4</value> + <value>5</value> + <value>2</value> + <value>123</value> + <value></value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>poster_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_text</column> + <column>post_delete_user</column> + <column>post_delete_time</column> + <column>post_delete_reason</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Approved</value> + <value>2</value> + <value>0</value> + <value></value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>2</value> + <value>Soft deleted</value> + <value>2</value> + <value>123</value> + <value>manually</value> + </row> + <row> + <value>3</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value>Unapproved</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + + <row> + <value>4</value> + <value>1</value> + <value>2</value> + <value>1</value> + <value>2</value> + <value>Soft deleted by topic soft delete</value> + <value>2</value> + <value>123</value> + <value></value> + </row> + <row> + <value>5</value> + <value>1</value> + <value>2</value> + <value>1</value> + <value>2</value> + <value>Soft deleted before the topic was soft deleted</value> + <value>2</value> + <value>120</value> + <value>manually</value> + </row> + <row> + <value>6</value> + <value>1</value> + <value>2</value> + <value>1</value> + <value>0</value> + <value>Unapproved before the topic was soft deleted</value> + <value>0</value> + <value>0</value> + <value></value> + </row> + </table> + <table name="phpbb_users"> + <column>user_id</column> + <column>user_posts</column> + <column>username</column> + <column>username_clean</column> + <column>user_permissions</column> + <column>user_sig</column> + <column>user_occ</column> + <column>user_interests</column> + <row> + <value>1</value> + <value>6</value> + <value>user 1</value> + <value>user 1</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/content_visibility/get_forums_visibility_sql_test.php b/tests/content_visibility/get_forums_visibility_sql_test.php new file mode 100644 index 0000000000..aa44fa4013 --- /dev/null +++ b/tests/content_visibility/get_forums_visibility_sql_test.php @@ -0,0 +1,143 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_content_visibility_get_forums_visibility_sql_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/get_forums_visibility_sql.xml'); + } + + public function get_forums_visibility_sql_data() + { + return array( + array( + 'phpbb_topics', + 'topic', array(1, 2, 3), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('topic_id' => 1), + array('topic_id' => 2), + array('topic_id' => 3), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + array('topic_id' => 7), + array('topic_id' => 8), + array('topic_id' => 9), + ), + ), + array( + 'phpbb_topics', + 'topic', array(1, 2), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('topic_id' => 1), + array('topic_id' => 2), + array('topic_id' => 3), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + ), + ), + array( + 'phpbb_topics', + 'topic', array(1, 2, 3), '', + array( + array('m_approve', true, array(2 => true)), + ), + array( + array('topic_id' => 2), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + array('topic_id' => 8), + ), + ), + array( + 'phpbb_posts', + 'post', array(1, 2, 3), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('post_id' => 1), + array('post_id' => 2), + array('post_id' => 3), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + array('post_id' => 7), + array('post_id' => 8), + array('post_id' => 9), + ), + ), + array( + 'phpbb_posts', + 'post', array(1, 2), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('post_id' => 1), + array('post_id' => 2), + array('post_id' => 3), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + ), + ), + array( + 'phpbb_posts', + 'post', array(1, 2, 3), '', + array( + array('m_approve', true, array(2 => true)), + ), + array( + array('post_id' => 2), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + array('post_id' => 8), + ), + ), + ); + } + + /** + * @dataProvider get_forums_visibility_sql_data + */ + public function test_get_forums_visibility_sql($table, $mode, $forum_ids, $table_alias, $permissions, $expected) + { + global $cache, $db, $auth, $phpbb_root_path, $phpEx; + + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + + // Create auth mock + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_getf') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap($permissions)); + $user = $this->getMock('phpbb_user'); + $content_visibility = new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + + $result = $db->sql_query('SELECT ' . $mode . '_id + FROM ' . $table . ' + WHERE ' . $content_visibility->get_forums_visibility_sql($mode, $forum_ids, $table_alias) . ' + ORDER BY ' . $mode . '_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + } +} diff --git a/tests/content_visibility/get_global_visibility_sql_test.php b/tests/content_visibility/get_global_visibility_sql_test.php new file mode 100644 index 0000000000..0f019ffa50 --- /dev/null +++ b/tests/content_visibility/get_global_visibility_sql_test.php @@ -0,0 +1,143 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_content_visibility_get_global_visibility_sql_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/get_forums_visibility_sql.xml'); + } + + public function get_global_visibility_sql_data() + { + return array( + array( + 'phpbb_topics', + 'topic', array(), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('topic_id' => 1), + array('topic_id' => 2), + array('topic_id' => 3), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + array('topic_id' => 7), + array('topic_id' => 8), + array('topic_id' => 9), + ), + ), + array( + 'phpbb_topics', + 'topic', array(3), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('topic_id' => 1), + array('topic_id' => 2), + array('topic_id' => 3), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + ), + ), + array( + 'phpbb_topics', + 'topic', array(), '', + array( + array('m_approve', true, array(2 => true)), + ), + array( + array('topic_id' => 2), + array('topic_id' => 4), + array('topic_id' => 5), + array('topic_id' => 6), + array('topic_id' => 8), + ), + ), + array( + 'phpbb_posts', + 'post', array(), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('post_id' => 1), + array('post_id' => 2), + array('post_id' => 3), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + array('post_id' => 7), + array('post_id' => 8), + array('post_id' => 9), + ), + ), + array( + 'phpbb_posts', + 'post', array(3), '', + array( + array('m_approve', true, array(1 => true, 2 => true, 3 => true)), + ), + array( + array('post_id' => 1), + array('post_id' => 2), + array('post_id' => 3), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + ), + ), + array( + 'phpbb_posts', + 'post', array(), '', + array( + array('m_approve', true, array(2 => true)), + ), + array( + array('post_id' => 2), + array('post_id' => 4), + array('post_id' => 5), + array('post_id' => 6), + array('post_id' => 8), + ), + ), + ); + } + + /** + * @dataProvider get_global_visibility_sql_data + */ + public function test_get_global_visibility_sql($table, $mode, $forum_ids, $table_alias, $permissions, $expected) + { + global $cache, $db, $auth, $phpbb_root_path, $phpEx; + + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + + // Create auth mock + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_getf') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap($permissions)); + $user = $this->getMock('phpbb_user'); + $content_visibility = new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + + $result = $db->sql_query('SELECT ' . $mode . '_id + FROM ' . $table . ' + WHERE ' . $content_visibility->get_global_visibility_sql($mode, $forum_ids, $table_alias) . ' + ORDER BY ' . $mode . '_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + } +} diff --git a/tests/content_visibility/get_visibility_sql_test.php b/tests/content_visibility/get_visibility_sql_test.php new file mode 100644 index 0000000000..cc6c10c649 --- /dev/null +++ b/tests/content_visibility/get_visibility_sql_test.php @@ -0,0 +1,90 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_content_visibility_get_visibility_sql_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/get_visibility_sql.xml'); + } + + public function get_visibility_sql_data() + { + return array( + array( + 'phpbb_posts', + 'post', 1, '', + array( + array('m_approve', 1, true), + ), + array( + array('post_id' => 1), + array('post_id' => 2), + array('post_id' => 3), + ), + ), + array( + 'phpbb_posts', + 'post', 1, '', + array( + ), + array( + array('post_id' => 2), + ), + ), + array( + 'phpbb_topics', + 'topic', 1, '', + array( + array('m_approve', 1, true), + ), + array( + array('topic_id' => 1), + array('topic_id' => 2), + array('topic_id' => 3), + ), + ), + array( + 'phpbb_topics', + 'topic', 1, '', + array(), + array( + array('topic_id' => 2), + ), + ), + ); + } + + /** + * @dataProvider get_visibility_sql_data + */ + public function test_get_visibility_sql($table, $mode, $forum_id, $table_alias, $permissions, $expected) + { + global $cache, $db, $auth, $phpbb_root_path, $phpEx; + + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + + // Create auth mock + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap($permissions)); + $user = $this->getMock('phpbb_user'); + $content_visibility = new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + + $result = $db->sql_query('SELECT ' . $mode . '_id + FROM ' . $table . ' + WHERE ' . $content_visibility->get_visibility_sql($mode, $forum_id, $table_alias) . ' + ORDER BY ' . $mode . '_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + } +} diff --git a/tests/content_visibility/set_post_visibility_test.php b/tests/content_visibility/set_post_visibility_test.php new file mode 100644 index 0000000000..81abf56c75 --- /dev/null +++ b/tests/content_visibility/set_post_visibility_test.php @@ -0,0 +1,143 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +class phpbb_content_visibility_set_post_visibility_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/set_post_visibility.xml'); + } + + public function set_post_visibility_data() + { + return array( + array( + ITEM_APPROVED, + 1, 1, 1, + 2, time(), 'approve', + true, false, + array( + array('post_id' => 1, 'post_visibility' => 1, 'post_delete_reason' => 'approve'), + array('post_id' => 2, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => 2, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 1, 'topic_last_post_id' => 2), + ), + ), + array( + ITEM_APPROVED, + 3, 1, 1, + 2, time(), 'approve', + false, true, + array( + array('post_id' => 1, 'post_visibility' => 0, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => 1, 'post_delete_reason' => 'approve'), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 2, 'topic_last_post_id' => 3), + ), + ), + array( + ITEM_DELETED, + 2, 1, 1, + 2, time(), 'deleted', + true, true, + array( + array('post_id' => 1, 'post_visibility' => 0, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => 2, 'post_delete_reason' => 'deleted'), + array('post_id' => 3, 'post_visibility' => 2, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 2, 'topic_first_post_id' => 1, 'topic_last_post_id' => 3), + ), + ), + array( + ITEM_DELETED, + 5, 2, 1, + 2, time(), 'deleted', + true, false, + array( + array('post_id' => 4, 'post_visibility' => 0, 'post_delete_reason' => ''), + array('post_id' => 5, 'post_visibility' => 2, 'post_delete_reason' => 'deleted'), + array('post_id' => 6, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 7, 'post_visibility' => 2, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 6, 'topic_last_post_id' => 6), + ), + ), + array( + ITEM_DELETED, + 6, 2, 1, + 2, time(), 'deleted', + false, true, + array( + array('post_id' => 4, 'post_visibility' => 0, 'post_delete_reason' => ''), + array('post_id' => 5, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 6, 'post_visibility' => 2, 'post_delete_reason' => 'deleted'), + array('post_id' => 7, 'post_visibility' => 2, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 5, 'topic_last_post_id' => 5), + ), + ), + array( + ITEM_DELETED, + 8, 3, 1, + 2, time(), 'deleted', + true, true, + array( + array('post_id' => 8, 'post_visibility' => 2, 'post_delete_reason' => 'deleted'), + ), + array( + array('topic_visibility' => 2, 'topic_first_post_id' => 8, 'topic_last_post_id' => 8), + ), + ), + ); + } + + /** + * @dataProvider set_post_visibility_data + */ + public function test_set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $expected, $expected_topic) + { + global $cache, $db, $auth, $phpbb_root_path, $phpEx; + + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + $auth = $this->getMock('phpbb_auth'); + $user = $this->getMock('phpbb_user'); + $content_visibility = new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + + $content_visibility->set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest); + + $result = $db->sql_query('SELECT post_id, post_visibility, post_delete_reason + FROM phpbb_posts + WHERE topic_id = ' . $topic_id . ' + ORDER BY post_id ASC'); + + $this->assertEquals($expected, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + + $result = $db->sql_query('SELECT topic_visibility, topic_first_post_id, topic_last_post_id + FROM phpbb_topics + WHERE topic_id = ' . $topic_id); + + $this->assertEquals($expected_topic, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + } +} diff --git a/tests/content_visibility/set_topic_visibility_test.php b/tests/content_visibility/set_topic_visibility_test.php new file mode 100644 index 0000000000..6b5d884a2b --- /dev/null +++ b/tests/content_visibility/set_topic_visibility_test.php @@ -0,0 +1,107 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_admin.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +class phpbb_content_visibility_set_topic_visibility_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/set_topic_visibility.xml'); + } + + public function set_topic_visibility_data() + { + return array( + array( + ITEM_DELETED, 1, 1, + 2, time(), 'delete', false, + array( + array('post_id' => 1, 'post_visibility' => 2, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => 2, 'post_delete_reason' => 'manually'), + array('post_id' => 3, 'post_visibility' => 0, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 2, 'topic_first_post_id' => 1, 'topic_last_post_id' => 3, 'topic_delete_reason' => 'delete'), + ), + ), + array( + ITEM_DELETED, 1, 1, + 2, time(), 'delete-forced', true, + array( + array('post_id' => 1, 'post_visibility' => 2, 'post_delete_reason' => ''), + array('post_id' => 2, 'post_visibility' => 2, 'post_delete_reason' => ''), + array('post_id' => 3, 'post_visibility' => 2, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 2, 'topic_first_post_id' => 1, 'topic_last_post_id' => 3, 'topic_delete_reason' => 'delete-forced'), + ), + ), + array( + ITEM_APPROVED, 2, 1, + 2, time(), 'approved', false, + array( + array('post_id' => 4, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 5, 'post_visibility' => 2, 'post_delete_reason' => 'manually'), + array('post_id' => 6, 'post_visibility' => 0, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 4, 'topic_last_post_id' => 4, 'topic_delete_reason' => 'approved'), + ), + ), + array( + ITEM_APPROVED, 2, 1, + 2, time(), 'approved-forced', true, + array( + array('post_id' => 4, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 5, 'post_visibility' => 1, 'post_delete_reason' => ''), + array('post_id' => 6, 'post_visibility' => 1, 'post_delete_reason' => ''), + ), + array( + array('topic_visibility' => 1, 'topic_first_post_id' => 4, 'topic_last_post_id' => 6, 'topic_delete_reason' => 'approved-forced'), + ), + ), + ); + } + + /** + * @dataProvider set_topic_visibility_data + */ + public function test_set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all, $expected_posts, $expected_topic) + { + global $cache, $db, $auth, $phpbb_root_path, $phpEx; + + $cache = new phpbb_mock_cache; + $db = $this->new_dbal(); + $auth = $this->getMock('phpbb_auth'); + $user = $this->getMock('phpbb_user'); + $content_visibility = new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE); + + $content_visibility->set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all); + + $result = $db->sql_query('SELECT post_id, post_visibility, post_delete_reason + FROM phpbb_posts + WHERE topic_id = ' . $topic_id . ' + ORDER BY post_id ASC'); + + $this->assertEquals($expected_posts, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + + $result = $db->sql_query('SELECT topic_visibility, topic_first_post_id, topic_last_post_id, topic_delete_reason + FROM phpbb_topics + WHERE topic_id = ' . $topic_id); + + $this->assertEquals($expected_topic, $db->sql_fetchrowset($result)); + $db->sql_freeresult($result); + } +} diff --git a/tests/functional/softdelete_test.php b/tests/functional/softdelete_test.php new file mode 100644 index 0000000000..bd4d34cf99 --- /dev/null +++ b/tests/functional/softdelete_test.php @@ -0,0 +1,761 @@ +<?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_softdelete_test extends phpbb_functional_test_case +{ + protected $data = array(); + + public function test_setup_forums() + { + $this->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' => 'Soft Delete #1', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Soft Delete #2', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + } + + public function test_create_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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 + $post = $this->create_topic($this->data['forums']['Soft Delete #1'], 'Soft Delete 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('Soft Delete Topic #1', $crawler->filter('html')->text()); + $this->data['topics']['Soft Delete Topic #1'] = (int) $post['topic_id']; + $this->data['posts']['Soft Delete 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']['Soft Delete #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']['Soft Delete Topic #1'], + ), 'after creating topic #1'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#2', 'This is a test post posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Re: Soft Delete Topic #1-#2', $crawler->filter('html')->text()); + $this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->eq(1)->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 2, + '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']['Re: Soft Delete Topic #1-#2'], + ), 'after replying'); + } + + public function test_softdelete_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 2, + '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']['Re: Soft Delete Topic #1-#2'], + ), 'before softdelete'); + + $this->add_lang('posting'); + $crawler = self::request('GET', "posting.php?mode=delete&f={$this->data['forums']['Soft Delete #1']}&p={$this->data['posts']['Re: Soft Delete Topic #1-#2']}&sid={$this->sid}"); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_DELETED', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after softdelete'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains($this->lang('POST_DISPLAY', '', ''), $crawler->text()); + } + + public function test_move_softdeleted_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'before moving #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'before moving #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('move'); + $crawler = self::submit($form); + $this->assertContainsLang('SELECT_DESTINATION_FORUM', $crawler->text()); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Yes')->form(); + $form['to_forum_id']->select($this->data['forums']['Soft Delete #2']); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_MOVED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete #2', $crawler->filter('.navlinks')->text()); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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, + ), 'after moving #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after moving #2'); + } + + public function test_softdelete_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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, + ), 'before softdeleting #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'before softdeleting #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $this->add_lang('posting'); + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('delete_topic'); + $crawler = self::submit($form); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_DELETED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete #2', $crawler->filter('.navlinks')->text()); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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, + ), 'after moving #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 2, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => 0, + ), 'after moving #2'); + } + + public function test_move_softdeleted_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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, + ), 'before moving #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 2, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => 0, + ), 'before moving #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('move'); + $crawler = self::submit($form); + $this->assertContainsLang('SELECT_DESTINATION_FORUM', $crawler->text()); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Yes')->form(); + $form['to_forum_id']->select($this->data['forums']['Soft Delete #1']); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_MOVED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete #1', $crawler->filter('.navlinks')->text()); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 2, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => 0, + ), 'after moving #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'after moving #2'); + } + + public function test_restore_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 2, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => 0, + ), 'before restoring #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'before restoring #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $this->add_lang('mcp'); + $form = $crawler->selectButton($this->lang('RESTORE'))->form(); + $crawler = self::submit($form); + $this->assertContainsLang('RESTORE_POST', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_RESTORED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete #1', $crawler->filter('.navlinks')->text()); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after restoring #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'after restoring #2'); + } + + public function test_split_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'before splitting #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'before splitting #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('split'); + $crawler = self::submit($form); + $this->assertContainsLang('SPLIT_TOPIC_EXPLAIN', $crawler->text()); + + $form = $crawler->selectButton('Submit')->form(array( + 'subject' => 'Soft Delete Topic #2', + )); + $form['to_forum_id']->select($this->data['forums']['Soft Delete #2']); + $form['post_id_list'][1]->tick(); + $crawler = self::submit($form); + + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_SPLIT_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + $this->assertNotContains('Re: Soft Delete Topic #1-#2', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #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']['Soft Delete Topic #1'], + ), 'after restoring #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => 0, + ), 'after restoring #2'); + } + + public function test_move_topic_back() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + 'Soft Delete Topic #2', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #2']}&sid={$this->sid}"); + + $form = $crawler->selectButton('Go')->eq(1)->form(); + $form['action']->select('move'); + $crawler = self::submit($form); + + $form = $crawler->selectButton('Yes')->form(); + $form['to_forum_id']->select($this->data['forums']['Soft Delete #1']); + $crawler = self::submit($form); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after moving back'); + } + + public function test_merge_topics() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + 'Soft Delete Topic #2', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 1, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'before merging #1'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #2']}&sid={$this->sid}"); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Go')->eq(1)->form(); + $form['action']->select('merge_topic'); + $crawler = self::submit($form); + $this->assertContainsLang('SELECT_MERGE', $crawler->text()); + + $crawler = self::request('GET', "mcp.php?f={$this->data['forums']['Soft Delete #1']}&t={$this->data['topics']['Soft Delete Topic #2']}&i=main&mode=forum_view&action=merge_topic&to_topic_id={$this->data['topics']['Soft Delete Topic #1']}"); + $this->assertContainsLang('MERGE_TOPICS_CONFIRM', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POSTS_MERGED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + $this->assertContains('Soft Delete Topic #1', $crawler->filter('h2')->text()); + $this->assertContainsLang('POST_DELETED', $crawler->filter('body')->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after merging #1'); + } + + public function test_fork_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Soft Delete #1', + 'Soft Delete #2', + ), + 'topics' => array( + 'Soft Delete Topic #1', + ), + 'posts' => array( + 'Soft Delete Topic #1', + 'Re: Soft Delete Topic #1-#2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'before forking #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], 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, + ), 'before forking #2'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('fork'); + $crawler = self::submit($form); + $this->assertContainsLang('FORK_TOPIC', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $form['to_forum_id']->select($this->data['forums']['Soft Delete #2']); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_FORKED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'], + ), 'after forking #1'); + + $this->assert_forum_details($this->data['forums']['Soft Delete #2'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 1, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Soft Delete Topic #1'] + 2, + ), 'after forking #2'); + } + + public 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}"); + } + + public 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); + } + } +} diff --git a/tests/mock/search.php b/tests/mock/search.php new file mode 100644 index 0000000000..6739719216 --- /dev/null +++ b/tests/mock/search.php @@ -0,0 +1,23 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +*/ +class phpbb_mock_search +{ + + public function __construct($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) + { + } + + public function index_remove($post_ids, $poster_ids, $forum_ids) + { + } +} + diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 59daf6c9cb..4e564ce23c 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -96,6 +96,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case // Container $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->set('content.visibility', new phpbb_content_visibility($auth, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); $user_loader = new phpbb_user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index f27e339bb7..119851d525 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -870,6 +870,7 @@ class phpbb_functional_test_case extends phpbb_test_case * Be sure to login before creating * * @param int $forum_id + * @param int $topic_id * @param string $subject * @param string $message * @param array $additional_form_data Any additional form data to be sent in the request @@ -926,18 +927,47 @@ class phpbb_functional_test_case extends phpbb_test_case // Instead, I send it as a request with the submit button "post" set to true. $crawler = self::request('POST', $posting_url, $form_data); $this->assertContains($this->lang('POST_STORED'), $crawler->filter('html')->text()); - $url = $crawler->selectLink($this->lang('VIEW_MESSAGE', '', ''))->link()->getUri(); - $matches = $topic_id = $post_id = false; - preg_match_all('#&t=([0-9]+)(&p=([0-9]+))?#', $url, $matches); - - $topic_id = (int) (isset($matches[1][0])) ? $matches[1][0] : 0; - $post_id = (int) (isset($matches[3][0])) ? $matches[3][0] : 0; - return array( - 'topic_id' => $topic_id, - 'post_id' => $post_id, + 'topic_id' => $this->get_parameter_from_link($url, 't'), + 'post_id' => $this->get_parameter_from_link($url, 'p'), ); } + + /* + * Returns the requested parameter from a URL + * + * @param string $url + * @param string $parameter + * @return string Value of the parameter in the URL, null if not set + */ + public function get_parameter_from_link($url, $parameter) + { + if (strpos($url, '?') === false) + { + return null; + } + + $url_parts = explode('?', $url); + if (isset($url_parts[1])) + { + $url_parameters = $url_parts[1]; + if (strpos($url_parameters, '#') !== false) + { + $url_parameters = explode('#', $url_parameters); + $url_parameters = $url_parameters[0]; + } + + foreach (explode('&', $url_parameters) as $url_param) + { + list($param, $value) = explode('=', $url_param); + if ($param == $parameter) + { + return $value; + } + } + } + return null; + } } |