skip to Main Content

For an example, if someone selects any county that is not the same county where the sotre is located, to disable the Local Pickup from the chekout.

This is the cart-shipping.php:

<?php
/**
 * Shipping Methods Display
 *
 * In 2.1 we show methods per package. This allows for multiple methods per order if so desired.
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-shipping.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see https://docs.woocommerce.com/document/template-structure/
 * @package WooCommerceTemplates
 * @version 3.6.0
 */

defined( 'ABSPATH' ) || exit;

$formatted_destination    = isset( $formatted_destination ) ? $formatted_destination : WC()->countries->get_formatted_address( $package['destination'], ', ' );
$has_calculated_shipping  = ! empty( $has_calculated_shipping );
$show_shipping_calculator = ! empty( $show_shipping_calculator );
$calculator_text          = '';
?>
<tr class="woocommerce-shipping-totals shipping">
    <th><?php echo wp_kses_post( $package_name ); ?></th>
    <td data-title="<?php echo esc_attr( $package_name ); ?>">
        <?php if ( $available_methods ) : ?>
            <ul id="shipping_method" class="woocommerce-shipping-methods">
                <?php foreach ( $available_methods as $method ) : ?>
                    <li>
                        <?php
                        if ( 1 < count( $available_methods ) ) {
                            printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) ); // WPCS: XSS ok.
                        } else {
                            printf( '<input type="hidden" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ) ); // WPCS: XSS ok.
                        }
                        printf( '<label for="shipping_method_%1$s_%2$s">%3$s</label>', $index, esc_attr( sanitize_title( $method->id ) ), wc_cart_totals_shipping_method_label( $method ) ); // WPCS: XSS ok.
                        do_action( 'woocommerce_after_shipping_rate', $method, $index );
                        ?>
                    </li>
                <?php endforeach; ?>
            </ul>
            <?php if ( is_cart() ) : ?>
                <p class="woocommerce-shipping-destination">
                    <?php
                    if ( $formatted_destination ) {
                        // Translators: $s shipping destination.
                        printf( esc_html__( 'Shipping to %s.', 'woocommerce' ) . ' ', '<strong>' . esc_html( $formatted_destination ) . '</strong>' );
                        $calculator_text = esc_html__( 'Change address', 'woocommerce' );
                    } else {
                        echo wp_kses_post( apply_filters( 'woocommerce_shipping_estimate_html', __( 'Shipping options will be updated during checkout.', 'woocommerce' ) ) );
                    }
                    ?>
                </p>
            <?php endif; ?>
            <?php
        elseif ( ! $has_calculated_shipping || ! $formatted_destination ) :
            if ( is_cart() && 'no' === get_option( 'woocommerce_enable_shipping_calc' ) ) {
                echo wp_kses_post( apply_filters( 'woocommerce_shipping_not_enabled_on_cart_html', __( 'Shipping costs are calculated during checkout.', 'woocommerce' ) ) );
            } else {
                echo wp_kses_post( apply_filters( 'woocommerce_shipping_may_be_available_html', __( 'Enter your address to view shipping options.', 'woocommerce' ) ) );
            }
        elseif ( ! is_cart() ) :
            echo wp_kses_post( apply_filters( 'woocommerce_no_shipping_available_html', __( 'There are no shipping options available. Please ensure that your address has been entered correctly, or contact us if you need any help.', 'woocommerce' ) ) );
        else :
            // Translators: $s shipping destination.
            echo wp_kses_post( apply_filters( 'woocommerce_cart_no_shipping_available_html', sprintf( esc_html__( 'No shipping options were found for %s.', 'woocommerce' ) . ' ', '<strong>' . esc_html( $formatted_destination ) . '</strong>' ) ) );
            $calculator_text = esc_html__( 'Enter a different address', 'woocommerce' );
        endif;
        ?>

        <?php if ( $show_package_details ) : ?>
            <?php echo '<p class="woocommerce-shipping-contents"><small>' . esc_html( $package_details ) . '</small></p>'; ?>
        <?php endif; ?>

        <?php if ( $show_shipping_calculator ) : ?>
            <?php woocommerce_shipping_calculator( $calculator_text ); ?>
        <?php endif; ?>
    </td>
</tr>

And I use another module that loads in predefined counties so the customers can’t input any county or fake counties. Here is the module’s code:

/**
 * Plugin Name: WC City Select
 * Plugin URI:  https://wordpress.org/plugins/wc-city-select/
 * Description: City Select for WooCommerce. Show a dropdown select as the cities input.
 * Version:     1.0.6
 * Author:      8manos
 * Author URI:  http://8manos.com
 * License:     GPLv2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 *
 * WC requires at least: 2.2
 * WC tested up to:      5.5
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

// Check if WooCommerce is active
if ( ( is_multisite() && array_key_exists( 'woocommerce/woocommerce.php', get_site_option( 'active_sitewide_plugins', array() ) ) ) ||
    in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {

    class WC_City_Select {

        // plugin version
        const VERSION = '1.0.1';

        private $plugin_path;
        private $plugin_url;

        private $cities;
        private $dropdown_cities;

        public function __construct() {
            add_filter( 'woocommerce_billing_fields', array( $this, 'billing_fields' ), 10, 2 );
            add_filter( 'woocommerce_shipping_fields', array( $this, 'shipping_fields' ), 10, 2 );
            add_filter( 'woocommerce_form_field_city', array( $this, 'form_field_city' ), 10, 4 );

            //js scripts
            add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) );
        }

        public function billing_fields( $fields, $country ) {
            $fields['billing_city']['type'] = 'city';

            return $fields;
        }

        public function shipping_fields( $fields, $country ) {
            $fields['shipping_city']['type'] = 'city';

            return $fields;
        }

        public function get_cities( $cc = null ) {
            if ( empty( $this->cities ) ) {
                $this->load_country_cities();
            }

            if ( ! is_null( $cc ) ) {
                return isset( $this->cities[ $cc ] ) ? $this->cities[ $cc ] : false;
            } else {
                return $this->cities;
            }
        }

        public function load_country_cities() {
            global $cities;

            // Load only the city files the shop owner wants/needs.
            $allowed = array_merge( WC()->countries->get_allowed_countries(), WC()->countries->get_shipping_countries() );

            if ( $allowed ) {
                foreach ( $allowed as $code => $country ) {
                    if ( ! isset( $cities[ $code ] ) && file_exists( $this->get_plugin_path() . '/cities/' . $code . '.php' ) ) {
                        include( $this->get_plugin_path() . '/cities/' . $code . '.php' );
                    }
                }
            }

            $this->cities = apply_filters( 'wc_city_select_cities', $cities );
        }

        private function add_to_dropdown($item) {
            $this->dropdown_cities[] = $item;
        }

        public function form_field_city( $field, $key, $args, $value ) {

            // Do we need a clear div?
            if ( ( ! empty( $args['clear'] ) ) ) {
                $after = '<div class="clear"></div>';
            } else {
                $after = '';
            }

            // Required markup
            if ( $args['required'] ) {
                $args['class'][] = 'validate-required';
                $required = ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce'  ) . '">*</abbr>';
            } else {
                $required = '';
            }

            // Custom attribute handling
            $custom_attributes = array();

            if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) {
                foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) {
                    $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
                }
            }

            // Validate classes
            if ( ! empty( $args['validate'] ) ) {
                foreach( $args['validate'] as $validate ) {
                    $args['class'][] = 'validate-' . $validate;
                }
            }

            // field p and label
            $field  = '<p class="form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $args['id'] ) . '_field">';
            if ( $args['label'] ) {
                $field .= '<label for="' . esc_attr( $args['id'] ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) .'">' . $args['label']. $required . '</label>';
            }

            // Get Country
            $country_key = $key == 'billing_city' ? 'billing_country' : 'shipping_country';
            $current_cc  = WC()->checkout->get_value( $country_key );

            $state_key = $key == 'billing_city' ? 'billing_state' : 'shipping_state';
            $current_sc  = WC()->checkout->get_value( $state_key );

            // Get country cities
            $cities = $this->get_cities( $current_cc );

            if ( is_array( $cities ) ) {

                $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="city_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '">
                    <option value="">'. __( 'Select an option&hellip;', 'woocommerce' ) .'</option>';

                if ( $current_sc && $cities[ $current_sc ] ) {
                    $this->dropdown_cities = $cities[ $current_sc ];
                } else {
                    $this->dropdown_cities = [];
                    array_walk_recursive( $cities, array( $this, 'add_to_dropdown' ) );
                    sort( $this->dropdown_cities );
                }

                foreach ( $this->dropdown_cities as $city_name ) {
                    $field .= '<option value="' . esc_attr( $city_name ) . '" '.selected( $value, $city_name, false ) . '>' . $city_name .'</option>';
                }

                $field .= '</select>';

            } else {

                $field .= '<input type="text" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) .'" value="' . esc_attr( $value ) . '"  placeholder="' . esc_attr( $args['placeholder'] ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
            }

            // field description and close wrapper
            if ( $args['description'] ) {
                $field .= '<span class="description">' . esc_attr( $args['description'] ) . '</span>';
            }

            $field .= '</p>' . $after;

            return $field;
        }

        public function load_scripts() {
            if ( is_cart() || is_checkout() || is_wc_endpoint_url( 'edit-address' ) ) {

                $city_select_path = $this->get_plugin_url() . 'assets/js/city-select.js';
                wp_enqueue_script( 'wc-city-select', $city_select_path, array( 'jquery', 'woocommerce' ), self::VERSION, true );

                $cities = json_encode( $this->get_cities() );
                wp_localize_script( 'wc-city-select', 'wc_city_select_params', array(
                    'cities' => $cities,
                    'i18n_select_city_text' => esc_attr__( 'Select an option&hellip;', 'woocommerce' )
                ) );
            }
        }

        public function get_plugin_path() {

            if ( $this->plugin_path ) {
                return $this->plugin_path;
            }

            return $this->plugin_path = plugin_dir_path( __FILE__ );
        }

        public function get_plugin_url() {

            if ( $this->plugin_url ) {
                return $this->plugin_url;
            }

            return $this->plugin_url = plugin_dir_url( __FILE__ );
        }
    }

    $GLOBALS['wc_city_select'] = new WC_City_Select();
}

and the cities and counties:

<?php
/**
 * Romanian cities
 */
global $cities;

$cities['RO'] = array(
    'AB' => array(
        'ALBA IULIA',
        'Sebes',
    ) ,
    'AG' => array(
        'PITESTI',
        'CURTEA DE ARGES',
    ) ,
    'CJ' => array(
        'CLUJ-NAPOCA',
        'Apahida',
        'FLORESTI',
    ) ,
);

I want to disable Local pickup if the select county isn’t the cities from CJ (the last conty).

2

Answers


  1. Chosen as BEST ANSWER

    Modified a but your current code.

    function hide_local_pickup_based_on_county( $rates, $package ) {
        $shipping_country = WC()->customer->get_shipping_country();
        $shipping_state = WC()->customer->get_shipping_state();
    
        // Check if the shipping country is Romania and the state is 'CJ' (Cluj-Napoca region)
        if ( $shipping_country === 'RO' && $shipping_state !== 'CJ' ) {
            // Loop through the rates and remove "local_pickup" if present
            foreach ( $rates as $rate_key => $rate ) {
                if ( $rate->method_id === 'local_pickup' ) {
                    unset( $rates[ $rate_key ] );
                }
            }
        }
    
        return $rates;
    }
    add_filter( 'woocommerce_package_rates', 'hide_local_pickup_based_on_county', 10, 2 );
    

  2. Try the following (untested):

    add_filter( 'woocommerce_package_rates', 'local_pickup_for_defined_cities', 10, 2 );
    function local_pickup_for_defined_cities( $rates, $package ) {
        global $cities;
    
        $shipping_city = $package['destination']['city'];
    
        if( isset($cities['RO']['CJ']) && ! in_array($shipping_city, $cities['RO']['CJ']) ) {
            foreach( $rates as $rate_key => $rate ) {
                if ( $rate->method_id === 'local_pickup' ) {
                    unset($rates[$rate_key]);
                }
            }
        }
        return $rates;
    }
    

    It could work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search