Discussions

How to show only non referenced products in the "product reference" widget?

When I create(or edit) "Product display" node in "Product reference" field widget I can chose any product entity.
I don't want to display products that are already referenced to other "Product display". I want to hide them in the "Product reference" field widget.
How can I show only non referenced products in the product reference widget?

P.S. Sorry for by bad English.

Posted: Feb 16, 2012

Comments

milkovsky on March 5, 2012

I've got products(hats) on the site. My product_display node - it's a hats model. It can have different sizes and colors, that are represented as related entities(by product reference field).
1 hat could be referenced to model only 1 time. I don't want user to reference this hat to many different models(product_display nodes).

I've found some solution. It's not the best but it works.
I've overridden hook_menu for commerce_product autocomplete that is in commerce_product.module .
Here is the code of my custom module (wghhooks_commerce):

<?php
/**
 * Implements hook_menu().
 */
function wdghooks_commerce_menu() {
 
$items = array();
 
// Override commerce_product autocomplete path of Commerce module
 
$items['commerce_product/autocomplete'] = array(
   
'title' => 'commerce_product autocomplete',
   
'page callback' => 'wdghooks_commerce_commerce_product_autocomplete',
   
'access callback' => TRUE,
   
'type' => MENU_CALLBACK,
  );

  return
$items;
}
?>

As you can see I've changed 'page callback' for my custom 'wdghooks_commerce_commerce_product_autocomplete' .
I copied the previous function and wrote there call of my function(_wdghooks_commerce_products_referended):

<?php
/**
 * Returns output for product autocompletes.
 * Filter products in autocomplete,
 * selecting only nonreferenced products and show them
 */
function wdghooks_commerce_commerce_product_autocomplete($entity_type, $field_name, $bundle, $string = '') {
  .......
   
$products = commerce_product_match_products($field, $instance, $tag_last, $match, array(), 10);

   
// Call of my function
   
$products = _wdghooks_commerce_products_referended($products);
  .......
 
drupal_json_output($matches);
}


/**
 * Select only non referenced products
 * @param type $products - all products
 * @return type - all non referenced products
 */
function _wdghooks_commerce_products_referended($products) {
 
// Select all referenced products
 
$referenced_products = db_select('field_data_field_product', 'p')
      ->
fields('p', array('field_product_product_id'))
      ->
execute();
 
$referenced_products_ids = array();
  foreach (
$referenced_products as $value) {
   
$referenced_products_ids[] = $value->field_product_product_id;
  }

  foreach (
$products as $product_id => $data) {
    if (
in_array($product_id, $referenced_products_ids)) {
      unset(
$products[$product_id]);
    }
  }
  return
$products;
}
?>