Last updated November 18, 2014. Created on February 5, 2008.
Edited by hass, mradcliffe, joshjalopy, axel.rutz. Log in to edit this page.

Impersonating Possibilities

There are many times when you may want your code to "impersonate" another user. An example of this is when a user takes an action that triggers another process. If that other process should be done as a different user then you want to impersonate that other user.

Here is some example code to impersonate another user which is unsafe:

<?php
global $user;
$original_user = $user;

$user = user_load(array('uid' => 1));

// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// NOTE: - this is the unsafe part - if your code here fails, then the user suddenly has the permissions of UID 1!
$user = $original_user;
?>

The safe way to implement this is to use the function session_save_session() (D6) or drupal_save_session() (D7) as follows:

For D6:

<?php
global $user;
$original_user = $user;
$old_state = session_save_session();
session_save_session(FALSE);
$user = user_load(array('uid' => 1));

// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// If your code fails, it's not a problem because the session will not be saved
$user = $original_user;
session_save_session($old_state);

// From here on the $user is back to normal so it's OK for the session to be saved
?>

For D7:

<?php
global $user;
$original_user = $user;
$old_state = drupal_save_session();
drupal_save_session(FALSE);
$user = user_load(1);

// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// If your code fails, it's not a problem because the session will not be saved
$user = $original_user;
drupal_save_session($old_state);

// From here on the $user is back to normal so it's OK for the session to be saved
?>

For D8:

You may use the Account Switcher (account_switcher) service to safely impersonate another user. This service will handle the session writing that was required in Drupal 6 and Drupal 7 above.

In Drupal 8, the core Cron service will always execute as an anonymous user when it invokes cron handlers and processes queues.

<?php
 
// Retrieve the account switcher service. Ideally you should inject the account_switcher service into your class.
 
$accountSwitcher = Drupal::service('account_switcher');
 
$accountSwitcher->switchTo(new Drupal\Core\Session\AnonymousUserSession());
 
 
// Take your action here. If your code fails, then you should catch an exception
  // and switch back (see below).

  // Restore user account.
 
$accountSwitcher->switchBack();
?>

or

<?php
 
// Retrieve the account switcher service. Ideally you should inject the account_switcher service into your class.
 
$accountSwitcher = Drupal::service('account_switcher');
 
$accountSwitcher->switchTo(new UserSession(array('uid' => 2)));
 
 
// Take your action here. If your code fails, then you should catch an exception
  // and switch back (see below).

  // Restore user account.
 
$accountSwitcher->switchBack();
?>

An alternative to the above that is related to Menu Tree access is to use a Menu Link Tree Manipulator service. Manipulators allow you to modify or transform a given menu tree by a callable method. This would allow you, for instance, to change a give menu tree by a particular user.

<?php
 
// Setup manipulators array to pass into the MenuTree transform method that
  // includes your module's manipulator service and method.
 
$manipulators = array(
   
'callable' => 'my_module.tree_manipulator_service::checkAccess',
  );
 
 
// Menu parameters
 
$parameters = new MenuTreeParameters();

 
// Transform the menu tree after loading the main menu.
 
$menu_tree = Drupal::service('menu.link_tree');
 
$tree = $menu_tree->load('main', $parameters);
 
$tree = $menu_tree->transform($tree, $manipulators);
?>

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

Matt Habermehl’s picture

I had tried Views Bulk Operations, Rules Bonus, and Views Rules to try to get my rules to work and I was banging my head off the desk at 2am. This saved the project. Thank you so much!

ben.hamelin’s picture

Thought I had this working, then it didn't appear so, then I modified the URI - bingo! Must have cached the original "404" request.