<p>If postie plugin can't add zone support, then you will need to limit the selections options on the front end and need the zones available in twig.</p>

<p>Postie implementing it would be the first preferance, as there would be no backend validation if you just hid the options in twig.</p>

<p>There currently is no <code>craft.commmerce.shippingZones</code> twig variable. You would need to expose it with a plugin.</p>

<p>Creating a plugin at the <a href="http://pluginfactory.io" rel="nofollow noreferrer">http://pluginfactory.io</a> with a variable class.</p>

<p>To the variable class within the plugin add:</p>

<pre><code>public function getAllShippingZones()
{
  return craft()-&gt;commerce_shippingZones-&gt;getAllShippingZones();
}

public function matchZoneAndAddress($zone, Commerce_AddressModel $address)
{
    if ($zone-&gt;countryBased)
    {
        $countryIds = $zone-&gt;getCountryIds();

        if (in_array($address-&gt;countryId, $countryIds))
        {
            return true;
        }
    }
    else
    {
        $states = [];
        $countries = [];
        $stateAbbrs = [];
        $stateNames = [];
        foreach ($zone-&gt;states as $state)
        {
            $states[] = $state-&gt;id;
            $stateNames[] = $state-&gt;name;
            $stateAbbrs[] = $state-&gt;abbreviation;
            $countries[] = $state-&gt;countryId;
        }

        if ($countries){
            array_filter($countries);
        }
        if ($stateNames){
            array_filter($stateNames);
        }
        if ($stateAbbrs){
            array_filter($stateAbbrs);
        }

        $countryAndStateMatch = (in_array($address-&gt;countryId, $countries) &amp;&amp; in_array($address-&gt;stateId, $states));
        $countryAndStateNameMatch = (in_array($address-&gt;countryId, $countries) &amp;&amp; $this-&gt;_inArrayCaseinsensitive($address-&gt;getStateText(), $stateNames));
        $countryAndStateAbbrMatch = (in_array($address-&gt;countryId, $countries) &amp;&amp; $this-&gt;_inArrayCaseinsensitive($address-&gt;getStateAbbreviation(), $stateAbbrs));

        if ($countryAndStateMatch || $countryAndStateNameMatch || $countryAndStateAbbrMatch)
        {
            return true;
        }
    }

    return false;
}

/**
 * @param $needle
 * @param $haystack
 * @return bool
 */
private function _inArrayCaseinsensitive($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack), false);
}
</code></pre>

<p>This would allow you to do:</p>

<pre><code>{% set doesMatch = craft.yourPlugin.matchZoneAndAddress(zone, cart.shippingAddress) %}
</code></pre>

<p>To determine if an address is within a zone.</p>

<p>Hope that helps.</p>

CC BY-SA 3.0
2018-03-21T16:29:47.877Z
This definitely got me on the right track. I appreciate the help.
Chad Crowell
CC BY-SA 3.0
2018-03-12T08:00:43.550Z
2018-03-12T17:29:04.623Z
2018-03-12T17:29:04.623Z
Luke Holder
<p>On the template for choosing shipping method, I need to be able to remove/hide some shipping methods from being shown, based on the shipping zone that has been set by Craft, which is based on the address entered, etc.</p>

<p>I'm using Postie for live Fedex rates, along with a couple of custom shipping methods, but Postie adds its live rates to the array of shipping methods regardless of the shipping zone, so I end up with my custom method, plus the Fedex methods, when I just want the custom one. </p>

<p>I'd like to evaluate shippingZone that is set for this cart, and if it is zone A or B, not how any Fedex methods, else, show them. I just need access to the shippingZone to do this. </p>

<p>Like so: <a href="https://d.pr/i/JCmTiT" rel="nofollow noreferrer">https://d.pr/i/JCmTiT</a></p>

<p>Any way to get it?</p>

<plugin-craftcommerce>
Commerce: Is shippingZone available as a variable on the shipping method selection template?
# Commerce: Is shippingZone available as a variable on the shipping method selection template?

(Asked by: username_0 on 2018-03-10)

On the template for choosing shipping method, I need to be able to remove/hide some shipping methods from being shown, based on the shipping zone that has been set by Craft, which is based on the address entered, etc.

I'm using Postie for live Fedex rates, along with a couple of custom shipping methods, but Postie adds its live rates to the array of shipping methods regardless of the shipping zone, so I end up with my custom method, plus the Fedex methods, when I just want the custom one.

I'd like to evaluate shippingZone that is set for this cart, and if it is zone A or B, not how any Fedex methods, else, show them. I just need access to the shippingZone to do this.

Like so: <https://d.pr/i/JCmTiT>

Any way to get it?

**Tags:** plugin-craftcommerce


---

## 1 answers

### Answer by username_1 on 2018-03-12. Score: 1 | Accepted answer

If postie plugin can't add zone support, then you will need to limit the selections options on the front end and need the zones available in twig.
Postie implementing it would be the first preferance, as there would be no backend validation if you just hid the options in twig.
There currently is no craft.commmerce.shippingZones twig variable. You would need to expose it with a plugin.
Creating a plugin at the http://pluginfactory.io with a variable class.
To the variable class within the plugin add:
public function getAllShippingZones()
{
  return craft()->commerce_shippingZones->getAllShippingZones();
}

public function matchZoneAndAddress($zone, Commerce_AddressModel $address)
{
    if ($zone->countryBased)
    {
        $countryIds = $zone->getCountryIds();

        if (in_array($address->countryId, $countryIds))
        {
            return true;
        }
    }
    else
    {
        $states = [];
        $countries = [];
        $stateAbbrs = [];
        $stateNames = [];
        foreach ($zone->states as $state)
        {
            $states[] = $state->id;
            $stateNames[] = $state->name;
            $stateAbbrs[] = $state->abbreviation;
            $countries[] = $state->countryId;
        }

        if ($countries){
            array_filter($countries);
        }
        if ($stateNames){
            array_filter($stateNames);
        }
        if ($stateAbbrs){
            array_filter($stateAbbrs);
        }

        $countryAndStateMatch = (in_array($address->countryId, $countries) && in_array($address->stateId, $states));
        $countryAndStateNameMatch = (in_array($address->countryId, $countries) && $this->_inArrayCaseinsensitive($address->getStateText(), $stateNames));
        $countryAndStateAbbrMatch = (in_array($address->countryId, $countries) && $this->_inArrayCaseinsensitive($address->getStateAbbreviation(), $stateAbbrs));

        if ($countryAndStateMatch || $countryAndStateNameMatch || $countryAndStateAbbrMatch)
        {
            return true;
        }
    }

    return false;
}

/**
 * @param $needle
 * @param $haystack
 * @return bool
 */
private function _inArrayCaseinsensitive($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack), false);
}

This would allow you to do:
{% set doesMatch = craft.yourPlugin.matchZoneAndAddress(zone, cart.shippingAddress) %}

To determine if an address is within a zone.
Hope that helps.

> **Comments:**
> **username_0**: This definitely got me on the right track. I appreciate the help.  

---

