7
Answers
Vote up!
6
Vote down!

How to get a node ID from a product display using the product ID

Extracting the product ID skus from an external source I had to update product display nodes linked to the product. Here's how I got it done:

First I needed the product ID. There are several ways of achieving this. You can query the database directly (the sku and the product ID can both be found in the 'commerce_product' table). Because chances are more actions must be performed on the product, it's better if we load it:

$product = commerce_product_load_by_sku($sku);

Now I can get the Product ID, which is needed for finding the Node ID of the Product Display Node ($product->product_id). With this I can perform an EntityFieldQuery. This is a query to fetch information from fields attached to entities. That's useful, because not everything can be found in the entity object itself.

$query = new EntityFieldQuery;

$query->entityCondition('entity_type', 'node', '=')
->propertyCondition('type', 'product_display')
->fieldCondition('field_product', 'product_id', $product->product_id, '=')
->range(0, 1);

if ($result = $query->execute()) {
//Do stuff with the result
}

That's all!

Hopefully this is useful information, I got the tip from Ryan Szrama (http://drupal.org/user/49344), thanks again!

Asked by: naveko
on June 1, 2012

7 Answers

Vote up!
2
Vote down!

User supplied the answer in the question :D

Josh Miller
Answer by: Josh Miller
Posted: Jun 18, 2012
Vote up!
2
Vote down!

Thanks a lot for your code! I turned it into a custom function that does not need to know the node's bundle nor the referencing field.

<?php
function mymodule_get_referencing_node_id($product) {
 
// Itterate thhrough fields which refer to products.
 
foreach (commerce_info_fields('commerce_product_reference') as $field['field_name']) {
   
// Build query.
   
$query = new EntityFieldQuery;
   
$query->entityCondition('entity_type', 'node', '=')
      ->
fieldCondition($field['field_name'], 'product_id', $product->product_id, '=')
      ->
range(0, 1);

    if (
$result = $query->execute()) {
     
// Return node id.
     
return array_shift(array_keys($result['node']));
    }
  }

  return
false;
}
?>

Cheers, Laurens Meurs

Answer by: lmeurs
Posted: Sep 5, 2013

Comments

Oops, small typo in the foreach statement:

<?php
function mymodule_get_referencing_node_id($product) {
 
// Itterate through all fields which refer to commerce products.
 
foreach (commerce_info_fields('commerce_product_reference') as $field) {
   
// Build query.
   
$query = new EntityFieldQuery;
   
$query->entityCondition('entity_type', 'node', '=')
      ->
fieldCondition($field['field_name'], 'product_id', $product->product_id, '=')
      ->
range(0, 1);

    if (
$result = $query->execute()) {
     
// Return node id.
     
return array_shift(array_keys($result['node']));
    }
  }

  return
false;
}
?>
- lmeurs on September 5, 2013

Thank you! It works well!

- petu on November 26, 2013

Be careful with this function... you are actually forcing only one result and if the site is multilingual it means that your default language always comes first. Here's a revision that might help folks doing language stuff...

<?php
function mymodule_get_referencing_node_id($product) {
  global
$language;

 
// Itterate thhrough fields which refer to products.
 
foreach (commerce_info_fields('commerce_product_reference') as $field['field_name']) {
   
// Build query.
   
$query = new EntityFieldQuery;
   
$query->entityCondition('entity_type', 'node', '=')
      ->
fieldCondition($field['field_name'], 'product_id', $product->product_id, '=')
      ->
propertyCondition('language', $language->language, '=')
      ->
range(0, 1);

    if (
$result = $query->execute()) {
     
// Return node id.
     
return array_shift(array_keys($result['node']));
    }
  }

  return
false;
}
?>

Cheers

- Shane Bill on December 11, 2013
Vote up!
2
Vote down!

$wrapper = entity_metadata_wrapper('commerce_product', $product);
$nodes = $wrapper->field_product_node->value();

Answer by: Khay Ong Tan
Posted: Jun 25, 2014
Vote up!
0
Vote down!

Thank you!

Answer by: Anonymous (not verified)
Posted: Oct 22, 2012
Vote up!
0
Vote down!

So if I'm understanding correctly, I can create an inner join query that will match sku's with node id's using only the commerce_product and node tables?

I have an image hosting site outside Drupal and I'm wanting to put a link next to each image that points to the correct node, so I'm trying to figure out the mysql query that I need to do this. I know the SKU for each image.

Answer by: ndavidg
Posted: Dec 12, 2012
Vote up!
0
Vote down!

if ($result = $query->execute()) {
//Do stuff with the result
$nid = array_shift(array_keys($result['node']));
}
Answer by: orzheshkovsky
Posted: Jul 11, 2013
Vote up!
0
Vote down!

In a rule where you have access to the order. Find the line item, the node entity_id is available as part of the line item data:

$pass_nid = $line_item->data['context']['entity']['entity_id'];

Answer by: Interlated
Posted: Jan 18, 2017