You are here

node_expire.cron.inc in Node expire 6

Cron functions. Its better to remove Cron's code from .module file because it wont be needed on every single page. It reduces the module footprint (memory consumption).

File

node_expire.cron.inc
View source
<?php

/**
 * @file
 * Cron functions. Its better to remove Cron's code from .module file
 * because it wont be needed on every single page. It reduces the module
 * footprint (memory consumption).
 */

/**
 * Implementation of hook_cron().
 */
function _node_expire_cron() {

  // Are email notifications enabled?
  if (variable_get('node-expire-enable-email', 1) == 1) {
    $updateids = array();
    $time = time();

    // Get a list of nodes that are past the expiration threshold and also
    // haven't been notified in the selected amount of time. For the qualifying
    // data, it gets the necessary information that a user might want to
    // include in the automatic email.
    $query = db_query("SELECT a.nid, a.expire, b.title, b.changed, c.name, c.mail\n      FROM {node_expire} a\n      LEFT JOIN {node} b ON a.nid = b.nid\n      LEFT JOIN {users} c ON b.uid = c.uid\n      WHERE a.expire <= %d AND a.expiremode != %d AND a.lastnotify <= %d AND b.status = 1\n      ORDER BY c.name ASC, b.title ASC", $time, NODE_EXPIRE_NONE, $time - variable_get('node-expire-renotify', 259200));
    while ($row = db_fetch_object($query)) {

      // Has this user received an out-of-date alert this run?
      if (!isset($newnotify[$row->name])) {
        $newnotify[$row->name] = array(
          'email' => $row->mail,
        );
      }

      // Has this node/book already been processed?
      $newnotify[$row->name][$row->nid] = array(
        'nid' => $row->nid,
        'title' => $row->title,
        'expire' => $row->expire,
        'changed' => $row->changed,
      );
    }

    // Now compile the messages. There are two lines to parse the data because
    // we want to do a bulk mailing method rather than emailing once per expired node.
    if (!empty($newnotify)) {

      // The subject and cc address are always the same so let's get them out of the way first.
      $subject = variable_get('node-expire-subject', '!site - Article Update Needed');
      $subject = str_replace('!site', variable_get('site_name', 'Drupal'), $subject);
      $cc = variable_get('node-expire-cc', '');

      // Go through the list of each user that will receive an alert.
      foreach ($newnotify as $user => $node) {

        // The e-mail address is stored in the array for easy access. We don't want to
        // count this as an expired node, so let's remove it from the data list.
        $to = $node['email'];
        unset($node['email']);

        // Make sure carriage returns are in UNIX format to prevent cross-OS problems.
        $body = str_replace("\r", "", variable_get('node-expire-body', "Hello !username,\r\n\r\nThe following article(s) are in " . "need for reviewing and updating. Please update these at your earliest convenience. If no changes are necessary, " . "simply open the editor and press 'Save'.\r\n\r\n!start_section!\r\nArticle: !section_article\r\nTime since " . "update: !section_timesinceupdate\r\nEdit Link: !section_editlink\r\n\r\n!stop_section!\r\n--  !site team"));

        // Replace allowed configurable variables
        $body = str_replace('!site', variable_get('site_name', 'Drupal'), $body);
        $body = str_replace('!username', $user, $body);

        // Grab just between !start_section! and !stop_section!
        $bodysec = drupal_substr($body, strpos($body, '!start_section!') + 15, strpos($body, '!stop_section!') - strpos($body, '!start_section!') - 15);

        // We usually have !start_section!, a carriage return, and then the
        // message for the sake of looking pretty during setup. Let's remove this
        // one instance. If an extra carriage return is requested, the user should
        // put it at the end of the loop as the default value is.
        $bodysec = preg_replace("/^\n/", "", $bodysec);
        $newbody = '';

        // Scan each message and process it according to the template.
        foreach ($node as $row) {
          $temp = $bodysec;
          $temp = str_replace('!section_article', $row['title'], $temp);
          $temp = str_replace('!section_timesinceupdate', format_interval(time() - $row['changed']) . ' ago', $temp);
          $temp = str_replace('!section_lastupdate', format_date($row['changed']), $temp);
          $temp = str_replace('!section_expirydate', format_date($row['expire']), $temp);
          $temp = str_replace('!section_nodelink', url('node/' . $row['nid'], array(
            'absolute' => TRUE,
          )), $temp);
          $temp = str_replace('!section_editlink', url('node/' . $row['nid'] . '/edit', array(
            'absolute' => TRUE,
          )), $temp);

          // Record this as sent so it's only notified once per the selected threshold.
          $updateids[] = $row['nid'];
          $updateids_sql[] = '%d';
          $newbody .= $temp;
        }

        // Ensure emails are treated as mailing list posts, not junk
        $headers['Precedence'] = "list";

        // Now let's take out the template from the settings, and replace it with the parsed data.
        $params = array(
          'body' => drupal_substr($body, 0, strpos($body, '!start_section!')) . $newbody . drupal_substr($body, strpos($body, '!stop_section!') + 15),
          'subject' => $subject,
          'headers' => $headers,
        );

        // This is just to prevent problems with "Anonymous" nodes.
        if ($to) {
          drupal_mail('node_expire', 'notice', $to, language_default(), $params);
        }

        // Send it to the requested carbon copy address, if any.
        if ($cc) {
          drupal_mail('node_expire', 'notice', $cc, language_default(), $params);
        }
      }
      array_unshift($updateids, $time);

      // Record which records were updated.
      db_query('UPDATE {node_expire} SET lastnotify = %d
        WHERE nid IN(' . implode(', ', $updateids_sql) . ')', $updateids);

      // Log the event
      watchdog('node_expire', format_plural(count($updateids), 'E-mail notice submitted for node !nodes', 'E-mail notice submitted for nodes !node'), array(
        '!node' => $updateids[0],
        '!nodes' => implode(', ', $updateids),
      ), WATCHDOG_NOTICE);
    }
  }

  // We run the code to unpublish expired documents after the email communications
  // are sent out because it only queries for published documents. This way,
  // people who want documents to instantly expire can still have email
  // notifications sent out about them too.
  if (variable_get('node-expire-unpublishtime', 0)) {

    // Find old documents.
    $query = db_query("SELECT n.nid FROM {node_expire} ne\n      INNER JOIN {node} n ON n.nid = ne.nid\n      WHERE n.status = 1 AND ne.expire <= '%s' AND ne.expiremode <> %d", time() - variable_get('node-expire-unpublishtime', 0), NODE_EXPIRE_NONE);
    while ($row = db_fetch_object($query)) {
      $unpublish[] = $row->nid;
    }

    // If any records are to be unpublished, unpublish them, and
    // log it through the watchdog service.
    if (!empty($unpublish)) {
      db_query('UPDATE {node} SET status = 0
        WHERE nid IN (' . implode(', ', $unpublish) . ')');
      $message = format_plural(count($unpublish), '@count node was automatically unpublished.', '@count nodes were automatically unpublished.');
      watchdog('node_expire', $message, WATCHDOG_NOTICE);
    }
  }
}

Functions

Namesort descending Description
_node_expire_cron Implementation of hook_cron().