You are here

function node_expire_cron in Node expire 5

Same name and namespace in other branches
  1. 8 node_expire.module \node_expire_cron()
  2. 6.2 node_expire.module \node_expire_cron()
  3. 6 node_expire.module \node_expire_cron()
  4. 7.2 node_expire.module \node_expire_cron()
  5. 7 node_expire.module \node_expire_cron()

Implementation of hook_cron().

File

./node_expire.module, line 67
Alerts administrators of possibly outdated materials and optionally unpublishes them.

Code

function node_expire_cron() {

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

    /**
     * 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, b.title, a.expire, b.changed, c.name, c.mail FROM {node_expire} a LEFT JOIN {node} b ON " . "a.nid = b.nid LEFT JOIN {users} c ON b.uid = c.uid WHERE a.expire <= NOW() AND a.expiremode != 'none' AND a.lastnotify <= %d " . "AND b.status = 1 ORDER BY c.name ASC, b.title ASC", 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 (count($newnotify) > 0) {

      // 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 $tech => $contents) {

        /**
         * 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 = $contents['email'];
        unset($contents['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', $tech, $body);

        // Grab just between !start_section! and !stop_section!
        $bodysec = 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 ($contents 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(strtotime($row['expire'])), $temp);
          $temp = str_replace('!section_unpublishdate', variable_get('node-expire-unpublishtime', 0) == 0 ? t('Never') : format_date(strtotime($row['expire']) + variable_get('node-expire-unpublishtime', 0)), $temp);
          $temp = str_replace('!section_nodelink', url('node/' . $row['nid'], null, null, true), $temp);
          $temp = str_replace('!section_editlink', url('node/' . $row['nid'] . '/edit', null, null, true), $temp);

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

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

        // This is just to prevent problems with "Anonymous" nodes.
        if ($to) {
          drupal_mail('notify-' . $tech, $to, $subject, $body);
        }

        // Send it to the author and the requested carbon copy address, if any.
        if ($cc) {
          drupal_mail('notify-' . $tech, $cc, $subject, $body);
        }
      }

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

      // Log the event
      watchdog('node_expire', format_plural(count($updateids), 'E-mail notice submitted for node #' . $updateids[0], 'E-mail notice submitted for 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) != 0) {

    // Find old documents.
    $unpublishme = array();
    $query = db_query("SELECT nid FROM {node_expire} WHERE expire <= '%s' AND expiremode != 'none'", date("Y-m-d H:i:s", time() - variable_get('node-expire-unpublishtime', 0)));
    while ($row = db_fetch_object($query)) {
      $unpublishme[] = $row->nid;
    }

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