? .svn
? feedapi_1_0_x_dedupe.patch
? feedapi_x_dedupe.patch
? feedapi_aggregator/.svn
? feedapi_aggregator/po/.svn
? feedapi_inherit/.svn
? feedapi_inherit/po/.svn
? feedapi_node/.svn
? feedapi_node/po/.svn
? feedapi_node_views/.svn
? feedapi_node_views/po/.svn
? parser_common_syndication/.svn
? parser_common_syndication/po/.svn
? parser_simplepie/.svn
? parser_simplepie/simplepie.inc
? parser_simplepie/po/.svn
? po/.svn
Index: feedapi_inherit/feedapi_inherit.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_inherit/Attic/feedapi_inherit.module,v
retrieving revision 1.1.2.13
diff -u -r1.1.2.13 feedapi_inherit.module
--- feedapi_inherit/feedapi_inherit.module	21 Dec 2007 10:54:15 -0000	1.1.2.13
+++ feedapi_inherit/feedapi_inherit.module	29 Jan 2008 22:29:53 -0000
@@ -30,10 +30,12 @@
 function feedapi_inherit_nodeapi(&$node, $op) {
   switch ($op) {
     case 'prepare':
-      if ($node->feedapi->feed_nid) {
-        $feed_node = node_load($node->feedapi->feed_nid);
-        if (feedapi_enabled($feed_node->type, 'feedapi_inherit')) {
-          _feedapi_inherit_do_inherit($node, $feed_node);
+      if ($node->feedapi_node->feed_nids) {
+        foreach ($node->feedapi_node->feed_nids as $feed_nid) {
+          $feed_node = node_load($feed_nid);
+          if (feedapi_enabled($feed_node->type, 'feedapi_inherit')) {
+            _feedapi_inherit_do_inherit($node, $feed_node);
+          }
         }
       }
       break;
Index: feedapi_node/feedapi_node.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_node/Attic/feedapi_node.install,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 feedapi_node.install
--- feedapi_node/feedapi_node.install	14 Dec 2007 21:16:21 -0000	1.1.2.7
+++ feedapi_node/feedapi_node.install	29 Jan 2008 22:29:53 -0000
@@ -21,6 +21,13 @@
         KEY url (url(255)),
         KEY guid (guid(255))
       ) DEFAULT CHARSET=latin1;");
+      db_query("CREATE TABLE {feedapi_node_item_feed} (
+          `feed_nid` int(10) unsigned NOT NULL default '0',
+          `feed_item_nid` int(10) unsigned NOT NULL default '0',
+          PRIMARY KEY  (`feed_nid`,`feed_item_nid`),
+          KEY `feed_nid` (`feed_nid`),
+          KEY `feed_item_nid` (`feed_item_nid`)
+        ) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
       break;
     case 'pgsql':
       db_query("CREATE TABLE {feedapi_node_item} (
@@ -36,6 +43,13 @@
       db_query("CREATE INDEX feed_nid_index on {feedapi_node_item}(feed_nid)");
       db_query("CREATE INDEX url_index on {feedapi_node_item}(url)");
       db_query("CREATE INDEX guid_index on {feedapi_node_item}(guid)");
+      db_query("CREATE TABLE {feedapi_node_item_feed} (
+          `feed_nid` int(10) unsigned NOT NULL default '0',
+          `feed_item_nid` int(10) unsigned NOT NULL default '0',
+          PRIMARY KEY  (`feed_nid`,`feed_item_nid`)
+        ) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
+      db_query("CREATE INDEX feed_nid_index on {feedapi_node_item_feed}(feed_nid)");
+      db_query("CREATE INDEX feed_item_nid_index on {feedapi_node_item_feed}(feed_item_nid)");
       break;
   }
   // Creating the content-types for the FeedAPI
@@ -51,7 +65,7 @@
   $info->custom = TRUE;
   node_type_save($info);
   // Adding default FeedAPI settings
-  $preset = unserialize('a:3:{s:7:"enabled";s:1:"1";s:12:"items_delete";s:1:"0";s:10:"processors";a:1:{s:12:"feedapi_node";a:7:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"promote";s:1:"3";s:9:"list_feed";s:1:"3";s:4:"user";s:5:"admin";}}}');
+  $preset = unserialize('a:3:{s:7:"enabled";s:1:"1";s:12:"items_delete";s:1:"0";s:10:"processors";a:1:{s:12:"feedapi_node";a:7:{s:7:"enabled";s:1:"1";s:6:"weight";s:1:"0";s:12:"content_type";s:5:"story";s:9:"node_date";s:4:"feed";s:7:"promote";s:1:"0";s:9:"list_feed";s:1:"3";s:4:"user";s:5:"admin";}}}');
   if (is_array(variable_get('feedapi_settings_feedapi_node', FALSE))) {
     $preset = array_merge($preset, variable_get('feedapi_settings_feedapi_node', FALSE));
   }
@@ -107,15 +121,40 @@
   return $ret;
 }
 
+/**
+ * Create and populate feed_nid / feed_item_nid table.
+ *
+ */
+function feedapi_node_update_3() {
+  switch ($GLOBALS['db_type']) {
+  case 'mysqli':
+  case 'mysql':
+    $ret[] = update_sql("CREATE TABLE IF NOT EXISTS {feedapi_node_item_feed} (
+          `feed_nid` int(10) unsigned NOT NULL default '0',
+          `feed_item_nid` int(10) unsigned NOT NULL default '0',
+          PRIMARY KEY  (`feed_nid`,`feed_item_nid`),
+          KEY `feed_nid` (`feed_nid`),
+          KEY `feed_item_nid` (`feed_item_nid`)
+        ) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
+    $ret[] = update_sql("REPLACE INTO {feedapi_node_item_feed} (feed_nid, feed_item_nid) SELECT feed_nid, nid FROM feedapi_node_item");
+    $ret[] = update_sql("ALTER TABLE {feedapi_node_item} DROP `feed_nid`");
+    break;
+  case 'pgsql':
+    break;
+  }
+  return $ret;
+}
+
 function feedapi_node_uninstall() {
   switch ($GLOBALS['db_type']) {
     case 'mysqli':
     case 'mysql':
     case 'pgsql':
       db_query("DROP TABLE {feedapi_node_item}");
+      db_query("DROP TABLE {feedapi_node_item_feed}");
       break;
   }
   node_type_delete('feedapi_node');
   variable_del('feedapi_settings_feedapi_node');
   menu_rebuild();
-}
\ No newline at end of file
+}
Index: feedapi_node/feedapi_node.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_node/Attic/feedapi_node.module,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 feedapi_node.module
--- feedapi_node/feedapi_node.module	24 Jan 2008 19:56:01 -0000	1.1.2.15
+++ feedapi_node/feedapi_node.module	29 Jan 2008 22:29:53 -0000
@@ -24,10 +24,44 @@
  */
 function feedapi_node_nodeapi(&$node, $op, $teaser) {
   switch ($op) {
+    case 'load':
+      $result = db_query('SELECT fi.*, ff.feed_nid FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON fi.nid = ff.feed_item_nid WHERE fi.nid = %d', $node->nid);
+      while ($f = db_fetch_object($result)) {
+        $node->feedapi_node = $f;
+        $feed_nids[$f->feed_nid] = $f->feed_nid;
+      }
+      if ($node->feedapi_node) {
+        $node->feedapi_node->feed_nids = $feed_nids;
+        unset($node->feedapi_node->feed_nid);
+      }
+      break;
+    case 'insert':
+      if ($node->feedapi_node->feed_item) {
+        $node->feedapi_node->feed_item->nid = $node->nid;
+        foreach ($node->feedapi_node->feed_nids as $feed_nid) {
+          db_query("INSERT INTO {feedapi_node_item_feed} (feed_nid, feed_item_nid) VALUES (%d, %d)", $feed_nid, $node->nid);
+        }
+        $feed_item = $node->feedapi_node->feed_item;
+        $feed_item->fiid = db_next_id('{feedapi_node_item}_fiid');
+        db_query("INSERT INTO {feedapi_node_item} (fiid, nid, url, timestamp, arrived, guid) VALUES (%d, %d, '%s', %d, %d, '%s')", $feed_item->fiid, $node->nid, $feed_item->options->original_url, $feed_item->options->timestamp, time(), $feed_item->options->guid);
+      }
+      break;
+    case 'update':
+      if ($node->feedapi_node) {
+        if ($node->feedapi_node->feed_item) {
+          $feed_item = $node->feedapi_node->feed_item;
+          db_query("UPDATE {feedapi_node_item} SET url = '%s', timestamp = %d, guid = '%s' WHERE fiid = %d", $feed_item->options->original_url, $feed_item->options->timestamp, $feed_item->options->guid, $feed_item->fiid);
+        }
+        db_query('DELETE FROM {feedapi_node_item_feed} WHERE feed_item_nid = %d', $node->nid);
+        foreach ($node->feedapi_node->feed_nids as $feed_nid) {
+          db_query("INSERT INTO {feedapi_node_item_feed} (feed_nid, feed_item_nid) VALUES (%d, %d)", $feed_nid, $node->nid);
+        }
+      }
+      break;
     case 'delete':
-      $result = db_fetch_object(db_query("SELECT fiid FROM {feedapi_node_item} WHERE nid = %d", $node->nid));
-      if (is_object($result)) {
-        _feedapi_node_delete($result);
+      if ($node->feedapi_node) {
+        db_query('DELETE FROM {feedapi_node_item} WHERE nid = %d', $node->nid);
+        db_query('DELETE FROM {feedapi_node_item_feed} WHERE feed_item_nid = %d', $node->nid);
       }
       break;
   }
@@ -38,22 +72,21 @@
  */
 function feedapi_node_link($type, $node = NULL) {
   if ($type == 'node') {
-    $result = db_fetch_array(db_query("SELECT feed_nid, fiid, url FROM {feedapi_node_item} WHERE nid = %d", $node->nid));
-    if (is_numeric($result['feed_nid'])) {
-      $feed_item->fiid = $result['fiid'];
-      $item = _feedapi_node_load($feed_item);
-      $node = node_load($result['feed_nid']);
-      if ((isset($node->feed->url) || isset($node->feed->guid)) && isset($node->title)) {
-        $links['feedapi_article'] = array(
-          'title' => t('Feed:') .' '. $node->title,
-          'href' => 'node/'. $node->nid,
+    if ($node->feedapi_node) {
+      $result = db_query("SELECT n.title, n.nid FROM {node} n WHERE n.nid IN (%s) ORDER BY title DESC", implode(', ', $node->feedapi_node->feed_nids));
+      while ($feed = db_fetch_object($result)) {
+        $links['feedapi_feed_'. $feed->nid] = array(
+          'title' => t('Feed:') .' '. $feed->title,
+          'href' => 'node/'. $feed->nid,
         );
+      }
+      if ($node->feedapi_node->url) {
         $links['feedapi_original'] = array(
           'title' => t('Original article'),
-          'href' => $item->options->original_url,
+          'href' => $node->feedapi_node->url,
         );
-        return $links;
       }
+      return $links;
     }
   }
 }
@@ -93,6 +126,13 @@
         '#description' => t('The newest N items per feed will be promoted to front page.'),
         '#default_value' => 3,
       );
+      $form['x_dedupe'] = array(
+        '#type' => 'radios',
+        '#title' => t('Duplicates'),
+        '#description' => t('If you choose "check for duplicates on all feeds", a feed item will not be created if it already exists on *ANY* feed. Instead, the existing feed item will be linked to the feed. If you are not sure, choose the first option.'),
+        '#options' => array(0 => t('Check for duplicates only within feed'), 1 => t('Check for duplicates on all feeds')),
+        '#default_value' => 0,
+        );
       break;
   }
   return $form;
@@ -118,23 +158,24 @@
  * Handle the promote N items to the frontpage setting
  */
 function feedapi_node_feedapi_after_refresh($feed) {
-  $promote = is_numeric($feed->settings['processors']['feedapi_node']['promote']) ? $feed->settings['processors']['feedapi_node']['promote'] : 15;
-  $result = db_query("SELECT n.nid FROM {node} n JOIN {feedapi_node_item} fi  ON fi.nid = n.nid  WHERE fi.feed_nid = %d ORDER BY fi.timestamp DESC", $feed->nid);
-  $to_promote = array();
-  $to_demote = array();
-  while ($item = db_fetch_object($result)) {
-    if ($promote-- > 0) {
-      $to_promote[] = $item->nid;
+  if ($promote = $feed->settings['processors']['feedapi_node']['promote']) {
+    $result = db_query("SELECT n.nid FROM {node} n JOIN {feedapi_node_item_feed} ff  ON ff.feed_item_nid = n.nid  WHERE ff.feed_nid = %d ORDER BY n.created DESC", $feed->nid);
+    $to_promote = array();
+    $to_demote = array();
+    while ($item = db_fetch_object($result)) {
+      if ($promote-- > 0) {
+        $to_promote[] = $item->nid;
+      }
+      else {
+        $to_demote[] = $item->nid;
+      }
     }
-    else {
-      $to_demote[] = $item->nid;
+    if (count($to_promote) > 0) {
+      db_query("UPDATE {node} SET promote = 1 WHERE nid IN (%s)", implode(',', $to_promote));
+    }
+    if (count($to_demote) > 0) {
+      db_query("UPDATE {node} SET promote = 0 WHERE nid IN (%s)", implode(',', $to_demote));
     }
-  }
-  if (count($to_promote) > 0) {
-    db_query("UPDATE {node} SET promote = 1 WHERE nid IN (%s)", implode(',', $to_promote));
-  }
-  if (count($to_demote) > 0) {
-    db_query("UPDATE {node} SET promote = 0 WHERE nid IN (%s)", implode(',', $to_demote));
   }
 }
 
@@ -157,7 +198,7 @@
   if ($settings['items_delete'] > FEEDAPI_NEVER_DELETE_OLD) {
     $timexpire = time() - $settings['items_delete'];
     // @ TODO Review this query conditions
-    $result = db_query("SELECT * FROM {feedapi_node_item} WHERE feed_nid = %d AND ( (timestamp > 0 AND timestamp < %d) OR (timestamp = 0 AND arrived > 0 AND arrived < %d) )", $feed->nid, $timexpire, $timexpire);
+    $result = db_query("SELECT * FROM {feedapi_node_item} fn JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fn.nid WHERE ff.feed_nid = %d AND ( (fn.timestamp > 0 AND fn.timestamp < %d) OR (fn.timestamp = 0 AND fn.arrived > 0 AND fn.arrived < %d) )", $feed->nid, $timexpire, $timexpire);
     while ($item = db_fetch_object($result)) {
       // We callback feedapi for deleting
       feedapi_expire_item($feed, $item);
@@ -180,6 +221,9 @@
   }
   // Construct the node object
   $node = new stdClass();
+  if (isset($feed_item->nid)) {
+    $node->nid = $feed_item->nid;
+  }
   $node->type = !empty($settings['content_type']) ? $settings['content_type'] : variable_get('feedapi_node_type', 'story');
   // Get the default options from the cont
   $options = variable_get('node_options_'. $node->type, FALSE);
@@ -200,20 +244,28 @@
     $node->teaser = $feed_item->options->teaser;
   }
   // Stick feed item on node so that add on modules can act on it.
-  // Todo: find common format for this.
-  $node->feedapi->feed_item = $feed_item;
+  // A feed item can come in from more than one feed.
+  $node->feedapi_node->feed_nids[$feed_nid] = $feed_nid;
+  $node->feedapi_node->feed_item = $feed_item;
+  // For backwards compatibility - todo: move to using feedapi_node->feed_nids and feedapi_node->feed_item.
   $node->feedapi->feed_nid = $feed_nid;
+  $node->feedapi->feed_item = $feed_item;
   node_object_prepare($node);
-  if (!isset($feed_item->nid)) {
-    node_save($node);
-    $feed_item->nid = $node->nid;
-    $feed_item->fiid = db_next_id('{feedapi_node_item}_fiid');
-    db_query("INSERT INTO {feedapi_node_item} (fiid, feed_nid, nid, url, timestamp, arrived, guid) VALUES (%d, %d, %d, '%s', %d, %d, '%s')", $feed_item->fiid, $feed_nid, $feed_item->nid, $feed_item->options->original_url, $feed_item->options->timestamp, time(), $feed_item->options->guid);
+  
+  // If there are dupes on other feeds, don't create new feed item, but link this feed
+  // to existing feed item.
+  // Heads up: if there is a duplicate on the SAME feed, 
+  // _feedapi_node_save() won't even be called.
+  if (isset($feed_item->feedapi_node->duplicates)) {
+    foreach ($feed_item->feedapi_node->duplicates as $fi_nid => $f_nids) {
+      $feed_item_node = node_load($fi_nid);
+      $feed_item_node->feedapi_node->feed_nids[$feed_nid] = $feed_nid;
+      node_object_prepare($feed_item_node);
+      node_save($feed_item_node);
+    }
   }
   else {
-    $node->nid = $feed_item->nid;
     node_save($node);
-    db_query("UPDATE {feedapi_node_item} SET url = '%s', timestamp = %d, guid = '%s' WHERE fiid = %d", $feed_item->options->original_url, $feed_item->options->timestamp, $feed_item->options->guid, $feed_item->fiid);
   }
   return $feed_item;
 }
@@ -238,28 +290,13 @@
  * Delete a node which already assigned to a feed item
  */
 function _feedapi_node_delete($feed_item) {
-  if (isset($feed_item->nid)) {
-    // It's the copy of node_delete(). it's needed because node_delete checks the permission
-    // and cron can be run anonymously and then the node is not deleted.
-    $node = node_load($feed_item->nid);
-    db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
-    db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);
-
-    // Call the node-specific callback (if any):
-    node_invoke($node, 'delete');
-    node_invoke_nodeapi($node, 'delete');
-
-    // Clear the cache so an anonymous poster can see the node being deleted.
-    cache_clear_all();
-
-    // Remove this node from the search index if needed.
-    if (function_exists('search_wipe')) {
-      search_wipe($node->nid, 'node');
-    }
-    drupal_set_message(t('%title has been deleted.', array('%title' => $node->title)));
-    watchdog('content', t('@type: deleted %title.', array('@type' => t($node->type), '%title' => $node->title)));
+    if (isset($feed_item->nid)) {
+    node_delete($feed_item->nid);
+  }
+  else {
+    // Let's throw an error on the off chance we land here.
+    watchdog('feedapi_node', t('No nid on feed item to delete.'));
   }
-  db_query("DELETE FROM {feedapi_node_item} WHERE fiid = %d", $feed_item->fiid);
 }
 
 /**
@@ -289,7 +326,7 @@
  *  The array of feed elements with basic information
  */
 function _feedapi_node_fetch($feed) {
-  $result = db_query("SELECT nid, fiid, feed_nid, arrived, timestamp FROM {feedapi_node_item} WHERE feed_nid = %d ORDER BY timestamp DESC", $feed->nid);
+  $result = db_query("SELECT fni.nid, fni.fiid, ff.feed_nid, fni.arrived, fni.timestamp FROM {feedapi_node_item} fni JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fni.nid WHERE ff.feed_nid = %d ORDER BY fni.timestamp DESC", $feed->nid);
   $items = array();
   while ($item = db_fetch_object($result)) {
     $node = node_load($item->nid);
@@ -309,20 +346,42 @@
  * @return
  *  TRUE if the item is new, FALSE if the item is a duplicated one
  */
-function _feedapi_node_unique($feed_item, $feed_nid) {
+function _feedapi_node_unique($feed_item, $feed_nid, $settings) {
   // Feed item is duplicate, if URL or GUID are duplicate or if they are both missing.
   if (isset($feed_item->options->original_url)) {
-    $count = db_result(db_query("SELECT fiid FROM {feedapi_node_item} WHERE url = '%s' AND feed_nid = %d", $feed_item->options->original_url, $feed_nid));
+    $count = db_result(db_query("SELECT fni.nid FROM {feedapi_node_item} fni JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fni.nid WHERE fni.url = '%s' AND ff.feed_nid = %d", $feed_item->options->original_url, $feed_nid));
     if ($count) {
       return FALSE;
     }
   }
   if (isset($feed_item->options->guid)) {
-    $count = db_result(db_query("SELECT fiid FROM {feedapi_node_item} WHERE guid = '%s' AND feed_nid = %d", $feed_item->options->guid, $feed_nid));
+    $count = db_result(db_query("SELECT fni.nid FROM {feedapi_node_item} fni JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fni.nid WHERE fni.guid = '%s' AND ff.feed_nid = %d", $feed_item->options->guid, $feed_nid));
     if ($count) {
       return FALSE;
     }
   }
+  // If cross feed de-dupeing is enabled, check now whether there is a duplicate item on other feeds.
+  // If so, store duplicates in array.
+  // There is *usually* only one. However, there might be more than one.
+  // Todo: don't link to feed items whose feed is not x_dedupe enabled.
+  if ($settings['x_dedupe']) {
+    
+    if (isset($feed_item->options->original_url)) {
+      $result = db_query("SELECT fni.nid, ff.feed_nid FROM {feedapi_node_item} fni JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fni.nid WHERE ff.feed_nid != %d AND fni.url = '%s'", $feed_nid, $feed_item->options->original_url);
+      $i = 0;
+      while ($existing_feed_item = db_fetch_object($result)) {
+        $feed_item->feedapi_node->duplicates[$existing_feed_item->nid][] = $existing_feed_item->feed_nid;
+      }
+    }
+    if (!isset($feed_item->feedapi_node->duplicates) && isset($feed_item->options->guid)) {
+      $result = db_query("SELECT fni.nid, ff.feed_nid FROM {feedapi_node_item} fni JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fni.nid WHERE ff.feed_nid != %d AND fni.guid = '%s'", $feed_nid, $feed_item->options->guid);
+      $i = 0;
+      while ($existing_feed_item = db_fetch_object($result)) {
+        $feed_item->feedapi_node->duplicates[$existing_feed_item->nid][] = $existing_feed_item->feed_nid;
+      }
+    }
+  }
+  
   if (isset($feed_item->options->original_url) || isset($feed_item->options->guid)) {
     return TRUE;
   }
Index: feedapi_node/feedapi_node.module.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_node/Attic/feedapi_node.module.test,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 feedapi_node.module.test
--- feedapi_node/feedapi_node.module.test	18 Jan 2008 22:37:10 -0000	1.1.2.4
+++ feedapi_node/feedapi_node.module.test	29 Jan 2008 22:29:53 -0000
@@ -59,7 +59,7 @@
     
     
     // Check the feed items
-    $result = db_query("SELECT nid FROM {feedapi_node_item} WHERE feed_nid = %d", $nid);
+    $result = db_query("SELECT fi.nid FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid);
     $types = array();
     $author_check = TRUE;
     $item_nids = array();
@@ -88,7 +88,7 @@
     node_delete($nid);
     
     // Check if the news items are deleted as well
-    $item_remain = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} WHERE feed_nid = %d", $nid));
+    $item_remain = db_result(db_query("SELECT COUNT(*) FROM {feedapi_node_item} fi JOIN {feedapi_node_item_feed} ff ON ff.feed_item_nid = fi.nid WHERE ff.feed_nid = %d", $nid));
     $this->assertEqual($item_remain, 0, 'All news item database entries are deleted because of feed deletion.');
     
     // Check if the nodes belong to the news items are really deleted
Index: feedapi_node_views/feedapi_node_views.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_node_views/Attic/feedapi_node_views.module,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 feedapi_node_views.module
--- feedapi_node_views/feedapi_node_views.module	5 Jan 2008 13:00:21 -0000	1.1.2.2
+++ feedapi_node_views/feedapi_node_views.module	29 Jan 2008 22:29:53 -0000
@@ -21,11 +21,6 @@
         'field' => 'nid'
       )
     ),
-    'fields' => array(
-      'feed_nid' => array(
-        'name' => t('Parent feed'),
-      ),
-    ),
     'sorts' => array(
       'timestamp' => array(
         'name' => t('FeedAPI Item: Time of the news item'),
@@ -33,6 +28,23 @@
         'option' => views_handler_sort_date_options(),
         'help' => t('Sort by the arrival date for a feed item.')
       )
+    )
+  );
+  $tables['feedapi_node_item_feed'] = array(
+    'name' => 'feedapi_node_item_feed',
+    'join' => array(
+      'left' => array(
+        'table' => 'node',
+        'field' => 'nid',
+      ),
+      'right' => array(
+        'field' => 'feed_nid'
+      )
+    ),
+    'fields' => array(
+      'feed_nid' => array(
+        'name' => t('Parent feed'),
+      )
     ),
     'filters' => array(
       'feed_nid' => array(
@@ -40,10 +52,9 @@
         'option' => 'integer',
         'operator' => views_handler_operator_gtlt(),
         'help' => t('This allows you to filter feed items based on parent feed. You should supply the feed\'s nid.'),
-      ),
+      )
     )
   );
-  
   return $tables;
 }
 
@@ -80,12 +91,11 @@
       $join = array();
       $join['left']['table'] = 'node';
       $join['left']['field'] = 'nid';
-      $join['right']['table'] = 'feedapi_node_item';
-      $join['right']['field'] = 'nid';
-      $query->add_table('feedapi_node_item', TRUE, 1, $join);
-      $query->add_field('nid', 'feedapi_node_item');
-      $query->add_orderby('feedapi_node_item', 'timestamp', 'DESC');
-      $query->add_where('feedapi_node_item.feed_nid = %d', $a2);
+      $join['right']['table'] = 'feedapi_node_item_feed';
+      $join['right']['field'] = 'feed_item_nid';
+      $query->add_table('feedapi_node_item_feed', TRUE, 1, $join);
+      $query->add_field('feed_item_nid', 'feedapi_node_item_feed');
+      $query->add_where('feedapi_node_item_feed.feed_nid = %d', $a2);
       break;
     case 'link':
       $query->num_nodes .= format_plural($query->num_nodes, ' item', ' items');
