Question

I want to re-save all user accounts on my site weekly because I wrote some code in hook_user_presave() that I want to update every week.

Specifically, my hook_user_presave() code updates the values of some fields like Total number of comments posted and Total number of articles posted, and it sends an email if the user hasn't logged in for more than a month. (This info is only available to the site admin, which is me, so it doesn't need to be perfectly in sync.)

Right now, I have a View with VBO that I can use to re-save all the user accounts manually. I want to automate this process by saving all the users automatically at 3 am on Sunday.

How do I schedule all user accounts to be saved? Is this a task for Queue API or does core/contrib provide something more appropriate for this use case?

Was it helpful?

Solution

Ultimate Cron

Provides a UI where you can schedule all the cron jobs. Example:

enter image description here


Job Scheduler

Provides an API to schedule jobs.

Simple example:

// Declare scheduler.

  function example_cron_job_scheduler_info() {
    $schedulers = [];
    $schedulers['example_unpublish'] = [
      'worker callback' => 'example_unpublish_nodes',
    ];
    return $schedulers;
  }

// Add a job.

  $job = [
    'name' => 'example_unpublish',
    'type' => 'story',
    'id' => 12, // must be unique
    'crontab' => * 3 * * 0, // Every Sunday at 3 AM
    'periodic' => TRUE, // set to false if you want to just run once.
  ];
  $service = \Drupal::service('job_scheduler.manager');
  $service->set($job);

// Work off a job.

  function example_update_users_total(\Drupal\job_scheduler\Entity\JobSchedule $job) {
    // Do stuff.
  }

There is more examples & info in the READ.ME, so read it.


Important

It's important to note that the above in reality is scheduled to run the next time someone visits the site after 3am on Sunday. So if no one visits the site until say 9am on Sunday, it will not run until 9am. This is because Drupal's Cron can only run when Drupal is initialized.

The only way to be sure that it runs at 3am, you have to set a cron job in your server (just know that your server time may not be the same as your timezone, so you'll have to check that), using the crontab -e command (for linux) will open the file where you can add jobs to the server. Have this server job run a file that contains code that performs a GET request on your site. OR alternatively a custom Drush command like Kevin commented.

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top