Postcode wildcards
-
This plugin is almost perfect but I would really like to be able to enter a list of postcode prefixes with wildcards instead of every single postcode. I need to restrict delivery to England & Wales only and disallow all Scottish and Irish postcodes. If there was wildcard support I could achieve this with a list of about 50 csvs rather than having to enter tens of thousands of postcodes.
i.e. NE*, NW*, etc….
Would you be able to update this plugin to allow wildcards?
https://www.ads-software.com/plugins/postcode-based-order-restriction/
-
No need to worry. I have edited the plugin myself to make it work. It now just compares the first two characters of the postcode to the allowed list making it easy for me to restrict delivery to England and Wales.
I have included the amended plugin code below for those that may need it and a list of English and Welsh postcodes are below that in case anyone else needs it.
<?php /** * Plugin Name: Postcode Based Order Restriction * Description: This WooCommerce plugin <strong>enables order restriction based on specific zip/post codes</strong>. You have to enter list of postcode in given area for which the order restriction works. When activated you will restrict selected gateways or billing address, shipping address and both address at checkout step based on specific zip/post codes. * Author: PrecursorWeb * Author URI: https://precursorweb.com/ * Plugin URI: https://precursorweb.com/ * Version: 1.1 * Contributors: PrecursorWeb, Sheldon Gold * Requires at least: 4.0 * Tested up to: 4.1.1 * * You should have received a copy of the GNU General Public License * License: GPL version 2 or later - <https://www.gnu.org/licenses/>. */ add_action('admin_enqueue_scripts', 'toggle_gateways_field'); function toggle_gateways_field() { wp_enqueue_script( 'woocommerce_admin_head', plugins_url( 'js/toggle-gateways.js', __FILE__ ), array('jquery') ); } function add_order_number_start_setting( $settings ) { global $woocommerce; $updated_settings = array(); foreach ( $settings as $section ) { /** * Add section at the bottom of the general options */ if ( isset( $section['id'] ) && 'general_options' == $section['id'] && isset( $section['type'] ) && 'sectionend' == $section['type'] ) { $updated_settings[] = array( 'type' => 'sectionend', 'id' => 'general_options'); // end the general options section /** * Start new section "Postcode Based Order Restriction". */ $updated_settings[] = array( 'title' => __( 'Postcode Based Order Restriction', 'woocommerce' ), 'type' => 'title', 'desc' => '', 'id' => 'postcode_order_restriction' ); /** * Enable postcode based order restriction */ $updated_settings[] = array( 'title' => __( 'Enable/Disable', 'woocommerce' ), 'desc' => __( 'Enable Postcode Based Order Restriction', 'woocommerce' ), 'id' => 'woocommerce_postcode_order_restriction_enabled', 'type' => 'checkbox', 'default' => 'No', ); /** * Restriction mode either allow or restrict */ $updated_settings[] = array( 'title' => __( 'Restriction Mode', 'woocommerce' ), 'desc' => __( 'Base on this option below zip codes are allowed/restricted at checkout. <br/> Allow - Allow specific postcode for buy.<br/> Restric - Restrict specific postcode for buy.', 'woocommerce' ), 'id' => 'woocommerce_allow_restrict', 'type' => 'select', 'class' => 'chosen_select', 'css' => 'min-width: 350px;', 'desc_tip' => true, 'default' => 'allow', 'options' => array( 'allow' => __( 'Allow', 'woocommerce' ), 'restrict' => __( 'Restrict', 'woocommerce' ) ) ); /** * Restriction mode for billing or shipping */ $updated_settings[] = array( 'title' => __( 'Default Order Restriction', 'woocommerce' ), 'desc' => __( 'Enable restriction base on postcodes at checkout.<br/> Billing - Order restriction apply for billing detail.<br/> Shipping - Order restriction apply for shipping detail.<br/> Both - Order restriction apply for billing & shipping details.', 'woocommerce' ), 'id' => 'woocommerce_restrict_option', 'type' => 'select', 'class' => 'chosen_select', 'css' => 'min-width: 350px;', 'desc_tip' => true, 'default' => 'billing', 'options' => array( 'billing' => __( 'Billing', 'woocommerce' ), 'shipping' => __( 'Shipping', 'woocommerce' ), 'both' => __( 'Both', 'woocommerce' ) ) ); /** * Zip/Post codes */ $updated_settings[] = array( 'title' => __( 'Zip/Post Codes', 'woocommerce' ), 'id' => 'woocommerce_postcode_order', 'css' => 'width:100%; height: 65px;', 'type' => 'textarea', 'desc' => 'Please enter valid postcode with comma like 12345, 56789 etc', 'desc_tip'=> true ); /** * Restrict through either disable place order or gateways */ $updated_settings[] = array( 'title' => __( 'Restrict Through', 'woocommerce' ), 'desc' => __( 'Disable Place Order - Place order button will disable at checkout base on postcode restriction.<br/> Gateway - Selected Gataways will disable at checkout base on postcode restriction.', 'woocommerce' ), 'id' => 'woocommerce_restrict_gateways_placeorder', 'type' => 'select', 'class' => 'chosen_select', 'css' => 'min-width: 350px;', 'desc_tip' => true, 'default' => 'gateways', 'options' => array( 'placeorder' => __( 'Disable Place Order', 'woocommerce' ), 'gateways' => __( 'Gateways', 'woocommerce' ) ) ); /** * Error message for disable place order */ $updated_settings[] = array( 'title' => __( 'Error Message', 'woocommerce' ), 'id' => 'woocommerce_error_placeorder', 'css' => 'width:94%;', 'type' => 'text', 'default' => 'Sorry, Currently we are not providing service for provided zipcode.', 'desc' => 'Optional', 'desc_tip'=> false ); /** * Multiselect available gateways */ $_available_gateways = array(); foreach($woocommerce->payment_gateways->payment_gateways as $key => $gateways): if ($gateways->is_available()): $_available_gateways[$gateways->id] = __($gateways->title,'woocommerce'); endif; endforeach; $updated_settings[] = array( 'title' => __('Restrict Available Gateways','woocommerce'), 'desc' => 'This option lets you limit available gateways for specific postcode in checkout.', 'id' => 'woocommerce_specific_allowed_gateways', 'css' => 'min-width: 350px;', 'default' => '', 'desc_tip'=> true, 'type' => 'multiselect', 'options' => $_available_gateways ); /** * Error message for gateways */ $updated_settings[] = array( 'title' => __( 'Error Message', 'woocommerce' ), 'id' => 'woocommerce_error_gateways', 'css' => 'width:94%;', 'type' => 'text', 'default' => 'Sorry, Currently %s payments methods are disable for provided zipcode.', 'desc' => 'Optional', 'desc_tip'=> false ); } $updated_settings[] = $section; } return $updated_settings; } add_filter( 'woocommerce_general_settings', 'add_order_number_start_setting' ); function postcode_based_payment_gateways( $methods ) { if(defined('WOOCOMMERCE_CHECKOUT') == 1){ global $woocommerce; $postcode_order_restriction_enabled = get_option( 'woocommerce_postcode_order_restriction_enabled' ); if($postcode_order_restriction_enabled == 'yes'){ // is enabled if($_available_gateways = (array)$woocommerce->payment_gateways->payment_gateways){ $woocommerce_restrict_by = get_option( 'woocommerce_restrict_gateways_placeorder' ); if($woocommerce_restrict_by == 'gateways'){ $all_postcode = ''; $woocommerce_postcode_order = get_option( 'woocommerce_postcode_order' ); // get list of all zip/postcode $all_postcode = array_map('trim', explode(",", $woocommerce_postcode_order)); if(count($all_postcode)){ $woocommerce_specific_allowed_gateways = ''; $woocommerce_error_gateways = ''; $woocommerce_allow_restrict = get_option( 'woocommerce_allow_restrict' ); // get restriction mode $woocommerce_restrict_option = get_option( 'woocommerce_restrict_option' ); // get restriction option $woocommerce_specific_allowed_gateways = get_option( 'woocommerce_specific_allowed_gateways' ); // get available selected gateways $woocommerce_error_gateways = get_option( 'woocommerce_error_gateways' ); // get error message if(!$woocommerce_error_gateways && $woocommerce_error_gateways == ''){ $woocommerce_error_gateways = 'Sorry, Currently %s payments methods are disable for provided zipcode.'; } $woocommerce_customer_postcode = null; if (preg_match("(^[A-Z0-9]{2})", trim(strtoupper($woocommerce->customer->postcode)), $match)) { $woocommerce_customer_postcode = $match[0]; } $woocommerce_shipping_postcode = null; if (preg_match("(^[A-Z0-9]{2})", trim(strtoupper($woocommerce->customer->shipping_postcode)), $match)) { $woocommerce_shipping_postcode = $match[0]; } if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'billing'){ $sel_gateways_title = array(); if (!in_array(trim($woocommerce_customer_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } else if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'shipping'){ $sel_gateways_title = array(); if (!in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } else if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'both'){ $sel_gateways_title = array(); if (!in_array(trim($woocommerce_customer_postcode), $all_postcode) || !in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'billing'){ $sel_gateways_title = array(); if (in_array(trim($woocommerce_customer_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'shipping'){ $sel_gateways_title = array(); if (in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'both'){ $sel_gateways_title = array(); if (in_array(trim($woocommerce_customer_postcode), $all_postcode) || in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { foreach($_available_gateways as $gateways): if (in_array($gateways->id, $woocommerce_specific_allowed_gateways)) { unset( $methods[array_search(get_class($gateways),$methods)] ); array_push($sel_gateways_title,$gateways->title); } endforeach; wc_add_notice( sprintf( __( $woocommerce_error_gateways, 'woocommerce' ), implode(" ,",$sel_gateways_title) ), 'error' ); } } } } } } } return $methods; } add_filter( 'woocommerce_payment_gateways', 'postcode_based_payment_gateways' ); function postcode_based_order_button_html() { global $woocommerce; $order_button_text = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ); $pl_btn = '<input type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="'.esc_attr( $order_button_text ).'" data-value="'.esc_attr( $order_button_text ).'" />'; $postcode_order_restriction_enabled = get_option( 'woocommerce_postcode_order_restriction_enabled' ); if($postcode_order_restriction_enabled == 'yes'){ // is enabled $woocommerce_restrict_by = get_option( 'woocommerce_restrict_gateways_placeorder' ); if($woocommerce_restrict_by == 'placeorder'){ $all_postcode = ''; $woocommerce_postcode_order = get_option( 'woocommerce_postcode_order' ); // get list of all zip/postcode $all_postcode = array_map('trim', explode(",", $woocommerce_postcode_order)); if(count($all_postcode)){ $notallow_pl_btn = ''; $woocommerce_allow_restrict = get_option( 'woocommerce_allow_restrict' ); // get restriction mode $woocommerce_restrict_option = get_option( 'woocommerce_restrict_option' ); // get restriction option $woocommerce_error_placeorder = get_option( 'woocommerce_error_placeorder' ); // error message if(!$woocommerce_error_placeorder && $woocommerce_error_placeorder == ''){ $notallow_pl_btn = '<ul class="woocommerce-error"><li>'. __('Sorry, Currently we are not providing service for provided zipcode.', 'woocommerce') .'</li></ul>'; } else { $notallow_pl_btn = '<ul class="woocommerce-error"><li>'. __($woocommerce_error_placeorder, 'woocommerce').'</li></ul>'; } $woocommerce_customer_postcode = null; if (preg_match("(^[A-Z0-9]{2})", trim(strtoupper($woocommerce->customer->postcode)), $match)) { $woocommerce_customer_postcode = $match[0]; } $woocommerce_shipping_postcode = null; if (preg_match("(^[A-Z0-9]{2})", trim(strtoupper($woocommerce->customer->shipping_postcode)), $match)) { $woocommerce_shipping_postcode = $match[0]; } if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'billing'){ if (!in_array(trim($woocommerce_customer_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'shipping'){ if (!in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else if($woocommerce_allow_restrict == 'allow' && $woocommerce_restrict_option == 'both'){ if (!in_array(trim($woocommerce_customer_postcode), $all_postcode) || !in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'billing'){ if (in_array(trim($woocommerce_customer_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'shipping'){ if (in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else if($woocommerce_allow_restrict == 'restrict' && $woocommerce_restrict_option == 'both'){ if (in_array(trim($woocommerce_customer_postcode), $all_postcode) || in_array(trim($woocommerce_shipping_postcode), $all_postcode)) { return $notallow_pl_btn; } else { return $pl_btn; } } else { return $pl_btn; } } } else { return $pl_btn; } } else { return $pl_btn; } } add_filter( 'woocommerce_order_button_html', 'postcode_based_order_button_html' ); ?>
\\ England and Wales Postcode Prefixes (first 2 characters)
AL, CB, CM, CO, EN, IG, IP, LU, MK, NR, PE, RM, SG, SS, WD, B1, B2, B3, B4, B5, B6, B7, B8, B9, CV, DE, DY, LE, NG, NN, ST, WS, WV, BD, DH, DL, DN, HD, HG, HU, HX, LN, LS, NE, S1, S2, S3, S4, S5, S6, S7, S8, S9, SR, TS, WF, YO, BB, BL, CA, CW, FY, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, M1, M2, M3, M4, M5, M6, M7, M8, M9, OL, PR, SK, SY, TF, WA, WN, CH, E1, E2, E3, E4, E5, E6, E7, E8, E9, EC, N1, N2, N3, N4, N5, N6, N7, N8, N9, NW, SE, SW, W1, W2, W3, W4, W5, W6, W7, W8, W9, WC, GU, HA, HP, OX, PO, RG, SL, SN, SO, SP, UB, BN, BR, CR, CT, DA, KT, ME, RH, SM, TN, TW, BA, BH, BS, DT, EX, GL, HR, PL, TA, TQ, TR, WR, CF, LD, LL, NP, SA, BT
I copied this to mine, but this first 2 character feature just doesn’t seem to work.
not sure why, is it possible to copy it again.
its stupid how this plugin, you next the exact postcode, which mean of every house in the area lol I just want to cover the whole area by just it recognising the first two characters.
Hi,
That’s the exact code that I had on the site and I haven’t heard of any issues from the client. All I’d really added was a way to truncate the user’s postcode to the first two letters and convert them to uppercase before comparing them to the permitted array of postcodes. It could be that a later version of woocommerce prevents this from working.
Best of luck with it, you may wish to keep searching for another plugin as it looks like this developer has abandoned the plugin entirely.
thanks for the reply.
that’s a shame as this plugin had potential, cant really find another similar one.
ill see if I can get it to work, but at the moment no matter what postcode i type, its always restricted.
thanks again
Hi guys
Try this code as a new plugin…
Note: No warranties implied, use at own risk, yadda yadda yadda
<?php /* Plugin Name: WooCommerce Local Shop Description: Make WooCommerce only serve customers in/not-in certain Postcodes/ZIP codes Version: 1.0 Author: Phil Meadows Author URI: https://www.philmeadows.com License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Exit if accessed directly if( ! defined( 'ABSPATH' ) ) exit; // Check class not defined if( ! class_exists( 'WoocommerceLocalShop' ) ) { // Define our class class WoocommerceLocalShop { private static $instance = NULL; private $className; private $pluginName; private $textDomain; private $locale; private $codeType; private $enabled; private $addressType; private $mode; private $postcodes; private $message; /** * Create or return instance of this class */ public static function instance() { $className = get_class(); if( ! isset( self::$instance ) && ! ( self::$instance instanceof $className ) && ( self::$instance === NULL ) ) { self::$instance = new $className; } return self::$instance; } // END instance() /** * Our constructor */ public function __construct() { $this->className = get_class(); $this->pluginName = 'WooCommerce Local Shop'; $this->textDomain = 'pkmwcls'; $this->locale = get_option( 'woocommerce_default_country' ); $this->codeType = $this->locale === 'US' ? 'Zip Code' : 'Postcode'; $this->enabled = get_option($this->textDomain.'_enabled'); $this->addressType = get_option($this->textDomain.'_restrict_address'); $this->mode = get_option($this->textDomain.'_restrict_mode'); $this->postcodes = get_option($this->textDomain.'_postcodes'); $this->message = get_option($this->textDomain.'_message'); if( ! $this->checkRequirements() ) return; add_filter( 'woocommerce_general_settings', array( &$this, 'addSettings' ) ); if( $this->enabled === 'yes' ) add_filter( 'woocommerce_order_button_html', array( $this, 'run' ) ); } // END __construct() /** * Check dependencies */ public function checkRequirements() { require_once(ABSPATH.'/wp-admin/includes/plugin.php'); if( !is_plugin_active( 'woocommerce/woocommerce.php' ) ) { add_action( 'admin_notices', array( &$this, 'requirementsNotice' ) ); deactivate_plugins( plugin_basename( __FILE__ ) ); return FALSE; } return TRUE; } // END checkRequirements() /** * Display requirement message */ public function requirementsNotice() { echo '<div id="message" class="error"><p><strong>'; echo __( 'Sorry, ' . $this->pluginName . ' requires WooCommerce to be installed and active. Please resolve this', $this->textDomain ); echo '</strong></p></div>'; } // END requirementsNotice() /** * Add our settings to the general options page */ public function addSettings($settings) { $newSettings = array(); foreach( $settings as $k => $setting ) { // Add our new section at the bottom of the general options if( $setting['id'] == 'general_options' && $setting['type'] == 'sectionend' ) { // end the general options section $newSettings[] = array( 'type' => 'sectionend', 'id' => 'general_options'); // Start new section "Postcode / ZIP Code Order Restriction" $newSettings[] = array( 'title' => __( $this->pluginName.': '. $this->codeType.' Order Restriction', 'woocommerce' ), 'type' => 'title', 'id' => $this->textDomain.'_postcode_restriction', ); // Enable Postcode / ZIP Code Order Restriction $newSettings[] = array( 'title' => __( 'Enable / Disable', 'woocommerce' ), 'desc' => __( 'Enable '.$this->codeType.' Order Restriction', 'woocommerce' ), 'id' => $this->textDomain.'_enabled', 'type' => 'checkbox', 'default' => 'No', ); // Restriction mode either allow or disallow $newSettings[] = array( 'title' => __( 'Restriction Mode', 'woocommerce' ), 'desc' => __( 'Do you want to allow or disallow certain '.$this->codeType.'s?', 'woocommerce' ), 'id' => $this->textDomain.'_restrict_mode', 'type' => 'select', 'class' => 'chosen_select', 'default' => 'allow', 'options' => array( 'allow' => __( 'Allow', 'woocommerce' ), 'disallow' => __( 'Disallow', 'woocommerce' ), ) ); // Which address(es) are we applying this to? $newSettings[] = array( 'title' => __( 'Base Restriction Upon', 'woocommerce' ), 'desc' => __( 'Which customer address do you wish to apply the restriction on?', 'woocommerce' ), 'id' => $this->textDomain.'_restrict_address', 'type' => 'select', 'class' => 'chosen_select', 'default' => 'shipping', 'options' => array( 'shipping' => __( 'Shipping Address', 'woocommerce' ), 'billing' => __( 'Billing Address', 'woocommerce' ), 'both' => __( 'Either Address', 'woocommerce' ), ) ); // Postcodes / ZIP Codes $newSettings[] = array( 'title' => __( $this->codeType.'s', 'woocommerce' ), 'id' => $this->textDomain.'_postcodes', 'type' => 'text', 'class' => 'regular-input', 'desc' => __( '<br>Separate codes with a comma. Accepts wildcards, e.g. <code>P*</code> will match a postcode of PE30 and PO1.<br>Also accepts a pattern, e.g. <code>NG1___</code> would match NG1 1AA but not NG10 1AA', 'woocommerce' ), 'placeholder' => 'e.g. WD23*,90210', ); // Message for customers who get jilted $newSettings[] = array( 'title' => __( 'Message to Customer', 'woocommerce' ), 'id' => $this->textDomain.'_message', 'css' => 'width:94%;', 'type' => 'text', 'default' => __('Sorry, we are not accepting orders for that'.($this->addressType !== 'both' ? ' '.$this->addressType : '').' address '.$this->codeType.'.', 'woocommerce' ), ); // end our settings section $newSettings[] = array( 'type' => 'sectionend', 'id' => $this->textDomain.'_postcode_restriction'); } else { $newSettings[] = $setting; } } return $newSettings; } // END addSettings() /** * Bust the postcodes/ZIP codes into an array */ private function getPostcodes() { $codes = array(); if ( $this->postcodes !== '' ) { foreach( explode( ',', $this->postcodes ) as $code ) { $codes[] = strtoupper( trim( $code ) ); } } return $codes; } // END getPostcodes() /** * Sanitise a postcode/ZIP code */ private function cleanPostcode( $code ) { return str_replace( '-', '', sanitize_title( $code ) ) . ( strstr( $code, '*' ) ? '*' : '' ); } // END cleanPostcode() /** * is a postcode/ZIP code valid? */ private function isValidPostcode( $postcode ) { $codes = $this->getPostcodes(); $postcode = $this->cleanPostcode( $postcode ); $formattedPostcode = wc_format_postcode( $postcode, $this->locale ); if ( in_array( $postcode, $codes ) || in_array( $formattedPostcode, $codes ) ) { return TRUE; } // Pattern matching foreach ( $codes as $c ) { $pattern = '/^' . str_replace( '_', '[0-9a-zA-Z]', preg_quote( $c ) ) . '$/i'; if ( preg_match( $pattern, $postcode ) ) { return TRUE; } } // Wildcard search $wildcardPostcode = $formattedPostcode . '*'; $postcodeLength = strlen( $formattedPostcode ); for ( $i = 0; $i < $postcodeLength; $i++ ) { if ( in_array( $wildcardPostcode, $codes ) ) { return TRUE; } $wildcardPostcode = substr( $wildcardPostcode, 0, -2 ) . '*'; } return FALSE; } // END isValidPostcode() /** * edit the Place Order button */ public function disablePaymentButton() { $output = ''; if( $this->message == '' ) { $output = '<ul class="woocommerce-error"><li>'. __('Sorry, we are not accepting orders for that'.($this->addressType !== 'both' ? ' '.$this->addressType : '').' address '.$this->codeType.'.', 'woocommerce' ) .'</li></ul>'; } else { $output = '<ul class="woocommerce-error"><li>'. __($this->message, 'woocommerce' ) .'</li></ul>'; } return $output; } // END disablePaymentButton() /** * is the transaction allowed? */ private function isOrderAllowed() { global $woocommerce; $shippingPostcode = $woocommerce->customer->shipping_postcode; $billingPostcode = $woocommerce->customer->postcode; if ( $this->addressType !== '' && $this->mode !== '' && $this->postcodes !== '' && $billingPostcode !== '' && $shippingPostcode !== '' ) { switch ( $this->addressType ) { case 'shipping': $outcome = $this->isValidPostcode( $shippingPostcode ); if ( $outcome === TRUE && $this->mode === 'allow' ) return TRUE; if ( $outcome === TRUE && $this->mode === 'disallow' ) return FALSE; if ( $outcome === FALSE && $this->mode === 'allow' ) return FALSE; if ( $outcome === FALSE && $this->mode === 'disallow' ) return TRUE; break; case 'billing': $outcome = $this->isValidPostcode( $billingPostcode ); if ( $outcome === TRUE && $this->mode === 'allow ') return TRUE; if ( $outcome === TRUE && $this->mode === 'disallow' ) return FALSE; if ( $outcome === FALSE && $this->mode === 'allow ') return FALSE; if ( $outcome === FALSE && $this->mode === 'disallow' ) return TRUE; break; case 'both': $outcomeA = $this->isValidPostcode( $shippingPostcode ); $outcomeB = $this->isValidPostcode( $billingPostcode ); if ( ( $outcomeA === TRUE || $outcomeB === TRUE ) && $this->mode === 'allow' ) return TRUE; if ( ( $outcomeA === TRUE || $outcomeB === TRUE ) && $this->mode === 'disallow' ) return FALSE; if ( ( $outcomeA === FALSE || $outcomeB === FALSE ) && $this->mode === 'allow' ) return FALSE; if ( ( $outcomeA === FALSE || $outcomeB === FALSE ) && $this->mode === 'disallow' ) return TRUE; break; } // END switch } // END if vars set } // END isOrderAllowed() public function run() { if ( ! $this->isOrderAllowed() ) { return $this->disablePaymentButton(); } else { $btnText = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ); $btn = '<input type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="'.esc_attr( $btnText ).'" data-value="'.esc_attr( $btnText ).'">'; return $btn; } } } // END class WoocommerceLocalShop // fire her up! WoocommerceLocalShop::instance(); } // END if no class
hmm, this could be good! just one slight problem, iv never made a plugin before looks like i best get researching!
hope i get it to work, is there any tutorials on-line you know off to show what i do with this script?
thanks phil, i think one i get it sorted it will be so helpful.
Download: pkm-wc-local-shop.zip – save to your Desktop / wherever
Go to Plugins > Add New > Upload Plugin
Phil, i managed to figure it out and just set it up, works perfect, just what i needed! cant thank you enough.
:))))))
You’re welcome
I may even put it in the WP Plugin repo, if I get time / can be bothered!
Phil ??
Hey guys,
Glad someone with a good bit of php knowledge swooped in and saved the day. I muddled through editing the one I’ve got for a couple of days until it worked but I don’t completely understand why it didn’t work for you. Really good to hear that you got it working with the code Phil provided.
I’ve just tested the one I’ve got implemented for the client at https://www.gumberryworktops.co.uk and it still seems to be working. I’m very confused… Maybe I should switch to Phil’s version just to be safe.
I hope you do find the time to make it into a real plugin Phil as there isn’t anything else out there with this useful functionality.
Cheers
SheldonTifosy, could you share the version you’ve got working so I can see it in action?
well i can definitely confirm it works the way we wanted it to Sheldon. I’ve put the first 2 characters of local town and cities post codes, to my allow list, and works a treat. if its not recognised then customer sees a message ‘sorry, this service is currently not available in your area’ message.
we got there in the end!
i got phils version to work. i made it into a plugin before i seen he kindly put the plugin version in here for us to download.
Dear Phil,
Thank you from the bottom of my heart, just what I was searching for. Giving it a whirl now.
Definitely you should put it in the repository.
M
- The topic ‘Postcode wildcards’ is closed to new replies.