1

On my site, user profiles are not public; the anonymous user does not have permission to access them. However, I want to send a view containing a list of member profiles in an email with Rules Scheduler. I am attaching the view to the email with views_embed_view(). However, the view content is not displayed because Rules Scheduler use cron, which embeds the view as anonymous user.

So my first thought was to somehow run cron as an admininistrator, but the Drupal documentation states this:

Running cron as an authenticated user (Drupal 6 and earlier only)

If triggering cron.php via the methods above, cron tasks will run as the anonymous user. For most cases this should be fine, but if Drupal cron has been customized to include tasks that must run as a certain site user (e.g. custom logic has been implemented in hook_cron() that requires special user permissions), the following script may be useful. This script authenticates a user of your choosing before calling cron.php.

Note that as of Drupal 7, cron always runs as an anonymous user, so this will not work in Drupal 7 and later versions!

It doesn't give the reason why, but I assume this is some kind of security issue, and there is no alternative listed. Is it flat-out impossible to run cron as an admin in Drupal 7+?

2
  • The usual trick in cron hooks is to switch user in the hook, not in cron itself. You might consider writing your own cron hook in which you switch to the desired user before invoking the rule. Dec 9, 2015 at 16:10

3 Answers 3

2

I don't think this is possible w/o some shenanigans. If you look at drupal_cron_run(), you will see that it changes the user to anonymous (around line 5337 in includes/common.inc):

// Force the current user to anonymous to ensure consistent permissions on
// cron runs.
$original_user = $GLOBALS['user'];
$GLOBALS['user'] = drupal_anonymous_user();

The only way around this would be to implement a hook_cron() and alter its weight so that it gets called first, and have it swap in the user that you want (which can be a little tricky in some cases. This may also cause problems with some cron hooks, like search_cron(), which assume the anonymous user, and end up with weird results (in this case, there may be a security problem where privileged information is revealed to the anonymous user).

2

Had the same issue in D10 so I'm adding this for reference for people using Drupal 8, 9, 10.

// Call the account switcher service.
$accountSwitcher = \Drupal::service('account_switcher');
// Switch to the admin user.
$accountSwitcher->switchTo(new \Drupal\Core\Session\UserSession(['uid' => 1]));

// Render view.
$view = \Drupal\views\Views::getView('VIEW_ID');
$view->setDisplay('DISPLAY_ID');
$view->execute();
$rendered = $view->render();
$output = \Drupal::service('renderer')->render($rendered);

// Switch back to the old session.
$accountSwitcher->switchBack();
0

Given that you've said you're calling views_embed_view() somewhere in order to attach the view to the email, you could try following these instructions on Safely Impersonating Another User.

For Drupal 7 this would mean wrapping your views_embed_view() inside the following snippet:

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

// Insert your views_embed_view() code here.

$user = $original_user;
drupal_save_session($old_state);

Note that this example impersonates the admin user. You may wish to use a different user ID in the $user = user_load(1); line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.