aggregator.admin.inc 13.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<?php

/**
 * @file
 * Admin page callbacks for the aggregator module.
 */

/**
 * Menu callback; displays the aggregator administration page.
 */
function aggregator_admin_overview() {
  return aggregator_view();
}

15 16 17 18 19 20
/**
 * Displays the aggregator administration page.
 *
 * @return
 *   The page HTML.
 */
21 22 23 24 25 26 27 28
function aggregator_view() {
  $result = db_query('SELECT f.*, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.etag, f.modified, f.image, f.block ORDER BY f.title');

  $output = '<h3>'. t('Feed overview') .'</h3>';

  $header = array(t('Title'), t('Items'), t('Last update'), t('Next update'), array('data' => t('Operations'), 'colspan' => '3'));
  $rows = array();
  while ($feed = db_fetch_object($result)) {
Gábor Hojtsy's avatar
Gábor Hojtsy committed
29 30 31 32 33 34 35 36 37
    $rows[] = array(
      l($feed->title, "aggregator/sources/$feed->fid"),
      format_plural($feed->items, '1 item', '@count items'),
      ($feed->checked ? t('@time ago', array('@time' => format_interval(time() - $feed->checked))) : t('never')),
      ($feed->checked ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - time()))) : t('never')),
      l(t('edit'), "admin/content/aggregator/edit/feed/$feed->fid"),
      l(t('remove items'), "admin/content/aggregator/remove/$feed->fid"),
      l(t('update items'), "admin/content/aggregator/update/$feed->fid", array('query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")))),
    );
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
  }
  $output .= theme('table', $header, $rows);

  $result = db_query('SELECT c.cid, c.title, count(ci.iid) as items FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid GROUP BY c.cid, c.title ORDER BY title');

  $output .= '<h3>'. t('Category overview') .'</h3>';

  $header = array(t('Title'), t('Items'), t('Operations'));
  $rows = array();
  while ($category = db_fetch_object($result)) {
    $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/content/aggregator/edit/category/$category->cid"));
  }
  $output .= theme('table', $header, $rows);

  return $output;
}

/**
 * Form builder; Generate a form to add/edit feed sources.
 *
 * @ingroup forms
59 60
 * @see aggregator_form_feed_validate()
 * @see aggregator_form_feed_submit()
61 62 63 64 65 66 67 68 69 70 71 72
 */
function aggregator_form_feed(&$form_state, $edit = array('refresh' => 900, 'title' => '', 'url' => '', 'fid' => NULL)) {
  $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval');

  if ($edit['refresh'] == '') {
    $edit['refresh'] = 3600;
  }

  $form['title'] = array('#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => $edit['title'],
    '#maxlength' => 255,
73
    '#description' => t('The name of the feed (or the name of the website providing the feed).'),
74 75 76 77 78 79 80 81 82 83 84 85 86
    '#required' => TRUE,
  );
  $form['url'] = array('#type' => 'textfield',
    '#title' => t('URL'),
    '#default_value' => $edit['url'],
    '#maxlength' => 255,
    '#description' => t('The fully-qualified URL of the feed.'),
    '#required' => TRUE,
  );
  $form['refresh'] = array('#type' => 'select',
    '#title' => t('Update interval'),
    '#default_value' => $edit['refresh'],
    '#options' => $period,
87
    '#description' => t('The length of time between feed updates. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', array('@cron' => url('admin/reports/status'))),
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
  );

  // Handling of categories:
  $options = array();
  $values = array();
  $categories = db_query('SELECT c.cid, c.title, f.fid FROM {aggregator_category} c LEFT JOIN {aggregator_category_feed} f ON c.cid = f.cid AND f.fid = %d ORDER BY title', $edit['fid']);
  while ($category = db_fetch_object($categories)) {
    $options[$category->cid] = check_plain($category->title);
    if ($category->fid) $values[] = $category->cid;
  }
  if ($options) {
    $form['category'] = array('#type' => 'checkboxes',
      '#title' => t('Categorize news items'),
      '#default_value' => $values,
      '#options' => $options,
103
      '#description' => t('New feed items are automatically filed in the checked categories.'),
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    );
  }
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));

  if ($edit['fid']) {
    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
    $form['fid'] = array('#type' => 'hidden', '#value' => $edit['fid']);
  }

  return $form;
}

/**
 * Validate aggregator_form_feed form submissions.
 */
function aggregator_form_feed_validate($form, &$form_state) {
  if ($form_state['values']['op'] == t('Save')) {
    // Ensure URL is valid.
    if (!valid_url($form_state['values']['url'], TRUE)) {
      form_set_error('url', t('The URL %url is invalid. Please enter a fully-qualified URL, such as http://www.example.com/feed.xml.', array('%url' => $form_state['values']['url'])));
    }
    // Check for duplicate titles.
    if (isset($form_state['values']['fid'])) {
127
      $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE (title = '%s' OR url = '%s') AND fid <> %d", $form_state['values']['title'], $form_state['values']['url'], $form_state['values']['fid']);
128 129
    }
    else {
130
      $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = '%s' OR url = '%s'", $form_state['values']['title'], $form_state['values']['url']);
131 132 133 134 135 136 137 138 139 140 141 142 143 144
    }
    while ($feed = db_fetch_object($result)) {
      if (strcasecmp($feed->title, $form_state['values']['title']) == 0) {
        form_set_error('title', t('A feed named %feed already exists. Please enter a unique title.', array('%feed' => $form_state['values']['title'])));
      }
      if (strcasecmp($feed->url, $form_state['values']['url']) == 0) {
        form_set_error('url', t('A feed with this URL %url already exists. Please enter a unique URL.', array('%url' => $form_state['values']['url'])));
      }
    }
  }
}

/**
 * Process aggregator_form_feed form submissions.
145
 *
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
 * @todo Add delete confirmation dialog.
 */
function aggregator_form_feed_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Delete')) {
    $title = $form_state['values']['title'];
    // Unset the title:
    unset($form_state['values']['title']);
  }
  aggregator_save_feed($form_state['values']);
  if (isset($form_state['values']['fid'])) {
    if (isset($form_state['values']['title'])) {
      drupal_set_message(t('The feed %feed has been updated.', array('%feed' => $form_state['values']['title'])));
      if (arg(0) == 'admin') {
        $form_state['redirect'] = 'admin/content/aggregator/';
        return;
      }
      else {
        $form_state['redirect'] = 'aggregator/sources/'. $form_state['values']['fid'];
        return;
      }
    }
    else {
      watchdog('aggregator', 'Feed %feed deleted.', array('%feed' => $title));
      drupal_set_message(t('The feed %feed has been deleted.', array('%feed' => $title)));
      if (arg(0) == 'admin') {
        $form_state['redirect'] = 'admin/content/aggregator/';
        return;
      }
      else {
        $form_state['redirect'] = 'aggregator/sources/';
        return;
      }
    }
  }
  else {
    watchdog('aggregator', 'Feed %feed added.', array('%feed' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/content/aggregator'));
    drupal_set_message(t('The feed %feed has been added.', array('%feed' => $form_state['values']['title'])));
  }
}

Gábor Hojtsy's avatar
Gábor Hojtsy committed
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
function aggregator_admin_remove_feed($form_state, $feed) {
  return confirm_form(
    array(
      'feed' => array(
        '#type' => 'value',
        '#value' => $feed,
      ),
    ),
    t('Are you sure you want to remove all items from the feed %feed?', array('%feed' => $feed['title'])),
    'admin/content/aggregator',
    t('This action cannot be undone.'),
    t('Remove items'),
    t('Cancel')
  );
}

202
/**
Gábor Hojtsy's avatar
Gábor Hojtsy committed
203
 * Remove all items from a feed and redirect to the overview page.
204 205 206
 *
 * @param $feed
 *   An associative array describing the feed to be cleared.
207
 */
Gábor Hojtsy's avatar
Gábor Hojtsy committed
208 209 210
function aggregator_admin_remove_feed_submit($form, &$form_state) {
  aggregator_remove($form_state['values']['feed']);
  $form_state['redirect'] = 'admin/content/aggregator';
211 212 213 214
}

/**
 * Menu callback; refreshes a feed, then redirects to the overview page.
215 216 217
 *
 * @param $feed
 *   An associative array describing the feed to be refreshed.
218 219
 */
function aggregator_admin_refresh_feed($feed) {
Gábor Hojtsy's avatar
Gábor Hojtsy committed
220 221 222
  if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'aggregator/update/' . $feed['fid'])) {
    return drupal_access_denied();
  }
223 224 225 226 227 228 229 230
  aggregator_refresh($feed);
  drupal_goto('admin/content/aggregator');
}

/**
 * Form builder; Configure the aggregator system.
 *
 * @ingroup forms
231
 * @see system_settings_form()
232 233 234 235 236 237 238 239
 */
function aggregator_admin_settings() {
  $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');

  $form['aggregator_allowed_html_tags'] = array(
    '#type' => 'textfield', '#title' => t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255,
    '#default_value' => variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'),
240
    '#description' => t('A space-separated list of HTML tags allowed in the content of feed items. (Tags in this list are not removed by Drupal.)')
241 242 243 244 245
  );

  $form['aggregator_summary_items'] = array(
    '#type' => 'select', '#title' => t('Items shown in sources and categories pages') ,
    '#default_value' => variable_get('aggregator_summary_items', 3), '#options' => $items,
246
    '#description' => t('Number of feed items displayed in feed and category summary pages.')
247 248 249
  );

  $form['aggregator_clear'] = array(
250
    '#type' => 'select', '#title' => t('Discard items older than'),
251
    '#default_value' => variable_get('aggregator_clear', 9676800), '#options' => $period,
252
    '#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')))
253 254 255 256 257
  );

  $form['aggregator_category_selector'] = array(
    '#type' => 'radios', '#title' => t('Category selection type'), '#default_value' => variable_get('aggregator_category_selector', 'checkboxes'),
    '#options' => array('checkboxes' => t('checkboxes'), 'select' => t('multiple selector')),
258
    '#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 work well with large numbers of categories.)')
259 260 261 262 263 264 265 266 267
  );

  return system_settings_form($form);
}

/**
 * Form builder; Generate a form to add/edit/delete aggregator categories.
 *
 * @ingroup forms
268 269
 * @see aggregator_form_category_validate()
 * @see aggregator_form_category_submit()
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
 */
function aggregator_form_category(&$form_state, $edit = array('title' => '', 'description' => '', 'cid' => NULL)) {
  $form['title'] = array('#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => $edit['title'],
    '#maxlength' => 64,
    '#required' => TRUE,
  );
  $form['description'] = array('#type' => 'textarea',
    '#title' => t('Description'),
    '#default_value' => $edit['description'],
  );
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));

  if ($edit['cid']) {
    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
    $form['cid'] = array('#type' => 'hidden', '#value' => $edit['cid']);
  }

  return $form;
}

/**
 * Validate aggregator_form_feed form submissions.
 */
function aggregator_form_category_validate($form, &$form_state) {
  if ($form_state['values']['op'] == t('Save')) {
    // Check for duplicate titles
    if (isset($form_state['values']['cid'])) {
299
      $category = db_fetch_object(db_query("SELECT cid FROM {aggregator_category} WHERE title = '%s' AND cid <> %d", $form_state['values']['title'], $form_state['values']['cid']));
300 301 302 303 304 305 306 307 308 309 310 311
    }
    else {
      $category = db_fetch_object(db_query("SELECT cid FROM {aggregator_category} WHERE title = '%s'", $form_state['values']['title']));
    }
    if ($category) {
      form_set_error('title', t('A category named %category already exists. Please enter a unique title.', array('%category' => $form_state['values']['title'])));
    }
  }
}

/**
 * Process aggregator_form_category form submissions.
312
 *
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
 * @todo Add delete confirmation dialog.
 */
function aggregator_form_category_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Delete')) {
    $title = $form_state['values']['title'];
    // Unset the title:
    unset($form_state['values']['title']);
  }
  aggregator_save_category($form_state['values']);
  if (isset($form_state['values']['cid'])) {
    if (isset($form_state['values']['title'])) {
      drupal_set_message(t('The category %category has been updated.', array('%category' => $form_state['values']['title'])));
      if (arg(0) == 'admin') {
        $form_state['redirect'] = 'admin/content/aggregator/';
        return;
      }
      else {
        $form_state['redirect'] = 'aggregator/categories/'. $form_state['values']['cid'];
        return;
      }
    }
    else {
      watchdog('aggregator', 'Category %category deleted.', array('%category' => $title));
      drupal_set_message(t('The category %category has been deleted.', array('%category' => $title)));
      if (arg(0) == 'admin') {
        $form_state['redirect'] = 'admin/content/aggregator/';
        return;
      }
      else {
        $form_state['redirect'] = 'aggregator/categories/';
        return;
      }
    }
  }
  else {
    watchdog('aggregator', 'Category %category added.', array('%category' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/content/aggregator'));
    drupal_set_message(t('The category %category has been added.', array('%category' => $form_state['values']['title'])));
  }
}