Can anyone tell me why I am getting a PHP warning for the below code?
The warning is triggered by this line:
foreach($available_shipping_methods as $carrier_id => $carrier){
The error message is:
PHP Warning: Invalid argument supplied for foreach() in /home/customer/www/website.com/public_html/wp-content/themes/theme-child/functions.php on line 000
The code:
add_filter('woocommerce_package_rates', 'wf_sort_shipping_methods', 10, 2);
function wf_sort_shipping_methods($available_shipping_methods, $package)
{
// Arrange shipping methods as per your requirement
$sort_order = array(
'wf_shipping_ups' => array(),
'flat_rate' => array(),
'local_pickup' => array(),
'request_shipping_quote' => array(),
);
// unsetting all methods that needs to be sorted
foreach($available_shipping_methods as $carrier_id => $carrier){
$carrier_name = current(explode(":",$carrier_id));
if(array_key_exists($carrier_name,$sort_order)){
$sort_order[$carrier_name][$carrier_id] = $available_shipping_methods[$carrier_id];
unset($available_shipping_methods[$carrier_id]);
}
}
// adding methods again according to sort order array
foreach($sort_order as $carriers){
$available_shipping_methods = array_merge($available_shipping_methods,$carriers);
}
return $available_shipping_methods;
}
Normally you don't need any code to rearrange shipping methods as this can be done directly in the settings for each shipping Zone, see:
Sort shipping methods displayed in WooCommerce Cart and Checkout
If you still need to sort shipping methods programmatically from an array of method IDs (slugs), use the following instead:
add_filter('woocommerce_package_rates', 'reorganize_shipping_methods_from_method_id', 10, 2 );
function reorganize_shipping_methods_from_method_id( $rates, $package )
{
// Here set the desired sorting by shipping method ID in the array
$desired_sorting = array( 'wf_shipping_ups', 'flat_rate', 'local_pickup', 'request_shipping_quote' );
$sorted_rates = array(); // Initializing
// Loop through desired shipping method sorting array
foreach( $desired_sorting as $method_id ) {
// Loop through shipping rates available for current shipping package
foreach( $rates as $rate_key => $rate ) {
if( $rate->method_id === $method_id ) {
$sorted_rates[$rate_key] = $rate;
unset($rates[$rate_key]);
}
}
}
// Merge both arrays (in case you didn't list all shipping methods IDs)
return array_merge( $sorted_rates, $rates );
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and work.
Important: You will have to empty your cart to refresh shipping method cache.
Other related threads: