Importing Commerce products and node displays using feeds

Tags: Tech Blog Published:

Recently, we built a Drupal Commerce site that has its it’s products created automatically from an XML feed. To import these products, we used the feeds module (https://www.drupal.org/project/feeds). The site also made use of the “inline_entity_form” module (https://www.drupal.org/project/inline_entity_form), making it possible to associate and update both a product entity and it’s node display at the same time. Two feeds were set up, one for the product entity and another for the node display. This unearthed a problem with using feeds though… the product entity needed to be created before the node display, so that the relativity could be set. If the node display is created first, the relativity is not set, resulting in a broken output.

To solve this, the feeds need to run in the correct order. As the feeds module by default will use cron to trigger the feeds to start, there isn’t a way to say which fires first.

Drupal Commerce

The solution below, involves creating a custom module...

The first thing to do is to stop your feeds running in the default schedule. To do this, edit your feed, and under “Basic settings”, set “Periodic import” to “Off”. (Note: you can leave the first feed that should run turned on, but in the example below, we trigger this within code using hook_cron() so that everything happens in the same place).

A handy function is available to use as a trigger : hook_feeds_after_import() (http://drupalcontrib.org/api/drupal/contributions!feeds!feeds.api.php/fu...). This runs after any feed has completed, so we can use it to trigger our second feed when the first has finished.

All that is required now is the action to run the feed. This can be done with:

 

<?php
$myFeed = feeds_source('your_computed_feed_name');
while (FEEDS_BATCH_COMPLETE != $myFeed->import());
?>

 

Piecing this together, we can then run the first feed using hook_cron(), with the completion of the first feed triggering the next one to run...

 

<?php
function your_module_name_cron() {

  $myFeed1 = feeds_source('your_computed_feed_name');
  while (FEEDS_BATCH_COMPLETE != $myFeed1->import());

}

function your_module_name_feeds_after_import(FeedsSource $source) {

 if ($source->id == 'your_computed_feed_name') {

    $myFeed2 = feeds_source('your_computed_feed_name_2');
    while (FEEDS_BATCH_COMPLETE != $myFeed2->import());

  }

}
?>