diff --git a/modules/user/user.module b/modules/user/user.module index 3b80247..31d28cb 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -3541,3 +3541,61 @@ function user_rdf_mapping() { ), ); } + +/** + * Impersonate another user. + * + * When this function is called for the first time the user is saved, + * subsequent calls that set a user do not overwrite the value of the + * original user. The user is restored when this function is called with + * a NULL value. + * + * @param $new_user + * User to switch to, either UID or user object. If nothing is provided the + * user will be reset to the original. + * @return + * Current user object. + * + * @see user_restore_user() + */ +function user_switch_user($new_user = NULL) { + global $user; + $user_original = &drupal_static(__FUNCTION__); + + if (empty($new_user)) { + if (isset($user_original)) { + // Restore the original user. + $user = $user_original; + unset($user_original); + drupal_save_session(TRUE); + } + return $user; + } + + // Backup the user the first time this is called. + if (!isset($user_original)) { + $user_original = $user; + drupal_save_session(FALSE); + } + + if (is_numeric($new_user)) { + $user = user_load(array('uid' => $new_user)); + } + else { + $user = is_object($new_user) ? $new_user : (object) $new_user; + } + + return $user; +} + +/** + * Revert to the previous user after an impersonation. + * + * @return + * Current user. + * + * @see user_switch_user() + */ +function user_restore_user() { + return user_switch_user(); +} diff --git a/modules/user/user.test b/modules/user/user.test index 3164945..f542eb8 100644 --- a/modules/user/user.test +++ b/modules/user/user.test @@ -1521,3 +1521,37 @@ class UserRoleAdminTestCase extends DrupalWebTestCase { } } +/** + * Test case for switching users. + */ +class UserSwitchUserTestCase extends DrupalWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Switch users', + 'description' => 'Temporarily switch the current user, and then restore the original user.', + 'group' => 'User', + ); + } + + function setUp() { + parent::setUp(); + $this->original_user = $this->drupalCreateUser(); + } + + function testUserSwitchUser() { + global $user; + + $this->drupalLogin($this->original_user); + $this->assertEqual($user->uid, $this->original_user->uid, t('Using original user. This user: !this-uid, original user: !orig-uid.', array('!this-uid' => $user->uid, '!orig-uid' => $this->original_user->uid))); + + // Create a new user and switch to it. + $new_user = $this->drupalCreateUser(); + user_switch_user($new_user->uid); + + $this->assertEqual($user->uid, $new_user->uid, t('Switched to new user. This user: !this-uid, new user: !orig-uid.', array('!this-uid' => $user->uid, '!orig-uid' => $new_user->uid))); + + user_restore_user(); + $this->assertEqual($user->uid, $this->original_user->uid, t('Switched back to original user. This user: !this-uid, original user: !orig-uid.', array('!this-uid' => $user->uid, '!orig-uid' => $this->original_user->uid))); + } +} \ No newline at end of file