Magento – Remove certain countries from country dropdown in onepage checkout while in Shipping Information part only

countriesmagento-1.8shipping

I wanted to remove certain countries from the 'countries dropdown' in magento onepage checkout at the section 'shipping information'.

It is to be noted that Billing information will have all the available countries in the dropdown but I want to restrict only incase of shipping information because there are certain law which doesn't allows my online shop to ship.

I can restrict shipping to particular country from admin end but I don't even want those countries to be shown in dropdown.

Best Answer

The main challenge comes from the assumption that valid countries to display are the same regardless of context, as both billing and shipping info blocks populate the country list from the same method in Mage_Checkout_Block_Onepage_Abstract:

public function getCountryOptions()
{
    $options    = false;
    $useCache   = Mage::app()->useCache('config');
    if ($useCache) {
        $cacheId    = 'DIRECTORY_COUNTRY_SELECT_STORE_' . Mage::app()->getStore()->getCode();
        $cacheTags  = array('config');
        if ($optionsCache = Mage::app()->loadCache($cacheId)) {
            $options = unserialize($optionsCache);
        }
    }

    if ($options == false) {
        $options = $this->getCountryCollection()->toOptionArray();
        if ($useCache) {
            Mage::app()->saveCache(serialize($options), $cacheId, $cacheTags);
        }
    }
    return $options;
}

If you are using configuration caching (which you absolutely should be doing), once this list is retrieved once the results are cached and will be used until the cache is cleared. Billing step happens first, so you can't filter this way. You'll need to handle caching and the custom collection by rewriting Mage_Checkout_Block_Onepage_Shipping.

First, the collection. You need to create a new method and property, e.g. getShippingCountryCollection(), similar to getCountryCollection(), which has your filters:

public function getShippingCountryCollection()
{
    if (!$this->_shippingCountryCollection) {
        $this->_shippingCountryCollection = Mage::getSingleton('directory/country')->getResourceCollection();
        //your collection filtering here...
        $this->_shippingCountryCollection->loadByStore();
    }
    return $this->_shippingCountryCollection;
}

Second, the caching. set getCountryOptions() to use a different cache ID & the new collection data:

public function getCountryOptions()
{
    $options    = false;
    $useCache   = Mage::app()->useCache('config');
    if ($useCache) {                                  //▾▾▾▾▾▾▾
        $cacheId    = 'DIRECTORY_COUNTRY_SELECT_STORE_SHIPPING_' . Mage::app()->getStore()->getCode();
        $cacheTags  = array('config');
        if ($optionsCache = Mage::app()->loadCache($cacheId)) {
            $options = unserialize($optionsCache);
        }
    }

    if ($options == false) {
        $options = $this->getShippingCountryCollection()->toOptionArray();
        if ($useCache) {
            Mage::app()->saveCache(serialize($options), $cacheId, $cacheTags);
        }
    }
    return $options;
}

If you want to make this more user-friendly, you should do a similar thing with Mage_Customer_Block_Address_Edit::getCountryHtmlSelect() and ::getCountryCollection() so that users cannot create shipping addresses with the disallowed countries.

Related Topic