Index: modules/aggregator/aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.426
diff -u -r1.426 aggregator.module
--- modules/aggregator/aggregator.module	12 Oct 2009 15:54:59 -0000	1.426
+++ modules/aggregator/aggregator.module	14 Oct 2009 20:04:34 -0000
@@ -23,8 +23,10 @@
       return $output;
     case 'admin/config/services/aggregator':
       $output = '<p>' . t('Thousands of sites (particularly news sites and blogs) publish their latest headlines and posts in feeds, using a number of standardized XML-based formats. Formats supported by the aggregator include <a href="@rss">RSS</a>, <a href="@rdf">RDF</a>, and <a href="@atom">Atom</a>.', array('@rss' => 'http://cyber.law.harvard.edu/rss/', '@rdf' => 'http://www.w3.org/RDF/', '@atom' => 'http://www.atomenabled.org')) . '</p>';
-      $output .= '<p>' . t('Current feeds are listed below, and <a href="@addfeed">new feeds may be added</a>. For each feed or feed category, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addfeed' => url('admin/config/services/aggregator/add/feed'), '@block' => url('admin/structure/block'))) . '</p>';
+      $output .= '<p>' . t('Current feeds are listed below, and <a href="@addfeed">new feeds may be added</a>. For each feed, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addfeed' => url('admin/config/services/aggregator/add/feed'), '@block' => url('admin/structure/block'))) . '</p>';
       return $output;
+    case 'admin/config/services/aggregator/categories':
+      return '<p>' . t('Current categories are listed below, and <a href="@addcategory">new categories may be added</a>. For each category, the <em>latest items</em> block may be enabled at the <a href="@block">blocks administration page</a>.', array('@addcategory' => url('admin/config/services/aggregator/add/category'), '@block' => url('admin/structure/block'))) . '</p>';
     case 'admin/config/services/aggregator/add/feed':
       return '<p>' . t('Add a feed in RSS, RDF or Atom format. A feed may only have one entry.') . '</p>';
     case 'admin/config/services/aggregator/add/category':
@@ -93,6 +95,18 @@
     'access arguments' => array('administer news feeds'),
     'file' => 'aggregator.admin.inc',
   );
+  $items['admin/config/services/aggregator/feeds'] = array(
+    'title' => 'Feed overview',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+  $items['admin/config/services/aggregator/categories'] = array(
+    'title' => 'Category overview',
+    'page callback' => 'aggregator_category_overview',
+    'access arguments' => array('administer news feeds'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'aggregator.admin.inc',
+  );
   $items['admin/config/services/aggregator/add/feed'] = array(
     'title' => 'Add feed',
     'page callback' => 'drupal_get_form',
@@ -133,11 +147,6 @@
     'type' => MENU_CALLBACK,
     'file' => 'aggregator.admin.inc',
   );
-  $items['admin/config/services/aggregator/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
   $items['admin/config/services/aggregator/settings'] = array(
     'title' => 'Settings',
     'description' => 'Configure the behavior of the feed aggregator, including when to discard feed items and how to present feed items and categories.',
Index: modules/aggregator/aggregator.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.admin.inc,v
retrieving revision 1.44
diff -u -r1.44 aggregator.admin.inc
--- modules/aggregator/aggregator.admin.inc	9 Oct 2009 00:59:55 -0000	1.44
+++ modules/aggregator/aggregator.admin.inc	14 Oct 2009 20:04:33 -0000
@@ -10,43 +10,73 @@
  * Menu callback; displays the aggregator administration page.
  */
 function aggregator_admin_overview() {
-  return aggregator_view();
-}
+  $count_query = db_select('aggregator_feed');
+  $count_query->addExpression('COUNT(fid)');
 
-/**
- * Displays the aggregator administration page.
- *
- * @return
- *   The page HTML.
- */
-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.hash, f.etag, f.modified, f.image, f.block ORDER BY f.title');
+  $query = db_select('aggregator_feed', 'f')->extend('PagerDefault')->extend('TableSort');
+  $query->leftJoin('aggregator_item', 'i', 'f.fid = i.fid');
+  $query->addExpression('COUNT(i.iid)', 'items');
+  $query = $query
+    ->fields('f', array('fid', 'title', 'refresh', 'checked',))
+    ->limit(50)
+    ->orderBy('f.title');
+  $query->setCountQuery($count_query);
+  $result = $query->execute();
 
-  $output = '<h3>' . t('Feed overview') . '</h3>';
+  $output = '';
 
   $header = array(t('Title'), t('Items'), t('Last update'), t('Next update'), array('data' => t('Operations'), 'colspan' => '3'));
   $rows = array();
   foreach ($result as $feed) {
-    $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(REQUEST_TIME - $feed->checked))) : t('never')), ($feed->checked && $feed->refresh ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : t('never')), l(t('edit'), "admin/config/services/aggregator/edit/feed/$feed->fid"), l(t('remove items'), "admin/config/services/aggregator/remove/$feed->fid"), l(t('update items'), "admin/config/services/aggregator/update/$feed->fid"));
+    if (isset($feed->fid)) {
+      $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(REQUEST_TIME - $feed->checked))) : t('never')), ($feed->checked && $feed->refresh ? t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : t('never')), l(t('edit'), "admin/config/services/aggregator/edit/feed/$feed->fid"), l(t('remove items'), "admin/config/services/aggregator/remove/$feed->fid"), l(t('update items'), "admin/config/services/aggregator/update/$feed->fid"));
+    }
   }
   if (empty($rows)) {
-    $rows[] = array(array('data' => t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => url('admin/content/aggregator/add/feed'))), 'colspan' => '5', 'class' => array('message')));
+    $rows[] = array(array('data' => t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => url('admin/config/services/aggregator/add/feed'))), 'colspan' => '5', 'class' => array('message')));
   }
+
   $output .= theme('table', array('header' => $header, 'rows' => $rows));
+  $output .= theme('pager', array('tags' => NULL));
+
+  return $output;
+}
 
-  $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');
+/**
+ * Menu callback; displays the aggregator category overview page.
+ *
+ * @return
+ *   The page HTML.
+ */
+function aggregator_category_overview() {
+  $count_query = db_select('aggregator_category');
+  $count_query->addExpression('COUNT(cid)');
+
+  $query = db_select('aggregator_category', 'c')->extend('PagerDefault')->extend('TableSort');
+  $query->leftJoin('aggregator_category_item', 'ci', 'c.cid = ci.cid');
+  $query->addExpression('COUNT(ci.iid)', 'items');
+  $query = $query
+    ->fields('c', array('cid', 'title',))
+    ->limit(50)
+    ->orderBy('title');
+  $query->setCountQuery($count_query);
+  $result = $query->execute();
 
-  $output .= '<h3>' . t('Category overview') . '</h3>';
+  $output = '';
 
   $header = array(t('Title'), t('Items'), t('Operations'));
   $rows = array();
   foreach ($result as $category) {
-    $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/config/services/aggregator/edit/category/$category->cid"));
+    if (isset($category->cid)) {
+      $rows[] = array(l($category->title, "aggregator/categories/$category->cid"), format_plural($category->items, '1 item', '@count items'), l(t('edit'), "admin/config/services/aggregator/edit/category/$category->cid"));
+    }
   }
   if (empty($rows)) {
     $rows[] = array(array('data' => t('No categories available. <a href="@link">Add category</a>.', array('@link' => url('admin/config/services/aggregator/add/category'))), 'colspan' => '5', 'class' => array('message')));
   }
+
   $output .= theme('table', array('header' => $header, 'rows' => $rows));
+  $output .= theme('pager', array('tags' => NULL));
 
   return $output;
 }
