I'm using the feeds module to pull in a set of publications into a Drupal content type. I have two separate feeds, which I hoped would work as follows:

Feed 1 - pulls in most of the fields
Feed 2 - accesses a separate url source and updates one field on the content type.

The problem I have is that feed 2 always creates a new set of nodes rather than updating the existing nodes (that were created using feed 1), despite the GUIDs being identical. I have looked at the feeds_items database table and it appears that each feed creates it's own set of GUID to entity_id mappings.

What I want to achieve is one of the following:

1. Allow feed 2 to update the same nodes as feed 1.

OR

2. Allow both URL sources to be used in one feed.

Is there any way to do this with custom code or otherwise?

Comments

littledynamo’s picture

I knocked something together that allows my second feed to update the nodes from my first feed. Not sure if this is the right way of doing things but it works. Here's what I did in case it helps someone else in future:

- Created a custom processor that extends FeedsNodeProcessor
- Copied across all of FeedsNodeProcessor's functions to the new class.
- Overrided the existingEntityId function as follows (harvard_format is my secondary feed and pure_feed is my primary feed):

protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
  if($source->id == 'harvard_format') {
      $query = db_select('feeds_item')
        ->fields('feeds_item', array('entity_id'))
        ->condition('feed_nid', $source->feed_nid)
        ->condition('entity_type', $this->entityType())
        ->condition('id', 'pure_feed');

      // Iterate through all unique targets and test whether they do already
      // exist in the database.
      foreach ($this->uniqueTargets($source, $result) as $target => $value) {
        switch ($target) {
          case 'url':
            $entity_id = $query->condition('url', $value)->execute()->fetchField();
            break;
          case 'guid':
            $entity_id = $query->condition('guid', $value)->execute()->fetchField();
            break;
        }
        if (isset($entity_id)) {
          // Return with the content id found.
          return $entity_id;
        }
      }
      return 0;
    }
    elseif ($nid = parent::existingEntityId($source, $result)) {
      return $nid;
    } else {

      // Iterate through all unique targets and test whether they do already
      // exist in the database.
      foreach ($this->uniqueTargets($source, $result) as $target => $value) {
        switch ($target) {
          case 'nid':
            $nid = db_query("SELECT nid FROM {node} WHERE nid = :nid", array(':nid' => $value))->fetchField();
            break;
          case 'title':
            $nid = db_query("SELECT nid FROM {node} WHERE title = :title AND type = :type", array(':title' => $value, ':type' => $this->config['content_type']))->fetchField();
            break;
          case 'feeds_source':
            if ($id = feeds_get_importer_id($this->config['content_type'])) {
              $nid = db_query("SELECT fs.feed_nid FROM {node} n JOIN {feeds_source} fs ON n.nid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $id, ':source' => $value))->fetchField();
            }
            break;
        }
        if ($nid) {
          // Return with the first nid found.
          return $nid;
        }
      }
      return 0;
    }
} 

- Copied across the the Process and newItemInfo functions from FeedsProcessor.
- Overrided newItemInfo as follows:

protected function newItemInfo($entity, $feed_nid, $hash = '') {

    $entity->feeds_item = new stdClass();
    $entity->feeds_item->entity_id = 0;
    $entity->feeds_item->entity_type = $this->entityType();
    // Specify the feed id, otherwise pure_feed's entries in the feeds_item table will be changed to harvard_format
    $entity->feeds_item->id = ($this->id == "harvard_format") ? "pure_feed" : $this->id;  
    $entity->feeds_item->feed_nid = $feed_nid;
    $entity->feeds_item->imported = REQUEST_TIME;
    $entity->feeds_item->hash = $hash;
    $entity->feeds_item->url = '';
    $entity->feeds_item->guid = '';
  } 
littledynamo’s picture

Status: Active » Closed (fixed)
littledynamo’s picture

I made life difficult for myself by creating a fork of the Node Processor, this issue is a duplicate of https://drupal.org/node/1539224 (issue contains a patch).