2

I have the following wordpress snippet that is working fine except for the ajax call. I am receiving alert yes but not alert data. I suspect that the ajax url is incorrect but have no idea where to point it to as all the code is in the same snippet. I am suppose to receive an alert that says yes and then hallo, if I can get that to work the rest should correct itself.

/*
if (isset($_POST['data_x'])) {
    //echo get_update_dynamic_price_xyz($_REQUEST['data_x']);
    echo 'hallo';
}
*/

add_action('wp_ajax_dynamic_price', 'get_update_dynamic_price_xyz');
add_action('wp_ajax_nopriv_dynamic_price', 'get_update_dynamic_price_xyz');

function get_update_dynamic_price_xyz($qty) {
    global $product;
    
    /**
    * Get the discount details of given product with custom price
    * @param $price float/integer
    * @param $product object (Product object Example: wc_get_product($product_id))
    * @param $quantity int
    * @param $custom_price float/integer (0 for calculate discount from product price)
    * @param $return_details string (Default value 'discounted_price' accepted values = 'discounted_price','all')
    * @param $manual_request boolean (Default value false: pass this as true for get discount even if there is no item in cart)
    * @param $is_cart boolean (Default value true)
    * @return array|float|int - is product has no discounts, returns $price;else return array of discount details based on $return_details
    */
    
    $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', $product->get_price(), $product->get_id(), $qty, 0, 'discounted_price', 'true', 'true');
    
    if ($price == '') {
        $price = $product->get_price();
    }
    
    echo $price;
}

function action_woocommerce_single_product_summary() {
    global $product;
    
    /**
    * Get the discount details of given product with custom price
    * @param $price float/integer
    * @param $product object (Product object Example: wc_get_product($product_id))
    * @param $quantity int
    * @param $custom_price float/integer (0 for calculate discount from product price)
    * @param $return_details string (Default value 'discounted_price' accepted values = 'discounted_price','all')
    * @param $manual_request boolean (Default value false: pass this as true for get discount even if there is no item in cart)
    * @param $is_cart boolean (Default value true)
    * @return array|float|int - is product has no discounts, returns $price;else return array of discount details based on $return_details
    */
    
    $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', $product->get_price(), $product->get_id(), 1, 0, 'discounted_price', 'true', 'true');
    
    if ($price == '') {
        $price = $product->get_price();
    }

    $currency_symbol = get_woocommerce_currency_symbol();
    
    // let's setup our div
    echo sprintf('<div id="product_total_price" style="margin-bottom:20px;">%s %s</div>', __('Product Total:','woocommerce'), '<span class="price">' . $currency_symbol . $price . '</span>' );
    ?>
    <script>
    jQuery(function($) {
        // jQuery variables
        var price = <?php echo $price; ?>, 
            currency = '<?php echo $currency_symbol; ?>',
            quantity =  $( '[name=quantity]' ).val();
            
        // Code to run when the document is ready
        var product_total = parseFloat( price * quantity );
        $( '#product_total_price .price' ).html( currency + product_total.toFixed( 2 ) );
            
        // On change
        $( '[name=quantity]' ).change( function() { 
            var quantity =  this.value;     
            
            /*
            $.ajax({
                url: '/wp-content/themes/astra/functions.php',
                type: 'POST',
                data: {data_x: '4'},
                success: function(data) { 
                    //var price = data;
                    alert('yes');
                    alert(data);
                }
            });
            */
            
        $.ajax({
            url: '<?php echo admin_url('admin-ajax.php') ?>',
            type: 'POST',
            data: {data_x: '4', action: 'dynamic_price'},
            success: function(data) { 
                //var price = data;
                alert('yes');
                alert(data);
            }
        });
            
            if ( ! ( this.value < 1 ) ) {
                product_total = parseFloat( price * this.value );

                $( '#product_total_price .price' ).html( currency + product_total.toFixed( 2 ) );
            }
        });
    });
    </script>

    <?php
}
// We are going to hook this on priority 31, so that it would display below add to cart button.
add_action( 'woocommerce_single_product_summary', 'action_woocommerce_single_product_summary', 31, 0 );
6
  • 1
    I see your top if block is supposed to give the response. It probably ought to 'die' after that, to stop generating the rest of the HTML page. But I think you want to either switch to registering a REST API endpoint and posting to that, or you can use an old-style admin_ajax endpoint if that's easier.
    – Rup
    Nov 2, 2021 at 12:00
  • 1
    But using your theme's functions.php as an endpoint is wrong. Most files that are intended to be included by WordPress deliberately abort early if they're called directly. I'd guess Astra's does too but I don't have a copy to check.
    – Rup
    Nov 2, 2021 at 12:03
  • Someone recommended I change the path to '/wp-admin/admin-ajax.php' but this also did not work. Did not even alert yes. Now I see something about wp_localize_script but have no idea how it works. Have you used it before.
    – B. Venter
    Nov 2, 2021 at 12:37
  • You can use admin ajax if you pass an action parameter and register a hook to handle it. That's what BlueSuiter's answer is trying to do, but it's not complete I don't think. I linked to the admin ajax docs above.
    – Rup
    Nov 2, 2021 at 12:39
  • wp_localise_script lets you set variables in script blocks on the page from PHP, i.e. you can include the price in the main page downloaded without having to make an AJAX call afterwards. This might work for you, but the value written into the page may well be cached depending on your setup.
    – Rup
    Nov 2, 2021 at 12:40

1 Answer 1

1

I have updated the code in your shared code. Please ask in the comments if you did not get changes.

add_action('wp_ajax_dynamic_price', 'get_update_dynamic_price_xyz');
add_action('wp_ajax_nopriv_dynamic_price', 'get_update_dynamic_price_xyz');

function get_update_dynamic_price_xyz()
{
    global $product;

    /**
    * Get the discount details of given product with custom price
    * @param $price float/integer
    * @param $product object (Product object Example: wc_get_product($product_id))
    * @param $quantity int
    * @param $custom_price float/integer (0 for calculate discount from product price)
    * @param $return_details string (Default value 'discounted_price' accepted values = 'discounted_price','all')
    * @param $manual_request boolean (Default value false: pass this as true for get discount even if there is no item in cart)
    * @param $is_cart boolean (Default value true)
    * @return array|float|int - is product has no discounts, returns $price;else return array of discount details based on $return_details
    */
    $qty = $_POST['quantity'];
    $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', $product->get_price(), $product->get_id(), $qty, 0, 'discounted_price', 'true', 'true');

    if ($price == '')
    {
        $price = $product->get_price();
    }

    echo $price;
}

function action_woocommerce_single_product_summary()
{
    global $product;

    /**
    * Get the discount details of given product with custom price
    * @param $price float/integer
    * @param $product object (Product object Example: wc_get_product($product_id))
    * @param $quantity int
    * @param $custom_price float/integer (0 for calculate discount from product price)
    * @param $return_details string (Default value 'discounted_price' accepted values = 'discounted_price','all')
    * @param $manual_request boolean (Default value false: pass this as true for get discount even if there is no item in cart)
    * @param $is_cart boolean (Default value true)
    * @return array|float|int - is product has no discounts, returns $price;else return array of discount details based on $return_details
    */

    $price = apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price', $product->get_price(), $product->get_id(), 1, 0, 'discounted_price', 'true', 'true');

    if ($price == '')
    {
        $price = $product->get_price();
    }

    $currency_symbol = get_woocommerce_currency_symbol();

    // let's setup our div
    echo sprintf('<div id="product_total_price" style="margin-bottom:20px;">%s %s</div>', __('Product Total:', 'woocommerce'), '<span class="price">' . $currency_symbol . $price . '</span>');
?>
    <script>
        jQuery(function($) {
            // jQuery variables
            var price = <?php echo $price; ?>,
                currency = '<?php echo $currency_symbol; ?>',
                quantity = $('[name=quantity]').val();

            // Code to run when the document is ready
            var product_total = parseFloat(price * quantity);
            $('#product_total_price .price').html(currency + product_total.toFixed(2));

            // On change
            $('[name=quantity]').change(function() {
                var quantity = this.value;

                $.ajax({
                    url: '<?php echo admin_url('admin-ajax.php') ?>',
                    type: 'POST',
                    data: {
                        quantity: quantity,
                        action: 'dynamic_price'
                    },
                    success: function(data) {
                        //var price = data;
                        alert('yes');
                        alert(data);
                    }
                });

                if (!(this.value < 1)) {
                    product_total = parseFloat(price * this.value);
                    $('#product_total_price .price').html(currency + product_total.toFixed(2));
                }
            });
        });
    </script>

<?php
}
// We are going to hook this on priority 31, so that it would display below add to cart button.
add_action('woocommerce_single_product_summary', 'action_woocommerce_single_product_summary', 31, 0);
22
  • How is get_update_dynamic_price_xyz passed the data_x value from the request?
    – Rup
    Nov 2, 2021 at 12:10
  • This is the function where you will process the received request on action dynamic_price
    – BlueSuiter
    Nov 2, 2021 at 12:14
  • OK, but get_update_dynamic_price_xyz accepts a single parameter value. How is the data_x value posted mapped onto that parameter? I don't think your answer will do that yet.
    – Rup
    Nov 2, 2021 at 12:41
  • Updated the answer; You have to capture the data received in $_POST.
    – BlueSuiter
    Nov 2, 2021 at 12:53
  • Thank you for everyone's input, I appreciate it. I have added the new ajax call and the 2 action hooks and deleted "(isset($_POST['data_x']))" but it still did not work. In the end the value of data_x needs to be passed to "get_update_dynamic_price_xyz($qty)" which will pass the quantity needed to calculate the dynamic pricing through hook "apply_filters('advanced_woo_discount_rules_get_product_discount_price_from_custom_price'".
    – B. Venter
    Nov 3, 2021 at 13:28

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.