1

Sorry guys, had to post this again as site wouldn't let me respond to comments (new account).

I have been working on some code to decrease quantity of a variable product based on the numeric values of a custom field.

This is working fine, however I have implemented a checkbox that will essentially TURN ON/OFF the feature on each product. This custom checkbox also works fine, appears in 'Product General Settings' and is storing the data fine - I have confirmed this with a VAR_DUMP() on the product page that is accurately dumping yes - (length = 3).

Although the data is storing, I can't seem to use it as a condition and when that condition is in place if ( 'yes' == $stock_weight_checkbox ) the correct decrease in quantity does not work.

I can't seem to get a VAR_DUMP() to work during this process either as it takes place during the checkout confirmation, so I can't see if any values are being displayed there at that point.

My assumptions are as follows: I am improperly calling the post_meta in this area (checkout). Perhaps this call works on the product page but I am missing something or the way I am approaching the call is incorrect.

This is a variable product that is looking for a custom field in the General Settings area during checkout, at which point it is unavailable? (Guess)

Below is the code:

// reduce stock based on 'custom_field'

add_filter( 'woocommerce_order_item_quantity', 'filter_order_item_quantity', 10, 3 ); 
function filter_order_item_quantity( $quantity, $order, $item )  
{
    $product   = $item->get_product();
    $term_name = $product->get_meta( 'custom_field', true );
    $stock_weight_checkbox = $product->get_meta( '_stock_weight_checkbox', true );

    // 'pa_weight' attribute value is "15 grams" - keep only the numbers
    $quantity_grams = preg_replace('/[^0-9.]+/', '', $term_name);

    // new quantity
    if( 'yes' == $stock_weight_checkbox && is_numeric ( $quantity_grams ) && $quantity_grams != 0 )
        $quantity *= $quantity_grams;

    return $quantity;
}

function validate_attribute_weight( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
    // Get custom field
    $weight = get_post_meta( $variation_id, 'custom_field', true );
    $stock_weight_checkbox = get_post_meta( get_the_id(),'_stock_weight_checkbox', true );

    if ( 'yes' == $stock_weight_checkbox && ! empty( $weight ) ) {
        // Get product object
        $product = wc_get_product( $product_id );

        // Get current product stock
        $product_stock = $product->get_stock_quantity();

        // ( Weight * quantity ) > product stock
        if( ( ( $weight * $quantity ) > $product_stock ) ) {
            wc_add_notice( sprintf( 'Sorry, you cannot add <strong>' . $weight .'</strong> of <strong>%1$s</strong> to the cart because there are only <strong>%2$sg</strong> left in our inventory. Please choose a lesser amount. We hope to have more in stock shortly.', $product->get_name(), $product_stock ), 'error' );
            $passed = false;
        }
    }

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'validate_attribute_weight', 10, 5 );

Can anyone notice something wrong? Or at the very least, let me know how I can view the VAR_DUMP() during the checkout process? (I'm used to just spitting it out on some part of my page ie: product page)

1

1 Answer 1

0

There are some points in your code might need to review practically.

Here is something you might be interested to update and a method for you to var_dump the process.

function validate_attribute_weight( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {

    // Get custom field

    // 1. I am not sure if you directly get the post meta using WP builtin return expected result or not since I can see you use $product->get_meta() before
    // $weight = get_post_meta( $variation_id, 'custom_field', true );
    // $stock_weight_checkbox = get_post_meta( get_the_id(),'_stock_weight_checkbox', true );

    // you may try to change to
    // current product from the filter, it is better than get_the_id() because if filter provides to you, more directly and bullet-proof
    $product           = wc_get_product( $product_id );

    // with $product fetched, you may use the same code previously which ensure consistency 
    $stock_weight_checkbox = $product->get_meta( '_stock_weight_checkbox', true );

    if ( 'yes' == $stock_weight_checkbox && ! empty( $weight ) ) {
        // Get product object
        // $product = wc_get_product( $product_id ); // since already get, no need to do so

        // Get current product stock
        $product_stock = $product->get_stock_quantity();

        // ( Weight * quantity ) > product stock
        if( ( ( $weight * $quantity ) > $product_stock ) ) {
            wc_add_notice( sprintf( 'Sorry, you cannot add <strong>' . $weight .'</strong> of <strong>%1$s</strong> to the cart because there are only <strong>%2$sg</strong> left in our inventory. Please choose a lesser amount. We hope to have more in stock shortly.', $product->get_name(), $product_stock ), 'error' );
            $passed = false;
        }
    }

    // what you concern is the testing logic, if you want to intercept, you may add exit()
    // var_dump() here
    exit();

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'validate_attribute_weight', 10, 5 );

Because the WordPress ajax process is like:

  • you click the add to cart
  • it pass the data by JS ajax with URL and then return with something, it will fire the action to the php to process <== this is the point that you can intercept, when the php exit here, anything during the process is in the middle and thus you could see the var_dump();
  • after process completed, the php return result (false/true) and return something to the page

Additional notes on intercepting the process: When you var_dump to track, it is better var_dump($_REQUEST) also. If you have options then need to confirm it is passed from the form to php. This could help to trace and confirm. If the parameter does not exist in $_REQUEST, most likely it is not in the form that is being submitted.

10
  • Thank you for this. Due to your help I was able to get the the if ( 'yes' === $stock_weight_checkbox) part tested and the see it was returning a boolean false in that part of the script. wc_get_product( $product_id ); fixed that and now the condition is accurately showing the error when necessary. The issue I am still having is in the first part of the script. When $stock_weight_checkbox is enabled it no longer correctly reduces the stock quantity according to the specified rules. If I eliminate the 'yes === condition, it works. A var_dump shows 'yes' on product page. Commented Apr 11, 2020 at 3:20
  • It seems that somewhere in the checkout process that product meta ($stock_weight_checkbox) is not being passed or considered. Commented Apr 11, 2020 at 3:21
  • I can see that you use === which means value + type is completely same. It could be type problem if value looks right, try == and see if the result is same. Commented Apr 11, 2020 at 3:32
  • What is the var_dump($stock_weight_checkbox) result? is $stock_weight_checkbox a product attribute? when it is submitted to cart, does it include in $_REQUEST when you var_dump? If not, then the $stock_weight_checkbox did not pass the value. And it is only for display. If so, it is not inside the form tag. Commented Apr 11, 2020 at 3:49
  • I have updated notes on tracing about the $_REQUEST. Commented Apr 11, 2020 at 4:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.