aggregator.processor.inc 7.62 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php
// $Id$

/**
 * @file
 * Processor functions for the aggregator module.
 */

/**
10
 * Implement hook_aggregator_process_info().
11 12 13 14 15 16 17 18 19
 */
function aggregator_aggregator_process_info() {
  return array(
    'title' => t('Default processor'),
    'description' => t('Creates lightweight records from feed items.'),
  );
}

/**
20
 * Implement hook_aggregator_process().
21 22 23 24 25 26 27 28
 */
function aggregator_aggregator_process($feed) {
  if (is_object($feed)) {
    if (is_array($feed->items)) {
      foreach ($feed->items as $item) {
        // Save this item. Try to avoid duplicate entries as much as possible. If
        // we find a duplicate entry, we resolve it and pass along its ID is such
        // that we can update it if needed.
29 30
        if (!empty($item['guid'])) {
          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND guid = :guid", array(':fid' => $feed->fid, ':guid' => $item['guid']))->fetchObject();
31
        }
32 33
        elseif ($item['link'] && $item['link'] != $feed->link && $item['link'] != $feed->url) {
          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND link = :link", array(':fid' => $feed->fid, ':link' => $item['link']))->fetchObject();
34 35
        }
        else {
36
          $entry = db_query("SELECT iid, timestamp FROM {aggregator_item} WHERE fid = :fid AND title = :title", array(':fid' => $feed->fid, ':title' => $item['title']))->fetchObject();
37
        }
38 39
        if (!$item['timestamp']) {
          $item['timestamp'] = isset($entry->timestamp) ? $entry->timestamp : REQUEST_TIME;
40
        }
41
        aggregator_save_item(array('iid' => (isset($entry->iid) ? $entry->iid : ''), 'fid' => $feed->fid, 'timestamp' => $item['timestamp'], 'title' => $item['title'], 'link' => $item['link'], 'author' => $item['author'], 'description' => $item['description'], 'guid' => $item['guid']));
42 43 44 45 46 47
      }
    }
  }
}

/**
48
 * Implement hook_aggregator_remove().
49 50 51 52 53 54 55 56 57 58 59
 */
function aggregator_aggregator_remove($feed) {
  $iids = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->fid))->fetchCol();
  if ($iids) {
    db_delete('aggregator_category_item')
      ->condition('iid', $iids, 'IN')
      ->execute();
  }
  db_delete('aggregator_item')
    ->condition('fid', $feed->fid)
    ->execute();
Dries's avatar
Dries committed
60

61 62 63 64
  drupal_set_message(t('The news items from %site have been removed.', array('%site' => $feed->title)));
}

/**
65
 * Implement hook_form_aggregator_admin_form_alter().
Dries's avatar
Dries committed
66
 *
67 68 69 70 71 72 73 74
 * Form alter aggregator module's own form to keep processor functionality
 * separate from aggregator API functionality.
 */
function aggregator_form_aggregator_admin_form_alter(&$form, $form_state) {
  if (in_array('aggregator', variable_get('aggregator_processors', array('aggregator')))) {
    $info = module_invoke('aggregator', 'aggregator_process', 'info');
    $items = array(0 => t('none')) + drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items');
    $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
75
    $period[AGGREGATOR_CLEAR_NEVER] = t('Never');
76 77 78 79 80 81 82 83 84 85 86 87 88 89

    // Only wrap into a collapsible fieldset if there is a basic configuration.
    if (isset($form['basic_conf'])) {
      $form['modules']['aggregator'] = array(
        '#type' => 'fieldset',
        '#title' => t('Default processor settings'),
        '#description' => $info['description'],
        '#collapsible' => TRUE,
        '#collapsed' => !in_array('aggregator', variable_get('aggregator_processors', array('aggregator'))),
      );
    }
    else {
      $form['modules']['aggregator'] = array();
    }
Dries's avatar
Dries committed
90

91
    $form['modules']['aggregator']['aggregator_summary_items'] = array(
Dries's avatar
Dries committed
92
      '#type' => 'select',
93
      '#title' => t('Items shown in sources and categories pages') ,
Dries's avatar
Dries committed
94
      '#default_value' => variable_get('aggregator_summary_items', 3),
95 96 97 98 99
      '#options' => $items,
      '#description' => t('Number of feed items displayed in feed and category summary pages.'),
    );

    $form['modules']['aggregator']['aggregator_clear'] = array(
Dries's avatar
Dries committed
100
      '#type' => 'select',
101
      '#title' => t('Discard items older than'),
Dries's avatar
Dries committed
102
      '#default_value' => variable_get('aggregator_clear', 9676800),
103 104 105 106 107
      '#options' => $period,
      '#description' => t('The length of time to retain feed items before discarding. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', array('@cron' => url('admin/reports/status'))),
    );

    $form['modules']['aggregator']['aggregator_category_selector'] = array(
Dries's avatar
Dries committed
108 109
      '#type' => 'radios',
      '#title' => t('Category selection type'),
110
      '#default_value' => variable_get('aggregator_category_selector', 'checkboxes'),
Dries's avatar
Dries committed
111
      '#options' => array('checkboxes' => t('checkboxes'),
112 113 114
      'select' => t('multiple selector')),
      '#description' => t('The type of category selection widget displayed on categorization pages. (For a small number of categories, checkboxes are easier to use, while a multiple selector works well with large numbers of categories.)'),
    );
115 116 117 118 119
    $form['modules']['aggregator']['aggregator_teaser_length'] = array(
      '#type' => 'select',
      '#title' => t('Length of trimmed description'),
      '#default_value' => 600,
      '#options' => drupal_map_assoc(array(0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000), '_aggregator_characters'),
120
      '#description' => t("The maximum number of characters used in the trimmed version of content.")
121 122
    );

123 124 125
  }
}

126 127 128 129 130 131 132
/**
 * Helper function for teaser length choices.
 */
function _aggregator_characters($length) {
  return ($length == 0) ? t('Unlimited') : format_plural($length, '1 character', '@count characters');
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
/**
 * Add/edit/delete an aggregator item.
 *
 * @param $edit
 *   An associative array describing the item to be added/edited/deleted.
 */
function aggregator_save_item($edit) {
  if ($edit['title'] && empty($edit['iid'])) {
    $edit['iid'] = db_insert('aggregator_item')
      ->fields(array(
        'title' => $edit['title'],
        'link' => $edit['link'],
        'author' => $edit['author'],
        'description' => $edit['description'],
        'guid' => $edit['guid'],
        'timestamp' => $edit['timestamp'],
        'fid' => $edit['fid'],
      ))
      ->execute();
  }
  if ($edit['iid'] && !$edit['title']) {
    db_delete('aggregator_item')
      ->condition('iid', $edit['iid'])
      ->execute();
    db_delete('aggregator_category_item')
      ->condition('iid', $edit['iid'])
      ->execute();
  }
  elseif ($edit['title'] && $edit['link']) {
    // file the items in the categories indicated by the feed
    $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $edit['fid']));
    foreach ($result as $category) {
      db_merge('aggregator_category_item')
166
        ->key(array('iid' => $edit['iid']))
167 168 169 170 171 172 173 174 175 176
        ->fields(array(
          'cid' => $category->cid,
        ))
        ->execute();
    }
  }
}

/**
 * Expire feed items on $feed that are older than aggregator_clear.
Dries's avatar
Dries committed
177
 *
178 179 180 181
 * @param $feed
 *   Object describing feed.
 */
function aggregator_expire($feed) {
182 183 184 185 186 187
  $aggregator_clear = variable_get('aggregator_clear', 9676800);

  if ($aggregator_clear != AGGREGATOR_CLEAR_NEVER) {
    // Remove all items that are older than flush item timer.
    $age = REQUEST_TIME - $aggregator_clear;
    $iids = db_query('SELECT iid FROM {aggregator_item} WHERE fid = :fid AND timestamp < :timestamp', array(
188
      ':fid' => $feed->fid,
189 190 191 192 193 194 195 196 197 198 199
      ':timestamp' => $age,
    ))
    ->fetchCol();
    if ($iids) {
      db_delete('aggregator_category_item')
        ->condition('iid', $iids, 'IN')
        ->execute();
      db_delete('aggregator_item')
        ->condition('iid', $iids, 'IN')
        ->execute();
    }
200 201
  }
}