[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/masquerade/ -> masquerade.module (source)

   1  <?php
   2  // $Id: masquerade.module,v 1.16.2.47 2010/10/28 17:57:18 deekayen Exp $
   3  
   4  /**
   5   * @file masquerade.module
   6   *
   7   * The masquerade module allows administrators to masquerade as other user.
   8   */
   9  
  10  /**
  11   * Implementation of hook_help().
  12   */
  13  function masquerade_help($path, $arg) {
  14    switch ($path) {
  15      case 'admin/help#masquerade':
  16        return t('<p>The masquerade module adds a link on a user\'s profile page that allows permitted users to masquerade as that user. Upon masquerading, a link to "switch back" to the original user will appear in the menu. While masquerading, the option to masquerade as another user will not appear. All masquerading transactions are logged, and $user->masquerading will be set; this could be displayed via theme.</p><p>In the masquerade settings a list of roles are presented; any checked role is considered an "administrator" and requires the second level "masquerade as admin" permission to masquerade as. User #1 is automatically considered an administrator, regardless of roles.</p>');
  17      case 'admin/settings/masquerade':
  18        return t('Only the users with <strong>masquerade as admin</strong> permission, will be able to masquerade as the users who belong to the roles selected below. User #1 is automatically considered an administrator, regardless of roles.');
  19    }
  20  }
  21  
  22  /**
  23   * Implementation of hook_perm().
  24   *
  25   * @return array
  26   */
  27  function masquerade_perm() {
  28    return array('masquerade as user', 'masquerade as admin');
  29  }
  30  
  31  /**
  32   * Implementation of hook_init().
  33   */
  34  function masquerade_init() {
  35    if (user_is_logged_in ()) {
  36      // load from table uid + session id
  37      $uid = db_result(db_query("SELECT uid_from FROM {masquerade} WHERE sid = '%s' AND uid_as = %d", session_id(), $GLOBALS['user']->uid));
  38      // using if so that we get unset rather than false if not masqing
  39      if ($uid) {
  40        $_SESSION['masquerading'] = $uid;
  41      }
  42      // Don't initialize $_SESSION for anonymous users to keep Pressflow compatiblity
  43      elseif (isset($_SESSION['masquerading'])) {
  44        $_SESSION['masquerading'] = NULL;
  45      }
  46    }
  47  }
  48  
  49  /**
  50   * Implementation of hook_cron()
  51   *
  52   * Cleanup masquerade records where people didn't use the switch back link
  53   * that would have cleanly removed the user switch record.
  54   */
  55  function masquerade_cron() {
  56    // see http://drupal.org/node/268487 before modifying this query
  57    db_query('DELETE FROM {masquerade} WHERE sid NOT IN (SELECT s.sid FROM {sessions} AS s)');
  58  }
  59  
  60  /**
  61   * Implementation of hook_menu().
  62   */
  63  function masquerade_menu() {
  64    $items = array();
  65  
  66    $default_test_user = _masquerade_user_load(variable_get('masquerade_test_user', ''));
  67    if ($default_test_user && ($default_test_user->uid || $default_test_user->name == variable_get('anonymous', t('Anonymous')))) {
  68      $items['masquerade/switch/' . $default_test_user->uid] = array(
  69        'title' => 'Masquerade as @testuser',
  70        'title arguments' => array('@testuser' => $default_test_user->name),
  71        'page callback' => 'masquerade_switch_user_page',
  72        'page arguments' => array(2),
  73        'access callback' => 'masquerade_access',
  74        'access arguments' => array('switch'),
  75        'type' => MENU_NORMAL_ITEM,
  76      );
  77    }
  78  
  79    $items['masquerade/switch/%'] = array(
  80      'title' => 'Masquerading',
  81      'page callback' => 'masquerade_switch_user_page',
  82      'page arguments' => array(2),
  83      'access callback' => 'masquerade_access',
  84      'access arguments' => array('switch', 2),
  85      'type' => MENU_NORMAL_ITEM,
  86    );
  87    $items['masquerade/unswitch'] = array(
  88      'title' => 'Switch back',
  89      'page callback' => 'masquerade_switch_back_page',
  90      'access callback' => 'masquerade_access',
  91      'access arguments' => array('unswitch'),
  92      'type' => MENU_NORMAL_ITEM,
  93    );
  94    $items['masquerade/autocomplete'] = array(
  95      'title' => '',
  96      'page callback' => 'masquerade_autocomplete',
  97      'access callback' => 'masquerade_access',
  98      'access arguments' => array('autocomplete'),
  99      'type' => MENU_CALLBACK,
 100    );
 101    $items['masquerade/autocomplete/multiple'] = array(
 102      'title' => '',
 103      'page callback' => 'masquerade_autocomplete_multiple',
 104      'access callback' => 'masquerade_access',
 105      'access arguments' => array('autocomplete'),
 106      'type' => MENU_CALLBACK,
 107    );
 108    $items['masquerade/autocomplete-user'] = array(
 109      'title' => 'Masquerade autocomplete',
 110      'page callback' => 'masquerade_autocomplete_user',
 111      'access arguments' => array('access user profiles'),
 112      'type' => MENU_CALLBACK,
 113    );
 114    $items['admin/settings/masquerade'] = array(
 115      'title' => 'Masquerade',
 116      'description' => 'Masquerade module allows administrators to masquerade as other users.',
 117      'page callback' => 'drupal_get_form',
 118      'page arguments' => array('masquerade_admin_settings'),
 119      'access callback' => 'user_access',
 120      'access arguments' => array('administer permissions'),
 121      'type' => MENU_NORMAL_ITEM,
 122    );
 123  
 124    return $items;
 125  }
 126  
 127  /**
 128   * Implementation of hook_menu_link_alter().
 129   *
 130   * We need to add a token to the Masquerade paths to protect against CSRF
 131   * attacks. Since menu items in Drupal do not support dynamic elements these
 132   * tokens need to be added during rendering via an implementation of
 133   * hook_translated_menu_link_alter. Set the 'alter'-option to TRUE to make sure
 134   * the links get passed through hook_translated_menu_link_alter.
 135   */
 136  function masquerade_menu_link_alter(&$item) {
 137    if (($item['page callback'] == 'masquerade_switch_user_page') || ($item['page callback'] == 'masquerade_switch_back_page')) {
 138      $item['options']['alter'] = TRUE;
 139    }
 140  }
 141  
 142  /**
 143   * Implementation of hook_translated_menu_link_alter().
 144   *
 145   * Dynamically add the CSRF protection token to the Masquerade menu items.
 146   */
 147  function masquerade_translated_menu_link_alter(&$item, $map) {
 148    if ($item['page_callback'] == 'masquerade_switch_user_page' && isset($map[2])) {
 149      $item['localized_options']['query']['token'] = drupal_get_token('masquerade/switch/' . $map[2]);
 150    }
 151    elseif ($item['page_callback'] == 'masquerade_switch_back_page') {
 152      $item['localized_options']['query']['token'] = drupal_get_token('masquerade/unswitch');
 153    }
 154  }
 155  
 156  
 157  /**
 158   * Determine if the current user has permission to switch users.
 159   *
 160   * @param string $type
 161   *   Either 'switch', 'unswitch', 'user', or 'autocomplete'.
 162   *
 163   * @param object $uid
 164   *   An optional parameter indicating a specific uid to switch to.
 165   *   Otherwise, return if the user can switch to any user account.
 166   *
 167   * @return
 168   *   TRUE, if the user can perform the requested action, FALSE otherwise.
 169   */
 170  function masquerade_access($type, $uid = NULL) {
 171    switch ($type) {
 172      case 'unswitch':
 173        return !empty($_SESSION['masquerading']) || arg(2) == 'menu-customize' || arg(2) == 'menu';
 174      case 'autocomplete':
 175        return !empty($_SESSION['masquerading']) || (user_access('masquerade as user') || user_access('masquerade as admin'));
 176        break;
 177      case 'user':
 178        global $user;
 179        return db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d", $user->uid));
 180        break;
 181      case 'switch':
 182        global $user;
 183        if ($uid) {
 184          if (!is_numeric($uid)) {
 185            return FALSE;
 186          }
 187          $account = user_load(array('uid' => $uid));
 188          $switch_to_account = db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d AND uid_to = %d", $user->uid, $account->uid));
 189        }
 190        return empty($_SESSION['masquerading']) && (user_access('masquerade as user') || user_access('masquerade as admin') || $switch_to_account);
 191        break;
 192    }
 193  }
 194  
 195  function masquerade_admin_settings() {
 196    // create a list of roles; all selected roles are considered administrative.
 197    $rids = array();
 198    $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
 199    while ($obj = db_fetch_object($result)) {
 200      $rids[$obj->rid] = $obj->name;
 201    }
 202  
 203    $form['masquerade_admin_roles'] = array(
 204      '#type' => 'checkboxes',
 205      '#title' => t('Roles that are considered "administrators" for masquerading'),
 206      '#options' => $rids,
 207      '#default_value' => variable_get('masquerade_admin_roles', array()),
 208    );
 209  
 210    $test_name = _masquerade_user_load(variable_get('masquerade_test_user', ''));
 211  
 212    $form['masquerade_test_user'] = array(
 213      '#type' => 'textfield',
 214      '#title' => t('Menu <em>Quick Switch</em> user'),
 215      '#autocomplete_path' => 'masquerade/autocomplete',
 216      '#default_value' => isset($test_name->name) ? check_plain($test_name->name) : '',
 217      '#description' => t('Enter the username of an account you wish to switch easily between via a menu item.'),
 218      '#maxlength' => NULL,
 219    );
 220  
 221    $quick_switch_users = array();
 222    foreach ((variable_get('masquerade_quick_switches', array())) as $uid) {
 223      $u = user_load(array('uid' => $uid));
 224      if ($uid == 0) {
 225        $u->name = variable_get('anonymous', t('Anonymous'));
 226      }
 227      $quick_switch_users[] = $u->name;
 228    }
 229    $form['masquerade_quick_switches'] = array(
 230      '#type' => 'textfield',
 231      '#title' => t('Masquerade Block <em>Quick Switch</em> users'),
 232      '#autocomplete_path' => 'masquerade/autocomplete/multiple',
 233      '#default_value' => !empty($quick_switch_users) ? implode(', ', $quick_switch_users) : '',
 234      '#description' => t('Enter the usernames, separated by commas, of accounts to show as quick switch links in the Masquerade block.'),
 235      '#maxlength' => NULL,
 236    );
 237  
 238    $form = system_settings_form($form);
 239    $form['#validate'][] = 'masquerade_admin_settings_validate';
 240    $form['#submit'][] = 'masquerade_admin_settings_submit';
 241  
 242    return $form;
 243  }
 244  
 245  function masquerade_admin_settings_validate($form, &$form_state) {
 246    if (!empty($form_state['values']['masquerade_test_user'])) {
 247      $test_user = _masquerade_user_load($form_state['values']['masquerade_test_user']);
 248      if (!$test_user) {
 249        form_set_error('masquerade_test_user', t('%user does not exist. Please enter a valid username.', array('%user' => $form_state['values']['masquerade_test_user'])));
 250      }
 251    }
 252    // Needs to rebuild menu in masquerade_admin_settings_submit().
 253    $form_state['masquerade_rebuild_menu'] = (variable_get('masquerade_test_user', '') != $form_state['values']['masquerade_test_user']);
 254  
 255    // A comma-separated list of users.
 256    $masquerade_switches = drupal_explode_tags($form_state['values']['masquerade_quick_switches']);
 257    // Change user names to user ID's for system_settings_form_submit() to save.
 258    $masquerade_uids = array();
 259    foreach ($masquerade_switches as $switch_user) {
 260      $test_user = _masquerade_user_load($switch_user);
 261      if (!$test_user) {
 262        form_set_error('masquerade_quick_switches', t('%user does not exist. Please enter a valid username.', array('%user' => $switch_user)));
 263      }
 264      else {
 265        $masquerade_uids[] = $test_user->uid;
 266      }
 267    }
 268    $form_state['values']['masquerade_quick_switches'] = $masquerade_uids;
 269  }
 270  
 271  function masquerade_admin_settings_submit($form, &$form_state) {
 272    // Rebuild the menu system so the menu "Quick Switch" user is updated.
 273    if ($form_state['masquerade_rebuild_menu']) {
 274      menu_rebuild();
 275    }
 276  }
 277  
 278  /**
 279   * Wrapper around user_load() to allow the loading of anonymous users.
 280   *
 281   * @param $username
 282   *   The username of the user you wish to load (i.e. $user->name). To load the
 283   *   anonymous user, pass the value of the 'anonymous' variable.
 284   *
 285   * @return
 286   *   A fully-loaded $user object upon successful user load or FALSE if user
 287   *   cannot be loaded.
 288   */
 289  function _masquerade_user_load($username) {
 290    if (!empty($username)) {
 291      $user = '';
 292      $anon = variable_get('anonymous', t('Anonymous'));
 293      if ($username == $anon) {
 294        $user = user_load(array('name' => ''));
 295        $user->name = $anon;
 296      }
 297      else {
 298        $user = user_load(array('name' => $username));
 299      }
 300      return $user;
 301    }
 302    return FALSE;
 303  }
 304  
 305  /**
 306   * Implementation of hook_user().
 307   */
 308  function masquerade_user($op, &$edit, &$edit_user, $category = NULL) {
 309    static $old_session_id;
 310  
 311    switch ($op) {
 312  
 313      case 'logout':
 314        if (!empty($edit_user->masquerading)) {
 315          global $user;
 316          cache_clear_all($user->uid, 'cache_menu', true);
 317          $real_user = user_load(array('uid' => $user->masquerading));
 318          watchdog('masquerade', "User %user no longer masquerading as %masq_as.", array('%user' => $real_user->name, '%masq_as' => $user->name), WATCHDOG_INFO);
 319          db_query("DELETE FROM {masquerade} WHERE sid = '%s' AND uid_as = %d", session_id(), $edit_user->uid);
 320        }
 321        break;
 322  
 323      case 'view':
 324        // check if user qualifies as admin
 325        $roles = array_keys(array_filter(variable_get('masquerade_admin_roles', array())));
 326        $perm = $edit_user->uid == 1 || array_intersect(array_keys((array)$edit_user->roles), $roles) ?
 327          'masquerade as admin' :
 328          'masquerade as user';
 329  
 330        global $user;
 331        if (user_access($perm) && empty($edit_user->masquerading) && $user->uid != $edit_user->uid) {
 332          $edit_user->content['Masquerade'] = array('#value' => l(t('Masquerade as !user', array('!user' => $edit_user->name)), 'masquerade/switch/'. $edit_user->uid, array('query' => array('token' => drupal_get_token('masquerade/switch/'. $edit_user->uid)), 'destination' => $_GET['q'], 'attributes' => array('class' => 'masquerade-switch'))),
 333            '#weight' => 10
 334          );
 335        }
 336        break;
 337  
 338      case 'form':
 339        $form = array();
 340        if ($category == 'account') {
 341          $form['masquerade'] = array(
 342            '#type' => 'fieldset',
 343            '#title' => t('Masquerade settings'),
 344            '#access' => user_access('administer permissions'),
 345          );
 346          $result = db_query("SELECT uid_to FROM {masquerade_users} WHERE uid_from = %d", $edit_user->uid);
 347          $masquerade_users = array();
 348          while ($uid_to = db_result($result)) {
 349            $u = user_load($uid_to);
 350            $masquerade_users[] = $u->name;
 351          }
 352          $form['masquerade']['masquerade_users'] = array(
 353            '#type' => 'textfield',
 354            '#title' => t('Enter the users this user is able to masquerade as'),
 355            '#description' => t('Enter a comma separated list of user names that this user can masquerade as.'),
 356            '#autocomplete_path' => 'masquerade/autocomplete-user',
 357            '#default_value' => implode(", ", $masquerade_users),
 358            '#maxlength' => NULL,
 359          );
 360        }
 361        return $form;
 362        break;
 363  
 364      case 'validate':
 365        if ($category == 'account' && isset($edit['masquerade_users'])) {
 366          $users = drupal_explode_tags($edit['masquerade_users']);
 367          foreach ($users as $user) {
 368            if (!user_load(array('name' => $user))) {
 369              form_set_error('masquerade_users', t('%user is not a valid user name.', array('%user' => $user)));
 370            }
 371          }
 372        }
 373        break;
 374  
 375      case 'submit':
 376        $old_session_id = session_id();
 377        break;
 378  
 379      case 'update':
 380        if ($category == 'account') {
 381          $users = drupal_explode_tags($edit['masquerade_users']);
 382          db_query("DELETE FROM {masquerade_users} WHERE uid_from = %d", $edit_user->uid);
 383          foreach ($users as $user) {
 384            $u = user_load(array('name' => $user));
 385            db_query("INSERT INTO {masquerade_users} VALUES (%d, %d)", $edit_user->uid, $u->uid);
 386          }
 387          $edit['masquerade_users'] = NULL;
 388        }
 389        break;
 390  
 391      case 'delete':
 392        db_query("DELETE FROM {masquerade_users} WHERE uid_from = %d OR uid_to = %d", $edit_user->uid, $edit_user->uid);
 393        break;
 394  
 395      case 'after_update':
 396        if (isset($old_session_id) && session_id() != $old_session_id) {
 397          db_query("UPDATE {masquerade} SET sid = '%s' WHERE sid = '%s'", session_id(), $old_session_id);
 398        }
 399        break;
 400    }
 401  }
 402  
 403  /**
 404   * Implementation of hook_block().
 405   */
 406  function masquerade_block($op = 'list', $delta = 0, $edit = array()) {
 407    switch ($op) {
 408      case 'list':
 409        $blocks[0]['info'] =  t('Masquerade');
 410        $blocks[0]['cache'] = BLOCK_CACHE_PER_USER;
 411        return $blocks;
 412      case 'view':
 413        switch ($delta) {
 414          case 0:
 415            if (masquerade_access('autocomplete') || masquerade_access('user')) {
 416              $block['subject'] = t('Masquerade');
 417              $block['content'] = drupal_get_form('masquerade_block_1');
 418              return $block;
 419            }
 420            break;
 421        }
 422        break;
 423    }
 424  }
 425  
 426  /**
 427   * Masquerade block form.
 428   */
 429  function masquerade_block_1($record) {
 430    global $user;
 431    $markup_value = '';
 432    if ($_SESSION['masquerading']) {
 433      $quick_switch_link[] = l(t('Switch back'), 'masquerade/unswitch', array('query' => array('token' => drupal_get_token('masquerade/unswitch'))));
 434      if ($user->uid > 0) {
 435        $markup_value = t('You are masquerading as <a href="@user-url">%masq_as</a>.', array('@user-url' => url('user/' . $user->uid), '%masq_as' => $user->name)) . theme('item_list', $quick_switch_link);
 436      }
 437      else {
 438        $markup_value = t('You are masquerading as %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous'))))  . theme('item_list', $quick_switch_link);
 439      }
 440    }
 441    else {
 442      $masquerade_switches = variable_get('masquerade_quick_switches', array());
 443  
 444      // Add in user-specific switches.
 445      $result = db_query("SELECT uid_to FROM {masquerade_users} WHERE uid_from = %d", $user->uid);
 446      while ($uid_to = db_result($result)) {
 447        $masquerade_switches[] = $uid_to;
 448      }
 449  
 450      foreach ($masquerade_switches as $switch_user) {
 451        if (!isset($_SESSION['user']->uid) || $switch_user != $_SESSION['user']->uid) {
 452          $user_name = user_load(array('uid' => $switch_user));
 453          $switch_link = 'masquerade/switch/'. $user_name->uid;
 454          if ($user_name->uid) {
 455            $quick_switch_link[] = l($user_name->name, $switch_link, array('query' => array('token' => drupal_get_token($switch_link))));
 456          }
 457          if ($switch_user == 0) {
 458            $user_name->name = variable_get('anonymous', t('Anonymous'));
 459            $quick_switch_link[] = l($user_name->name, $switch_link, array('query' => array('token' => drupal_get_token($switch_link))));
 460          }
 461        }
 462      }
 463  
 464      if (masquerade_access('autocomplete')) {
 465        $markup_value .= t('Enter the username to masquerade as.');
 466        $form['masquerade_user_field'] = array(
 467          '#prefix' => '<div class="container-inline">',
 468          '#type' => 'textfield',
 469          '#size' => '18',
 470          '#default_value' => $_SESSION['masquerading'] ? t('Switch back to use') : '',
 471          '#autocomplete_path' => 'masquerade/autocomplete',
 472          '#required' => TRUE,
 473        );
 474        $form['submit'] = array(
 475          '#type' => 'submit',
 476          '#value' => t('Go'),
 477          '#suffix' => '</div>',
 478        );
 479      }
 480  
 481      if (isset($quick_switch_link) && count($quick_switch_link)) {
 482        $markup_value .= '<div id="quick_switch_links">'. t('Quick switches:') . theme('item_list', $quick_switch_link) .'</div>';
 483      }
 484    }
 485    $form['masquerade_desc'] = array(
 486      '#prefix' => '<div class="form-item"><div class="description">',
 487      '#type' => 'markup',
 488      '#value' => $markup_value,
 489      '#suffix' => '</div></div>',
 490    );
 491    return $form;
 492  }
 493  
 494  /**
 495   * Masquerade block form validation.
 496   */
 497  function masquerade_block_1_validate($form, &$form_state) {
 498    global $user;
 499    unset($form);
 500    $name = $form_state['values']['masquerade_user_field'];
 501    if ($name == variable_get('anonymous', t('Anonymous'))) {
 502      $name = '';
 503    }
 504    if ($_SESSION['masquerading']) {
 505      form_set_error('masquerade_user_field', t('You are already masquerading. Please <a href="@unswitch">switch back</a> to your account to masquerade as another user.', array('@unswitch' => url('masquerade/unswitch', array('query' => array('token' => drupal_get_token('masquerade/unswitch')))))));
 506    }
 507    if (module_exists('alt_login')) {
 508      $alt_login = db_fetch_object(db_query("SELECT u.name FROM {users} u INNER JOIN {alt_login} al ON u.uid = al.uid WHERE al.alt_login = '%s'", $name));
 509      if ($alt_login->name) {
 510        $name = $alt_login->name;
 511      }
 512    }
 513    $masq_user = user_load(array('name' => $name));
 514    if (!$masq_user) {
 515      form_set_error('masquerade_user_field', t('User %masq_as does not exist. Please enter a valid username.', array('%masq_as' => $form_state['values']['masquerade_user_field'])));
 516    }
 517    else if ($masq_user->uid == $user->uid) {
 518      form_set_error('masquerade_user_field', t('You cannot masquerade as yourself. Please choose a different user to masquerade as.'));
 519    }
 520    else if (variable_get('site_offline', 0) && !user_access('administer site configuration', $masq_user)) {
 521      form_set_error('masquerade_user_field', t('It is not possible to masquerade in off-line mode as !user does not have the %config-perm permission. Please <a href="@site-maintenance">set the site status</a> to "online" to masquerade as !user.', array('!user' => theme('username', $masq_user), '%config-perm' => 'administer site configuration', '@site-maintenance' => url('admin/settings/site-maintenance'))));
 522    }
 523    else {
 524      $form_state['values']['masquerade_user_field'] = $name;
 525    }
 526  }
 527  
 528  /**
 529   * Masquerade block form submission.
 530   */
 531  function masquerade_block_1_submit($form, &$form_state) {
 532    unset($form);
 533    $masq_user = user_load(array('name' => $form_state['values']['masquerade_user_field']));
 534    if (!masquerade_switch_user($masq_user->uid)) {
 535      drupal_access_denied();
 536    }
 537    else {
 538      drupal_goto(referer_uri());
 539    }
 540  }
 541  
 542  /**
 543   * Returns JS array for Masquerade autocomplete fields.
 544   */
 545  function masquerade_autocomplete($string) {
 546    $matches = array();
 547    $result = db_query_range("SELECT u.name FROM {users} u WHERE LOWER(u.name) LIKE LOWER('%s%%')", $string, 0, 10);
 548    while ($user = db_fetch_object($result)) {
 549      $matches[$user->name] = check_plain($user->name);
 550    }
 551    if (stripos(variable_get('anonymous', t('Anonymous')), $string) === 0) {
 552      $matches[variable_get('anonymous', t('Anonymous'))] = variable_get('anonymous', t('Anonymous'));
 553    }
 554    if (module_exists('devel')) {
 555      $GLOBALS['devel_shutdown'] = FALSE;
 556    }
 557    exit(drupal_json($matches));
 558  }
 559  
 560  /**
 561   * Returns JS array for Masquerade autocomplete fields. Supports multiple entries separated by a comma.
 562   */
 563  function masquerade_autocomplete_multiple($string) {
 564    // The user enters a comma-separated list of users. We only autocomplete the last user.
 565    $array = drupal_explode_tags($string);
 566  
 567    // Fetch last tag
 568    $last_string = trim(array_pop($array));
 569  
 570    $matches = array();
 571    $result = db_query_range("SELECT u.name FROM {users} u WHERE LOWER(u.name) LIKE LOWER('%s%%')", $last_string, 0, 10);
 572  
 573    $prefix = count($array) ? implode(', ', $array) .', ' : '';
 574  
 575    while ($user = db_fetch_object($result)) {
 576      $matches[$prefix . $user->name] = check_plain($user->name);
 577    }
 578    // This will add anonymous to the list, but not sorted.
 579    if (stripos(variable_get('anonymous', t('Anonymous')), $last_string) === 0) {
 580      $matches[$prefix . variable_get('anonymous', t('Anonymous'))] = variable_get('anonymous', t('Anonymous'));
 581    }
 582    if (module_exists('alt_login')) {
 583      $result = db_query_range("SELECT alt_login FROM {alt_login} u WHERE LOWER(alt_login) LIKE LOWER('%s%%')", $string, 0, 10);
 584      while ($user = db_fetch_object($result)) {
 585        $matches[$user->alt_login] = check_plain($user->alt_login);
 586      }
 587    }
 588    if (module_exists('devel')) {
 589      $GLOBALS['devel_shutdown'] = FALSE;
 590    }
 591    exit(drupal_json($matches));
 592  }
 593  
 594  /**
 595   * Replacement function for user_autocomplete which allows the use of a comma
 596   * separated list of user names.
 597   */
 598  function masquerade_autocomplete_user($string) {
 599    $array = drupal_explode_tags($string);
 600    $search = trim(array_pop($array));
 601    $matches = array();
 602    if ($search) {
 603      $prefix = count($array) ? implode(', ', $array) .', ' : '';
 604      $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $search, 0, 10);
 605      while ($user = db_fetch_object($result)) {
 606        $matches[$prefix . $user->name] = check_plain($user->name);
 607      }
 608    }
 609  
 610    drupal_json($matches);
 611  }
 612  
 613  /**
 614   * Page callback to switch users.
 615   */
 616  function masquerade_switch_user_page($uid) {
 617    if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'masquerade/switch/' . $uid) && masquerade_switch_user($uid)) {
 618      drupal_goto(referer_uri());
 619    }
 620    else {
 621      drupal_access_denied();
 622    }
 623  }
 624  
 625  /**
 626   * Function that allows a user with the right permissions to become
 627   * the selected user.
 628   *
 629   * @param $uid
 630   *   The user ID to switch to.
 631   *
 632   * @return
 633   *   TRUE if the user was sucessfully switched, or FALSE if there was an error.
 634   */
 635  function masquerade_switch_user($uid) {
 636    global $user;
 637    if (!is_numeric($uid)) {
 638      drupal_set_message(t('A user id was not correctly passed to the switching function.'));
 639      watchdog('masquerade', 'The user id provided to switch users was not numeric.', NULL, WATCHDOG_ERROR);
 640      return drupal_goto(referer_uri());
 641    }
 642  
 643    $new_user = user_load(array('uid' => $uid));
 644  
 645    $roles = array_keys(array_filter(variable_get('masquerade_admin_roles', array())));
 646    $perm = $uid == 1 || array_intersect(array_keys($new_user->roles), $roles) ?
 647      'masquerade as admin' :
 648      'masquerade as user';
 649  
 650    // Check to see if we need admin permission.
 651    if (!user_access($perm) && !$_SESSION['masquerading'] && !db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d AND uid_to = %d", $user->uid, $new_user->uid))) {
 652      watchdog('masquerade', 'This user requires administrative permissions to switch to the user %user.', array('%user' => $new_user->name), WATCHDOG_ERROR);
 653      return FALSE;
 654    }
 655  
 656    if ($user->uid == $uid || isset($user->masquerading)) {
 657      watchdog('masquerade', 'This user is already %user.', array('%user' => $new_user->name), WATCHDOG_ERROR);
 658      return FALSE;
 659    }
 660  
 661    if (variable_get('site_offline', 0) && !user_access('administer site configuration', $new_user)) {
 662      drupal_set_message(t('It is not possible to masquerade in off-line mode as %user does not have the %config-perm permission. Please <a href="@site-maintenance">set the site status</a> to "online" to masquerade as %user.', array('%user' => $new_user->name, '%config-perm' => 'administer site configuration', '@site-maintenance' => url('admin/settings/site-maintenance'))));
 663      return FALSE;
 664    }
 665  
 666    db_query("INSERT INTO {masquerade} (uid_from, uid_as, sid) VALUES (%d, %d, '%s')",
 667    $user->uid, $new_user->uid, session_id());
 668    // switch user
 669  
 670    watchdog('masquerade', 'User %user now masquerading as %masq_as.', array('%user' => $user->name, '%masq_as' => $new_user->name ? $new_user->name : variable_get('anonymous', t('Anonymous'))), WATCHDOG_INFO);
 671    drupal_set_message(t('You are now masquerading as !masq_as.', array('!masq_as' => theme('username', $new_user))));
 672    $user->masquerading = $new_user->uid;
 673    $user = $new_user;
 674    return TRUE;
 675  }
 676  
 677  /**
 678   * Page callback that allows a user who is currently masquerading to become
 679   * a new user.
 680   */
 681  function masquerade_switch_back_page() {
 682    if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'masquerade/unswitch')) {
 683      global $user;
 684      $olduser = $user;
 685      masquerade_switch_back();
 686      drupal_set_message(t('You are no longer masquerading as !masq_as and are now logged in as !user.', array('!user' => theme('username', $user), '!masq_as' => theme('username', $olduser))));
 687      drupal_goto(referer_uri());
 688    }
 689    else {
 690      drupal_access_denied();
 691    }
 692  }
 693  
 694  /**
 695   * Function for a masquerading user to switch back to the previous user.
 696   */
 697  function masquerade_switch_back() {
 698    // switch user
 699    global $user;
 700    cache_clear_all($user->uid, 'cache_menu', true);
 701    $uid = db_result(db_query("SELECT m.uid_from FROM {masquerade} m WHERE m.sid = '%s' AND m.uid_as = %d ", session_id(), $user->uid));
 702    // erase record
 703    db_query("DELETE FROM {masquerade} WHERE sid = '%s' AND uid_as = %d ", session_id(), $user->uid);
 704    $oldname = ($user->uid == 0 ? variable_get('anonymous', t('Anonymous')) : $user->name);
 705    $user = user_load(array('uid' => $uid));
 706    watchdog('masquerade', 'User %user no longer masquerading as %masq_as.', array('%user' => $user->name, '%masq_as' => $oldname), WATCHDOG_INFO);
 707  }
 708  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7