2

Goal

I want to make a Rule that automatically changes the user account last-access date to "now" for certain users.

Use case

I have a view that displays users by last access date, but I need some users to consistently appear near the top of the search results. Previously, I simply assigned all the users that I needed at the top to a specific role, and then sorted the view so that that role came first, but the problem with such an approach is that the same users always appear at the top in the same order. I want the order to look a bit random, so I want to update the access date with a rule that automatically re-schedules itself every x hours.

Problem

I can write a rule that re-schedules itself. However, to update the "last access" date, when I use the Set a data value action, I receive the following message:

The selected data property doesn't support writing.

How can I get around this and refresh the last access date in Rules? I can write a custom rules action if necessary, but I don't know what to put in the action to reset the access date.

1

Two options:

  1. Just as you said, a custom rules action:

    function MY_MODULE_rules_action_info() {
      return array(
        'MYMODULE_action_update_last_access' => array(
          'label' => t('Update last accessed timestamp'),
          'group' => t('Custom'),
          'access callback' => 'rules_user_integration_access',
          'parameter' => array(
            'account' => array(
              'type' => 'user',
              'label' => t('User'),
              'description' => t('User account whose last accessed timestamp will be updated.'),
            ),
          ),
        ),
      );
    }
    
    function MYMODULE_action_update_last_access($account) {
      // There might be another way to update the last accessed date, but you can
      // also do it directly in the database.
      //
      // NOTE: the code below will update the last access to current timestamp.
      // You could also do something like this, to get a random value in the last
      // 24 hours:
      //    $timestamp = rand(REQUEST_TIME - 24 * 60 * 60, REQUEST_TIME);
      $timestamp = REQUEST_TIME;
      // Update the data in database.
      db_update('users')
        ->fields(array('access' => $timestamp))
        ->condition('uid', $account->uid)
        ->execute();
    }
    
  2. Use hook_cron() implementation in a custom module. This can be cleaner if you don't need to configure this more than once.

    function MYMODULE_cron() {
      // Decide how often you want to do this, e.g. daily, weekly, etc.
      // Below is an example for daily trigger.
      $last_updated = variable_get('MYMODULE_var_last_time_access_updated', NULL);
      if (!$last_updated || $last_updated != format_date(REQUEST_TIME, 'custom', 'z')) {
        // Define user IDs which need to be updated.
        $accounts_to_update = array(1, 2, 3);
        // Update them.
        foreach ($accounts_to_update as $account_to_update) {
          // See #1 above; I'll use a random timestamp in last 12 hours this time.
          $timestamp = rand(REQUEST_TIME - 12 * 60 * 60, REQUEST_TIME);
          // Execute the query.
          db_update('users')
            ->fields(array('access' => $timestamp))
            ->condition('uid', $account_to_update)
            ->execute();
        }
      }
    }
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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