diff --git a/phpBB/adm/style/acp_users.html b/phpBB/adm/style/acp_users.html
index 34e4147356..da7d2a495b 100644
--- a/phpBB/adm/style/acp_users.html
+++ b/phpBB/adm/style/acp_users.html
@@ -83,6 +83,10 @@
+
+
+
+
diff --git a/phpBB/adm/style/acp_users_warnings.html b/phpBB/adm/style/acp_users_warnings.html
new file mode 100644
index 0000000000..be9ef06825
--- /dev/null
+++ b/phpBB/adm/style/acp_users_warnings.html
@@ -0,0 +1,39 @@
+
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 7fdbc5ac00..5f79341a14 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -199,6 +199,7 @@
[Feature] Detect when a post has been altered by someone else while editing. (Patch by bantu)
[Feature] Add unread posts quick search option (Bug #46765 - Patch by rxu)
[Feature] Add option to disable remote upload avatars (Bug #45375 - Patch by nickvergessen)
+ [Feature] Ability to delete warnings and keep warnings permanently (Bug #43375 - Patch by nickvergessen)
1.ii. Changes since 3.0.4
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 1cd7a405d5..d8fef3f547 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -1065,6 +1065,148 @@ class acp_users
break;
+ case 'warnings':
+ $user->add_lang('mcp');
+
+ // Set up general vars
+ $start = request_var('start', 0);
+ $deletemark = (isset($_POST['delmarked'])) ? true : false;
+ $deleteall = (isset($_POST['delall'])) ? true : false;
+ $confirm = (isset($_POST['confirm'])) ? true : false;
+ $marked = request_var('mark', array(0));
+ $message = utf8_normalize_nfc(request_var('message', '', true));
+
+ // Sort keys
+ $sort_days = request_var('st', 0);
+ $sort_key = request_var('sk', 't');
+ $sort_dir = request_var('sd', 'd');
+
+ // Delete entries if requested and able
+ if ($deletemark || $deleteall || $confirm)
+ {
+ if (confirm_box(true))
+ {
+ $where_sql = '';
+ $deletemark = request_var('delmarked', 0);
+ $deleteall = request_var('delall', 0);
+ if ($deletemark && $marked)
+ {
+ $sql_in = array();
+ foreach ($marked as $mark)
+ {
+ $sql_in[] = $mark;
+ }
+ $where_sql = ' AND ' . $db->sql_in_set('warning_id', $sql_in);
+ unset($sql_in);
+ }
+
+ if ($where_sql || $deleteall)
+ {
+ $sql = 'DELETE FROM ' . WARNINGS_TABLE . "
+ WHERE user_id = $user_id
+ $where_sql";
+ $db->sql_query($sql);
+
+ if ($deleteall)
+ {
+ $deleted_warnings = '0';
+ }
+ else
+ {
+ $deleted_warnings = ' user_warnings - ' . $db->sql_affectedrows();
+ }
+
+ $sql = 'UPDATE ' . USERS_TABLE . "
+ SET user_warnings = $deleted_warnings
+ WHERE user_id = $user_id";
+ $db->sql_query($sql);
+
+ add_log('admin', 'LOG_WARNING_DELETED', $user_row['username']);
+ }
+ }
+ else
+ {
+ $s_hidden_fields = array(
+ 'i' => $id,
+ 'mode' => $mode,
+ 'u' => $user_id,
+ 'mark' => $marked,
+ );
+ if (isset($_POST['delmarked']))
+ {
+ $s_hidden_fields['delmarked'] = 1;
+ }
+ if (isset($_POST['delall']))
+ {
+ $s_hidden_fields['delall'] = 1;
+ }
+ if (isset($_POST['delall']) || (isset($_POST['delmarked']) && sizeof($marked)))
+ {
+ confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
+ }
+ }
+ }
+
+ $sql = 'SELECT w.warning_id, w.warning_time, w.post_id, l.log_operation, l.log_data, l.user_id AS mod_user_id, m.username AS mod_username, m.user_colour AS mod_user_colour
+ FROM ' . WARNINGS_TABLE . ' w
+ LEFT JOIN ' . LOG_TABLE . ' l
+ ON (w.log_id = l.log_id)
+ LEFT JOIN ' . USERS_TABLE . ' m
+ ON (l.user_id = m.user_id)
+ WHERE w.user_id = ' . $user_id . '
+ ORDER BY w.warning_time DESC';
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ if (!$row['log_operation'])
+ {
+ // We do not have a log-entry anymore, so there is no data available
+ $row['action'] = $user->lang['USER_WARNING_LOG_DELETED'];
+ }
+ else
+ {
+ $row['action'] = (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}';
+ if (!empty($row['log_data']))
+ {
+ $log_data_ary = @unserialize($row['log_data']);
+ $log_data_ary = ($log_data_ary === false) ? array() : $log_data_ary;
+
+ if (isset($user->lang[$row['log_operation']]))
+ {
+ // Check if there are more occurrences of % than arguments, if there are we fill out the arguments array
+ // It doesn't matter if we add more arguments than placeholders
+ if ((substr_count($row['action'], '%') - sizeof($log_data_ary)) > 0)
+ {
+ $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($row['action'], '%') - sizeof($log_data_ary), ''));
+ }
+ $row['action'] = vsprintf($row['action'], $log_data_ary);
+ $row['action'] = bbcode_nl2br(censor_text($row['action']));
+ }
+ else if (!empty($log_data_ary))
+ {
+ $row['action'] .= '
' . implode('', $log_data_ary);
+ }
+ }
+ }
+
+
+ $template->assign_block_vars('warn', array(
+ 'ID' => $row['warning_id'],
+ 'USERNAME' => ($row['log_operation']) ? get_username_string('full', $row['mod_user_id'], $row['mod_username'], $row['mod_user_colour']) : '-',
+ 'ACTION' => make_clickable($row['action']),
+ 'DATE' => $user->format_date($row['warning_time']),
+ ));
+ }
+ $db->sql_freeresult($result);
+
+ $template->assign_vars(array(
+ 'S_WARNINGS' => true,
+ 'S_CLEARLOGS' => $auth->acl_get('a_clearlogs'),
+ ));
+
+ break;
+
case 'profile':
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
diff --git a/phpBB/includes/acp/info/acp_users.php b/phpBB/includes/acp/info/acp_users.php
index 0cd5f7ae97..10081ac870 100644
--- a/phpBB/includes/acp/info/acp_users.php
+++ b/phpBB/includes/acp/info/acp_users.php
@@ -22,6 +22,7 @@ class acp_users_info
'modes' => array(
'overview' => array('title' => 'ACP_MANAGE_USERS', 'auth' => 'acl_a_user', 'cat' => array('ACP_CAT_USERS')),
'feedback' => array('title' => 'ACP_USER_FEEDBACK', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')),
+ 'warnings' => array('title' => 'ACP_USER_WARNINGS', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')),
'profile' => array('title' => 'ACP_USER_PROFILE', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')),
'prefs' => array('title' => 'ACP_USER_PREFS', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')),
'avatar' => array('title' => 'ACP_USER_AVATAR', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')),
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 74f7e31bee..eaaa8aaf6a 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -4025,7 +4025,7 @@ function page_footer($run_cron = true)
// Tidy the cache
$cron_type = 'tidy_cache';
}
- else if (time() - $config['warnings_gc'] > $config['warnings_last_gc'])
+ else if ($config['warnings_last_gc'] && (time() - $config['warnings_gc'] > $config['warnings_last_gc']))
{
$cron_type = 'tidy_warnings';
}
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 31d7976033..e13bc1d546 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -1122,6 +1122,49 @@ function change_database_data(&$no_updates, $version)
}
}
+ // Also install the "User Warning" module
+ $sql = 'SELECT module_id
+ FROM ' . MODULES_TABLE . "
+ WHERE module_class = 'acp'
+ AND module_langname = 'ACP_USER_MANAGEMENT'
+ AND module_mode = ''
+ AND module_basename = ''";
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $category_id = (int) $row['module_id'];
+
+ // Check if we actually need to add the module or if it is already added. ;)
+ $sql = 'SELECT *
+ FROM ' . MODULES_TABLE . "
+ WHERE module_class = 'acp'
+ AND module_langname = 'ACP_USER_WARNINGS'
+ AND module_mode = 'warnings'
+ AND module_auth = 'acl_a_user'
+ AND parent_id = {$category_id}";
+ $result2 = $db->sql_query($sql);
+ $row2 = $db->sql_fetchrow($result2);
+ $db->sql_freeresult($result2);
+
+ if (!$row2)
+ {
+ $module_data = array(
+ 'module_basename' => 'users',
+ 'module_enabled' => 1,
+ 'module_display' => 0,
+ 'parent_id' => $category_id,
+ 'module_class' => 'acp',
+ 'module_langname' => 'ACP_USER_WARNINGS',
+ 'module_mode' => 'warnings',
+ 'module_auth' => 'acl_a_user',
+ );
+
+ $_module->update_module_data($module_data, true);
+ }
+ }
+ $db->sql_freeresult($result);
+
$_module->remove_cache_file();
// Add newly_registered group... but check if it already exists (we always supported running the updater on any schema)
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 720aba6002..9f69fe3790 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -186,6 +186,7 @@ $lang = array_merge($lang, array(
'ACP_USER_ROLES' => 'User roles',
'ACP_USER_SECURITY' => 'User security',
'ACP_USER_SIG' => 'Signature',
+ 'ACP_USER_WARNINGS' => 'Warnings',
'ACP_VC_SETTINGS' => 'Visual confirmation settings',
'ACP_VC_CAPTCHA_DISPLAY' => 'CAPTCHA image preview',
@@ -697,6 +698,7 @@ $lang = array_merge($lang, array(
'LOG_USER_REACTIVATE_USER' => 'Forced user account reactivation',
'LOG_USER_UNLOCK' => 'User unlocked own topic
» %s',
'LOG_USER_WARNING' => 'Added user warning
» %s',
+ 'LOG_WARNING_DELETED' => 'Deleted user warning
» %s',
'LOG_USER_WARNING_BODY' => 'The following warning was issued to this user
» %s',
'LOG_USER_GROUP_CHANGE' => 'User changed default group
» %s',
diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php
index d2e09f43e7..a2d1b3911c 100644
--- a/phpBB/language/en/acp/users.php
+++ b/phpBB/language/en/acp/users.php
@@ -77,6 +77,7 @@ $lang = array_merge($lang, array(
'MOVE_POSTS_EXPLAIN' => 'Please select the forum to which you wish to move all the posts this user has made.',
'NO_SPECIAL_RANK' => 'No special rank assigned',
+ 'NO_WARNINGS' => 'No warnings.',
'NOT_MANAGE_FOUNDER' => 'You tried to manage a user with founder status. Only founders are allowed to manage other founders.',
'QUICK_TOOLS' => 'Quick tools',
@@ -130,6 +131,7 @@ $lang = array_merge($lang, array(
'USER_RANK' => 'User rank',
'USER_RANK_UPDATED' => 'User rank updated.',
'USER_SIG_UPDATED' => 'User signature successfully updated.',
+ 'USER_WARNING_LOG_DELETED' => 'No information available. Possibly the log entry has been deleted.',
'USER_TOOLS' => 'Basic tools',
));