diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 99b23e9db1..6756e19078 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,14 +108,18 @@ class mcp_main
case 'delete_topic':
$user->add_lang('viewtopic');
+ // 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_var('f', 0);
$topic_ids = (!$quickmod) ? request_var('topic_id_list', array(0)) : array(request_var('t', 0));
+ $soft_delete = (($auth->acl_get('m_softdelete', $forum_id) && $request->is_set_post('soft_delete')) || !$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_var('delete_reason', '', true) : '');
break;
case 'delete_post':
@@ -130,6 +134,19 @@ class mcp_main
mcp_delete_post($post_ids);
break;
+
+ case 'restore_topic':
+ $user->add_lang('posting');
+
+ $topic_ids = (!$quickmod) ? request_var('topic_id_list', array(0)) : array(request_var('t', 0));
+
+ if (!sizeof($topic_ids))
+ {
+ trigger_error('NO_TOPIC_SELECTED');
+ }
+
+ mcp_restore_topic($topic_ids);
+ break;
}
switch ($mode)
@@ -628,10 +645,82 @@ function mcp_move_topic($topic_ids)
}
}
+/**
+* Restore Topics
+*/
+function mcp_restore_topic($topic_ids)
+{
+ global $auth, $user, $db, $phpEx, $phpbb_root_path;
+
+ if (!check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_approve')))
+ {
+ return;
+ }
+
+ $redirect = request_var('redirect', build_url(array('action', 'quickmod')));
+ $forum_id = request_var('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);
+
+ 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_var('t', 0);
+ if (!isset($_REQUEST['quickmod']))
+ {
+ $redirect = request_var('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] . '
' . sprintf($user->lang['RETURN_' . $redirect_message], '', ''));
+ }
+}
+
/**
* Delete Topics
*/
-function mcp_delete_topic($topic_ids)
+function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = '')
{
global $auth, $user, $db, $phpEx, $phpbb_root_path;
@@ -647,8 +736,8 @@ function mcp_delete_topic($topic_ids)
'topic_id_list' => $topic_ids,
'f' => $forum_id,
'action' => 'delete_topic',
- 'redirect' => $redirect)
- );
+ 'redirect' => $redirect,
+ ));
$success_msg = '';
if (confirm_box(true))
@@ -665,23 +754,55 @@ 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)
+ {
+ $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');
+
+ $template->assign_vars(array(
+ '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),
+ ));
+
+ confirm_box(false, (sizeof($topic_ids) == 1) ? 'DELETE_TOPIC' : 'DELETE_TOPICS', $s_hidden_fields, 'posting_delete_post_body.html');
}
+ $topic_id = request_var('t', 0);
if (!isset($_REQUEST['quickmod']))
{
$redirect = request_var('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);
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 91a35311bc..a2fe426415 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -554,9 +554,12 @@ $lang = array_merge($lang, array(
'LOG_POST_APPROVED' => 'Approved post
» %s',
'LOG_POST_DISAPPROVED' => 'Disapproved post “%1$s” with the following reason
» %2$s',
'LOG_POST_EDITED' => 'Edited post “%1$s” written by
» %2$s',
- 'LOG_POST_RESTORED' => 'Restored post
» %s',
+ 'LOG_POST_RESTORED' => 'Restored post
» %s',
'LOG_REPORT_CLOSED' => 'Closed report
» %s',
'LOG_REPORT_DELETED' => 'Deleted report
» %s',
+ 'LOG_RESTORE_TOPIC' => 'Restored topic “%1$s” written by
» %2$s',
+ 'LOG_SOFTDELETE_POST' => 'Soft deleted post “%1$s” written by
» %2$s',
+ 'LOG_SOFTDELETE_TOPIC' => 'Soft deleted topic “%1$s” written by
» %2$s',
'LOG_SPLIT_DESTINATION' => 'Moved split posts
» to %s',
'LOG_SPLIT_SOURCE' => 'Split posts
» from %s',
diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php
index a57a907423..10e1d48d38 100644
--- a/phpBB/language/en/posting.php
+++ b/phpBB/language/en/posting.php
@@ -82,6 +82,8 @@ $lang = array_merge($lang, array(
'DELETE_POST_SOFT_EXP' => 'Soft deleted posts can be recovered by a moderator',
'DELETE_POST_REASON' => 'Soft delete reason',
'DELETE_POST_WARN' => 'Once deleted the post cannot be recovered',
+ 'DELETE_TOPIC_SOFT' => 'Soft delete topic',
+ 'DELETE_TOPIC_SOFT_EXP' => 'Soft deleted topics can be recovered by a moderator',
'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 a5739a6586..4e78bcfde3 100644
--- a/phpBB/language/en/viewtopic.php
+++ b/phpBB/language/en/viewtopic.php
@@ -98,7 +98,8 @@ $lang = array_merge($lang, array(
'QUOTE' => 'Quote',
'REPLY_TO_TOPIC' => 'Reply to topic',
- 'RESTORE' => 'Restore',
+ '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 d322aacb2f..4c87838306 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;
diff --git a/phpBB/posting.php b/phpBB/posting.php
index f82ae049dc..d1c48b38b0 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -1565,14 +1565,14 @@ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_sof
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'] . '
' . sprintf($user->lang['RETURN_TOPIC'], '', '');
diff --git a/phpBB/styles/prosilver/template/posting_delete_post_body.html b/phpBB/styles/prosilver/template/posting_delete_post_body.html
index 4c69d1d9bc..967ecaca78 100644
--- a/phpBB/styles/prosilver/template/posting_delete_post_body.html
+++ b/phpBB/styles/prosilver/template/posting_delete_post_body.html
@@ -9,7 +9,12 @@