You are here

notifications_feed.module in Notifications 6

Same filename and directory in other branches
  1. 5 notifications_feed/notifications_feed.module

Subscriptions to FeedAPI feeds

This module defines

  • Event types: feed
  • Subscription type: feed

File

notifications_feed/notifications_feed.module
View source
<?php

/**
 * @file
 * Subscriptions to FeedAPI feeds
 * 
 * This module defines 
 * - Event types: feed
 * - Subscription type: feed
 * 
 */

// Max number of feeds per page
define('NOTIFICATIONS_FEED_PAGER', 20);

// Include notifications node API
require_once drupal_get_path('module', 'notifications') . '/notifications.node.inc';

/**
 * Menu access callback
 */
function notifications_feed_access($account) {
  global $user;
  return $account->uid && $account->uid == $user->uid && user_access('subscribe to feeds') || user_access('administer notifications') && user_access('subscribe to feeds', $account);
}

/**
 * Implementation of hook_perm()
 */
function notifications_feed_perm() {
  return array(
    'subscribe to feeds',
  );
}

/**
 * Implementation of hook_notifications().
 */
function notifications_feed_notifications($op, &$arg0, $arg1 = NULL, $arg2 = NULL) {
  switch ($op) {
    case 'names':
      $subs =& $arg0;
      if ($subs->event_type == 'feed') {
        if (!empty($subs->fields['feed-nid'])) {
          $feed = node_load($subs->fields['feed-nid']);
          $subs->names['feed-nid'] = t('Feed: %name', array(
            '%name' => $feed->title,
          ));
        }
      }
      break;
    case 'subscription types':
      $types['feed'] = array(
        'event_type' => 'feed',
        'title' => t('Feed'),
        'access' => 'subscribe to feeds',
        'fields' => array(
          'feed-nid',
        ),
        'page callback' => 'notifications_feed_user_page',
      );
      return $types;
    case 'subscription fields':

      // Information about available fields for subscriptions
      $fields['feed-nid'] = array(
        'name' => t('Feed'),
        'field' => 'feed-nid',
        'type' => 'int',
        'format callback' => 'notifications_node_nid2title',
      );

      // If available node types, add autocomplete information
      if ($node_types = feedapi_get_types()) {
        $fields['feed-nid'] += array(
          'value callback' => 'notifications_feed_title2nid',
          'autocomplete path' => 'notifications/autocomplete/node/type/' . implode(',', array_keys($node_types)),
          'autocomplete callback' => 'notifications_feed_nid2autocomplete',
        );
      }
      return $fields;
    case 'query':
      if ($arg0 == 'event' && $arg1 == 'feed' && ($node = $arg2->feed) || $arg0 == 'user' && $arg1 == 'feed' && ($node = $arg2)) {
        $query[]['fields'] = array(
          'feed-nid' => $node->nid,
        );
        return $query;
      }
      break;
    case 'event types':
      $types[] = array(
        'type' => 'feed',
        'action' => 'update',
        'name' => 'Feed: [title]',
        'line' => "The feed [title] has been updated\n[feed-updated-items]",
        'digest' => array(
          'feed',
          'type',
        ),
      );
      return $types;
    case 'event objects':
      return array(
        'feed' => t('FeedAPI feed'),
      );
    case 'event load':
      $event =& $arg0;
      if ($event->type == 'feed') {
        if (!empty($event->params['nid'])) {

          // For practical reasons like tokens we pass it as node too
          $event->objects['node'] = $feed = node_load($event->params['nid']);

          // Add some more data and we have the feed
          $feed->items_new = $event->params['items_new'];
          $feed->items_updated = $event->params['items_updated'];
          $event->objects['feed'] = $feed;
        }
      }
      break;
    case 'node options':
      return _notifications_feed_node_options($arg0, $arg1);
  }
}
function _notifications_feed_node_options($account, $node) {

  // If node is a feed type
  if ($node->feed) {
    $options[] = array(
      'name' => t('To items in this feed'),
      'type' => 'feed',
      'fields' => array(
        'feed-nid' => $node->nid,
      ),
    );
    return $options;
  }
}

/**
 * Subscription field mapping
 * 
 * Wrapper for notifications_node_title2nid restricting fo feedapi node types
 */
function notifications_feed_title2nid($name, $field = NULL) {
  return notifications_node_title2nid($name, $field, array_keys(feedapi_get_types()));
}

/**
 * Implementation of hook_nodeapi()
 */
function notifications_feed_nodeapi(&$node, $op, $arg = 0) {
  switch ($op) {
    case 'delete':

      // Remove all feed subscriptions for this node
      notifications_delete_subscriptions(array(
        'type' => 'feed',
      ), array(
        'feed-nid' => $node->nid,
      ));
  }
}

/**
 * Implementation of hook_messaging()
 */
function notifications_feed_messaging($op, $type = NULL, $arg2 = NULL, $arg3 = NULL, $arg4 = NULL) {
  switch ($op) {
    case 'message groups':

      // Generic notifications event
      $info['notifications-event-feed'] = array(
        'module' => 'notifications_content',
        'name' => t('Notifications for feed events'),
        'fallback' => 'notifications-event',
      );
      return $info;
    case 'message keys':
      switch ($type) {
        case 'notifications-event-feed':

          // Some parts will be re-used from 'notifications-event' group
          // So we specify only subject and main message
          return array(
            'subject' => t('Subject'),
            'main' => t('Content'),
            'digest' => t('Digest line'),
          );
          break;
      }
      break;
    case 'messages':

      // Event notifications
      switch ($type) {
        case 'notifications-event-feed':
          return array(
            'subject' => t('Feed updated: [title]'),
            'main' => array(
              t('Some feed items have been updated:'),
              '[feed-items-refresh]',
              t('Read more [feed-url]'),
            ),
            'digest' => t('New content for feed [feed-name]. Read more [feed-url]'),
          );
      }
      break;
    case 'tokens':
      if ($type == 'notifications-event-feed') {
        return array(
          'feed',
        );
      }
      break;
  }
}

/**
 * Implementation of hook_feedapi_after_refresh()
 * 
 * We use the is_new and is_updated for each item
 */
function notifications_feed_feedapi_after_refresh($feed) {
  $updated = $new = array();
  foreach ($feed->items as $index => $item) {
    if ($item->is_new) {
      $new[$index] = $item->title;
    }
    if ($item->is_updated) {
      $updated[$index] = $item->title;
    }
  }
  if ($new || $updated) {
    $event = array(
      'module' => 'notifications_feed',
      'uid' => 0,
      'oid' => $feed->nid,
      'type' => 'feed',
      'action' => 'items',
      'feed' => $feed,
      'params' => array(
        'nid' => $feed->nid,
        'items_new' => $new,
        'items_updated' => $updated,
      ),
    );
    notifications_event($event);
  }
}

/**
 * Implementation of hook_token_list(). Documents the individual
 * tokens handled by the module.
 */
function notifications_feed_token_list($type = 'all') {
  $tokens = array();
  if ($type == 'feed' || $type == 'all') {
    $tokens['feed']['feed-name'] = t('The feed name');
    $tokens['feed']['feed-teaser'] = t('The feed teaser.');
    $tokens['feed']['feed-url'] = t('The URL for the feed');
    $tokens['feed']['feed-items-refresh'] = t('The list of refreshed (new and updated) items.');
    $tokens['feed']['feed-items-updated'] = t('The list of updated feed items.');
    $tokens['feed']['feed-items-new'] = t('The list of new feed items');
  }
  return $tokens;
}

/**
 * Implementation of hook_token_values()
 */
function notifications_feed_token_values($type, $object = NULL, $options = array()) {
  switch ($type) {
    case 'feed':
      if ($feed = $object) {
        $values['feed-name'] = check_plain($feed->title);
        $values['feed-teaser'] = $feed->teaser ? check_markup($feed->teaser, $feed->format, FALSE) : '';

        // We may need to use a different link here
        $values['feed-url'] = url('node/' . $feed->nid, array(
          'absolute' => TRUE,
        ));

        // Item lists
        $updated = !empty($feed->items_updated) ? array_map('check_plain', $feed->items_updated) : array();
        $new = !empty($feed->items_new) ? array_map('check_plain', $feed->items_new) : array();
        $refreshed = array();
        foreach ($new as $item) {
          $refreshed[] = t('New: !title', array(
            '!title' => $item,
          ));
        }
        foreach ($updated as $item) {
          $refreshed[] = t('Updated: !title', array(
            '!title' => $item,
          ));
        }
        $values['feed-items-updated'] = theme('notifications_feed_items', $updated);
        $values['feed-items-new'] = theme('notifications_feed_items', $new);
        $values['feed-items-refresh'] = theme('notifications_feed_items', $refreshed);
        return $values;
      }
      break;
  }
}

/**
 * Menu callback. User subscriptions to groups.
 */
function notifications_feed_user_page($account = NULL) {
  global $user;
  $account = $account ? $account : $user;

  // query string for feed subscriptions
  $query = "SELECT s.*, f.value AS nid, n.type AS node_type, n.title FROM {notifications} s \n    INNER JOIN {notifications_fields} f ON s.sid = f.sid LEFT JOIN {node} n ON f.value = CAST(n.nid AS CHAR)\n    WHERE s.uid = %d AND s.type = 'feed' AND s.event_type = 'feed' AND s.conditions = 1 AND f.field = 'feed-nid'\n    ORDER BY node_type, n.title";
  $results = pager_query($query, NOTIFICATIONS_FEED_PAGER, 0, NULL, $account->uid);
  $subscriptions = $list = array();
  while ($sub = db_fetch_object($results)) {
    $subscriptions[$sub->nid] = $sub;
    $list[$sub->nid] = l($sub->title, 'node/' . $sub->nid);
  }
  if (!$subscriptions) {
    $output = t('There are no active feed subscriptions.');
  }
  else {
    $defaults = array(
      'type' => 'feed',
      'event_type' => 'feed',
    );
    $options = array(
      'title' => t('Feed'),
    );
    $output = drupal_get_form('notifications_user_form', $account, 'feed', $subscriptions, $list, $defaults, $options);
    $output .= theme('pager', NOTIFICATIONS_FEED_PAGER);
  }
  return $output;
}

/**
 * Implementation of hook_theme()
 */
function notifications_feed_theme() {
  return array(
    'notifications_feed_items' => array(
      'arguments' => array(
        'items' => NULL,
      ),
    ),
  );
}

/**
 * Theme item list for the message
 * 
 * @param $items
 *  Array
 */
function theme_notifications_feed_items($items) {
  if ($items) {
    return '- ' . implode("\n- ", $items) . "\n";
  }
  else {
    return '';
  }
}

Functions

Namesort descending Description
notifications_feed_access Menu access callback
notifications_feed_feedapi_after_refresh Implementation of hook_feedapi_after_refresh()
notifications_feed_messaging Implementation of hook_messaging()
notifications_feed_nodeapi Implementation of hook_nodeapi()
notifications_feed_notifications Implementation of hook_notifications().
notifications_feed_perm Implementation of hook_perm()
notifications_feed_theme Implementation of hook_theme()
notifications_feed_title2nid Subscription field mapping
notifications_feed_token_list Implementation of hook_token_list(). Documents the individual tokens handled by the module.
notifications_feed_token_values Implementation of hook_token_values()
notifications_feed_user_page Menu callback. User subscriptions to groups.
theme_notifications_feed_items Theme item list for the message
_notifications_feed_node_options

Constants