2

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.

1

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.

  • I was thinking to achieve this in simplier way like in the function loadByStore in collection.php, we will just check if the control is at shipping information section in onepage checkout page, then we would do something like if (#condition to check for control at shipping information section) { $excludeCountries = array('RU'); $this->addFieldToFilter("country_id", array('nin' => $excludeCountries)); } Let me know your thoughts on this and the way to check if the control is in shipping information section.. – Anurag Khandelwal Oct 13 '15 at 7:26
  • The logic is okay, but if you want to control the way that this is presented to users, you have to take into account the caching. Handling this only in the collection will result in the full list being used, because billing step executes first. – benmarks Oct 13 '15 at 11:15
  • Can you please tell me the logic to how to check if my control is at shipping section in onepage checkout to be used in collection.php? – Anurag Khandelwal Oct 14 '15 at 14:01
  • I won't tell you, because it won't make a difference. – benmarks Oct 14 '15 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.