Thanks for doing this module. One small request. As SKU is a unique field, it would be good to set it as 'optional_unique' in the feeds import. To do this, all that is needed is to add a line in the model array as follows:-

// Model
		$targets['model'] = array(
			'name' => t('UC: Model/SKU'),
			'callback' => 'uc_feeds_feeds_set_target',
			'description' => 'Ubercart:'. t('Model/SKU'),
			'optional_unique' => TRUE,
		);

This would go in as line 16 in the uc_feeds.module file. That would be great.

Comments

christoph’s picture

I've realised that this won't work, as the Feed Processor needs to use this unique identifier to return the right line to update. I can't see any hook which will allow this to be done - so to achieve this it is likely a processor which extends FeedsNodeProcessor will need to be written. I'll see what I can do.

christoph’s picture

StatusFileSize
new2.84 KB

The suggestion I made above doesn't work - it needed a specific processor written for it in order to get that data into the product and using Feeds' unique target mapping. I've written a rough and ready module which suited our own need to get data loaded. It may be valuable for someone else or maybe eventually integrated into this module. The core code is in the OlamaluFeedsProductProcessor and basically extends the FeedsNodeProcessor but does a little extra when loading Ubercart Products. Happy for any of this code to be copied/used under the same license as the uc_feeds module. (Olamalu is our company name, just in case you're wondering).

dubs’s picture

Thanks Christoph. In a quieter moment, I'll take a look and see what can be integrated. It does make sense to make the SKU the unique target so that should be done I think.

smscotten’s picture

Christoph, thanks for sharing. Hoping I can wrap my brain around what you have done. I'm still not sure why SKU needs its own processor when GUID and URL don't seem to.

problue solutions’s picture

Hi christoph,

Why does the module use Feed Nodes Processor instead of Node processor?

Maybe I'm missing something, but when I select Feeds Node processor I can't choose my product content type, I can only do that with Node processor.

There is no OlamaluFeedsProductProcessor to select.

christoph’s picture

Hi thiokol,

Good question. It's been a while and I'm not sure.

On checking inside the feeds module which I was working with, I think I only found a FeedsNodeProcessor inside the plugins directory. Is there a NodeProcessor elsewhere in another module.

I think there are 2 choices with feeds. You can alternatively use a 'feeds_node_processor_targets_alter' which alters the node processor (I guess this is what you mentioned... and I think this may actually be the FeedsNodeProcessor but I'm really not sure)., or you can completely implement your own processor. The targets_alter gives you the node processor functionality plus any you add via this method. Implementing your own requires extending from FeedsProcessor or one of it's descendants. So I think that is what I did.

Looking quickly back over my code, it uses quite a bit of the core functionality by calling parent::xxx_function_xxx and then adds it's own stuff - such as in the getMappingTargets() function. So for the mapping, it gets all the node stuff and then adds all sorts of ubercart stuff.

To make a processor visible, in the module file you need to implement the hook_feeds_plugin function to say that this is a processor which is available. The processor should then be selectable.

This stuff was really internal code we were using - so you'd obviously want to drop all the 'olamalu' references!

Hope that answers the question you were asking & sorry for the delay in answering - been a bit slack with coming onto drupal.org.

Masala’s picture

Thanks Christoph.
string "'optional_unique' => TRUE," show marker in 7.x too, but no realy unique. I am looking for something which works in 7.x.

dubs’s picture

Status: Active » Closed (won't fix)

I'm going to close this for now. If a patch is supplied please reopen and I will apply it.

zeezhao’s picture

Pls have you seen or tried this - http://drupal.org/node/1307732#field_as_unique_id_7
[although for D7]

ikee’s picture

If you have not dealt with this problem I suggest you the following solution.

step 1.
uc_feeds.module - 16 line

    // Model
    $targets['uc_product:model'] = array(
      'name' => t('UC: Model/SKU'),
      'callback' => 'uc_feeds_feeds_set_target',
      'description' => t('Ubercart: !mapper', array('!mapper' => t('Model/SKU'))),
	  'optional_unique' => TRUE,
    );

step 1.
FeedsNodeProcessor.inc - 353 line

  protected function existingItemId(FeedsImportBatch $batch, FeedsSource $source) {

    // Iterate through all unique targets and test whether they do already
    // exist in the database.
    foreach ($this->uniqueTargets($batch) as $target => $value) {
      switch ($target) {
        case 'nid':
          $nid = db_result(db_query("SELECT nid FROM {node} WHERE nid = %d", $value));
          break;
        case 'url':
          $nid = db_result(db_query("SELECT nid FROM {feeds_node_item} WHERE feed_nid = %d AND id = '%s' AND url = '%s'", $source->feed_nid, $source->id, $value));
          break;
        case 'guid':
          $nid = db_result(db_query("SELECT nid FROM {feeds_node_item} WHERE feed_nid = %d AND id = '%s' AND guid = '%s'", $source->feed_nid, $source->id, $value));
          break;
        case 'uc_product:model':
          $nid = db_result(db_query("SELECT nid FROM {uc_products} WHERE model = '%s'", $value));
          break;
      }
      if ($nid) {
        // Return with the first nid found.
        return $nid;
      }
    }
    return 0;
  }
Frando’s picture

Status: Closed (won't fix) » Needs review
StatusFileSize
new3.18 KB

Here is a patch that solves the problem properly. It adds an UbercartFeedsNodeProcessor that allows to map to existing entities based on Model/SKU. This is a minimal processor based on FeedsNodeProcessor. To use it, just select it as processor, add a mapping on Model/SKU and set it as unique.

This is basically as described in #10, but without having to hack feeds module, which is a no go for a proper implementation.

m.stenta’s picture

StatusFileSize
new12.83 KB

I wrote a patch for this a month ago, but hadn't posted it. It's basically the same as @Frando's patch, but also does a few extra things. This is what it does:

  • Provides a new "Ubercart Feeds Product Processor" class that extends FeedsNodeProcessor (like @Frando's patch).
  • Moves all of the Ubercart product targets defined in uc_feeds_feeds_node_processor_targets_alter() into the new class (using the getMappingTargets() method). I would argue that this is the better way to do it, because you don't want to allow mapping product-specific fields to non-product node types. See the next item below for enforcing that... The only issue with doing this is that it will break existing importers that are using uc_feeds mappings, unless they are updated to use the new processor.
  • Overrides the config form for the processor to ensure that only product node types can be selected.
  • Fixes the "name" of pkg_qty and default_qty mapping targets. They were "UC: pkg_qty" and "UC: default_qty", respectively. Now they are "UC: Package Quantity" and "UC: Default Quantity".
  • Overrides the buildNode() method and adds a "$node->uc_feeds_import = TRUE;" flag to nodes. This is just a handy flag that I'm using in hook_nodeapi() to act only on nodes that are being created/updated via this processor.

Maybe it makes sense to break this up into multiple patches, but I figured I would post it in full and open it up for discussion.

m.stenta’s picture

StatusFileSize
new12.83 KB

Minor whitespace fixes to previous patch.

GregoryThomasFox’s picture

Issue summary: View changes

Where is it that you place this patch for it to work?

GregoryThomasFox’s picture

I have placed UCFeedsProductProcessor.inc in modules/feeds/plugins and editied the uc_feeds.module however I am getting a error message on my site stating:Missing Feeds plugin UCFeedsProductProcessor. See __none__. Check whether all required libraries and modules are installed properly

GregoryThomasFox’s picture

Issue with this patch it allows you to set the SKU as unique but when importing all data related to UC is not stored.

m.stenta’s picture

@GregoryThomasFox: there is a great resource on how to apply patches on Drupal.org here: http://drupal.org/patch/apply -- please follow the instructions there, or ask for help in a more general location, so we can keep this issue focused on the issue.

Apply the patch using the standard patch application procedure, and be sure to clear your cache after you do so, because this patch adds a new processor class, which needs to be registered via CTools (will happen automatically with a cache clear). I suspect that doing both of those things will solve the issue you described in #15.

Can you elaborate on your comment in #16? It doesn't make sense to me.

GregoryThomasFox’s picture

@m.stenta I applied this patch manually and it has allowed me to set the SKU as a unique target in the feeds setting however when I upload a CSV file containing product information none of the Ubercart fields such as SKU and sale price get updated.

m.stenta’s picture

@GregoryThomasFox: you cannot *update* the SKU of a product if that is the field you're using as *unique*. If you try to do that, it will probably just create a new product for you with the new SKU.

GregoryThomasFox’s picture

What I mean is adding this patch allows me to set the Sku as unique however when importing the ubercart fields for a product dont get pulled through (even though they are mapped to do so) for instance the products title and image are pulled through as they are originally drupal fields but fields such as sell price and sku are not pulled through.

adamt19’s picture

Like Masala, looking for a patch that works with D7 vers. of UC Feed Mappers

chilligroup’s picture

subscribe

nikolay shapovalov’s picture

Status: Needs review » Reviewed & tested by the community

Patch #13 working awesome.

nikolay shapovalov’s picture

Now we need to port it to D7.

mcaden’s picture

StatusFileSize
new1.86 KB

Created patch for D7.

This seems to be working for me. I realize that there's better ways of writing drupal queries now but this does seem to do the trick. Feel free to refactor.

nightonfire’s picture

I tried patch #25 and could not get it to work.

When I was debugging I found that the model array looks correct at the end of the processor_targets_alter call however using devels dd function I could not get any thing from the uc_feeds_sku_mapper_unique function. I think the function is not being called at all. Anyone have any ideas as to why that would be?

[model] => Array
(
  [name] => UC: Model/SKU
  [callback] => uc_feeds_set_target
  [description] => Ubercart:Model/SKU
  [optional_unique] => 1
  [unique_callbacks] => Array
  (
    [0] => uc_feeds_sku_mapper_unique
  )
)
nightonfire’s picture

Nevermind I got it to work properly. I had an out of date module.