1

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

This is the cart-shipping.php:

<?php

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:


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 county).

SavPhill
  • 636
  • 6
  • 24
GFT
  • 63
  • 7

2 Answers2

3

Updated

Try the following (untested):

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

It should work.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • I tried it, but no matter what I choose in shipping location, the `Local Pickup` will still be there. Mention that the code you provided I added it in functions.php in theme. – GFT Aug 22 '23 at 14:08
  • Forgot to mention, that `cart-shipping.php` is not in the child theme. – GFT Aug 22 '23 at 14:16
  • I have updated my code with something a bit different based on the shipping package destination country and state instead of the `WC()->customer` data. It should also work the same way, than your answer code. – LoicTheAztec Aug 23 '23 at 16:33
0

Modified a bit 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 );
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
GFT
  • 63
  • 7