mirror of
https://github.com/phpbb/phpbb.git
synced 2025-05-04 06:39:14 +02:00
[feature/soft-delete] Update post counts within set_post_visibility
This is an additional query in some rare cases, but it makes it much easier to use and understand. This is mostly a preparation for the restore case. PHPBB3-9567
This commit is contained in:
parent
91398c9e48
commit
53e01bba19
@ -155,81 +155,6 @@ class phpbb_content_visibility
|
||||
return $where_sqls[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void
|
||||
*/
|
||||
static public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
|
||||
{
|
||||
global $db;
|
||||
|
||||
if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$force_update_all)
|
||||
{
|
||||
$sql = 'SELECT topic_visibility, topic_delete_time
|
||||
FROM ' . TOPICS_TABLE . '
|
||||
WHERE topic_id = ' . (int) $topic_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$original_topic_data = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$original_topic_data)
|
||||
{
|
||||
// The topic does not exist...
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ' . TOPICS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $data) . '
|
||||
WHERE topic_id = ' . (int) $topic_id;
|
||||
$db->sql_query($sql);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change visibility status of one post or all posts of a topic
|
||||
*
|
||||
@ -245,7 +170,7 @@ class phpbb_content_visibility
|
||||
* @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 void
|
||||
* @return array Changed post data, empty array if an error occured.
|
||||
*/
|
||||
static 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)
|
||||
{
|
||||
@ -253,7 +178,7 @@ class phpbb_content_visibility
|
||||
|
||||
if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
|
||||
{
|
||||
return;
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($post_id)
|
||||
@ -266,8 +191,9 @@ class phpbb_content_visibility
|
||||
{
|
||||
$where_sql = 'post_id = ' . (int) $post_id;
|
||||
}
|
||||
$where_sql .= ' AND topic_id = ' . (int) $topic_id;
|
||||
}
|
||||
else if ($topic_id)
|
||||
else
|
||||
{
|
||||
$where_sql = 'topic_id = ' . (int) $topic_id;
|
||||
|
||||
@ -284,9 +210,43 @@ class phpbb_content_visibility
|
||||
$where_sql .= ' AND post_delete_time = ' . (int) $limit_delete_time;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
$sql = 'SELECT poster_id, post_id, post_postcount, post_visibility
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE ' . $where_sql;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$post_ids = $poster_postcounts = $postcounts = $postcount_visibility = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
return;
|
||||
$post_ids[] = (int) $row['post_id'];
|
||||
|
||||
if ($row['post_visibility'] != $visibility)
|
||||
{
|
||||
if ($row['post_postcount'] && !isset($poster_postcounts[$row['poster_id']]))
|
||||
{
|
||||
$poster_postcounts[$row['poster_id']] = 1;
|
||||
}
|
||||
else if ($row['post_postcount'])
|
||||
{
|
||||
$poster_postcounts[$row['poster_id']]++;
|
||||
}
|
||||
|
||||
if (!isset($postcount_visibility[$row['post_visibility']]))
|
||||
{
|
||||
$postcount_visibility[$row['post_visibility']] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$postcount_visibility[$row['post_visibility']]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (empty($post_ids))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = array(
|
||||
@ -298,9 +258,44 @@ class phpbb_content_visibility
|
||||
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $data) . '
|
||||
WHERE ' . $where_sql;
|
||||
WHERE ' . $db->sql_in_set('post_id', $post_ids);
|
||||
$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 ' . USERS_TABLE . '
|
||||
SET user_posts = 0
|
||||
WHERE ' . $db->sql_in_set('user_id', $poster_ids) . '
|
||||
AND user_posts < ' . $num_posts;
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET user_posts = user_posts - ' . $num_posts . '
|
||||
WHERE ' . $db->sql_in_set('user_id', $poster_ids) . '
|
||||
AND user_posts >= ' . $num_posts;
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET user_posts = user_posts + ' . $num_posts . '
|
||||
WHERE ' . $db->sql_in_set('user_id', $poster_ids) . '
|
||||
AND user_posts >= ' . $num_posts;
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
|
||||
$update_topic_postcount = true;
|
||||
|
||||
// Sync the first/last topic information if needed
|
||||
if (!$is_starter && $is_latest)
|
||||
{
|
||||
@ -319,7 +314,171 @@ class phpbb_content_visibility
|
||||
// ... 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)
|
||||
{
|
||||
$num_posts = 0;
|
||||
foreach ($postcount_visibility as $post_visibility => $visibility_posts)
|
||||
{
|
||||
// If we soft delete, we need to substract approved posts from the counters ...
|
||||
if ($post_visibility == ITEM_APPROVED && $visibility == ITEM_DELETED)
|
||||
{
|
||||
$num_posts += $visibility_posts;
|
||||
}
|
||||
// ... and when we approve/restore, all others.
|
||||
else if ($post_visibility != ITEM_APPROVED && $visibility == ITEM_APPROVED)
|
||||
{
|
||||
$num_posts += $visibility_posts;
|
||||
}
|
||||
}
|
||||
|
||||
if ($num_posts)
|
||||
{
|
||||
$sql_num_posts = (($visibility == ITEM_DELETED) ? ' - ' : ' + ') . $num_posts;
|
||||
|
||||
// Update the number for replies and posts
|
||||
$sql = 'UPDATE ' . TOPICS_TABLE . "
|
||||
SET topic_replies = topic_replies $sql_num_posts
|
||||
WHERE topic_id = $topic_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . FORUMS_TABLE . "
|
||||
SET forum_posts = forum_posts $sql_num_posts
|
||||
WHERE forum_id = $forum_id";
|
||||
$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.
|
||||
*/
|
||||
static public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
|
||||
{
|
||||
global $db;
|
||||
|
||||
if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!$force_update_all)
|
||||
{
|
||||
$sql = 'SELECT topic_visibility, topic_delete_time
|
||||
FROM ' . TOPICS_TABLE . '
|
||||
WHERE topic_id = ' . (int) $topic_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$original_topic_data = $db->sql_fetchrow($result);
|
||||
$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 ' . TOPICS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $data) . '
|
||||
WHERE topic_id = ' . (int) $topic_id;
|
||||
$db->sql_query($sql);
|
||||
|
||||
if (!$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
|
||||
*/
|
||||
static public function add_post_to_statistic($data, &$sql_data)
|
||||
{
|
||||
$sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_replies = topic_replies + 1';
|
||||
|
||||
$sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts = forum_posts + 1';
|
||||
|
||||
if ($data['post_postcount'])
|
||||
{
|
||||
$sql_data[USERS_TABLE] = (($sql_data[USERS_TABLE]) ? $sql_data[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
|
||||
*/
|
||||
static public function remove_post_from_statistic($data, &$sql_data)
|
||||
{
|
||||
$sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_replies = topic_replies - 1';
|
||||
|
||||
$sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts = forum_posts - 1';
|
||||
|
||||
if ($data['post_postcount'])
|
||||
{
|
||||
$sql_data[USERS_TABLE] = (($sql_data[USERS_TABLE]) ? $sql_data[USERS_TABLE] . ', ' : '') . 'user_posts = user_posts - 1';
|
||||
}
|
||||
|
||||
set_config_count('num_posts', -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,28 +525,6 @@ class phpbb_content_visibility
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove post from topic and forum statistics
|
||||
*
|
||||
* @param $forum_id int Forum where the topic is found
|
||||
* @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
|
||||
*/
|
||||
static public function remove_post_from_statistic($forum_id, $data, &$sql_data)
|
||||
{
|
||||
$sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_replies = topic_replies - 1';
|
||||
|
||||
$sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts = forum_posts - 1';
|
||||
|
||||
if ($data['post_postcount'])
|
||||
{
|
||||
$sql_data[USERS_TABLE] = (($sql_data[USERS_TABLE]) ? $sql_data[USERS_TABLE] . ', ' : '') . 'user_posts = user_posts - 1';
|
||||
}
|
||||
|
||||
set_config_count('num_posts', -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* One function to rule them all... and unhide posts and topics. This could
|
||||
* reasonably be broken up, I straight copied this code from the mcp_queue.php
|
||||
|
@ -1601,21 +1601,19 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
|
||||
break;
|
||||
}
|
||||
|
||||
if (($post_mode == 'delete') || ($post_mode == 'delete_last_post') || ($post_mode == 'delete_first_post' && !$is_soft))
|
||||
{
|
||||
if ($data['post_visibility'] == ITEM_APPROVED)
|
||||
{
|
||||
phpbb_content_visibility::remove_post_from_statistic($forum_id, $data, $sql_data);
|
||||
}
|
||||
|
||||
if (!$is_soft)
|
||||
{
|
||||
$sql_data[TOPICS_TABLE] .= ', topic_replies_real = topic_replies_real - 1';
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_replies_real = topic_replies_real - 1';
|
||||
}
|
||||
|
||||
$sql = 'SELECT 1 AS has_attachments
|
||||
FROM ' . ATTACHMENTS_TABLE . '
|
||||
WHERE topic_id = ' . $topic_id;
|
||||
@ -1625,7 +1623,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1969,7 +1967,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
|
||||
// Correctly set back the topic replies and forum posts... but only if the post was approved before.
|
||||
if (!$post_approval && $data['post_visibility'] == ITEM_APPROVED)
|
||||
{
|
||||
//phpbb_content_visibility::remove_post_from_statistic($forum_id, $current_time, $sql_data);
|
||||
//phpbb_content_visibility::remove_post_from_statistic($current_time, $sql_data);
|
||||
// ^^ remove_post_from_statistic SQL is identical, except that it does not include the ['stat'] sub-array
|
||||
$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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user