my goal is to be able to dynamically manipulate price of a product using its parameters (= inputs from the form, e.g. quantity). When the customer changes a parameter, the price will be recalculated and it must happen on the server side. The calculations formulas will be quite complicated and will use, along with the dynamic inputs from the customer, many static inputs (saved in a database, in a csv file etc.) and mathematical functions. I looked at some plugins but none seems to be able to handle the complexity. So I'd like to try and do it myself in the code.
Please note that this is my very first wordpress project. I am not sure this is a correct way to do it but that is where my research got me. I have been able to grasp (to a certain extent) the concept of the hooks, actions and filters and I found that to be able to read the inputs from the form without reloading the page I need to use AJAX. Here is what I have managed to put together so far:
I have this in functions.php:
<?php
// functions.php
global $formData;
wp_register_script( 'ajax-form', admin_url('js/jz_skripty/ajax-form.js'), array('jquery') );
wp_localize_script('ajax-form', 'ajax_object', array('ajaxurl' => admin_url('admin-ajax.php')));
wp_enqueue_script( 'jquery' );
wp_enqueue_script('ajax-form');
add_action('wp_ajax_yReadFormData', 'yReadFormData');
add_action('wp_ajax_nopriv_yReadFormData', 'yReadFormData');
function yReadFormData() {
global $formData;
$formData = $_POST; // get the values from the form
print_r($formData);
wp_die(); // end the ajax request
}
/**
* Manipulate prices
*/
// Variable
add_filter('woocommerce_product_variation_get_price', 'yCalculatePrice' , 99, 2 );
function yCalculatePrice( $price, $product ) {
// Delete product cached price (if needed)
wc_delete_product_transients($product->get_id());
global $formData;
$quantity = $formData['quantity'];
$price = $price * log($quantity);
return $price;
}
// Variations (of a variable product)
add_filter('woocommerce_variation_prices_price', 'yCalculatePrice_variants', 99, 3 );
function yCalculatePrice_variants( $price, $variation, $product ) {
// Delete product cached price (if needed)
wc_delete_product_transients($variation->get_id());
global $formData;
$quantity = $formData['quantity'];
$price = $price * log($quantity);
return $price;
}
This is the AJAX:
// ajax-form.js
jQuery(document).ready(function ($) {
var prevQuantity = 0; // initialize a variable to store the previous quantity value
$('.input-text.qty.text').change(function (e) {
e.preventDefault(); // prevent default form submission
var quantity = $(this).val(); // get the value of the input field
if (quantity != prevQuantity) { // check if the quantity value has changed
$.ajax({
type: 'POST',
url: ajax_object.ajaxurl, // use the localized variable
//dataType: 'json',
data: {
action: 'yReadFormData',
quantity: quantity
}, // send the action and the input value
success: function (response) {
console.log(response); // display the response from the server
}
});
prevQuantity = quantity; // update the previous quantity value
}
});
// trigger the change event on page load
$('.input-text.qty.text').trigger('change');
});
If I load the page and check the console, it outputs some data. Whne I change the quantity in the form, it does chnage the output. So this sems to work:
But at the same time I am getting a warning: Warning: Trying to access array offset on value of type null in functions.php on line 41 (and similarly for other lines – this is reference to the lines with $quantity = $formData['quantity'];
). In the function yReadFormData()
it seems there is the content in the array $formData
, but in other functions it is null. Why? What am I missing?
Any hints will be much appreciated. Thank you.