You are here

function privatemsg_cron in Privatemsg 6.2

Same name and namespace in other branches
  1. 5.3 privatemsg.module \privatemsg_cron()
  2. 5 privatemsg.module \privatemsg_cron()
  3. 6 privatemsg.module \privatemsg_cron()
  4. 7.2 privatemsg.module \privatemsg_cron()
  5. 7 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 608
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));
    $result = db_query($query['query']);
    $flushed = 0;
    while (($row = db_fetch_array($result)) && $flushed < variable_get('privatemsg_flush_max', 200)) {
      $message = privatemsg_message_load($row['mid']);
      module_invoke_all('privatemsg_message_flush', $message);

      // Delete recipients of the message.
      db_query('DELETE FROM {pm_index} WHERE mid = %d', $row['mid']);

      // Delete message itself.
      db_query('DELETE FROM {pm_message} WHERE mid = %d', $row['mid']);
      $flushed++;
    }
  }

  // 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 (" . db_placeholders($types, 'varchar') . ") AND pmi.is_new = 1", $types);
  while ($row = db_fetch_object($result)) {

    // 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_query("UPDATE {pm_index} SET is_new = %d WHERE mid = %d AND recipient = %d AND type = '%s'", PRIVATEMSG_READ, $row->mid, $row->recipient, $row->type);

      // 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;
    }
  }
}