hide a shipping method if there is not shipping class in cart - woocommerce

I have been looking all over for clues but what I have found so far does not work. I want to hide a shipping method if there are no items in the cart with a specific shipping class. i have found methods to hide if there is a class in cart and can't seem to tweak it to get it to work for me. Can anyone modify this so that the cart will hide local delivery if shipping class "Cannabis" is not in the cart?
// Hides other shipping methods if cannabis is in cart
add_filter('woocommerce_package_rates', 'hide_shipping_method_when_shipping_class_product_is_in_cart', 10, 2);
function hide_shipping_method_when_shipping_class_product_is_in_cart($available_shipping_methods, $package)
{
// Shipping class IDs that need the method removed
$shipping_class_ids = array(
31
);
$shipping_services_to_hide = array(
'wf_shipping_usps:D_PRIORITY_MAIL',
'wf_shipping_usps:D_EXPRESS_MAIL',
'wf_shipping_usps:flat_rate_box_priority'
);
$shipping_class_exists = false;
foreach(WC()->cart->cart_contents as $key => $values) {
if (in_array($values['data']->get_shipping_class_id() , $shipping_class_ids)) {
$shipping_class_exists = true;
break;
}
}
if ($shipping_class_exists) {
foreach($shipping_services_to_hide as & $value) {
unset($available_shipping_methods[$value]);
}
}
return $available_shipping_methods;
}

Here is the updated code which will hide a shipping method if there are no items in the cart with a specific shipping class.
For details, please refer this article.
// Hides other shipping methods if items of specific Shipping Class is NOT in cart
add_filter('woocommerce_package_rates', 'xa_hide_shipping_method_when_shipping_class_product_is_in_cart', 10, 2);
function xa_hide_shipping_method_when_shipping_class_product_is_in_cart($available_shipping_methods, $package)
{
// Shipping class IDs that need the method removed
$shipping_class_ids = array(
31
);
$shipping_services_to_hide = array(
'wf_shipping_usps:D_PRIORITY_MAIL',
'wf_shipping_usps:D_EXPRESS_MAIL',
'wf_shipping_usps:flat_rate_box_priority'
);
$shipping_class_exists = false;
foreach(WC()->cart->cart_contents as $key => $values) {
if (in_array($values['data']->get_shipping_class_id() , $shipping_class_ids)) {
$shipping_class_exists = true;
break;
}
}
// Negation of shipping class exists.
if (!$shipping_class_exists) {
foreach($shipping_services_to_hide as & $value) {
unset($available_shipping_methods[$value]);
}
}
return $available_shipping_methods;
}

Related

Get scale unit at cart

I need the scale unit at my cart to show it at the frontend, but I do not get it.
I tried by a subscriber and to load the product, but I do not get the selected scale unit.
public function onLoadCart(OffcanvasCartPageLoadedEvent $event)
{
foreach ($event->getPage()->getCart()->getLineItems() as $item) {
$product = $this->productRepository->search(
new Criteria(
[
$item->getId()
]
),
$event->getContext()
)->first();
dd($product);
}
}
The term scale unit offset me a little at first. I assume you are looking for the ProductUnit. The ProductUnit is an association, and you need to add this to your criteria.
public function onLoadCart(OffcanvasCartPageLoadedEvent $event)
{
foreach ($event->getPage()->getCart()->getLineItems() as $item) {
$criteria = new Criteria(
[
$item->getId()
]
);
$criteria->addAssociation('unit');
$product = $this->productRepository->search(
$criteria,
$event->getContext()
)->first();
dd($product);
}
}

Polylang + ACF - Fields Group on front page is not displaying on translated pages

I've just installed Polylang (Free version) and I have field group that is set to be displayed on front-page.
In the admin, fields are displaying correctly on the main language's front page but not on the translated front-page.
I've searched to see what could go wrong and it's obviously because of ACF that is only checking if we are on the front page with get_option('page_on_front').
And polylang doesn't seems to filter the value to set the right front-page.
So I found this mu-plugin:
<?php
class ACF_Page_Type_Polylang {
// Whether we hooked page_on_front
private $filtered = false;
public function __construct() {
add_filter( 'acf/location/rule_match/page_type', array( $this, 'hook_page_on_front' ) );
}
public function hook_page_on_front( $match ) {
if ( ! $this->filtered ) {
add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) );
// Prevent second hooking
$this->filtered = true;
}
return $match;
}
public function translate_page_on_front( $value ) {
if ( function_exists( 'pll_get_post' ) ) {
$value = pll_get_post( $value );
}
return $value;
}
}
new ACF_Page_Type_Polylang();
but it does not resolve the issue and i don't know why, the code seems correct.
If I only take this part :
add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) );
and convert it to :
add_filter( 'option_page_on_front',function() { return '346' });
(346 is the translated front-page ID)
it filters properly the option page_on_front and my fields are displaying correctly.
Can you help me make the mu-plugin works ?
I've found a way to make it work but I don't know if it's the right way ... can you please tell me ?
<?php
class ACF_Page_Type_Polylang {
// Whether we hooked page_on_front
private $filtered = false;
public function __construct() {
add_filter( 'acf/location/rule_match/page_type', array( $this, 'hook_page_on_front' ) );
}
public function hook_page_on_front( $match ) {
// Abort if polylang not activated
if ( !function_exists( 'pll_get_post' ) ) {
return $match;
}
// Get the main language front page
$front_page = (int) get_option('page_on_front');
// Get the translated page of the curent language
$translated_page = pll_get_post($front_page);
// Check if it's the same as the current page and set match to true if so
if($translated_page === get_the_id()) {
$match = true;
}
return $match;
}
}
new ACF_Page_Type_Polylang();

How to pre-select a selct box in Ninja Forms from a query string

I am trying to pre select a value within a select field in my contact from on the contact page from another page by passing a query string ?request=call-back. I am using Ninja Forms and the values that I have in my select field are: email-us, call-back
I have tried the following:
add_filter( 'ninja_forms_render_default_value', 'my_ninja_forms_pre_populate', 10, 3 );
function my_ninja_forms_pre_populate( $default_value, $field_type, $field_settings ){
if( 'request' == $field_settings[ 'key' ] ){
$default_value = $_GET['request'];
}
return $default_value;
}
I would like the select field to have call-back already selected.
I didnt need to use the filter that I was attempting. I changed the key value under administration within the ninja form builder and I made sure that none of the values were pre selected.
This drove me mad... but finally I've got a solution:
// register custom get parameter (to use it with get_query_var() for safety reasons)
function add_get_val() {
global $wp;
$wp->add_query_var('request');
}
add_action('init', 'add_get_val');
add_filter('ninja_forms_localize_field_listselect', function ($field) {
if (get_query_var('request')) {
$request = get_query_var('request');
$optionExists = FALSE;
// check if field exists
foreach ($field['settings']['options'] as $option) {
if ($option['value'] === $request) {
$optionExists = TRUE;
break;
}
}
if ($optionExists) {
foreach ($field['settings']['options'] as $key => $option) {
// deselect all fields
$field['settings']['options'][$key]['selected'] = 0;
// select parameter
if ($option['value'] === $request) {
$field['settings']['options'][$key]['selected'] = 1;
}
}
}
}
return $field;
});

Get total price after ajax update in woocommerce

I am trying to take the price in the filter woocommerce_update_order_review_fragments, but failing to understand where it resides
add_filter('woocommerce_update_order_review_fragments', 'price_bottom_checkout');
function price_bottom_checkout($arr) {
$price = ? // how to get it over here?
$price_txt = '<span class="total-pay">'.$price.'</span>';
$arr['.total-pay'] = $price;
return $arr;
}
Managed to find out how. Needed to see the session cart which is updated on every cart refresh via ajax.
add_filter('woocommerce_update_order_review_fragments', 'price_bottom_checkout');
function price_bottom_checkout($arr) {
global $woocommerce;
$the_total = '';
foreach ($woocommerce->cart->cart_contents as $cart_item) {
$the_total = $cart_item['line_total'];
break;
}
$price_txt = '<span class="total-pay">'.wc_price($the_total).'</span>';
$arr['.total-pay'] = $price_txt;
return $arr;
}

How to Overriding the existing quantity of products already in cart?

I am using the latest version of wordpress and Woocommerce.
My Functionality is " Overriding the existing Quantity of Products already in cart". I already try this idea but its failure. See the Code and its errors.
add_action('woocommerce_add_to_cart_handler', 'update_product_in_cart', 11, 2);
function update_product_in_cart($p, $q) {
global $woocommerce;
$cartItem = $woocommerce->cart->cart_contents;
$currentProductId = $q->id;
$wCart = $woocommerce->cart->get_cart();
// If cart already exists, and product exists, than remove product, and add the new product to it.
if ($wCart)
{
$cart_item_keys = array_keys($wCart);
foreach($cart_item_keys as $key)
{
foreach($cartItem as $item)
{
$productItemId = $item['product_id'];
if ($productItemId == $currentProductId)
{
// If you want to empty the entire cart...
// $woocommerce->cart->empty_cart();
// If you want to remove just the product from the cart...
$woocommerce->cart->set_quantity($key, 0);
}
}
}
}
// This adds the product to the cart...
return $q;
}
Its Error is:
Catchable fatal error: Object of class WC_Product_Grouped could not be converted to string in plugins\woocommerce\includes\class-wc-form-handler.php on line 715
This code is the answer, Previously I added on comment boxes....
add_action('woocommerce_add_to_cart_handler', 'update_product_in_cart', 11, 2);function update_product_in_cart($p, $q) { global $woocommerce; $cartItem = $woocommerce->cart->cart_contents; $currentProductId = $q->id; $wCart = $woocommerce->cart->get_cart(); if ($wCart){ $cart_item_keys = array_keys($wCart); foreach($cart_item_keys as $key) {foreach($cartItem as $item) {$productItemId = $item['product_id']; if ($productItemId == $currentProductId) {$woocommerce->cart->set_quantity($key, 0); }}}}return $q; }

Resources