| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Provides an interim step between account blocking and account deletion.
|
| 7 |
*/
|
| 8 |
|
| 9 |
define('USER_SUSPEND_DEFAULT_EMAIL', '!username,
|
| 10 |
|
| 11 |
Your account on !site has been suspended. You will not be able to login with your username or password until the account is reinstated.
|
| 12 |
|
| 13 |
|
| 14 |
-- !site team');
|
| 15 |
define('USER_SUSPEND_REINSTATE_EMAIL', '!username,
|
| 16 |
|
| 17 |
Your account on !site has been reinstated. You will now be able to login with your previous username or password.
|
| 18 |
|
| 19 |
|
| 20 |
-- !site team');
|
| 21 |
|
| 22 |
/**
|
| 23 |
* Implementation of hook_help().
|
| 24 |
*/
|
| 25 |
function user_suspend_help($section) {
|
| 26 |
switch ($section) {
|
| 27 |
case 'admin/modules#description':
|
| 28 |
return t('Provides an interim step between account blocking and account deletion.');
|
| 29 |
|
| 30 |
case 'admin/help#user_suspend':
|
| 31 |
return '<p>' . t('User Suspend provides an interim step between account blocking and account deletion. Unlike setting a user\'s status to Blocked, the user record, user roles and optionally user-created nodes and comments are transferred to separate tables where they are not accessible by the normal Drupal system. Users can be suspended via Update options on the !user_list and viewed on the !user_suspend_list.', array('!user_list' => l('Users list', 'admin/user/user'), '!user_suspend_list' => l('Suspended Users list', 'admin/user/user/suspend'))) . '</p><p>' . t('Suspended users can not login to their accounts, nor can they create new accounts with the same user ID or email address. Suspended users can be reinstated at any time, recovering all of their previous settings, roles, nodes and comments. Deleting suspended users will completely remove the user accounts and user-created nodes and comments from the system. Once deleted, a user will be able to create a new account with the same user ID and/or email address.') . "</p>\n";
|
| 32 |
|
| 33 |
case 'admin/user/settings/user_suspend':
|
| 34 |
return t('User Suspend provides an interim step between account blocking and account deletion. Unlike setting a user\'s status to Blocked, the user record, user roles and optionally user-created nodes and comments are transferred to separate tables where they are not accessible by the normal Drupal system. Users can be suspended via Update options on the !user_list and viewed on the !user_suspend_list.', array('!user_list' => l('Users list', 'admin/user/user'), '!user_suspend_list' => l('Suspended Users list', 'admin/user/user/suspend')));
|
| 35 |
|
| 36 |
case 'admin/user/user/suspend':
|
| 37 |
return t('Suspended users can not login to their accounts, nor can they create new accounts with the same user ID or email address. Suspended users can be reinstated at any time, recovering all of their previous settings, roles, nodes and comments. Deleting suspended users will completely remove the user accounts and user-created nodes and comments from the system. Once deleted, a user will be able to create a new account with the same user ID and/or email address.');
|
| 38 |
}
|
| 39 |
}
|
| 40 |
|
| 41 |
/**
|
| 42 |
* Implementation of hook_menu().
|
| 43 |
*
|
| 44 |
*/
|
| 45 |
function user_suspend_menu($may_cache) {
|
| 46 |
$items = array();
|
| 47 |
if ($may_cache) {
|
| 48 |
$items[] = array(
|
| 49 |
'path' => 'admin/user/settings/user_suspend',
|
| 50 |
'title' => 'User suspend',
|
| 51 |
'description' => t('Provides an interim step between account blocking and account deletion.'),
|
| 52 |
'callback' => 'drupal_get_form',
|
| 53 |
'callback arguments' => 'user_suspend_admin_settings',
|
| 54 |
'type' => MENU_NORMAL_ITEM,
|
| 55 |
'access' => user_access('administer site configuration'), //do we *really* need yet another permission??
|
| 56 |
);
|
| 57 |
$items[] = array(
|
| 58 |
'path' => 'admin/user/user/suspend',
|
| 59 |
'title' => t('Suspended Users'),
|
| 60 |
'callback' => 'drupal_get_form',
|
| 61 |
'callback arguments' => 'user_suspend_admin',
|
| 62 |
'access' => user_access('administer users'),
|
| 63 |
'type' => MENU_LOCAL_TASK,
|
| 64 |
'weight' => -9
|
| 65 |
);
|
| 66 |
|
| 67 |
}
|
| 68 |
return $items;
|
| 69 |
}
|
| 70 |
|
| 71 |
/**
|
| 72 |
* Menu callback
|
| 73 |
*
|
| 74 |
* @return
|
| 75 |
* array of form content.
|
| 76 |
*/
|
| 77 |
function user_suspend_admin_settings() {
|
| 78 |
_user_suspend_schema_diff();
|
| 79 |
|
| 80 |
$form['user_suspend_remove_nodes'] = array(
|
| 81 |
'#type' => 'checkbox',
|
| 82 |
'#title' => t('Remove user nodes?'),
|
| 83 |
'#default_value' => variable_get('user_suspend_remove_nodes', 1),
|
| 84 |
'#description' => t('If enabled, nodes created by the suspended user will be removed from the node table, but can be restored if a user is ever reinstated. If disabled, nodes created by the suspended user will remain in the nodes table, but be permanently orphaned (uid set to 0).')
|
| 85 |
);
|
| 86 |
$form['user_suspend_remove_comments'] = array(
|
| 87 |
'#type' => 'checkbox',
|
| 88 |
'#title' => t('Remove user comments?'),
|
| 89 |
'#default_value' => variable_get('user_suspend_remove_comments', 1),
|
| 90 |
'#description' => t('If enabled, comments created by the suspended user will be removed from the comments table, but can be restored if a user is ever reinstated. If disabled, comments created by the suspended user will remain in the comments table, but be permanently orphaned (uid set to 0).')
|
| 91 |
);
|
| 92 |
|
| 93 |
$form['suspend'] = array('#type' => 'fieldset', '#title' => t('User suspend e-mail settings'));
|
| 94 |
$form['suspend']['user_suspend_email_suspend'] = array(
|
| 95 |
'#type' => 'checkbox',
|
| 96 |
'#title' => t('Send email on user suspend?'),
|
| 97 |
'#default_value' => variable_get('user_suspend_email_suspend', 0),
|
| 98 |
);
|
| 99 |
$form['suspend']['user_suspend_email_suspend_subject'] = array(
|
| 100 |
'#type' => 'textfield',
|
| 101 |
'#title' => t('Subject of user suspend e-mail'),
|
| 102 |
'#default_value' => variable_get('user_suspend_email_suspend_subject', 'Account suspended for !username at !site'),
|
| 103 |
'#description' => t('Customize the subject of your user suspend e-mail. Available variables are: !username, !site, !uri, !login_url, !mailto, !date.'),
|
| 104 |
);
|
| 105 |
$form['suspend']['user_suspend_email_suspend_body'] = array(
|
| 106 |
'#type' => 'textarea',
|
| 107 |
'#title' => t('Body of user suspend e-mail'),
|
| 108 |
'#rows' => 8,
|
| 109 |
'#cols' => 60,
|
| 110 |
'#default_value' => variable_get('user_suspend_email_suspend_body', USER_SUSPEND_DEFAULT_EMAIL),
|
| 111 |
'#description' => t('Customize the body of your user suspend e-mail. Available variables are: !username, !site, !uri, !login_url, !mailto, !date.'),
|
| 112 |
);
|
| 113 |
|
| 114 |
$form['reinstate'] = array('#type' => 'fieldset', '#title' => t('User reinstate e-mail settings'));
|
| 115 |
$form['reinstate']['user_suspend_email_reinstate'] = array(
|
| 116 |
'#type' => 'checkbox',
|
| 117 |
'#title' => t('Send email on user reinstate?'),
|
| 118 |
'#default_value' => variable_get('user_suspend_email_reinstate', 0),
|
| 119 |
);
|
| 120 |
$form['reinstate']['user_suspend_email_reinstate_subject'] = array(
|
| 121 |
'#type' => 'textfield',
|
| 122 |
'#title' => t('Subject of user reinstate e-mail'),
|
| 123 |
'#default_value' => variable_get('user_suspend_email_reinstate_subject', 'Account reinstated for !username at !site'),
|
| 124 |
'#description' => t('Customize the subject of your user reinstate e-mail. Available variables are: !username, !site, !uri, !login_url, !mailto, !date.'),
|
| 125 |
);
|
| 126 |
$form['reinstate']['user_suspend_email_reinstate_body'] = array(
|
| 127 |
'#type' => 'textarea',
|
| 128 |
'#title' => t('Body of user reinstate e-mail'),
|
| 129 |
'#rows' => 8,
|
| 130 |
'#cols' => 60,
|
| 131 |
'#default_value' => variable_get('user_suspend_email_reinstate_body', USER_SUSPEND_REINSTATE_EMAIL),
|
| 132 |
'#description' => t('Customize the body of your user reinstate e-mail. Available variables are: !username, !site, !uri, !login_url, !mailto, !date.'),
|
| 133 |
);
|
| 134 |
|
| 135 |
return system_settings_form($form);
|
| 136 |
}
|
| 137 |
|
| 138 |
/**
|
| 139 |
* Theme user administration overview.
|
| 140 |
*/
|
| 141 |
function theme_user_suspend_admin($form) {
|
| 142 |
// Overview table:
|
| 143 |
$header = array(
|
| 144 |
theme('table_select_header_cell'),
|
| 145 |
array('data' => t('Username'), 'field' => 'u.name'),
|
| 146 |
array('data' => t('Email'), 'field' => 'u.mail'),
|
| 147 |
t('Roles'),
|
| 148 |
t('Nodes'),
|
| 149 |
t('Comments'),
|
| 150 |
array('data' => t('Suspended'), 'field' => 'r.suspended', 'sort' => 'desc')
|
| 151 |
);
|
| 152 |
|
| 153 |
$output = drupal_render($form['options']);
|
| 154 |
if (isset($form['name']) && is_array($form['name'])) {
|
| 155 |
foreach (element_children($form['name']) as $key) {
|
| 156 |
$rows[] = array(
|
| 157 |
drupal_render($form['accounts'][$key]),
|
| 158 |
drupal_render($form['name'][$key]),
|
| 159 |
drupal_render($form['mail'][$key]),
|
| 160 |
drupal_render($form['roles'][$key]),
|
| 161 |
drupal_render($form['nodes'][$key]),
|
| 162 |
drupal_render($form['comments'][$key]),
|
| 163 |
drupal_render($form['suspended'][$key]),
|
| 164 |
);
|
| 165 |
}
|
| 166 |
}
|
| 167 |
else {
|
| 168 |
$rows[] = array(array('data' => t('No suspended users available.'), 'colspan' => '8'));
|
| 169 |
}
|
| 170 |
|
| 171 |
$output .= theme('table', $header, $rows);
|
| 172 |
if ($form['pager']['#value']) {
|
| 173 |
$output .= drupal_render($form['pager']);
|
| 174 |
}
|
| 175 |
|
| 176 |
$output .= drupal_render($form);
|
| 177 |
|
| 178 |
return $output;
|
| 179 |
}
|
| 180 |
|
| 181 |
/**
|
| 182 |
* Implementation of hook_user_operations().
|
| 183 |
*
|
| 184 |
* Suspend selected users.
|
| 185 |
*/
|
| 186 |
function user_suspend_user_operations() {
|
| 187 |
global $form_values;
|
| 188 |
if (!user_access('administer users')) return;
|
| 189 |
$operations = array(
|
| 190 |
'suspend' => array(
|
| 191 |
'label' => t('Suspend the selected users'),
|
| 192 |
'callback' => 'user_suspend_operations_suspend',
|
| 193 |
),
|
| 194 |
);
|
| 195 |
return $operations;
|
| 196 |
}
|
| 197 |
|
| 198 |
/**
|
| 199 |
* Callback function for admin mass suspending users.
|
| 200 |
*/
|
| 201 |
function user_suspend_operations_suspend($accounts) {
|
| 202 |
global $user;
|
| 203 |
|
| 204 |
if (count($accounts)) {
|
| 205 |
foreach ($accounts as $uid) {
|
| 206 |
if ($uid == $user->uid) {
|
| 207 |
drupal_set_message(t('You cannot suspend your own account.'), 'error');
|
| 208 |
continue;
|
| 209 |
}
|
| 210 |
|
| 211 |
if ($user_name = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', (int)$uid))) {
|
| 212 |
if (_user_suspend_user($uid)) {
|
| 213 |
drupal_set_message(t('Suspended user: %user.', array('%user' => $user_name)));
|
| 214 |
}
|
| 215 |
else {
|
| 216 |
drupal_set_message(t('%user cannot be suspended.', array('%user' => $user_name)), 'error');
|
| 217 |
}
|
| 218 |
}
|
| 219 |
}
|
| 220 |
}
|
| 221 |
else {
|
| 222 |
drupal_set_message(t('No accounts selected to suspend.'), 'error');
|
| 223 |
}
|
| 224 |
}
|
| 225 |
|
| 226 |
/**
|
| 227 |
* Menu callback
|
| 228 |
*
|
| 229 |
* @return
|
| 230 |
* array of form content.
|
| 231 |
*/
|
| 232 |
function user_suspend_admin() {
|
| 233 |
_user_suspend_schema_diff();
|
| 234 |
|
| 235 |
$header = array(
|
| 236 |
array(),
|
| 237 |
array('data' => t('Username'), 'field' => 'u.name'),
|
| 238 |
array('data' => t('Email'), 'field' => 'u.mail'),
|
| 239 |
t('Roles'),
|
| 240 |
t('Nodes'),
|
| 241 |
t('Comments'),
|
| 242 |
array('data' => t('Suspended'), 'field' => 'r.suspended', 'sort' => 'desc')
|
| 243 |
);
|
| 244 |
|
| 245 |
$sql = 'SELECT DISTINCT u.uid, u.name, u.mail, r.suspended, COUNT(n.nid) as nodes, COUNT(c.cid) as comments
|
| 246 |
FROM {user_suspend_users} u
|
| 247 |
LEFT JOIN {user_suspend} r USING (uid)
|
| 248 |
LEFT JOIN {user_suspend_users_roles} ur USING (uid)
|
| 249 |
LEFT JOIN {user_suspend_node} n USING (uid)
|
| 250 |
LEFT JOIN {user_suspend_comments} c USING (uid)
|
| 251 |
WHERE u.uid != 0 GROUP BY uid';
|
| 252 |
$sql .= tablesort_sql($header);
|
| 253 |
$query_count = 'SELECT COUNT(DISTINCT u.uid) FROM {user_suspend_users} u WHERE u.uid != 0';
|
| 254 |
$result = pager_query($sql, 50, 0, $query_count);
|
| 255 |
|
| 256 |
$roles = user_roles(1);
|
| 257 |
|
| 258 |
while ($account = db_fetch_object($result)) {
|
| 259 |
$accounts[$account->uid] = '';
|
| 260 |
$form['name'][$account->uid] = array('#value' => $account->name);
|
| 261 |
$form['mail'][$account->uid] = array('#value' => $account->mail);
|
| 262 |
$users_roles = array();
|
| 263 |
$roles_result = db_query('SELECT rid FROM {user_suspend_users_roles} WHERE uid = %d', $account->uid);
|
| 264 |
while ($user_role = db_fetch_object($roles_result)) {
|
| 265 |
$users_roles[] = $roles[$user_role->rid];
|
| 266 |
}
|
| 267 |
asort($users_roles);
|
| 268 |
$form['roles'][$account->uid][0] = array('#value' => theme('item_list', $users_roles));
|
| 269 |
$form['nodes'][$account->uid] = array('#value' => $account->nodes);
|
| 270 |
$form['comments'][$account->uid] = array('#value' => $account->comments);
|
| 271 |
$form['suspended'][$account->uid] = array('#value' => $account->suspended ? t('@time ago', array('@time' => format_interval(time() - $account->suspended))) : t('never'));
|
| 272 |
}
|
| 273 |
$form['accounts'] = array(
|
| 274 |
'#type' => 'checkboxes',
|
| 275 |
'#options' => $accounts
|
| 276 |
);
|
| 277 |
|
| 278 |
$form['reinstate'] = array(
|
| 279 |
'#type' => 'button',
|
| 280 |
'#value' => t('Reinstate Users'),
|
| 281 |
);
|
| 282 |
$form['delete'] = array(
|
| 283 |
'#type' => 'button',
|
| 284 |
'#value' => t('Delete Users'),
|
| 285 |
);
|
| 286 |
$form['pager'] = array('#value' => theme('pager', NULL, 50));
|
| 287 |
|
| 288 |
return $form;
|
| 289 |
}
|
| 290 |
|
| 291 |
/**
|
| 292 |
* Validation of user suspend admin form.
|
| 293 |
*
|
| 294 |
* @param $form_id
|
| 295 |
* The unique string identifying the form.
|
| 296 |
* @param $form_values
|
| 297 |
* An array of values mirroring the values returned by the form
|
| 298 |
* when it is submitted by a user.
|
| 299 |
*
|
| 300 |
* @return
|
| 301 |
* Any form validation errors encountered.
|
| 302 |
*/
|
| 303 |
function user_suspend_admin_validate($form_id, $form_values) {
|
| 304 |
global $base_url;
|
| 305 |
$time = time();
|
| 306 |
$users_selected = array();
|
| 307 |
foreach ($form_values['accounts'] as $uid => $value) {
|
| 308 |
if ($value) {
|
| 309 |
if ((int)$uid > 1) {
|
| 310 |
$users_selected[] = $uid;
|
| 311 |
}
|
| 312 |
}
|
| 313 |
}
|
| 314 |
if (!sizeof($users_selected)) {
|
| 315 |
form_set_error('', t('No users selected.'));
|
| 316 |
return;
|
| 317 |
}
|
| 318 |
|
| 319 |
$delete = ($_POST['op'] == t('Delete Users')) ? true : false;
|
| 320 |
foreach ($users_selected as $uid) {
|
| 321 |
$user = db_fetch_array(db_query('SELECT name, mail FROM {user_suspend_users} WHERE uid = %d', $uid));
|
| 322 |
$message = array('%user' => $user['name'], '%email' => '<'. $user['mail'] .'>');
|
| 323 |
//sanity check
|
| 324 |
$user_exists = db_result(db_query('SELECT uid FROM {users} WHERE uid = %d', $uid));
|
| 325 |
if (!$user_exists) {
|
| 326 |
if (_user_suspend_copy_table($uid, 'users')) {
|
| 327 |
if (_user_suspend_copy_table($uid, 'users_roles')) {
|
| 328 |
|
| 329 |
//nodes cannot be loaded without a valid user object!
|
| 330 |
$result_nodes_delete = false;
|
| 331 |
if (db_num_rows(db_query("SELECT * FROM {user_suspend_node} WHERE uid = %d", $uid))) { //nodes to work with
|
| 332 |
if (variable_get('user_suspend_remove_nodes', 1)) { //enable remove nodes
|
| 333 |
if (_user_suspend_copy_table($uid, 'node')) {
|
| 334 |
$result_nodes_delete = true;
|
| 335 |
if ($delete) {
|
| 336 |
$result = db_query("SELECT nid FROM {user_suspend_node} WHERE uid = %d", $uid);
|
| 337 |
while ($row = db_fetch_object($result)) {
|
| 338 |
node_delete($row->nid);
|
| 339 |
}
|
| 340 |
}
|
| 341 |
//delete user_suspend tables
|
| 342 |
db_query('DELETE FROM {user_suspend_node} WHERE uid = %d', $uid);
|
| 343 |
}
|
| 344 |
else {
|
| 345 |
drupal_set_message(t('%user nodes cannot be saved.', $message));
|
| 346 |
}
|
| 347 |
}
|
| 348 |
}
|
| 349 |
|
| 350 |
//comments cannot be loaded without a valid user object!
|
| 351 |
$result_comments_delete = false;
|
| 352 |
if (db_num_rows(db_query("SELECT * FROM {user_suspend_comments} WHERE uid = %d", $uid))) { //comments to work with
|
| 353 |
if (variable_get('user_suspend_remove_comments', 1)) { //enable remove comments
|
| 354 |
if (_user_suspend_copy_table($uid, 'comments')) {
|
| 355 |
$result_comments_delete = true;
|
| 356 |
if ($delete) {
|
| 357 |
$query = db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {user_suspend_comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.uid = %d', $uid);
|
| 358 |
while ($comment = db_fetch_object($query)) {
|
| 359 |
_comment_delete_thread($comment); //deletes comment and all replies!
|
| 360 |
}
|
| 361 |
}
|
| 362 |
//delete user_suspend tables
|
| 363 |
db_query('DELETE FROM {user_suspend_comments} WHERE uid = %d', $uid);
|
| 364 |
}
|
| 365 |
else {
|
| 366 |
drupal_set_message(t('%user comments cannot be saved.', $message));
|
| 367 |
}
|
| 368 |
}
|
| 369 |
}
|
| 370 |
|
| 371 |
//delete user_suspend tables
|
| 372 |
db_query('DELETE FROM {user_suspend} WHERE uid = %d', $uid);
|
| 373 |
db_query('DELETE FROM {user_suspend_users} WHERE uid = %d', $uid);
|
| 374 |
db_query('DELETE FROM {user_suspend_users_roles} WHERE uid = %d', $uid);
|
| 375 |
|
| 376 |
if ($delete) {
|
| 377 |
user_delete(array('confirm' => 1), $uid);
|
| 378 |
//watchdog and messages supplied by node_delete and user_delete
|
| 379 |
}
|
| 380 |
else { //reinstate user
|
| 381 |
drupal_set_message(t('Reinstated user: %user %email.', $message));
|
| 382 |
watchdog('user suspend', t('Reinstated user: %user %email.', $message), WATCHDOG_NOTICE);
|
| 383 |
if ($result_nodes_delete) {
|
| 384 |
drupal_set_message(t('%user nodes restored.', $message));
|
| 385 |
}
|
| 386 |
if ($result_comments_delete) {
|
| 387 |
drupal_set_message(t('%user comments restored.', $message));
|
| 388 |
}
|
| 389 |
//user notify
|
| 390 |
if (variable_get('user_suspend_email_reinstate', 0)) {
|
| 391 |
$from = variable_get('site_mail', ini_get('sendmail_from'));
|
| 392 |
$variables = array('!username' => $user['name'], '!site' => variable_get('site_name', 'Drupal'), '!uri' => $base_url, '!login_url' => url('user', NULL, NULL, TRUE), '!mailto' => $user['mail'], '!date' => format_date($time));
|
| 393 |
$subject = strtr(variable_get('user_suspend_email_reinstate_subject', 'Account reinstated for !username at !site'), $variables);
|
| 394 |
$body = strtr(variable_get('user_suspend_email_reinstate_body', USER_SUSPEND_REINSTATE_EMAIL), $variables);
|
| 395 |
$mail_success = drupal_mail('user-suspend', $user['mail'], $subject, $body, $from);
|
| 396 |
if ($mail_success) {
|
| 397 |
watchdog('user suspend', t('Account reinstate notification mailed to %user at %email.', $message));
|
| 398 |
}
|
| 399 |
else {
|
| 400 |
watchdog('user suspend', t('Error mailing account reinstate notification to %user at %email.', $message), WATCHDOG_ERROR);
|
| 401 |
}
|
| 402 |
}
|
| 403 |
}
|
| 404 |
}
|
| 405 |
else {
|
| 406 |
drupal_set_message(t('%user roles cannot be saved.', $message), 'error');
|
| 407 |
}
|
| 408 |
|
| 409 |
}
|
| 410 |
else {
|
| 411 |
drupal_set_message(t('%user cannot be saved.', $message), 'error');
|
| 412 |
}
|
| 413 |
}
|
| 414 |
else {
|
| 415 |
drupal_set_message(t('%user already exists.', $message), 'error');
|
| 416 |
}
|
| 417 |
} //end foreach
|
| 418 |
|
| 419 |
if ($delete) {
|
| 420 |
drupal_goto('admin/user/user/suspend');
|
| 421 |
}
|
| 422 |
else {
|
| 423 |
drupal_goto('admin/user/user');
|
| 424 |
}
|
| 425 |
|
| 426 |
}
|
| 427 |
|
| 428 |
/**
|
| 429 |
* Implementation of hook_form_alter().
|
| 430 |
*/
|
| 431 |
function user_suspend_form_alter($form_id, &$form) {
|
| 432 |
global $form_values;
|
| 433 |
|
| 434 |
if ($form_id == 'user_register') {
|
| 435 |
$form['#validate'] = array('user_suspend_user_register_validate' => array()) + (array)$form['#validate'];
|
| 436 |
}
|
| 437 |
}
|
| 438 |
|
| 439 |
/**
|
| 440 |
* Validation of hook_form_alter().
|
| 441 |
*
|
| 442 |
* User registration hook to prevent registration with suspended email address.
|
| 443 |
*/
|
| 444 |
|
| 445 |
function user_suspend_user_register_validate($form_id, $form_values) {
|
| 446 |
if (db_num_rows(db_query("SELECT uid FROM {user_suspend_users} WHERE LOWER(name) = LOWER('%s')", $form_values['name'])) > 0) {
|
| 447 |
form_set_error('name', t('The name %name is already taken.', array('%name' => $form_values['name'])));
|
| 448 |
}
|
| 449 |
if (db_num_rows(db_query("SELECT uid FROM {user_suspend_users} WHERE LOWER(mail) = LOWER('%s')", $form_values['mail'])) > 0) {
|
| 450 |
form_set_error('mail', t('An account with this e-mail address has already been suspended.'));
|
| 451 |
}
|
| 452 |
}
|
| 453 |
|
| 454 |
/**
|
| 455 |
* Suspend user.
|
| 456 |
*
|
| 457 |
* @param $uid
|
| 458 |
* The user ID of the user to suspend.
|
| 459 |
*
|
| 460 |
* @return
|
| 461 |
* true is success, false if user does not exist.
|
| 462 |
*/
|
| 463 |
function _user_suspend_user($uid) {
|
| 464 |
global $base_url;
|
| 465 |
$uid = (int)$uid;
|
| 466 |
$time = time();
|
| 467 |
|
| 468 |
//sanity check
|
| 469 |
if ($uid < 1) {
|
| 470 |
watchdog('user suspend', t('Invalid User ID: %uid.', array('%uid' => $uid)), WATCHDOG_ERROR);
|
| 471 |
return false;
|
| 472 |
}
|
| 473 |
elseif ($uid == 1) {
|
| 474 |
watchdog('user suspend', t('Cannot suspend superuser'), WATCHDOG_ERROR);
|
| 475 |
return false;
|
| 476 |
}
|
| 477 |
|
| 478 |
$account = db_fetch_array(db_query('SELECT name, mail FROM {users} WHERE uid = %d', $uid));
|
| 479 |
$message = array('%user' => $account['name'], '%email' => '<'. $account['mail'] .'>');
|
| 480 |
if (!$account['name']) {
|
| 481 |
watchdog('user suspend', t('Invalid User ID: %uid.', array('%uid' => $uid)), WATCHDOG_ERROR);
|
| 482 |
return false;
|
| 483 |
}
|
| 484 |
|
| 485 |
if (db_result(db_query('SELECT uid FROM {user_suspend_users} WHERE uid = %d', $uid))) {
|
| 486 |
watchdog('user suspend', t('User already suspended: %user %email.', $message), WATCHDOG_ERROR);
|
| 487 |
return false;
|
| 488 |
}
|
| 489 |
|
| 490 |
if (_user_suspend_copy_table($uid, 'users', 'user_suspend')) {
|
| 491 |
if (_user_suspend_copy_table($uid, 'users_roles', 'user_suspend')) {
|
| 492 |
//nodes
|
| 493 |
$result_nodes_delete = false;
|
| 494 |
$result_nodes_orphan = false;
|
| 495 |
if (db_num_rows(db_query("SELECT * FROM {node} WHERE uid = %d", $uid))) { //nodes to work with
|
| 496 |
if (variable_get('user_suspend_remove_nodes', 1)) { //enable remove nodes
|
| 497 |
if (_user_suspend_copy_table($uid, 'node', 'user_suspend')) {
|
| 498 |
$result_nodes_delete = db_query('DELETE FROM {node} WHERE uid = %d', $uid);
|
| 499 |
}
|
| 500 |
else {
|
| 501 |
watchdog('user suspend', t('User nodes cannot be saved: %user %email.', $message), WATCHDOG_ERROR);
|
| 502 |
}
|
| 503 |
}
|
| 504 |
else { //orphan nodes
|
| 505 |
$result_nodes_orphan = true;
|
| 506 |
db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $uid);
|
| 507 |
db_query('UPDATE {node_revisions} SET uid = 0 WHERE uid = %d', $uid);
|
| 508 |
}
|
| 509 |
}
|
| 510 |
if ($result_nodes_delete) {
|
| 511 |
watchdog('user suspend', t('User nodes removed: %user %email.', $message), WATCHDOG_NOTICE);
|
| 512 |
}
|
| 513 |
elseif ($result_nodes_orphan) {
|
| 514 |
watchdog('user suspend', t('User nodes orphaned: %user %email.', $message), WATCHDOG_NOTICE);
|
| 515 |
}
|
| 516 |
|
| 517 |
//comments: needs work to handle replies... when a comment is deleted, the entire thread is deleted
|
| 518 |
$result_comments_delete = false;
|
| 519 |
$result_comments_orphan = false;
|
| 520 |
if (db_num_rows(db_query("SELECT * FROM {comments} WHERE uid = %d", $uid))) { //comments to work with
|
| 521 |
if (variable_get('user_suspend_remove_comments', 1)) { //enable remove comments
|
| 522 |
if (_user_suspend_copy_table($uid, 'comments', 'user_suspend')) {
|
| 523 |
$result_comments_delete = db_query('DELETE FROM {comments} WHERE uid = %d', $uid);
|
| 524 |
}
|
| 525 |
else {
|
| 526 |
watchdog('user suspend', t('User comments cannot be saved: %user %email.', $message), WATCHDOG_ERROR);
|
| 527 |
}
|
| 528 |
}
|
| 529 |
else { //orphan comments
|
| 530 |
$result_comments_orphan = true;
|
| 531 |
db_query('UPDATE {comments} SET uid = 0 WHERE uid = %d', $uid);
|
| 532 |
}
|
| 533 |
db_query('UPDATE {node_comment_statistics} SET last_comment_uid = 0 WHERE last_comment_uid = %d', $uid);
|
| 534 |
}
|
| 535 |
if ($result_comments_delete) {
|
| 536 |
watchdog('user suspend', t('User comments removed: %user %email.', $message), WATCHDOG_NOTICE);
|
| 537 |
}
|
| 538 |
elseif ($result_comments_orphan) {
|
| 539 |
watchdog('user suspend', t('User comments orphaned: %user %email.', $message), WATCHDOG_NOTICE);
|
| 540 |
}
|
| 541 |
|
| 542 |
//user cleanup
|
| 543 |
sess_destroy_uid($uid);
|
| 544 |
db_query('DELETE FROM {users} WHERE uid = %d', $uid);
|
| 545 |
db_query('DELETE FROM {users_roles} WHERE uid = %d', $uid);
|
| 546 |
db_query('INSERT INTO {user_suspend} (uid,suspended) VALUES (%d,%d)', $uid, $time);
|
| 547 |
//user notify
|
| 548 |
if (variable_get('user_suspend_email_suspend', 0)) {
|
| 549 |
$from = variable_get('site_mail', ini_get('sendmail_from'));
|
| 550 |
$variables = array('!username' => $account['name'], '!site' => variable_get('site_name', 'Drupal'), '!uri' => $base_url, '!login_url' => url('user', NULL, NULL, TRUE), '!mailto' => $account['mail'], '!date' => format_date($time));
|
| 551 |
$subject = strtr(variable_get('user_suspend_email_suspend_subject', 'Account suspended for !username at !site'), $variables);
|
| 552 |
$body = strtr(variable_get('user_suspend_email_suspend_body', USER_SUSPEND_DEFAULT_EMAIL), $variables);
|
| 553 |
$mail_success = drupal_mail('user-suspend', $account['mail'], $subject, $body, $from);
|
| 554 |
if ($mail_success) {
|
| 555 |
watchdog('user suspend', t('Account suspension notification mailed to %user at %email.', $message));
|
| 556 |
}
|
| 557 |
else {
|
| 558 |
watchdog('user suspend', t('Error mailing account suspension notification to %user at %email.', $message), WATCHDOG_ERROR);
|
| 559 |
}
|
| 560 |
}
|
| 561 |
watchdog('user suspend', t('Suspended user: %user %email.', $message), WATCHDOG_NOTICE);
|
| 562 |
return true;
|
| 563 |
}
|
| 564 |
else {
|
| 565 |
watchdog('user suspend', t('User roles cannot be saved: %user %email.', $message), WATCHDOG_ERROR);
|
| 566 |
return false;
|
| 567 |
}
|
| 568 |
}
|
| 569 |
else {
|
| 570 |
watchdog('user suspend', t('User cannot be saved: %user %email.', $message), WATCHDOG_ERROR);
|
| 571 |
return false;
|
| 572 |
}
|
| 573 |
}
|
| 574 |
|
| 575 |
/**
|
| 576 |
* Internal functions
|
| 577 |
*/
|
| 578 |
function _user_suspend_copy_table($uid, $table = 'users', $to_table = '') {
|
| 579 |
if (!(int)$uid) return false;
|
| 580 |
if (!in_array($table, array('node', 'comments', 'users', 'users_roles'))) return false;
|
| 581 |
if ($to_table == '') {
|
| 582 |
$from_table = 'user_suspend_';
|
| 583 |
}
|
| 584 |
else if ($to_table == 'user_suspend') {
|
| 585 |
$to_table = 'user_suspend_';
|
| 586 |
$from_table = '';
|
| 587 |
}
|
| 588 |
else return false;
|
| 589 |
|
| 590 |
$schema = implode(',', _user_suspend_get_drupal_schema($table));
|
| 591 |
return db_query('INSERT INTO {'. $to_table . $table . '} (' . $schema . ') SELECT ' . $schema . ' FROM {' . $from_table . $table . '} WHERE uid = %d', $uid);
|
| 592 |
}
|
| 593 |
|
| 594 |
function _user_suspend_schema_diff() {
|
| 595 |
$tables = array('node', 'comments', 'users', 'users_roles');
|
| 596 |
foreach ($tables as $table) {
|
| 597 |
$schema_diff = array_diff(_user_suspend_get_drupal_schema($table, FALSE), _user_suspend_get_drupal_schema($table));
|
| 598 |
if (count($schema_diff)) {
|
| 599 |
drupal_set_message(t('User Suspend does not recognize table %table as default Drupal schema and cannot preserve data from fields %fields when suspending users.', array('%table' => $table, '%fields' => implode(" and ", $schema_diff))), 'warning');
|
| 600 |
}
|
| 601 |
}
|
| 602 |
}
|
| 603 |
|
| 604 |
function _user_suspend_get_drupal_schema($table = 'node', $default = TRUE) {
|
| 605 |
if (in_array($table, array('node', 'comments', 'users', 'users_roles'))) {
|
| 606 |
if ($default) {
|
| 607 |
if ($table == 'node') return array('nid', 'vid', 'type', 'title', 'uid', 'status', 'created', 'changed', 'comment', 'promote', 'moderate', 'sticky');
|
| 608 |
if ($table == 'comments') return array('cid', 'pid', 'nid', 'uid', 'subject', 'comment', 'hostname', 'timestamp', 'score', 'status', 'format', 'thread', 'users', 'name', 'mail', 'homepage');
|
| 609 |
if ($table == 'users_roles') return array('uid', 'rid');
|
| 610 |
return array('uid', 'name', 'pass', 'mail', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'access', 'login', 'status', 'timezone', 'language', 'picture', 'init', 'data');
|
| 611 |
}
|
| 612 |
//get dynamic schema
|
| 613 |
$result = db_query('SELECT * FROM {' . $table . '} LIMIT 0,1');
|
| 614 |
if (db_num_rows($result)) {
|
| 615 |
return array_keys(db_fetch_array($result));
|
| 616 |
}
|
| 617 |
}
|
| 618 |
return array();
|
| 619 |
}
|