I have a Woocommerce based shop.
I used This Link to Change variations product prices via a hook by LoicTheAztec.
It's working perfect, but i found that when user open product page or any page including price, it will giving error (stored in error log file and users can not see that).
Means Error is shown in Debug mode and also stored in error_log file in Root.
Error: [25-Feb-2020 11:12:57 ...] PHP Warning: A non-numeric value encountered in /home/website/public_html/wp-content/themes/name/functions.php on line 1147
Line 1147: return $price * get_price_multiplier();
This hook is used:
// Utility function to change the prices with a multiplier (number)
function get_price_multiplier() {
return 1.2; // x2 for testing
}
// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
return $price * get_price_multiplier();
}
// Variable (price range)
add_filter('woocommerce_variation_prices_price', 'custom_variable_price', 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variable_price', 99, 3 );
function custom_variable_price( $price, $variation, $product ) {
// Delete product cached price (if needed)
// wc_delete_product_transients($variation->get_id());
return $price * get_price_multiplier();
}
// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', 'add_price_multiplier_to_variation_prices_hash', 99, 1 );
function add_price_multiplier_to_variation_prices_hash( $hash ) {
$hash[] = get_price_multiplier();
return $hash;
}
Woocommerce Version: 3.9.2
PHP version: 7.2
Before return you can convert $price to a numeric value.
$price = (float)$price;
Related
I am using the following code in my WordPress site to increase the product price by 10%. It works fine but the issue is that the price is updated every time by 10% when making any edit in the product. I want it increases the price by 10% only when adding a new product.
I am using WC Marketplace plugin. The code works in the vendor side but not in the WordPress admin panel.
Here is the code I am using:
function get_price_multiplier() {
return get_option(10);
}
// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
$price_per = round($price * get_price_multiplier()/100);
return round($price + $price_per);
}
Any help is appreciated.
I have a setup with Woocommerce "Variable Products" where the only variation is 'size' attribute: 15 grams, 100 grams, 250 grams. What I want to do is use that variation amount to pass to the Woo wc-stock-functions, so that when a product variation '15 grams' is purchased, the overall stock goes down by 15, not 1.
Inside Woo, there is file wc-stock-functions (http://hookr.io/plugins/woocommerce/3.0.6/files/includes-wc-stock-functions/) - and this even gives a filter, woocommerce_order_item_quantity. I want to use this to multiply the inventory number by the # of grams, and to reduce inventory this way by grams.
I'm trying this:
// define the woocommerce_order_item_quantity callback
function filter_woocommerce_order_item_quantity( $item_get_quantity, $order,
$item ) {
$original_quantity = $item_get_quantity;
$item_quantity_grams = $item->get_attribute('pa_size');
// attribute value is "15 grams" - so remove all but the numerals
$item_quantity_grams = preg_replace('/[^0-9.]+/', '', $item_quantity_grams);
// multiply for new quantity
$item_get_quantity = ($item_quantity_grams * $original_quantity);
return $item_get_quantity;
};
// add the filter
add_filter( 'woocommerce_order_item_quantity',
'filter_woocommerce_order_item_quantity', 10, 3 );
but am getting internal server error as a response right now.
Does anyone have an idea of what I'm doing wrong with the above code? Thanks for any help.
First error is in $item->get_attribute('pa_size'); as $item is an instance of WC_Order_Item_Product object and get_attribute() method doesn't exist for WC_Order_Item_Product Class.
Instead you need to get the an instance of the WC_Product object using get_product() method from WC_Order_Item_Product Class…
So your code should be:
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_attribute('pa_size');
// The 'pa_size' attribute value is "15 grams" And we keep only the numbers
$quantity_grams = preg_replace('/[^0-9.]+/', '', $term_name);
// Calculated new quantity
if( is_numeric ( $quantity_grams ) && $quantity_grams != 0 )
$quantity *= $quantity_grams;
return $quantity;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: This hooked function is going to reduce the stock quantity based on that new returned increased quantity value (in this case the real quantity multiplied by 15)
I have a Woocommerce store set up with various product categories.
I want to apply a 20% discount to all products, which belong to the product category Cuckoo
For now all I'm trying to achieve is set a sale price in my functions.php
It tried as follows:
/*
* For a specific date, 20% off all products with product category as cuckoo clock.
*/
function cuckoo_minus_twenty($sale_price, $product) {
$sale_price = $product->get_price() * 0.8;
return $sale_price;
};
// add the action
add_filter( 'woocommerce_get_sale_price', 'cuckoo_minus_twenty', 10, 2 );
If I var_dump the result of $sale_price after the calculation I get the correct answer, however the price display on the front-end strikes out the regular price and displays the sale price as the regular price.
Is there a hook/filter I can use to achieve this?
I've also tried setting the sale price by doing:
$product->set_sale_price($sale_price);
to no avail.
The hook woocommerce_get_sale_price is deprecated since WooCommerce 3 and replaced by woocommerce_product_get_sale_price.
Also Product displayed prices are cached. When sale price is active, regular price is also active.
Try this instead:
// Generating dynamically the product "regular price"
add_filter( 'woocommerce_product_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
function custom_dynamic_regular_price( $regular_price, $product ) {
if( empty($regular_price) || $regular_price == 0 )
return $product->get_price();
else
return $regular_price;
}
// Generating dynamically the product "sale price"
add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
function custom_dynamic_sale_price( $sale_price, $product ) {
$rate = 0.8;
if( empty($sale_price) || $sale_price == 0 )
return $product->get_regular_price() * $rate;
else
return $sale_price;
};
// Displayed formatted regular price + sale price
add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
function custom_dynamic_sale_price_html( $price_html, $product ) {
if( $product->is_type('variable') ) return $price_html;
$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
return $price_html;
}
Code goes in function.php file of your active child theme (active theme).
Tested and works on single product, shop, product category and tag archive pages.
The continuation in:
Wrong Woocommerce cart item price after setting programmatically product sale price
I realiced, you more or less need all of the following filters to make the HTML work out of the box.
add_filter( 'woocommerce_product_get_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_variation_prices_price', 'custom_dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_variation_prices_sale_price', 'custom_dynamic_sale_price', 10, 2 );
And you need to make sure you've changed the woocommerce_get_variation_prices_hash becasue of the stored transients if you want to display it correctly for variable products.
You may find the gist i've created for a client useful
https://gist.github.com/xandl/743fb6af60827eb95ad42b20b478b020
use woocomerce_get_sale_price filter.
add_filter('woocommerce_get_sale_price', 'my_custom_price', 99, 2);
add_filter('woocommerce_get_price', 'my_custom_price', 99, 2);
function my_custom_price( $price, $product )
{
//your logic for calculating the new price here
$price = $product->get_regular_price() * 0.8;
//Return the new price (this is the price that will be used everywhere in the store)
return $price;
}
IN WooCommerce, I need to multiply all product prices by a number. So I have used the following (via a plugin):
add_filter('woocommerce_get_regular_price', array( $this, 'my_custom_price'), 99);
add_filter('woocommerce_get_price', array( $this, 'my_custom_price'), 99);
function my_custom_price( $original_price ) {
global $post, $woocommerce;
//Logic for calculating the new price here
$new_price = $original_price * 2;
//Return the new price (this is the price that will be used everywhere in the store)
return $new_price;
}
But, that doesn't work for variation products. I have tried the following hooks with no luck:
add_filter('woocommerce_get_variation_regular_price', array( $this, 'my_custom_price'), 99);
add_filter('woocommerce_get_variation_price', array( $this, 'my_custom_price'), 99);
The only one that works half way is this one:
add_filter('woocommerce_variation_prices_price', array( $this, 'my_custom_price'), 99);
But that just changed the overall price, not the selected variation price. See the image below, price is BsF. 200 and the overall price is right, 200 x 2 = 400, but the variation price when selected still shows 200:
Note: I need it to actually change, so display html hooks wont work.
Is there anything I'm missing, or something wrong?
Update (December 2020)
2 code versions for themes and plugins (works in Woocommerce 3.3.x too)
Cached variations prices in Woocommerce 3 (Update and addition): Now using woocommerce_get_variation_prices_hash filter hook much more efficient, instead of wc_delete_product_transients()… See this related thread
Added product price filter widget hooks (see at the end).
1) Plugin version with a constructor function:
The hooks that you are using are deprecated in WooCommerce 3+
To make it work for all products prices, including variations prices, you should use this:
## The following goes inside the constructor ##
// Simple, grouped and external products
add_filter('woocommerce_product_get_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', array( $this, 'custom_price' ), 99, 2 );
add_filter('woocommerce_product_variation_get_price', array( $this, 'custom_price' ), 99, 2 );
// Variable (price range)
add_filter('woocommerce_variation_prices_price', array( $this, 'custom_variable_price' ), 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', array( $this, 'custom_variable_price' ), 99, 3 );
// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'add_price_multiplier_to_variation_prices_hash' ), 99, 3 );
## This goes outside the constructor ##
// Utility function to change the prices with a multiplier (number)
public function get_price_multiplier() {
return 2; // x2 for testing
}
public function custom_price( $price, $product ) {
return (float) $price * get_price_multiplier();
}
public function custom_variable_price( $price, $variation, $product ) {
return (float) $price * get_price_multiplier();
}
public function add_price_multiplier_to_variation_prices_hash( $price_hash, $product, $for_display ) {
$price_hash[] = get_price_multiplier();
return $price_hash;
}
The code tested and perfectly works (only) in WooCommerce 3+.
2) For theme version: functions.php file on active child theme (or active theme):
// Utility function to change the prices with a multiplier (number)
function get_price_multiplier() {
return 2; // x2 for testing
}
// Simple, grouped and external products
add_filter('woocommerce_product_get_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'custom_price', 99, 2 );
// Variations
add_filter('woocommerce_product_variation_get_regular_price', 'custom_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
return (float) $price * get_price_multiplier();
}
// Variable (price range)
add_filter('woocommerce_variation_prices_price', 'custom_variable_price', 99, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'custom_variable_price', 99, 3 );
function custom_variable_price( $price, $variation, $product ) {
// Delete product cached price (if needed)
// wc_delete_product_transients($variation->get_id());
return (float) $price * get_price_multiplier();
}
// Handling price caching (see explanations at the end)
add_filter( 'woocommerce_get_variation_prices_hash', 'add_price_multiplier_to_variation_prices_hash', 99, 3 );
function add_price_multiplier_to_variation_prices_hash( $price_hash, $product, $for_display ) {
$price_hash[] = get_price_multiplier();
return $price_hash;
}
Tested and works on woocommerce 3+
For products in sale you have those hooks:
woocommerce_product_get_sale_price (Simple, grouped and external products)
woocommerce_variation_prices_sale_price (Variable products (min-max))
woocommerce_product_variation_get_sale_price (Products variations)
Cached prices and woocommerce 3:
The 3 filters hooks involved in variations cached prices are:
woocommerce_variation_prices_price
woocommerce_variation_prices_regular_price
woocommerce_variation_prices_sale_price
Introduced in Woocommerce 3, woocommerce_get_variation_prices_hash filter hook will allow to refresh variations cached prices in a much more efficient way, without deleting related transients anytime that this hooks are executed.
So performances will stay boosted (Thanks to Matthew Clark that pointed this better way)
See: Caching and dynamic pricing – upcoming changes to the get_variation_prices method
For filtering product prices with a widget (min and max price), use the following hooks:
woocommerce_price_filter_widget_min_amount that has one argument $price
woocommerce_price_filter_widget_max_amount that has one argument $price
I need to change the price of my products in my store, with a 10% discount, if my customer is from some specific place, so, I wrote this code:
add_filter('woocommerce_price_html', 'my_price_edit');
function my_price_edit() {
$product = new WC_Product( get_the_ID() );
$price = $product->price;
echo $price * 0.9;
}
Ok, it works! But when in the checkout the price are normals without the 10% discount!
Does have some hook for change the price of the products in the checkout area or some different code to change correctly in the both (in the product page and checkout)?
New in Woocommerce too.
Your question looks really similiar to this one.
Adding Custom price with woocomerce product price in Cart & Checkout
I think you need to use the woocommerce_cart_item_subtotal hook to change the price in the cart directly (not exactly as a parameter)
I made a slightly modification to the code (changed price formula). I think that may help you.
add_filter( 'woocommerce_get_discounted_price', 'calculate_discounted_price', 10, 2 );
// Display the line total price
add_filter( 'woocommerce_cart_item_subtotal', 'display_discounted_price', 10, 2 );
function calculate_discounted_price( $price, $values ) {
// You have all your data on $values;
$price = $price*.09;
return $price;
}
// wc_price => format the price with your own currency
function display_discounted_price( $values, $item ) {
return wc_price( $item[ 'line_total' ] );
}