Reputation: 61
In WooCommerce, for some reason I am getting this error:
Warning: Invalid argument supplied for foreach() in /home//wp-content/themes/flat/functions.php on line 32
The error only appears with simple products, not variable products with multiple variations. This error seems to be at this line :
foreach($available as $i) {
Any help would be amazing!!
Here is my code:
/**
* Backorder Hook
**/
function backorder_text($available) {
foreach($available as $i) {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
return $available;
}
add_filter('woocommerce_get_availability', 'backorder_text');
add_filter( 'woocommerce_get_availability' , 'revised_woocommerce_get_availability' , 10, 2 );
function revised_woocommerce_get_availability( $available_array , $product) {
if ( $product->managing_stock() ) {
if ( !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' )) && ($product->backorders_allowed() && $product->backorders_require_notification()) ) {
$custom_meta_value = get_post_meta( $product->id, 'Out_of_stock_message', true );
$available_array["availability"] = $custom_meta_value;
}
}
return $available_array;
}
Upvotes: 3
Views: 5586
Reputation: 253919
You can use 2 different hooks for this. And as you are using the same hooks for 2 functions, you can merge it in one function.
The woocommerce_get_availability
filter hook: is used in get_availability()
method:
public function get_availability() {
return apply_filters( 'woocommerce_get_availability', array(
'availability' => $this->get_availability_text(),
'class' => $this->get_availability_class(),
), $this );
}
So you can see also that it's an array with 2 keys 'availability'
and 'class'
. The key 'availability'
is the one that you need and uses get_availability_text()
method and that you can use directly woocommerce_get_availability_text
filter hook at the end of the method code.
1) Using woocommerce_get_availability_text
filter hook (the best choice):
add_filter( 'woocommerce_get_availability_text', 'customizing_availability_text', 10, 2);
function customizing_availability_text( $availability, $product ) {
if ( $_product->is_in_stock() )
$availability = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $availability);
if ( $product->managing_stock() && !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' )) && ($product->backorders_allowed() && $product->backorders_require_notification()) ) {
$availability = get_post_meta( $product->id, 'Out_of_stock_message', true );
return $availability;
}
2) Using woocommerce_get_availability
filter hook.
Here you need to target the 'availability'
in the array, this way:
add_filter( 'woocommerce_get_availability', 'customizing_availability_text', 10, 2);
function customizing_availability_text( $availability, $product ) {
if ( $_product->is_in_stock() )
$availability['availability'] = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $availability['availability']);
if ( $product->managing_stock() && !($product->is_in_stock() && $product->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' )) && ($product->backorders_allowed() && $product->backorders_require_notification()) ) {
$availability['availability'] = get_post_meta( $product->id, 'Out_of_stock_message', true );
return $availability;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
I haven't test your code as it's very specific, but it should work.
Reference: Action and Filter Hook Reference
Upvotes: 2
Reputation: 417
Since the error is on the foreach line, you are probably trying to iterate over a variable that is not an array. Adding a conditional check if the $availability variable is an array should solve the problem. Like this:
function backorder_text($available) {
if (is_array($available)) {
foreach($available as $i) {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available );
}
} else {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
return $available;
}
However, there is an even better way. Since str_replace can accept arrays or strings as parameters, this will work in all situations as well. It is actually what your code does when it is working. In your code the foreach loop is unnecessary, since you are calling str_replace on the $availability variable not the element in that array ($i). The following is simpler and will work whether $availability is an array or a string.
function backorder_text($available) {
return str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
Upvotes: 0
Reputation: 1646
use is_array
function to check if it is an array
function backorder_text($available) {
is_array($available){
foreach($available as $i) {
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
} else{
$available = str_replace('Available on backorder', 'This size is on backorder : Dont Miss out!<BR><span style="font-weight: normal;">Buy it now and we will dispatch as soon as they arrive</span>', $available);
}
return $available;
}
Upvotes: 0