Title: Postcode wildcards
Last modified: August 24, 2016

---

# Postcode wildcards

 *  Resolved [sheldongold](https://wordpress.org/support/users/sheldongold/)
 * (@sheldongold)
 * [10 years, 11 months ago](https://wordpress.org/support/topic/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://wordpress.org/plugins/postcode-based-order-restriction/](https://wordpress.org/plugins/postcode-based-order-restriction/)

Viewing 14 replies - 1 through 14 (of 14 total)

 *  Thread Starter [sheldongold](https://wordpress.org/support/users/sheldongold/)
 * (@sheldongold)
 * [10 years, 11 months ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007365)
 * 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: http://precursorweb.com/
        * Plugin URI: http://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 - <http://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`
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007578)
 * 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.
 *  Thread Starter [sheldongold](https://wordpress.org/support/users/sheldongold/)
 * (@sheldongold)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007579)
 * 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.
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007580)
 * 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
 *  [Philip K Meadows](https://wordpress.org/support/users/philmeadows/)
 * (@philmeadows)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007583)
 * 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: http://www.philmeadows.com
       License: GPLv2 or later
       License URI: http://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
       ```
   
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007584)
 * 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.
 *  [Philip K Meadows](https://wordpress.org/support/users/philmeadows/)
 * (@philmeadows)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007585)
 * Download: [pkm-wc-local-shop.zip](http://philmeadows.com/wp-stuff/uploads/pkm-wc-local-shop.zip)–
   save to your Desktop / wherever
 * Go to Plugins > Add New > Upload Plugin
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007586)
 * Phil, i managed to figure it out and just set it up, works perfect, just what
   i needed! cant thank you enough.
 * :))))))
 *  [Philip K Meadows](https://wordpress.org/support/users/philmeadows/)
 * (@philmeadows)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007587)
 * You’re welcome
 * I may even put it in the WP Plugin repo, if I get time / can be bothered!
 * Phil 😉
 *  Thread Starter [sheldongold](https://wordpress.org/support/users/sheldongold/)
 * (@sheldongold)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007588)
 * 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 [http://www.gumberryworktops.co.uk](http://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
    Sheldon
 *  Thread Starter [sheldongold](https://wordpress.org/support/users/sheldongold/)
 * (@sheldongold)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007589)
 * Tifosy, could you share the version you’ve got working so I can see it in action?
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007590)
 * 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!
 *  [tifosy](https://wordpress.org/support/users/tifosy/)
 * (@tifosy)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007591)
 * 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.
 *  [m0majeed](https://wordpress.org/support/users/m0majeed/)
 * (@m0majeed)
 * [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007592)
 * 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

Viewing 14 replies - 1 through 14 (of 14 total)

The topic ‘Postcode wildcards’ is closed to new replies.

 * ![](https://ps.w.org/postcode-based-order-restriction/assets/icon-128x128.png?
   rev=1129006)
 * [Postcode Based Order Restriction for WooCommerce](https://wordpress.org/plugins/postcode-based-order-restriction/)
 * [Support Threads](https://wordpress.org/support/plugin/postcode-based-order-restriction/)
 * [Active Topics](https://wordpress.org/support/plugin/postcode-based-order-restriction/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/postcode-based-order-restriction/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/postcode-based-order-restriction/reviews/)

 * 14 replies
 * 4 participants
 * Last reply from: [m0majeed](https://wordpress.org/support/users/m0majeed/)
 * Last activity: [10 years, 1 month ago](https://wordpress.org/support/topic/postcode-wildcards/#post-6007592)
 * Status: resolved