Drupal PHP Cross Reference Content Management Systems

Source: /modules/aggregator/aggregator.pages.inc - 563 lines - 19422 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /**
   4   * @file
   5   * User page callbacks for the aggregator module.
   6   */
   7  
   8  /**
   9   * Menu callback; displays the most recent items gathered from any feed.
  10   *
  11   * @return
  12   *   The items HTML.
  13   */
  14  function aggregator_page_last() {
  15    drupal_add_feed('aggregator/rss', variable_get('site_name', 'Drupal') . ' ' . t('aggregator'));
  16  
  17    $items = aggregator_feed_items_load('sum');
  18  
  19    return _aggregator_page_list($items, arg(1));
  20  }
  21  
  22  /**
  23   * Menu callback; displays all the items captured from a particular feed.
  24   *
  25   * @param $feed
  26   *   The feed for which to display all items.
  27   *
  28   * @return
  29   *   The rendered list of items for a feed.
  30   */
  31  function aggregator_page_source($feed) {
  32    drupal_set_title($feed->title);
  33    $feed_source = theme('aggregator_feed_source', array('feed' => $feed));
  34  
  35    // It is safe to include the fid in the query because it's loaded from the
  36    // database by aggregator_feed_load.
  37    $items = aggregator_feed_items_load('source', $feed);
  38  
  39    return _aggregator_page_list($items, arg(3), $feed_source);
  40  }
  41  
  42  /**
  43   * Menu callback; displays a form with all items captured from a feed.
  44   *
  45   * @param $feed
  46   *   The feed for which to list all the aggregated items.
  47   *
  48   * @return
  49   *   The rendered list of items for a feed.
  50   *
  51   * @see aggregator_page_source()
  52   */
  53  function aggregator_page_source_form($form, $form_state, $feed) {
  54    return aggregator_page_source($feed);
  55  }
  56  
  57  /**
  58   * Menu callback; displays all the items aggregated in a particular category.
  59   *
  60   * @param $category
  61   *   The category for which to list all the aggregated items.
  62   *
  63   * @return
  64  *   The rendered list of items for a category.
  65   */
  66  function aggregator_page_category($category) {
  67    drupal_add_feed('aggregator/rss/' . $category['cid'], variable_get('site_name', 'Drupal') . ' ' . t('aggregator - @title', array('@title' => $category['title'])));
  68  
  69    // It is safe to include the cid in the query because it's loaded from the
  70    // database by aggregator_category_load.
  71    $items = aggregator_feed_items_load('category', $category);
  72  
  73    return _aggregator_page_list($items, arg(3));
  74  }
  75  
  76  /**
  77   * Menu callback; displays a form containing items aggregated in a category.
  78   *
  79   * @param $category
  80   *   The category for which to list all the aggregated items.
  81   *
  82   * @return
  83  *   The rendered list of items for a category.
  84   *
  85   * @see aggregator_page_category()
  86   */
  87  function aggregator_page_category_form($form, $form_state, $category) {
  88    return aggregator_page_category($category);
  89  }
  90  
  91  /**
  92   * Loads and optionally filters feed items.
  93   *
  94   * @param $type
  95   *   The type of filter for the items. Possible values are:
  96   *   - sum: No filtering.
  97   *   - source: Filter the feed items, limiting the result to items from a
  98   *     single source.
  99   *   - category: Filter the feed items by category.
 100   * @param $data
 101   *   Feed or category data used for filtering. The type and value of $data
 102   *   depends on $type:
 103   *   - source: $data is an object with $data->fid identifying the feed used to
 104   *     as filter.
 105   *   - category: $data is an array with $data['cid'] being the category id to
 106   *     filter on.
 107   *   The $data parameter is not used when $type is 'sum'.
 108   *
 109   * @return
 110   *   An array of the feed items.
 111   */
 112  function aggregator_feed_items_load($type, $data = NULL) {
 113    $items = array();
 114    switch ($type) {
 115      case 'sum':
 116        $query = db_select('aggregator_item', 'i');
 117        $query->join('aggregator_feed', 'f', 'i.fid = f.fid');
 118        $query->fields('i');
 119        $query->addField('f', 'title', 'ftitle');
 120        $query->addField('f', 'link', 'flink');
 121        break;
 122      case 'source':
 123        $query = db_select('aggregator_item', 'i');
 124        $query
 125          ->fields('i')
 126          ->condition('i.fid', $data->fid);
 127        break;
 128      case 'category':
 129        $query = db_select('aggregator_category_item', 'c');
 130        $query->leftJoin('aggregator_item', 'i', 'c.iid = i.iid');
 131        $query->leftJoin('aggregator_feed', 'f', 'i.fid = f.fid');
 132        $query
 133          ->fields('i')
 134          ->condition('cid', $data['cid']);
 135        $query->addField('f', 'title', 'ftitle');
 136        $query->addField('f', 'link', 'flink');
 137        break;
 138    }
 139  
 140    $result = $query
 141      ->extend('PagerDefault')
 142      ->limit(20)
 143      ->orderBy('i.timestamp', 'DESC')
 144      ->orderBy('i.iid', 'DESC')
 145      ->execute();
 146  
 147    foreach ($result as $item) {
 148      $item->categories = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = :iid ORDER BY c.title', array(':iid' => $item->iid))->fetchAll();
 149      $items[] = $item;
 150    }
 151  
 152    return $items;
 153  }
 154  
 155  /**
 156   * Prints an aggregator page listing a number of feed items.
 157   *
 158   * Various menu callbacks use this function to print their feeds.
 159   *
 160   * @param $items
 161   *   The items to be listed.
 162   * @param $op
 163   *   Which form should be added to the items. Only 'categorize' is now
 164   *   recognized.
 165   * @param $feed_source
 166   *   The feed source URL.
 167   *
 168   * @return
 169   *   The rendered list of items for a feed.
 170   */
 171  function _aggregator_page_list($items, $op, $feed_source = '') {
 172    if (user_access('administer news feeds') && ($op == 'categorize')) {
 173      // Get form data.
 174      $output = aggregator_categorize_items($items, $feed_source);
 175    }
 176    else {
 177      // Assemble themed output.
 178      $output = $feed_source;
 179      foreach ($items as $item) {
 180        $output .= theme('aggregator_item', array('item' => $item));
 181      }
 182      $output = theme('aggregator_wrapper', array('content' => $output));
 183    }
 184  
 185    return $output;
 186  }
 187  
 188  /**
 189   * Form constructor to build the page list form.
 190   *
 191   * @param $items
 192   *   An array of the feed items.
 193   * @param $feed_source
 194   *   The feed source URL.
 195   *
 196   * @ingroup forms
 197   * @see aggregator_categorize_items_submit()
 198   */
 199  function aggregator_categorize_items($items, $feed_source = '') {
 200    $form['#submit'][] = 'aggregator_categorize_items_submit';
 201    $form['#theme'] = 'aggregator_categorize_items';
 202    $form['feed_source'] = array(
 203      '#value' => $feed_source,
 204    );
 205    $categories = array();
 206    $done = FALSE;
 207    $form['items'] = array();
 208    $form['categories'] = array(
 209      '#tree' => TRUE,
 210    );
 211    foreach ($items as $item) {
 212      $form['items'][$item->iid] = array('#markup' => theme('aggregator_item', array('item' => $item)));
 213      $form['categories'][$item->iid] = array();
 214      $categories_result = db_query('SELECT c.cid, c.title, ci.iid FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid AND ci.iid = :iid', array(':iid' => $item->iid));
 215      $selected = array();
 216      foreach ($categories_result as $category) {
 217        if (!$done) {
 218          $categories[$category->cid] = check_plain($category->title);
 219        }
 220        if ($category->iid) {
 221          $selected[] = $category->cid;
 222        }
 223      }
 224      $done = TRUE;
 225      $form['categories'][$item->iid] = array(
 226        '#type' => variable_get('aggregator_category_selector', 'checkboxes'),
 227        '#default_value' => $selected,
 228        '#options' => $categories,
 229        '#size' => 10,
 230        '#multiple' => TRUE
 231      );
 232    }
 233    $form['actions'] = array('#type' => 'actions');
 234    $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save categories'));
 235  
 236    return $form;
 237  }
 238  
 239  /**
 240   * Form submission handler for aggregator_categorize_items().
 241   */
 242  function aggregator_categorize_items_submit($form, &$form_state) {
 243    if (!empty($form_state['values']['categories'])) {
 244      foreach ($form_state['values']['categories'] as $iid => $selection) {
 245        db_delete('aggregator_category_item')
 246          ->condition('iid', $iid)
 247          ->execute();
 248        $insert = db_insert('aggregator_category_item')->fields(array('iid', 'cid'));
 249        $has_values = FALSE;
 250        foreach ($selection as $cid) {
 251          if ($cid && $iid) {
 252            $has_values = TRUE;
 253            $insert->values(array(
 254              'iid' => $iid,
 255              'cid' => $cid,
 256            ));
 257          }
 258        }
 259        if ($has_values) {
 260          $insert->execute();
 261        }
 262      }
 263    }
 264    drupal_set_message(t('The categories have been saved.'));
 265  }
 266  
 267  /**
 268   * Returns HTML for the aggregator page list form for assigning categories.
 269   *
 270   * @param $variables
 271   *   An associative array containing:
 272   *   - form: A render element representing the form.
 273   *
 274   * @ingroup themeable
 275   */
 276  function theme_aggregator_categorize_items($variables) {
 277    $form = $variables['form'];
 278  
 279    $output = drupal_render($form['feed_source']);
 280    $rows = array();
 281    if (!empty($form['items'])) {
 282      foreach (element_children($form['items']) as $key) {
 283        $rows[] = array(
 284          drupal_render($form['items'][$key]),
 285          array('data' => drupal_render($form['categories'][$key]), 'class' => array('categorize-item')),
 286        );
 287      }
 288    }
 289    $output .= theme('table', array('header' => array('', t('Categorize')), 'rows' => $rows));
 290    $output .= drupal_render($form['submit']);
 291    $output .= drupal_render_children($form);
 292  
 293    return theme('aggregator_wrapper', array('content' => $output));
 294  }
 295  
 296  /**
 297   * Processes variables for aggregator-wrapper.tpl.php.
 298   *
 299   * @see aggregator-wrapper.tpl.php
 300   */
 301  function template_preprocess_aggregator_wrapper(&$variables) {
 302    $variables['pager'] = theme('pager');
 303  }
 304  
 305  /**
 306   * Processes variables for aggregator-item.tpl.php.
 307   *
 308   * @see aggregator-item.tpl.php
 309   */
 310  function template_preprocess_aggregator_item(&$variables) {
 311    $item = $variables['item'];
 312  
 313    $variables['feed_url'] = check_url($item->link);
 314    $variables['feed_title'] = check_plain($item->title);
 315    $variables['content'] = aggregator_filter_xss($item->description);
 316  
 317    $variables['source_url'] = '';
 318    $variables['source_title'] = '';
 319    if (isset($item->ftitle) && isset($item->fid)) {
 320      $variables['source_url'] = url("aggregator/sources/$item->fid");
 321      $variables['source_title'] = check_plain($item->ftitle);
 322    }
 323    if (date('Ymd', $item->timestamp) == date('Ymd')) {
 324      $variables['source_date'] = t('%ago ago', array('%ago' => format_interval(REQUEST_TIME - $item->timestamp)));
 325    }
 326    else {
 327      $variables['source_date'] = format_date($item->timestamp, 'custom', variable_get('date_format_medium', 'D, m/d/Y - H:i'));
 328    }
 329  
 330    $variables['categories'] = array();
 331    foreach ($item->categories as $category) {
 332      $variables['categories'][$category->cid] = l($category->title, 'aggregator/categories/' . $category->cid);
 333    }
 334  }
 335  
 336  /**
 337   * Menu callback; displays all the feeds used by the aggregator.
 338   */
 339  function aggregator_page_sources() {
 340    $result = db_query('SELECT f.fid, f.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.description, f.image ORDER BY last DESC, f.title');
 341  
 342    $output = '';
 343    foreach ($result as $feed) {
 344      // Most recent items:
 345      $summary_items = array();
 346      if (variable_get('aggregator_summary_items', 3)) {
 347        $items = db_query_range('SELECT i.title, i.timestamp, i.link FROM {aggregator_item} i WHERE i.fid = :fid ORDER BY i.timestamp DESC', 0, variable_get('aggregator_summary_items', 3), array(':fid' => $feed->fid));
 348        foreach ($items as $item) {
 349          $summary_items[] = theme('aggregator_summary_item', array('item' => $item));
 350        }
 351      }
 352      $feed->url = url('aggregator/sources/' . $feed->fid);
 353      $output .= theme('aggregator_summary_items', array('summary_items' => $summary_items, 'source' => $feed));
 354    }
 355    $output .= theme('feed_icon', array('url' => 'aggregator/opml', 'title' => t('OPML feed')));
 356  
 357    return theme('aggregator_wrapper', array('content' => $output));
 358  }
 359  
 360  /**
 361   * Menu callback; displays all the categories used by the aggregator.
 362   */
 363  function aggregator_page_categories() {
 364    $result = db_query('SELECT c.cid, c.title, c.description FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid LEFT JOIN {aggregator_item} i ON ci.iid = i.iid GROUP BY c.cid, c.title, c.description');
 365  
 366    $output = '';
 367    foreach ($result as $category) {
 368      if (variable_get('aggregator_summary_items', 3)) {
 369        $summary_items = array();
 370        $items = db_query_range('SELECT i.title, i.timestamp, i.link, f.title as feed_title, f.link as feed_link FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON i.iid = ci.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE ci.cid = :cid ORDER BY i.timestamp DESC', 0, variable_get('aggregator_summary_items', 3), array(':cid' => $category->cid));
 371        foreach ($items as $item) {
 372          $summary_items[] = theme('aggregator_summary_item', array('item' => $item));
 373        }
 374      }
 375      $category->url = url('aggregator/categories/' . $category->cid);
 376      $output .= theme('aggregator_summary_items', array('summary_items' => $summary_items, 'source' => $category));
 377    }
 378  
 379    return theme('aggregator_wrapper', array('content' => $output));
 380  }
 381  
 382  /**
 383   * Menu callback; generate an RSS 0.92 feed of aggregator items or categories.
 384   */
 385  function aggregator_page_rss() {
 386    $result = NULL;
 387    // arg(2) is the passed cid, only select for that category.
 388    if (arg(2)) {
 389      $category = db_query('SELECT cid, title FROM {aggregator_category} WHERE cid = :cid', array(':cid' => arg(2)))->fetchObject();
 390      $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = :cid ORDER BY timestamp DESC, i.iid DESC', 0, variable_get('feed_default_items', 10), array(':cid' => $category->cid));
 391    }
 392    // Or, get the default aggregator items.
 393    else {
 394      $category = NULL;
 395      $result = db_query_range('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.fid = f.fid ORDER BY i.timestamp DESC, i.iid DESC', 0, variable_get('feed_default_items', 10));
 396    }
 397  
 398    $feeds = $result->fetchAll();
 399    return theme('aggregator_page_rss', array('feeds' => $feeds, 'category' => $category));
 400  }
 401  
 402  /**
 403   * Prints the RSS page for a feed.
 404   *
 405   * @param $variables
 406   *   An associative array containing:
 407   *   - feeds: An array of the feeds to theme.
 408   *   - category: A common category, if any, for all the feeds.
 409   *
 410   * @return void
 411   *
 412   * @ingroup themeable
 413   */
 414  function theme_aggregator_page_rss($variables) {
 415    $feeds = $variables['feeds'];
 416    $category = $variables['category'];
 417  
 418    drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
 419  
 420    $items = '';
 421    $feed_length = variable_get('feed_item_length', 'fulltext');
 422    foreach ($feeds as $feed) {
 423      switch ($feed_length) {
 424        case 'teaser':
 425          $summary = text_summary($feed->description, NULL, variable_get('aggregator_teaser_length', 600));
 426          if ($summary != $feed->description) {
 427            $summary .= '<p><a href="' . check_url($feed->link) . '">' . t('read more') . "</a></p>\n";
 428          }
 429          $feed->description = $summary;
 430          break;
 431        case 'title':
 432          $feed->description = '';
 433          break;
 434      }
 435      $items .= format_rss_item($feed->ftitle . ': ' . $feed->title, $feed->link, $feed->description, array('pubDate' => date('r', $feed->timestamp)));
 436    }
 437  
 438    $site_name = variable_get('site_name', 'Drupal');
 439    $url = url((isset($category) ? 'aggregator/categories/' . $category->cid : 'aggregator'), array('absolute' => TRUE));
 440    $description = isset($category) ? t('@site_name - aggregated feeds in category @title', array('@site_name' => $site_name, '@title' => $category->title)) : t('@site_name - aggregated feeds', array('@site_name' => $site_name));
 441  
 442    $output  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 443    $output .= "<rss version=\"2.0\">\n";
 444    $output .= format_rss_channel(t('@site_name aggregator', array('@site_name' => $site_name)), $url, $description, $items);
 445    $output .= "</rss>\n";
 446  
 447    print $output;
 448  }
 449  
 450  /**
 451   * Menu callback; generates an OPML representation of all feeds.
 452   *
 453   * @param $cid
 454   *   If set, feeds are exported only from a category with this ID. Otherwise, all feeds are exported.
 455   * @return
 456   *   The output XML.
 457   */
 458  function aggregator_page_opml($cid = NULL) {
 459    if ($cid) {
 460      $result = db_query('SELECT f.title, f.url FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} c on f.fid = c.fid WHERE c.cid = :cid ORDER BY title', array(':cid' => $cid));
 461    }
 462    else {
 463      $result = db_query('SELECT * FROM {aggregator_feed} ORDER BY title');
 464    }
 465  
 466    $feeds = $result->fetchAll();
 467    return theme('aggregator_page_opml', array('feeds' => $feeds));
 468  }
 469  
 470  /**
 471   * Prints the OPML page for a feed.
 472   *
 473   * @param $variables
 474   *   An associative array containing:
 475   *   - feeds: An array of the feeds to theme.
 476   *
 477   * @return void
 478   *
 479   * @ingroup themeable
 480   */
 481  function theme_aggregator_page_opml($variables) {
 482    $feeds = $variables['feeds'];
 483  
 484    drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');
 485  
 486    $output  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 487    $output .= "<opml version=\"1.1\">\n";
 488    $output .= "<head>\n";
 489    $output .= '<title>' . check_plain(variable_get('site_name', 'Drupal')) . "</title>\n";
 490    $output .= '<dateModified>' . gmdate(DATE_RFC2822, REQUEST_TIME) . "</dateModified>\n";
 491    $output .= "</head>\n";
 492    $output .= "<body>\n";
 493    foreach ($feeds as $feed) {
 494      $output .= '<outline text="' . check_plain($feed->title) . '" xmlUrl="' . check_url($feed->url) . "\" />\n";
 495    }
 496    $output .= "</body>\n";
 497    $output .= "</opml>\n";
 498  
 499    print $output;
 500  }
 501  
 502  /**
 503   * Processes variables for aggregator-summary-items.tpl.php.
 504   *
 505   * @see aggregator-summary-items.tpl.php
 506   */
 507  function template_preprocess_aggregator_summary_items(&$variables) {
 508    $variables['title'] = check_plain($variables['source']->title);
 509    $variables['summary_list'] = theme('item_list', array('items' => $variables['summary_items']));
 510    $variables['source_url'] = $variables['source']->url;
 511  }
 512  
 513  /**
 514   * Processes variables for aggregator-summary-item.tpl.php.
 515   *
 516   * @see aggregator-summary-item.tpl.php
 517   */
 518  function template_preprocess_aggregator_summary_item(&$variables) {
 519    $item = $variables['item'];
 520  
 521    $variables['feed_url'] = check_url($item->link);
 522    $variables['feed_title'] = check_plain($item->title);
 523    $variables['feed_age'] = t('%age old', array('%age' => format_interval(REQUEST_TIME - $item->timestamp)));
 524  
 525    $variables['source_url'] = '';
 526    $variables['source_title'] = '';
 527    if (!empty($item->feed_link)) {
 528      $variables['source_url'] = check_url($item->feed_link);
 529      $variables['source_title'] = check_plain($item->feed_title);
 530    }
 531  }
 532  
 533  /**
 534   * Processes variables for aggregator-feed-source.tpl.php.
 535   *
 536   * @see aggregator-feed-source.tpl.php
 537   */
 538  function template_preprocess_aggregator_feed_source(&$variables) {
 539    $feed = $variables['feed'];
 540  
 541    $variables['source_icon'] = theme('feed_icon', array('url' => $feed->url, 'title' => t('!title feed', array('!title' => $feed->title))));
 542  
 543    if (!empty($feed->image) && !empty($feed->title) && !empty($feed->link)) {
 544      $variables['source_image'] = l(theme('image', array('path' => $feed->image, 'alt' => $feed->title)), $feed->link, array('html' => TRUE, 'attributes' => array('class' => 'feed-image')));
 545    }
 546    else {
 547      $variables['source_image'] = '';
 548    }
 549  
 550    $variables['source_description'] = aggregator_filter_xss($feed->description);
 551    $variables['source_url'] = check_url(url($feed->link, array('absolute' => TRUE)));
 552  
 553    if ($feed->checked) {
 554      $variables['last_checked'] = t('@time ago', array('@time' => format_interval(REQUEST_TIME - $feed->checked)));
 555    }
 556    else {
 557      $variables['last_checked'] = t('never');
 558    }
 559  
 560    if (user_access('administer news feeds')) {
 561      $variables['last_checked'] = l($variables['last_checked'], 'admin/config/services/aggregator');
 562    }
 563  }

title

Description

title

Description

title

Description

title

title

Body