You are here

function _notify_send in Notify 7

Same name and namespace in other branches
  1. 8 notify.module \_notify_send()
  2. 5.2 notify.module \_notify_send()
  3. 5 notify.module \_notify_send()
  4. 6 notify.module \_notify_send()
  5. 2.0.x notify.module \_notify_send()
  6. 1.0.x notify.module \_notify_send()

Helper function to send the notification e-mail batch.

2 calls to _notify_send()
notify_admin_queue_submit in ./notify.admin.inc
Submit for the notify_admin_queue form.
notify_cron in ./notify.module
Implements hook_cron().

File

./notify.module, line 646
Notify module sends e-mail digests of new content and comments.

Code

function _notify_send() {
  global $user;
  $separator = "------------------------------------------------------------------------------\n";
  $mini_separator = "----\n";
  $send_start = variable_get('notify_send_start', 0);
  $num_sent = 0;
  $num_fail = 0;
  list($res_nodes, $res_comms, $res_nopub, $res_copub, $res_nounp, $res_counp) = _notify_select_content();
  _notify_get_content_types($defaultlist, TRUE);

  // Get the nodes and comments queued.
  $count = 0;
  $nodes = $comments = array();

  // Ordinary nodes
  foreach ($res_nodes as $row) {
    $nodes[$row->nid] = node_load($row->nid);
    $count++;
  }

  // Ordinary comments
  if ($res_comms) {
    foreach ($res_nopub as $row) {
      if (!isset($nodes[$row->nid])) {
        $nodes[$row->nid] = node_load($row->nid);
        $count++;
      }
    }
    foreach ($res_comms as $row) {
      $comment = comment_load($row->cid);
      $comments[$comment->nid][$row->cid] = $comment;
      $count++;
    }
    foreach ($res_copub as $row) {
      if (!isset($comments[$row->nid][$row->cid])) {
        $comments[$row->nid][$row->cid] = comment_load($row->cid);
        $count++;
      }
    }
  }

  // Published nodes in unpublished queue
  foreach ($res_nopub as $row) {
    if (!isset($nodes[$row->nid])) {
      $nodes[$row->nid] = node_load($row->nid);
      $count++;
    }
  }

  // Unpublished nodes in unpublished queue
  foreach ($res_nounp as $row) {
    if (!isset($nodes[$row->nid])) {
      $nodes[$row->nid] = node_load($row->nid);
      $count++;
    }
  }
  if ($count) {
    $uresult = variable_get('notify_users', array());
    if (empty($uresult)) {

      // Set up for sending a new batch. Init all variables.
      $sql = 'SELECT u.uid, u.name, u.mail, u.language, n.status, n.node, n.teasers, n.comment
        FROM {notify} n
        INNER JOIN {users} u
        ON n.uid = u.uid
        WHERE (n.status = :nstatus) AND (u.status = :ustatus) AND (n.attempts <= :attempts)
        ORDER BY u.uid asc';
      $uresult = db_query($sql, array(
        ':nstatus' => 1,
        'ustatus' => 1,
        ':attempts' => 5,
      ))
        ->fetchAll(PDO::FETCH_ASSOC);
      variable_set('notify_send_start', REQUEST_TIME);
      variable_set('notify_users', $uresult);
      variable_set('notify_num_sent', 0);
      variable_set('notify_num_failed', 0);
    }
    $batchlimit = variable_get('notify_batchsize', 100);
    $batchcount = 0;

    //$s1 = t('Never', array(), array('langcode' => 'nb'));

    // Allow to safely impersonate the recipient so that the node is rendered
    // with correct field permissions.
    $original_user = $user;
    $old_state = drupal_save_session();
    drupal_save_session(FALSE);
    $notify_skip_nodes = variable_get('notify_skip_nodes', array());
    $notify_skip_comments = variable_get('notify_skip_comments', array());
    foreach ($uresult as $index => $userrow) {
      if (++$batchcount > $batchlimit) {
        break;
      }
      $userobj = user_load($userrow['uid']);

      // Intentionally replacing the Global $user.
      $user = $userobj;
      $upl = user_preferred_language($user);
      $node_body = $comment_body = '';

      // Consider new node content if user has permissions and nodes are ready.
      // $userrow['node']: user subscribes to nodes.
      // user_access('access content', $userobj): user allowed to view published
      // count($nodes): nodes are queued
      if ($userrow['node'] && user_access('access content', $userobj) && count($nodes)) {
        $node_count = 0;

        // Look at the node
        foreach ($nodes as $node) {

          // Skip to next if skip flag set for node.
          if (in_array($node->nid, $notify_skip_nodes)) {
            continue;
          }

          // Skip to next if user is not allowed to view this node.
          if (!user_access('administer nodes', $userobj) && NODE_NOT_PUBLISHED == $node->status) {
            continue;
          }
          if (!user_access('administer nodes', $userobj) && !in_array($node->type, $defaultlist)) {
            continue;
          }
          if (!variable_get('notify_unpublished', 1) && NODE_NOT_PUBLISHED == $node->status) {
            continue;
          }
          if (!node_access('view', $node, $userobj)) {
            continue;
          }
          if (_notify_user_has_subscriptions($userrow['uid'])) {

            // Custom subscriptions exists, use those.
            $field = db_query('SELECT uid FROM {notify_subscriptions} WHERE (uid = :uid) AND (type = :type)', array(
              ':uid' => $userrow['uid'],
              ':type' => $node->type,
            ))
              ->fetchObject();
            $default = $field ? TRUE : FALSE;
            if (!$default) {
              continue;
            }
          }
          $ml_level = variable_get('notify_multilingual', 1);
          if (!user_access('administer notify')) {
            if ($ml_level && $node->tnid) {
              if ($node->language != $upl->language) {
                continue;
              }
            }
            if (2 == $ml_level && 0 == $node->tnid && LANGUAGE_NONE != $node->language) {
              continue;
            }
            $ignore_unverified = variable_get('notify_unverified', 0);
            if ($ignore_unverified && !$node->uid) {
              continue;
            }
          }
          $node_revs_list = node_revision_list($node);
          $nrl_vals = array_values($node_revs_list);
          $vers = array_shift($nrl_vals);
          if ($node_count > 0) {
            $node_body .= $mini_separator;
          }
          $node_body .= ++$node_count . '. ' . $node->title . '. ';
          if (count($node_revs_list) > 1) {
            $update = '(' . t('last updated by !author', array(
              '!author' => format_username($vers) ? format_username($vers) : variable_get('anonymous', 'Anonymous'),
            ), array(
              'langcode' => $upl->language,
            )) . ') ';
          }
          else {
            $update = '';
          }
          if (user_access('administer nodes', $userobj)) {
            $status = $node->status == NODE_PUBLISHED ? t('[Published]', array(), array(
              'langcode' => $upl->language,
            )) : t('[Unpublished]', array(), array(
              'langcode' => $upl->language,
            ));
          }
          else {
            $status = '';
          }
          $node_body .= t('!type by !author !update!status', array(
            '!type' => node_type_get_name($node),
            '!author' => format_username($node) ? format_username($node) : variable_get('anonymous', 'Anonymous'),
            '!update' => $update,
            '!status' => $status,
          ), array(
            'langcode' => $upl->language,
          )) . "\n";
          $alias = drupal_multilingual() ? TRUE : FALSE;
          $node_body .= '   [ ' . url('node/' . $node->nid, array(
            'absolute' => TRUE,
            'alias' => $alias,
            'language' => (object) array(
              'language' => FALSE,
            ),
          )) . " ]\n";
          $node_body .= _notify_content($node, NULL, $userrow['teasers']) . "\n";
        }

        // Prepend node e-mail header as long as user could access at
        // least one node.
        if ($node_count > 0) {
          $node_body = $separator . t('Recent nodes - !count', array(
            '!count' => format_plural($node_count, '1 new post', '@count new posts', array(), array(
              'langcode' => $upl->language,
            )),
          ), array(
            'langcode' => $upl->language,
          )) . "\n" . $separator . $node_body;
        }
      }

      // Consider new comments if user has permissions and comments are ready.
      // $userrow['comment']: user subscribes to nodes.
      // user_access('access comments', $userobj): user allowed to view published
      // count($comments): comments are queued
      if ($userrow['comment'] && user_access('access comments', $userobj) && count($comments)) {
        $total_comment_count = 0;

        // Look at the comment
        foreach ($comments as $nid => $value) {

          // If we don't already have the node, fetch it.
          if (isset($nodes[$nid])) {
            $node = $nodes[$nid];
          }
          else {
            $node = node_load($nid);
          }
          if (!node_access('view', $node, $userobj)) {
            continue;
          }
          $comment_count = 0;
          $onecomment = '';

          // Look at the comment
          foreach ($value as $commobj) {
            if (in_array($commobj->cid, $notify_skip_comments)) {
              continue;
            }
            if (!user_access('administer comments', $userobj) && COMMENT_NOT_PUBLISHED == $commobj->status) {
              continue;
            }
            if (!user_access('administer comments', $userobj) && !in_array($node->type, $defaultlist)) {
              continue;
            }
            if (!variable_get('notify_unpublished', 1) && COMMENT_NOT_PUBLISHED == $commobj->status) {
              continue;
            }

            // Determine whether to show comment status.
            if (user_access('administer comments', $userobj)) {
              $status = $commobj->status == COMMENT_PUBLISHED ? t('[Published]', array(), array(
                'langcode' => $upl->language,
              )) : t('[Unpublished]', array(), array(
                'langcode' => $upl->language,
              ));
            }
            else {
              $status = '';
            }
            $onecomment .= '   ' . ++$comment_count . '. ' . t('!title by !author !status', array(
              '!title' => $commobj->subject,
              '!author' => format_username($commobj) ? format_username($commobj) : variable_get('anonymous', 'Anonymous'),
              '!status' => $status,
            ), array(
              'langcode' => $upl->language,
            )) . "\n" . '      [ ' . url('node/' . $nid, array(
              'fragment' => 'comment-' . $commobj->cid,
              'absolute' => TRUE,
            )) . " ]\n\n";
            $total_comment_count++;
            $onecomment .= _notify_content($node, $commobj, $userrow['teasers']);
          }
          if ($comment_count) {
            if ($comment_body) {
              $comment_body .= $mini_separator;
            }
            $comment_body .= t('!count attached to !type posted by !author: !title', array(
              '!count' => format_plural($comment_count, '1 new comment', '@count new comments'),
              '!title' => $node->title,
              '!type' => node_type_get_name($node),
              '!author' => format_username($node) ? format_username($node) : variable_get('anonymous', 'Anonymous'),
            ), array(
              'langcode' => $upl->language,
            )) . "\n\n" . $onecomment;
          }
        }
        if ($total_comment_count > 0) {
          $comment_body = $separator . t('Recent comments - !count', array(
            '!count' => format_plural($total_comment_count, '1 new comment', '@count new comments'),
          ), array(
            'langcode' => $upl->language,
          )) . "\n" . $separator . $comment_body;
        }
      }
      $body = $node_body . $comment_body;

      //if (variable_get('notify_unpublished', 1)) {}

      // If there was anything new, send mail.
      if ($body) {
        $watchdog_level = variable_get('notify_watchdog', 0);
        if (drupal_mail('notify', 'send', $userrow['mail'], user_preferred_language($userrow), array(
          'content' => $body,
          'user' => $userobj,
          'viewmode' => $userrow['teasers'],
        ))) {
          if ($watchdog_level == 0) {
            watchdog('notify', 'User %name (%mail) notified successfully.', array(
              '%name' => $userrow['name'],
              '%mail' => $userrow['mail'],
            ), WATCHDOG_INFO);
          }
          $num_sent++;
        }
        else {
          $num_fail++;
          db_update('notify')
            ->expression('attempts', 'attempts + 1')
            ->condition('uid', $userrow['uid'])
            ->execute();
          if ($watchdog_level <= 2) {
            watchdog('notify', 'User %name (%mail) could not be notified. Mail error.', array(
              '%name' => $userrow['name'],
              '%mail' => $userrow['mail'],
            ), WATCHDOG_ERROR);
          }
        }
      }
      unset($uresult[$index]);
      variable_set('notify_users', $uresult);
    }

    // Restore the original user session.
    $user = $original_user;
    drupal_save_session($old_state);
  }
  else {
    variable_del('notify_users');
  }
  $rest = count(variable_get('notify_users', array()));

  // If $rest is empty, then set notify_send_last.
  if (!$rest) {
    $send_start = variable_get('notify_send_start', 0);
    variable_set('notify_send_last', $send_start);
    variable_set('notify_cron_next', 0);

    // Force reset
    list($res_nodes, $res_comms, $res_nopub, $res_copub, $res_nounp, $res_counp) = _notify_select_content();
    foreach ($res_nopub as $row) {
      db_query('DELETE FROM {notify_unpublished_queue} WHERE cid = :cid AND nid = :nid', array(
        ':cid' => 0,
        ':nid' => $row->nid,
      ));
    }
    if ($res_copub) {
      foreach ($res_copub as $row) {
        db_query('DELETE FROM {notify_unpublished_queue} WHERE cid = :cid AND nid = :nid', array(
          ':cid' => $row->cid,
          ':nid' => $row->nid,
        ));
      }
    }
  }
  return array(
    $num_sent,
    $num_fail,
  );
}