2
Answers
Vote up!
0
Vote down!

Get array value for product variations.

I have a case where I'm creating a e-shop for resellers and private customers, my client have requested that some products should be available only to resellers but still visible to private customers but with the Add to Cart form disabled.

So far, so good. I have a function that is able to read a boolean from the product that controls if the product is available for private customers or not. I get this value with hook_node_view_alter and use the value to change the $form with hook_form_FORM_ID_alter in order to disable certain parts of the Add to Cart form while keeping the select list for product variations enabled.

However, the $build variable only gets the value from the first product variation loaded and such my module stops workings it's magic once a user change the product variation displayed.

I figure that I should be able to get the module to read the value of each product variation by running a foreach-loop through the product display's product_reference array, but I can't for the love of my life figure out how to get these values out.

I'm fairly used to working with commerce while inside Drupal but my knowledge of php and making custom modules is limited, any tips on how I can access an array of product variations and use this in my module would be very helpful.

Thanks beforehand.

Asked by: A.hjelm
on October 15, 2013

2 Answers

Vote up!
0
Vote down!

hey A.hjelm, have u tried to make this with Rules? Set up a Rule depends on User-Role to enable or disable the add to cart form. - only is an idea...

Answer by: dufink
Posted: Oct 15, 2013
Vote up!
0
Vote down!

Hello, Dufink, thank you for your answer.

My initial thought was also to make this happen with rules but I soon realized that I needed some extra functionality that rules couldn't give me. Like keeping parts of the add to cart form still accessible and printing out a message in it's own div inside the form. Maybe it's possible to do however and it's just my understanding of rules that's lacking.

My second plan was to simply hide certain elements with jQuery, but thankfully I didn't have to do that either.

What I in the end managed to do, with the help of a colleague of mine, was to utilize the "commerce_cart_attributes_refresh_alter" function to check the boolean(That controls if the product is available for private customers.) for the ajax-loaded product variation, then double check that value with an array of viable roles.

It's not the most beautiful of solutions but It's a one-time set thing that won't need any altering in any foreseeable future so it works fine for my needs.

Posting code in case anyone else have need for a similar thing.

<?php
/**
* Implements hook_form_alter().
*
* Alter the Commerce 'Add to Cart' form.
**/

function product_access_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state, &$form_id) {
    global
$user;
   
   
//Gets the default product for the loaded Product Display.
   
$default_product = $form['product_id']['#default_value'];
   
//Load the product.
   
$product = commerce_product_load($default_product);
   
   
//Check that the value for "field_available_for_private_customers is set on the loaded product.
   
if(isset($product->field_available_for_private_customers['und'][0]['value'])){
       
//hämtar produkt accessen för privatkunder
       
$product_access = $product->field_available_for_private_customers['und'][0]['value'];

       
//Check the list of available roles.
       
$roles_allowed_to_buy = array(
               
'reseller',
               
//'administrator',
                //'guest'
                //'moderator'
       
);

       
//Adds the message-div regardless of it's going to be used or not.
       
$form['help'] = array(
           
'#markup' => '<div id="test-info"> </div>',
        );
       
       
// If the logged-in users roll is NOT 'reseller' and product_access != 0
        // a message will be shown and the "add to cart" and "quantity" buttons will be unset.
        // This is if the loaded product shouldn't be available for private customers.'

       
if (!array_intersect($user->roles, $roles_allowed_to_buy) && $product_access != 1) {
           
$form['help'] = array(
               
'#markup' => t(
                   
'
                    <div id="test-info"><p>
                    This product is only available through our resellers.
                    </p>
                    </div>
                    '
               
),
            );
            unset(
$form['submit']);
            unset(
$form['quantity']);
        }
    }
}

function
product_access_commerce_cart_attributes_refresh_alter(&$commands, &$form, $form_state){
    global
$user;   
   
   
//Get the product ID.
   
$product_id = $form_state['values']['product_id'];
   
//load the product.
   
$product = commerce_product_load($product_id);
   
   
//Check that the value for "field_available_for_private_customers" is set.
   
if(isset($product->field_available_for_private_customers['und'][0]['value'])){
       
//Get the product_access
       
$product_access = $product->field_available_for_private_customers['und'][0]['value'];
       
       
//ID selector for help-text, add-to-cart button and quantity-select.
       
$selector = '#test-info';
       
$selector_submit = '#' . $form['submit']['#id'];
       
$selector_quantity = '.form-item-quantity';

       
//Messages to be shown dependant on product_access value.
       
$public_product = '';
       
$non_public_product = '<p>This product is only available through our resellers.</p>';
       
       
//vilka roller ska ha access
       
$roles_allowed_to_buy = array(
           
'reseller',
           
#'administrator',
            #'guest'
            #'moderator'
       
);
       
       
// If the logged-in users roll is NOT 'reseller' and product_access != 0
        // a message will be shown and the "add to cart" and "quantity" buttons will be unset.
       
       
if(!array_intersect($user->roles, $roles_allowed_to_buy) && $product_access != 1){
           
$commands[] = ajax_command_replace($selector, $non_public_product);
           
$commands[] = ajax_command_invoke($selector_submit, 'hide');
           
$commands[] = ajax_command_invoke($selector_quantity, 'hide');
        }else{
           
$commands[] = ajax_command_replace($selector, $public_product);
        }
    }
   
}
?>
Answer by: A.hjelm
Posted: Oct 28, 2013