Index: modules/aggregator/aggregator.install =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v retrieving revision 1.16 diff -u -r1.16 aggregator.install --- modules/aggregator/aggregator.install 15 May 2008 21:27:32 -0000 1.16 +++ modules/aggregator/aggregator.install 10 Aug 2008 21:33:33 -0000 @@ -64,11 +64,12 @@ $schema['aggregator_category_feed'] = array( 'description' => t('Bridge table; maps feeds to categories.'), 'fields' => array( - 'fid' => array( + 'nid' => array( 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'description' => t("The feed's {aggregator_feed}.fid."), + 'description' => t("The feed's {aggregator_feed}.nid."), ), 'cid' => array( 'type' => 'int', @@ -77,9 +78,9 @@ 'description' => t('The {aggregator_category}.cid to which the feed is being assigned.'), ) ), - 'primary key' => array('cid', 'fid'), + 'primary key' => array('cid', 'nid'), 'indexes' => array( - 'fid' => array('fid'), + 'nid' => array('nid'), ), ); @@ -108,17 +109,12 @@ $schema['aggregator_feed'] = array( 'description' => t('Stores feeds to be parsed by the aggregator.'), 'fields' => array( - 'fid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => t('Primary Key: Unique feed ID.'), - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 255, + 'nid' => array( + 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => '', - 'description' => t('Title of the feed.'), + 'default' => 0, + 'description' => t("The feed's {node}.nid."), ), 'url' => array( 'type' => 'varchar', @@ -179,10 +175,9 @@ 'description' => t("Number of items to display in the feed's block."), ) ), - 'primary key' => array('fid'), + 'primary key' => array('nid'), 'unique keys' => array( 'url' => array('url'), - 'title' => array('title'), ), ); @@ -194,11 +189,12 @@ 'not null' => TRUE, 'description' => t('Primary Key: Unique ID for feed item.'), ), - 'fid' => array( + 'nid' => array( 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'description' => t('The {aggregator_feed}.fid to which this item belongs.'), + 'description' => t('The {aggregator_feed}.nid to which this item belongs.'), ), 'title' => array( 'type' => 'varchar', @@ -241,7 +237,7 @@ ), 'primary key' => array('iid'), 'indexes' => array( - 'fid' => array('fid'), + 'nid' => array('nid'), ), ); Index: modules/aggregator/aggregator.test =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.test,v retrieving revision 1.5 diff -u -r1.5 aggregator.test --- modules/aggregator/aggregator.test 3 Aug 2008 18:16:51 -0000 1.5 +++ modules/aggregator/aggregator.test 10 Aug 2008 21:33:35 -0000 @@ -9,7 +9,7 @@ */ function setUp() { parent::setUp('aggregator'); - $web_user = $this->drupalCreateUser(array('administer news feeds', 'access news feeds')); + $web_user = $this->drupalCreateUser(array('administer news feeds', 'access news feeds', 'create feed content', 'delete any feed content', 'edit any feed content')); $this->drupalLogin($web_user); } @@ -20,10 +20,10 @@ */ function createFeed() { $edit = $this->getFeedEditArray(); - $this->drupalPost('admin/content/aggregator/add/feed', $edit, t('Save')); - $this->assertRaw(t('The feed %name has been added.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title']))); + $this->drupalPost('node/add/feed', $edit, t('Save')); + $this->assertRaw(t('Feed %name has been created.', array('%name' => $edit['title'])), t('The feed !name has been added.', array('!name' => $edit['title']))); - $feed = db_fetch_object(db_query("SELECT * FROM {aggregator_feed} WHERE title = '%s' AND url='%s'", $edit['title'], $edit['url'])); + $feed = db_fetch_object(db_query("SELECT f.*, n.title FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE n.title = '%s' AND f.url='%s'", $edit['title'], $edit['url'])); $this->assertTrue(!empty($feed), t('The feed found in database.')); return $feed; } @@ -34,8 +34,8 @@ * @param object $feed Feed object representing the feed. */ function deleteFeed($feed) { - $this->drupalPost('admin/content/aggregator/edit/feed/' . $feed->fid, array(), t('Delete')); - $this->assertRaw(t('The feed %title has been deleted.', array('%title' => $feed->title)), t('Feed deleted successfully.')); + $this->drupalPost("node/$feed->nid/delete", array(), t('Delete')); + $this->assertRaw(t('Feed %title has been deleted.', array('%title' => $feed->title)), t('Feed deleted successfully.')); } /** @@ -65,15 +65,14 @@ $this->assertResponse(200, t('rss.xml is reachable.')); // Our tests are based off of rss.xml, so let's find out how many elements should be related. - $feed_count = db_result(db_query_range(db_rewrite_sql('SELECT COUNT(*) FROM {node} n WHERE n.promote = 1 AND n.status = 1'), 0, variable_get('feed_default_items', 10))); + $feed_count = db_result(db_query_range(db_rewrite_sql('SELECT COUNT(nid) FROM {node} WHERE promote = 1 AND status = 1'), 0, variable_get('feed_default_items', 10))); $feed_count = $feed_count > 10 ? 10 : $feed_count; // Refresh the feed (simulated link click). - $this->drupalGet('admin/content/aggregator/update/' . $feed->fid); + $this->drupalGet('admin/content/aggregator/update/' . $feed->nid); // Ensure we have the right number of items. - $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = %d', $feed->fid); - $items = array(); + $result = db_query('SELECT iid FROM {aggregator_item} WHERE nid = %d', $feed->nid); $feed->items = array(); while ($item = db_fetch_object($result)) { $feed->items[] = $item->iid; @@ -88,7 +87,7 @@ * @param object $feed Feed object representing the feed. */ function removeFeedItems($feed) { - $this->drupalPost('admin/content/aggregator/remove/' . $feed->fid, array(), t('Remove items')); + $this->drupalPost('admin/content/aggregator/remove/' . $feed->nid, array(), t('Remove items')); $this->assertRaw(t('The news items from %title have been removed.', array('%title' => $feed->title)), t('Feed items removed.')); } @@ -99,7 +98,7 @@ */ function getFeedCategories($feed) { // add the categories to the feed so we can use them - $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = %d', $feed->fid); + $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE nid = %d', $feed->nid); while ($category = db_fetch_object($result)) { $feed->categories[] = $category->cid; } @@ -113,7 +112,7 @@ * @return boolean Feed is unique. */ function uniqueFeed($feed_name, $feed_url) { - $result = db_result(db_query("SELECT count(*) FROM {aggregator_feed} WHERE title = '%s' AND url='%s'", $feed_name, $feed_url)); + $result = db_result(db_query("SELECT count(f.*) FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE n.title = '%s' AND f.url='%s'", $feed_name, $feed_url)); return (1 == $result); } @@ -216,11 +215,11 @@ $feed = $this->createFeed(); // Check feed data. - $this->assertEqual($this->getUrl(), url('admin/content/aggregator/add/feed', array('absolute' => TRUE)), t('Directed to correct url.')); + $this->assertEqual($this->getUrl(), url('node/' . $feed->nid, array('absolute' => TRUE)), t('Directed to correct url.')); $this->assertTrue($this->uniqueFeed($feed->title, $feed->url), t('The feed is unique.')); // Check feed source. - $this->drupalGet('aggregator/sources/' . $feed->fid); + $this->drupalGet('node/' . $feed->nid); $this->assertResponse(200, t('Feed source exists.')); $this->assertText($feed->title, t('Page title')); @@ -250,15 +249,15 @@ // Get new feed data array and modify newly created feed. $edit = $this->getFeedEditArray(); $edit['refresh'] = 1800; // Change refresh value. - $this->drupalPost('admin/content/aggregator/edit/feed/' . $feed->fid, $edit, t('Save')); - $this->assertRaw(t('The feed %name has been updated.', array('%name' => $edit['title'])), t('The feed %name has been updated.', array('%name' => $edit['title']))); + $this->drupalPost('node/' . $feed->nid . '/edit', $edit, t('Save')); + $this->assertRaw(t('Feed %name has been updated.', array('%name' => $edit['title'])), t('Feed %name has been updated.', array('%name' => $edit['title']))); // Check feed data. - $this->assertEqual($this->getUrl(), url('admin/content/aggregator/', array('absolute' => TRUE))); + $this->assertEqual($this->getUrl(), url('node/' . $feed->nid, array('absolute' => TRUE))); $this->assertTrue($this->uniqueFeed($edit['title'], $edit['url']), t('The feed is unique.')); // Check feed source. - $this->drupalGet('aggregator/sources/' . $feed->fid); + $this->drupalGet('node/' . $feed->nid); $this->assertResponse(200, t('Feed source exists.')); $this->assertText($edit['title'], t('Page title')); @@ -290,11 +289,11 @@ $this->deleteFeed($feed); // Check feed source. - $this->drupalGet('aggregator/sources/' . $feed->fid); + $this->drupalGet('node/' . $feed->nid); $this->assertResponse(404, t('Deleted feed source does not exists.')); // Check database for feed. - $result = db_result(db_query("SELECT count(*) FROM {aggregator_feed} WHERE title = '%s' AND url='%s'", $feed->title, $feed->url)); + $result = db_result(db_query("SELECT count(*) FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE n.title = '%s' AND f.url='%s'", $feed->title, $feed->url)); $this->assertFalse($result, t('Feed not found in database')); } } @@ -348,7 +347,7 @@ // Add and remove feed items and ensure that the count is zero. $this->updateFeedItems($feed); $this->removeFeedItems($feed); - $count = db_result(db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE fid = %d', $feed->fid)); + $count = db_result(db_query('SELECT COUNT(*) FROM {aggregator_item} WHERE nid = %d', $feed->nid)); $this->assertTrue($count == 0); // Delete feed. @@ -501,7 +500,7 @@ $after = db_result(db_query('SELECT COUNT(*) FROM {aggregator_feed}')); $this->assertEqual($after, 2, t('Verifying that two distinct feeds were added.')); - $feeds_from_db = db_query("SELECT f.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf ON f.fid = cf.fid"); + $feeds_from_db = db_query("SELECT n.title, f.url, f.refresh, cf.cid FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} cf CROSS JOIN {node} n ON f.nid = cf.nid AND n.nid = f.nid"); $refresh = $category = TRUE; while ($feed = db_fetch_array($feeds_from_db)) { $title[$feed['url']] = $feed['title']; Index: modules/aggregator/aggregator.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.pages.inc,v retrieving revision 1.15 diff -u -r1.15 aggregator.pages.inc --- modules/aggregator/aggregator.pages.inc 16 Jul 2008 21:59:25 -0000 1.15 +++ modules/aggregator/aggregator.pages.inc 10 Aug 2008 21:33:34 -0000 @@ -15,7 +15,7 @@ function aggregator_page_last() { drupal_add_feed(url('aggregator/rss'), variable_get('site_name', 'Drupal') . ' ' . t('aggregator')); - $items = aggregator_feed_items_load('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'); + $items = aggregator_feed_items_load('SELECT i.*, n.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.nid = f.nid LEFT JOIN {node} n ON f.nid = n.nid ORDER BY i.timestamp DESC, i.iid DESC'); return _aggregator_page_list($items, arg(1)); } @@ -35,16 +35,16 @@ function aggregator_page_source($arg1, $arg2 = NULL) { // If there are two arguments then this function is the categorize form, and // $arg1 is $form_state and $arg2 is $feed. Otherwise, $arg1 is $feed. - $feed = is_array($arg2) ? $arg2 : $arg1; + $feed = is_object($arg2) ? $arg2 : $arg1; $feed = (object)$feed; drupal_set_title(check_plain($feed->title)); $feed_source = theme('aggregator_feed_source', $feed); // It is safe to include the fid in the query because it's loaded from the // database by aggregator_feed_load. - $items = aggregator_feed_items_load('SELECT * FROM {aggregator_item} WHERE fid = ' . $feed->fid . ' ORDER BY timestamp DESC, iid DESC'); + $items = aggregator_feed_items_load('SELECT * FROM {aggregator_item} WHERE nid = ' . $feed->nid . ' ORDER BY timestamp DESC, iid DESC'); - return _aggregator_page_list($items, arg(3), $feed_source); + return _aggregator_page_list($items, arg(2), $feed_source); } /** @@ -69,7 +69,7 @@ // It is safe to include the cid in the query because it's loaded from the // database by aggregator_category_load. - $items = aggregator_feed_items_load('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 = ' . $category['cid'] . ' ORDER BY timestamp DESC, i.iid DESC'); + $items = aggregator_feed_items_load('SELECT i.*, n.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.nid = f.nid LEFT JOIN {node} n ON f.nid = n.nid WHERE cid = ' . $category['cid'] . ' ORDER BY timestamp DESC, i.iid DESC'); return _aggregator_page_list($items, arg(3)); } @@ -282,19 +282,19 @@ * Menu callback; displays all the feeds used by the aggregator. */ function aggregator_page_sources() { - $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'); + $result = db_query('SELECT f.nid, n.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid LEFT JOIN {aggregator_item} i ON f.nid = i.nid WHERE n.status = 1 GROUP BY f.nid, n.title, f.description, f.image ORDER BY last ASC, n.title'); $output = ''; while ($feed = db_fetch_object($result)) { // Most recent items: $summary_items = array(); if (variable_get('aggregator_summary_items', 3)) { - $items = db_query_range('SELECT i.title, i.timestamp, i.link FROM {aggregator_item} i WHERE i.fid = %d ORDER BY i.timestamp DESC', $feed->fid, 0, variable_get('aggregator_summary_items', 3)); + $items = db_query_range('SELECT i.title, i.timestamp, i.link FROM {aggregator_item} i WHERE i.nid = %d ORDER BY i.timestamp DESC', $feed->nid, 0, variable_get('aggregator_summary_items', 3)); while ($item = db_fetch_object($items)) { $summary_items[] = theme('aggregator_summary_item', $item); } } - $feed->url = url('aggregator/sources/' . $feed->fid); + $feed->url = url('node/' . $feed->nid); $output .= theme('aggregator_summary_items', $summary_items, $feed); } $output .= theme('feed_icon', url('aggregator/opml'), t('OPML feed')); @@ -312,7 +312,7 @@ while ($category = db_fetch_object($result)) { if (variable_get('aggregator_summary_items', 3)) { $summary_items = array(); - $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 = %d ORDER BY i.timestamp DESC', $category->cid, 0, variable_get('aggregator_summary_items', 3)); + $items = db_query_range('SELECT i.title, i.timestamp, i.link, n.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.nid = f.nid LEFT JOIN {node} n ON f.nid = n.nid WHERE ci.cid = %d ORDER BY i.timestamp DESC', $category->cid, 0, variable_get('aggregator_summary_items', 3)); while ($item = db_fetch_object($items)) { $summary_items[] = theme('aggregator_summary_item', $item); } @@ -332,13 +332,13 @@ // arg(2) is the passed cid, only select for that category. if (arg(2)) { $category = db_fetch_object(db_query('SELECT cid, title FROM {aggregator_category} WHERE cid = %d', arg(2))); - $sql = '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 = %d ORDER BY timestamp DESC, i.iid DESC'; + $sql = 'SELECT i.*, n.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.nid = f.nid LEFT JOIN {node} n ON n.nid = f.nid WHERE cid = %d ORDER BY timestamp DESC, i.iid DESC'; $result = db_query_range($sql, $category->cid, 0, variable_get('feed_default_items', 10)); } // Or, get the default aggregator items. else { $category = NULL; - $sql = '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'; + $sql = 'SELECT i.*, n.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.nid = f.nid LEFT JOIN {node} n ON n.nid = f.nid ORDER BY i.timestamp DESC, i.iid DESC'; $result = db_query_range($sql, 0, variable_get('feed_default_items', 10)); } @@ -402,10 +402,10 @@ */ function aggregator_page_opml($cid = NULL) { if ($cid) { - $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 = %d ORDER BY title', $cid); + $result = db_query('SELECT n.title, f.url FROM {node} n LEFT JOIN {aggregator_feed} f ON f.nid = n.nid LEFT JOIN {aggregator_category_feed} c on f.nid = c.nid WHERE c.cid = %d ORDER BY title', $cid); } else { - $result = db_query('SELECT * FROM {aggregator_feed} ORDER BY title'); + $result = db_query('SELECT f.*, n.title FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid ORDER BY n.title'); } $feeds = array(); Index: modules/aggregator/aggregator.module =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v retrieving revision 1.385 diff -u -r1.385 aggregator.module --- modules/aggregator/aggregator.module 8 Aug 2008 20:09:22 -0000 1.385 +++ modules/aggregator/aggregator.module 10 Aug 2008 21:33:33 -0000 @@ -87,14 +87,6 @@ 'page callback' => 'aggregator_admin_overview', 'access arguments' => array('administer news feeds'), ); - $items['admin/content/aggregator/add/feed'] = array( - 'title' => 'Add feed', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('aggregator_form_feed'), - 'access arguments' => array('administer news feeds'), - 'type' => MENU_LOCAL_TASK, - 'parent' => 'admin/content/aggregator', - ); $items['admin/content/aggregator/add/category'] = array( 'title' => 'Add category', 'page callback' => 'drupal_get_form', @@ -194,39 +186,6 @@ 'type' => MENU_LOCAL_TASK, 'weight' => 1, ); - $items['aggregator/sources/%aggregator_feed'] = array( - 'page callback' => 'aggregator_page_source', - 'page arguments' => array(2), - 'access arguments' => array('access news feeds'), - 'type' => MENU_CALLBACK, - ); - $items['aggregator/sources/%aggregator_feed/view'] = array( - 'title' => 'View', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - $items['aggregator/sources/%aggregator_feed/categorize'] = array( - 'title' => 'Categorize', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('aggregator_page_source', 2), - 'access arguments' => array('administer news feeds'), - 'type' => MENU_LOCAL_TASK, - ); - $items['aggregator/sources/%aggregator_feed/configure'] = array( - 'title' => 'Configure', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('aggregator_form_feed', 2), - 'access arguments' => array('administer news feeds'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - ); - $items['admin/content/aggregator/edit/feed/%aggregator_feed'] = array( - 'title' => 'Edit feed', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('aggregator_form_feed', 5), - 'access arguments' => array('administer news feeds'), - 'type' => MENU_CALLBACK, - ); $items['admin/content/aggregator/edit/category/%aggregator_category'] = array( 'title' => 'Edit category', 'page callback' => 'drupal_get_form', @@ -235,6 +194,14 @@ 'type' => MENU_CALLBACK, ); + $items['node/%node/categorize'] = array( + 'title' => 'Categorize', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('aggregator_page_source', 1), + 'access arguments' => array('administer news feeds'), + 'type' => MENU_LOCAL_TASK, + ); + return $items; } @@ -269,10 +236,13 @@ * Implementation of hook_perm(). */ function aggregator_perm() { - return array( + $perms = node_list_permissions('feed'); + $perms += array( 'administer news feeds' => t('Add, edit or delete news feeds that are aggregated to your site.'), 'access news feeds' => t('View aggregated news feed items.'), ); + + return $perms; } /** @@ -281,7 +251,7 @@ * Checks news feeds for updates once their refresh interval has elapsed. */ function aggregator_cron() { - $result = db_query('SELECT * FROM {aggregator_feed} WHERE checked + refresh < %d', time()); + $result = db_query('SELECT f.*, n.title FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE f.checked + f.refresh < %d', time()); while ($feed = db_fetch_array($result)) { aggregator_refresh($feed); } @@ -299,9 +269,9 @@ while ($category = db_fetch_object($result)) { $block['category-' . $category->cid]['info'] = t('!title category latest items', array('!title' => $category->title)); } - $result = db_query('SELECT fid, title FROM {aggregator_feed} ORDER BY fid'); + $result = db_query('SELECT f.nid, n.title FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid ORDER BY f.nid'); while ($feed = db_fetch_object($result)) { - $block['feed-' . $feed->fid]['info'] = t('!title feed latest items', array('!title' => $feed->title)); + $block['feed-' . $feed->nid]['info'] = t('!title feed latest items', array('!title' => $feed->title)); } } elseif ($op == 'configure') { @@ -310,7 +280,7 @@ $value = db_result(db_query('SELECT block FROM {aggregator_category} WHERE cid = %d', $id)); } else { - $value = db_result(db_query('SELECT block FROM {aggregator_feed} WHERE fid = %d', $id)); + $value = db_result(db_query('SELECT block FROM {aggregator_feed} WHERE nid = %d', $id)); } $form['block'] = array('#type' => 'select', '#title' => t('Number of news items in block'), '#default_value' => $value, '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))); return $form; @@ -321,17 +291,17 @@ $value = db_query('UPDATE {aggregator_category} SET block = %d WHERE cid = %d', $edit['block'], $id); } else { - $value = db_query('UPDATE {aggregator_feed} SET block = %d WHERE fid = %d', $edit['block'], $id); + $value = db_query('UPDATE {aggregator_feed} SET block = %d WHERE nid = %d', $edit['block'], $id); } } elseif ($op == 'view') { list($type, $id) = explode('-', $delta); switch ($type) { case 'feed': - if ($feed = db_fetch_object(db_query('SELECT fid, title, block FROM {aggregator_feed} WHERE fid = %d', $id))) { + if ($feed = db_fetch_object(db_query('SELECT f.nid, n.title, f.block FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE f.nid = %d', $id))) { $block['subject'] = check_plain($feed->title); - $result = db_query_range('SELECT * FROM {aggregator_item} WHERE fid = %d ORDER BY timestamp DESC, iid DESC', $feed->fid, 0, $feed->block); - $read_more = theme('more_link', url('aggregator/sources/' . $feed->fid), t("View this feed's recent news.")); + $result = db_query_range('SELECT * FROM {aggregator_item} WHERE nid = %d ORDER BY timestamp DESC, iid DESC', $feed->nid, 0, $feed->block); + $read_more = theme('more_link', url('node/' . $feed->nid), t("View this feed's recent news.")); } break; @@ -360,6 +330,236 @@ } /** + * Implementation of hook_node_info(). + */ +function aggregator_node_info() { + return array( + 'feed' => array( + 'name' => t('Feed'), + 'module' => 'aggregator', + 'description' => t("Add a feed in RSS, RDF or Atom format."), + 'has_title' => TRUE, + 'title_label' => t('Title'), + 'has_body' => FALSE, + ) + ); +} + +/** + * Implementation of hook_access(). + */ +function aggregator_access($op, $node, $account) { + switch ($op) { + case 'create': + return user_access('create feed content', $account); + case 'update': + return user_access('edit any feed content', $account) || (user_access('edit own feed content', $account) && ($node->uid == $account->uid)); + case 'delete': + return user_access('delete any feed content', $account) || (user_access('delete own feed content', $account) && ($node->uid == $account->uid)); + } +} + +/** + * Implementation of hook_form(). + */ +function aggregator_form(&$node) { + global $user; + + $admin = user_access('administer nodes') || user_access('edit any feed content') || (user_access('edit own feed content') && $user->uid == $node->uid); + + // The site admin can decide if this node type has a title and body, and how + // the fields should be labeled. We need to load these settings so we can + // build the node form correctly. + $type = node_get_types('type', $node); + + if ($type->has_title) { + $form['title'] = array( + '#type' => 'textfield', + '#title' => check_plain($type->title_label), + '#description' => t('The name of the feed (or the name of the website providing the feed).'), + '#default_value' => $node->title, + '#maxlength' => 255, + '#required' => TRUE, + '#weight' => -5 + ); + } + + if ($type->has_body) { + // In Drupal 6, we can use node_body_field() to get the body and filter + // elements. This replaces the old textarea + filter_form() method of + // setting this up. It will also ensure the teaser splitter gets set up + // properly. + $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); + } + + $period = drupal_map_assoc(array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200), 'format_interval'); + + $form['url'] = array( + '#type' => 'textfield', + '#title' => t('URL'), + '#default_value' => isset($node->url) ? $node->url : '', + '#maxlength' => 255, + '#description' => t('The fully-qualified URL of the feed.'), + '#required' => TRUE, + '#weight' => -4 + ); + + $form['settings'] = array( + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#title' => t('Feed settings'), + '#weight' => -3, + '#access' => $admin, + ); + $form['settings']['refresh'] = array( + '#type' => 'select', + '#title' => t('Update interval'), + '#default_value' => isset($node->refresh) ? $node->refresh : 3600, + '#options' => $period, + '#description' => t('The length of time between feed updates. (Requires a correctly configured cron maintenance task.)', array('@cron' => url('admin/reports/status'))), + ); + + // Handling of categories. + $options = array(); + $values = isset($node->categories) ? $node->categories : array(); + $categories = db_query('SELECT cid, title FROM {aggregator_category} ORDER BY title'); + while ($category = db_fetch_object($categories)) { + $options[$category->cid] = check_plain($category->title); + if (isset($node->categories) && in_array($category->cid, $node->categories)) { + $values[] = $category->cid; + } + } + if ($options) { + $form['settings']['categories'] = array( + '#type' => 'checkboxes', + '#title' => t('Categorize news items'), + '#default_value' => $values, + '#options' => $options, + '#description' => t('New feed items are automatically filed in the checked categories.'), + ); + } + + return $form; +} + +/** + * Implementation of hook_validate(). + */ +function aggregator_validate(&$node) { + // Ensure URL is valid. + if (!valid_url($node->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' => $node->url))); + } + // Check for duplicate titles. + if (isset($node->nid)) { + $result_title = db_result(db_query("SELECT title FROM {node} WHERE title = '%s' AND nid <> %d AND type = 'feed'", $node->title, $node->nid)); + $result_url = db_result(db_query("SELECT url FROM {aggregator_feed} WHERE url = '%s' AND nid <> %d", $node->url, $node->nid)); + } + else { + $result_title = db_result(db_query("SELECT title FROM {node} WHERE title = '%s' AND type = 'feed'", $node->title)); + $result_url = db_result(db_query("SELECT url FROM {aggregator_feed} WHERE url = '%s'", $node->url)); + } + + if (strcasecmp($result_title, $node->title) == 0) { + form_set_error('title', t('A feed named %feed already exists. Please enter a unique title.', array('%feed' => $node->title))); + } + if (strcasecmp($result_url, $node->url) == 0) { + form_set_error('url', t('A feed with this URL %url already exists. Please enter a unique URL.', array('%url' => $node->url))); + } +} + +/** + * Implementation of hook_insert(). + */ +function aggregator_insert($node) { + db_query("INSERT INTO {aggregator_feed} (nid, url, refresh, block, description, image) VALUES (%d, '%s', %d, 5, '', '')", $node->nid, $node->url, $node->refresh); + + // The feed is being saved, save the categories as well. + if (!empty($node->categories)) { + foreach ($node->categories as $cid => $value) { + if ($value) { + db_query('INSERT INTO {aggregator_category_feed} (nid, cid) VALUES (%d, %d)', $node->nid, $cid); + } + } + } +} + +/** + * Implementation of hook_update(). + */ +function aggregator_update($node) { + // An existing feed is being modified, delete the category listings. + db_query('DELETE FROM {aggregator_category_feed} WHERE nid = %d', $node->nid); + + db_query("UPDATE {aggregator_feed} SET url = '%s', refresh = %d WHERE nid = %d", $node->url, $node->refresh, $node->nid); + + // The feed is being saved, save the categories as well. + if (!empty($node->categories)) { + foreach ($node->categories as $cid => $value) { + if ($value) { + db_query('INSERT INTO {aggregator_category_feed} (nid, cid) VALUES (%d, %d)', $node->nid, $cid); + } + } + } +} + +/** + * Implementation of hook_delete(). + */ +function aggregator_delete($node) { + // An existing feed is being modified, delete the category listings. + db_query('DELETE FROM {aggregator_category_feed} WHERE nid = %d', $node->nid); + + $items = array(); + $result = db_query('SELECT iid FROM {aggregator_item} WHERE nid = %d', $node->nid); + while ($item = db_fetch_object($result)) { + $items[] = "iid = $item->iid"; + } + if (!empty($items)) { + db_query('DELETE FROM {aggregator_category_item} WHERE ' . implode(' OR ', $items)); + } + db_query('DELETE FROM {aggregator_item} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {aggregator_feed} WHERE nid = %d', $node->nid); + // Make sure there is no active block for this feed. + db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'aggregator', 'feed-' . $node->nid); +} + +/** + * Implementation of hook_load(). + */ +function aggregator_load($node) { + $additions = db_fetch_object(db_query('SELECT url, refresh, checked, link, description, image, etag, modified, block FROM {aggregator_feed} WHERE nid = %d', $node->nid)); + $categories = db_query('SELECT cid FROM {aggregator_category_feed} WHERE nid = %d', $node->nid); + while ($category = db_fetch_object($categories)) { + $additions->categories[] = $category->cid; + } + return $additions; +} + +/** + * Implementation of hook_view(). + */ +function aggregator_view($node, $teaser = FALSE, $page = FALSE) { + $node->content['body'] = array( + '#markup' => theme('aggregator_feed_source', $node), + '#weight' => 1, + ); + + if ($page && isset($node->nid)) { + // It is safe to include the fid in the query because it's loaded from the + // database by aggregator_feed_load. + $items = aggregator_feed_items_load('SELECT * FROM {aggregator_item} WHERE nid = ' . $node->nid . ' ORDER BY timestamp DESC, iid DESC'); + + $node->content['items'] = array( + '#markup' => _aggregator_page_list($items, arg(3)), + '#weight' => 2, + ); + } + + return $node; +} + +/** * Add/edit/delete aggregator categories. * * @param $edit @@ -393,66 +593,21 @@ } /** - * Add/edit/delete an aggregator feed. - * - * @param $edit - * An associative array describing the feed to be added/edited/deleted. - */ -function aggregator_save_feed($edit) { - if (!empty($edit['fid'])) { - // An existing feed is being modified, delete the category listings. - db_query('DELETE FROM {aggregator_category_feed} WHERE fid = %d', $edit['fid']); - } - if (!empty($edit['fid']) && !empty($edit['title'])) { - db_query("UPDATE {aggregator_feed} SET title = '%s', url = '%s', refresh = %d WHERE fid = %d", $edit['title'], $edit['url'], $edit['refresh'], $edit['fid']); - } - elseif (!empty($edit['fid'])) { - $items = array(); - $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = %d', $edit['fid']); - while ($item = db_fetch_object($result)) { - $items[] = "iid = $item->iid"; - } - if (!empty($items)) { - db_query('DELETE FROM {aggregator_category_item} WHERE ' . implode(' OR ', $items)); - } - db_query('DELETE FROM {aggregator_feed} WHERE fid = %d', $edit['fid']); - db_query('DELETE FROM {aggregator_item} WHERE fid = %d', $edit['fid']); - // Make sure there is no active block for this feed. - db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'aggregator', 'feed-' . $edit['fid']); - } - elseif (!empty($edit['title'])) { - db_query("INSERT INTO {aggregator_feed} (title, url, refresh, block, description, image) VALUES ('%s', '%s', %d, 5, '', '')", $edit['title'], $edit['url'], $edit['refresh']); - // A single unique ID for bundles and feeds, to use in blocks. - $edit['fid'] = db_last_insert_id('aggregator_feed', 'fid'); - } - if (!empty($edit['title'])) { - // The feed is being saved, save the categories as well. - if (!empty($edit['category'])) { - foreach ($edit['category'] as $cid => $value) { - if ($value) { - db_query('INSERT INTO {aggregator_category_feed} (fid, cid) VALUES (%d, %d)', $edit['fid'], $cid); - } - } - } - } -} - -/** * Removes all items from a feed. * * @param $feed * An associative array describing the feed to be cleared. */ function aggregator_remove($feed) { - $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = %d', $feed['fid']); + $result = db_query('SELECT iid FROM {aggregator_item} WHERE nid = %d', $feed['nid']); while ($item = db_fetch_object($result)) { $items[] = "iid = $item->iid"; } if (!empty($items)) { db_query('DELETE FROM {aggregator_category_item} WHERE ' . implode(' OR ', $items)); } - db_query('DELETE FROM {aggregator_item} WHERE fid = %d', $feed['fid']); - db_query("UPDATE {aggregator_feed} SET checked = 0, etag = '', modified = 0 WHERE fid = %d", $feed['fid']); + db_query('DELETE FROM {aggregator_item} WHERE nid = %d', $feed['nid']); + db_query("UPDATE {aggregator_feed} SET checked = 0, etag = '', modified = 0 WHERE nid = %d", $feed['nid']); drupal_set_message(t('The news items from %site have been removed.', array('%site' => $feed['title']))); } @@ -593,7 +748,7 @@ // Process HTTP response code. switch ($result->code) { case 304: - db_query('UPDATE {aggregator_feed} SET checked = %d WHERE fid = %d', time(), $feed['fid']); + db_query('UPDATE {aggregator_feed} SET checked = %d WHERE nid = %d', time(), $feed['nid']); drupal_set_message(t('There is no new syndicated content from %site.', array('%site' => $feed['title']))); break; case 301: @@ -628,7 +783,7 @@ $etag = empty($result->headers['ETag']) ? '' : $result->headers['ETag']; // Update the feed data. - db_query("UPDATE {aggregator_feed} SET url = '%s', checked = %d, link = '%s', description = '%s', image = '%s', etag = '%s', modified = %d WHERE fid = %d", $feed['url'], time(), $channel['LINK'], $channel['DESCRIPTION'], $image, $etag, $modified, $feed['fid']); + db_query("UPDATE {aggregator_feed} SET url = '%s', checked = %d, link = '%s', description = '%s', image = '%s', etag = '%s', modified = %d WHERE nid = %d", $feed['url'], time(), $channel['LINK'], $channel['DESCRIPTION'], $image, $etag, $modified, $feed['nid']); // Clear the cache. cache_clear_all(); @@ -788,21 +943,21 @@ // we find a duplicate entry, we resolve it and pass along its ID is such // that we can update it if needed. if (!empty($guid)) { - $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE fid = %d AND guid = '%s'", $feed['fid'], $guid)); + $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE nid = %d AND guid = '%s'", $feed['nid'], $guid)); } else if ($link && $link != $feed['link'] && $link != $feed['url']) { - $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE fid = %d AND link = '%s'", $feed['fid'], $link)); + $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE nid = %d AND link = '%s'", $feed['nid'], $link)); } else { - $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE fid = %d AND title = '%s'", $feed['fid'], $title)); + $entry = db_fetch_object(db_query("SELECT iid FROM {aggregator_item} WHERE nid = %d AND title = '%s'", $feed['nid'], $title)); } $item += array('AUTHOR' => '', 'DESCRIPTION' => ''); - aggregator_save_item(array('iid' => (isset($entry->iid) ? $entry->iid: ''), 'fid' => $feed['fid'], 'timestamp' => $timestamp, 'title' => $title, 'link' => $link, 'author' => $item['AUTHOR'], 'description' => $item['DESCRIPTION'], 'guid' => $guid)); + aggregator_save_item(array('iid' => (isset($entry->iid) ? $entry->iid: ''), 'nid' => $feed['nid'], 'timestamp' => $timestamp, 'title' => $title, 'link' => $link, 'author' => $item['AUTHOR'], 'description' => $item['DESCRIPTION'], 'guid' => $guid)); } // Remove all items that are older than flush item timer. $age = time() - variable_get('aggregator_clear', 9676800); - $result = db_query('SELECT iid FROM {aggregator_item} WHERE fid = %d AND timestamp < %d', $feed['fid'], $age); + $result = db_query('SELECT iid FROM {aggregator_item} WHERE nid = %d AND timestamp < %d', $feed['nid'], $age); $items = array(); $num_rows = FALSE; @@ -812,7 +967,7 @@ } if ($num_rows) { db_query('DELETE FROM {aggregator_category_item} WHERE iid IN (' . implode(', ', $items) . ')'); - db_query('DELETE FROM {aggregator_item} WHERE fid = %d AND timestamp < %d', $feed['fid'], $age); + db_query('DELETE FROM {aggregator_item} WHERE nid = %d AND timestamp < %d', $feed['nid'], $age); } return TRUE; @@ -833,10 +988,10 @@ db_query('DELETE FROM {aggregator_category_item} WHERE iid = %d', $edit['iid']); } elseif ($edit['title'] && $edit['link']) { - db_query("INSERT INTO {aggregator_item} (fid, title, link, author, description, timestamp, guid) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $edit['fid'], $edit['title'], $edit['link'], $edit['author'], $edit['description'], $edit['timestamp'], $edit['guid']); + db_query("INSERT INTO {aggregator_item} (nid, title, link, author, description, timestamp, guid) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $edit['nid'], $edit['title'], $edit['link'], $edit['author'], $edit['description'], $edit['timestamp'], $edit['guid']); $edit['iid'] = db_last_insert_id('aggregator_item', 'iid'); // file the items in the categories indicated by the feed - $categories = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = %d', $edit['fid']); + $categories = db_query('SELECT cid FROM {aggregator_category_feed} WHERE nid = %d', $edit['nid']); while ($category = db_fetch_object($categories)) { db_query('INSERT INTO {aggregator_category_item} (cid, iid) VALUES (%d, %d)', $category->cid, $edit['iid']); } @@ -846,18 +1001,18 @@ /** * Load an aggregator feed. * - * @param $fid - * The feed id. + * @param $nid + * The feed nid. * @return * An associative array describing the feed. */ -function aggregator_feed_load($fid) { +function aggregator_feed_load($nid) { static $feeds; - if (!isset($feeds[$fid])) { - $feeds[$fid] = db_fetch_array(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', $fid)); + if (!isset($feeds[$nid])) { + $feeds[$nid] = db_fetch_array(db_query('SELECT f.*, n.title FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE f.nid = %d', $nid)); } - return $feeds[$fid]; + return $feeds[$nid]; } /** Index: modules/aggregator/aggregator.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.admin.inc,v retrieving revision 1.11 diff -u -r1.11 aggregator.admin.inc --- modules/aggregator/aggregator.admin.inc 3 Aug 2008 05:46:55 -0000 1.11 +++ modules/aggregator/aggregator.admin.inc 10 Aug 2008 21:33:32 -0000 @@ -8,26 +8,20 @@ /** * Menu callback; displays the aggregator administration page. - */ -function aggregator_admin_overview() { - return aggregator_view(); -} - -/** - * 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.etag, f.modified, f.image, f.block ORDER BY f.title'); +function aggregator_admin_overview() { + $result = db_query('SELECT f.*, n.title, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid LEFT JOIN {aggregator_item} i ON i.nid = f.nid WHERE n.status = 1 + GROUP BY f.nid, n.title, f.url, f.refresh, f.checked, f.link, f.description, f.etag, f.modified, f.image, f.block ORDER BY n.title'); $output = '

' . t('Feed overview') . '

'; $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)) { - $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")); + $rows[] = array(l($feed->title, "node/$feed->nid"), 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'), "node/$feed->nid/edit"), l(t('remove items'), "admin/content/aggregator/remove/$feed->nid"), l(t('update items'), "admin/content/aggregator/update/$feed->nid")); } $output .= theme('table', $header, $rows); @@ -45,147 +39,6 @@ return $output; } -/** - * Form builder; Generate a form to add/edit feed sources. - * - * @ingroup forms - * @see aggregator_form_feed_validate() - * @see aggregator_form_feed_submit() - */ -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, - '#description' => t('The name of the feed (or the name of the website providing the feed).'), - '#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, - '#description' => t('The length of time between feed updates. (Requires a correctly configured cron maintenance task.)', array('@cron' => url('admin/reports/status'))), - ); - - // 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, - '#description' => t('New feed items are automatically filed in the checked categories.'), - ); - } - $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'])) { - $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']); - } - else { - $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = '%s' OR url = '%s'", $form_state['values']['title'], $form_state['values']['url']); - } - 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. - * - * @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']))); - } -} - function aggregator_admin_remove_feed($form_state, $feed) { return confirm_form( array( @@ -284,6 +137,8 @@ * Process aggregator_form_opml form submissions. */ function aggregator_form_opml_submit($form, &$form_state) { + global $user; + $data = ''; if ($file = file_save_upload('upload')) { $data = file_get_contents($file->filepath); @@ -301,29 +156,34 @@ return; } + // Initialize node object. + $node = new stdClass(); + $node->type = 'feed'; + + // Set meaningful defaults for the form. + $form_state['values']['name'] = $user->name; + $form_state['values']['promote'] = '0'; $form_state['values']['op'] = t('Save'); foreach ($feeds as $feed) { - $result = db_query("SELECT title, url FROM {aggregator_feed} WHERE title = '%s' OR url = '%s'", $feed['title'], $feed['url']); - $duplicate = FALSE; + $result = db_query("SELECT n.title, f.url FROM {aggregator_feed} f LEFT JOIN {node} n ON n.nid = f.nid WHERE n.type = 'feed' AND (n.title = '%s' OR f.url = '%s')", $feed['title'], $feed['url']); while ($old = db_fetch_object($result)) { if (strcasecmp($old->title, $feed['title']) == 0) { drupal_set_message(t('A feed named %title already exists.', array('%title' => $old->title)), 'warning'); - $duplicate = TRUE; - continue; + continue 2; } if (strcasecmp($old->url, $feed['url']) == 0) { drupal_set_message(t('A feed with the URL %url already exists.', array('%url' => $old->url)), 'warning'); - $duplicate = TRUE; - continue; + continue 2; } } - if (!$duplicate) { - $form_state['values']['title'] = $feed['title']; - $form_state['values']['url'] = $feed['url']; - drupal_execute('aggregator_form_feed', $form_state); - } + + $form_state['values']['title'] = $feed['title']; + $form_state['values']['url'] = $feed['url']; + drupal_execute('feed_node_form', $form_state, $node); } + + $form_state['redirect'] = 'admin/content/aggregator'; } /**