You are here

function privatemsg_cron in Privatemsg 7

Same name and namespace in other branches
  1. 5.3 privatemsg.module \privatemsg_cron()
  2. 5 privatemsg.module \privatemsg_cron()
  3. 6.2 privatemsg.module \privatemsg_cron()
  4. 6 privatemsg.module \privatemsg_cron()
  5. 7.2 privatemsg.module \privatemsg_cron()

Implements hook_cron().

If the flush feature is enabled, a given amount of deleted messages that are old enough are flushed.

2 calls to privatemsg_cron()
PrivatemsgRolesTestCase::testSendMessagetoRoleCron in privatemsg_roles/privatemsg_roles.test
PrivatemsgTestCase::testPrivatemsgFlush in ./privatemsg.test
Tests for the flush feature

File

./privatemsg.module, line 601
Allows users to send private messages to other users.

Code

function privatemsg_cron() {
  if (variable_get('privatemsg_flush_enabled', FALSE)) {
    $query = _privatemsg_assemble_query('deleted', variable_get('privatemsg_flush_days', 30), variable_get('privatemsg_flush_max', 200));
    foreach ($query
      ->execute()
      ->fetchCol() as $mid) {
      $message = privatemsg_message_load($mid);
      module_invoke_all('privatemsg_message_flush', $message);

      // Delete recipients of the message.
      db_delete('pm_index')
        ->condition('mid', $mid)
        ->execute();

      // Delete message itself.
      db_delete('pm_message')
        ->condition('mid', $mid)
        ->execute();
    }
  }

  // Number of user ids to process for this cron run.
  $total_remaining = variable_get('privatemgs_cron_recipient_per_run', 1000);
  $current_process = variable_get('privatemsg_cron_recipient_process', array());

  // Instead of doing the order by in the database, which can be slow, we load
  // all results and the do the handling there. Additionally, explicitly specify
  // the desired types. If there are more than a few dozen results the site is
  // unhealthy anyway because this cron is unable to keep up with the
  // unprocessed recipients.
  $rows = array();

  // Get all type keys except user.
  $types = privatemsg_recipient_get_types();
  unset($types['user']);
  $types = array_keys($types);

  // If there are no other recipient types, there is nothing to do.
  if (empty($types)) {
    return;
  }
  $result = db_query("SELECT pmi.recipient, pmi.type, pmi.mid FROM {pm_index} pmi WHERE pmi.type IN (:types) AND pmi.is_new = 1", array(
    ':types' => $types,
  ));
  foreach ($result as $row) {

    // If this is equal to the row that is currently processed, add it first in
    // the array.
    if (!empty($current_process) && $current_process['mid'] == $row->mid && $current_process['type'] == $row->type && $current_process['recipient'] == $row->recipient) {
      array_unshift($rows, $row);
    }
    else {
      $rows[] = $row;
    }
  }
  foreach ($rows as $row) {
    $type = privatemsg_recipient_get_type($row->type);
    if (isset($type['load']) && is_callable($type['load'])) {
      $loaded = $type['load'](array(
        $row->recipient,
      ));
      if (empty($loaded)) {
        continue;
      }
      $recipient = reset($loaded);
    }

    // Check if we already started to process this recipient.
    $offset = 0;
    if (!empty($current_process) && $current_process['mid'] == $row->mid && $current_process['recipient'] == $row->recipient && $current_process['type'] == $row->type) {
      $offset = $current_process['offset'];
    }
    $load_function = $type['generate recipients'];
    $uids = $load_function($recipient, $total_remaining, $offset);
    if (!empty($uids)) {
      foreach ($uids as $uid) {
        privatemsg_message_change_recipient($row->mid, $uid, 'hidden');
      }
    }

    // If less than the total remaining uids were returned, we are finished.
    if (count($uids) < $total_remaining) {
      $total_remaining -= count($uids);
      db_update('pm_index')
        ->fields(array(
        'is_new' => PRIVATEMSG_READ,
      ))
        ->condition('mid', $row->mid)
        ->condition('recipient', $row->recipient)
        ->condition('type', $row->type)
        ->execute();

      // Reset current process if necessary.
      if ($offset > 0) {
        variable_set('privatemsg_cron_recipient_process', array());
      }
    }
    else {

      // We are not yet finished, save current process and break.
      $existing_offset = isset($current_process['offset']) ? $current_process['offset'] : 0;
      $current_process = (array) $row;
      $current_process['offset'] = $existing_offset + count($uids);
      variable_set('privatemsg_cron_recipient_process', $current_process);
      break;
    }
  }
}