Question

How do i reorder the Country default drop down order in Magento. Like United States should be first in the select option list rather than by alphabetic sorting.

I couldn't find either in database or in xml,csv,php files, where these countries list stored. Please help me out of this.

Was it helpful?

Solution

I've not done this, though I've thought about it. I'm guessing you could override the controller the block that pulls that data from the database. Select boxes are just arrays of values, so perhaps you could call the function that gets the array of country values, reorder them "manually" with php and then assign the newly ordered array to the "field" object.

OTHER TIPS

I was looking for the same, and eventually did it by myself. Decided to post it here, Hope this helps someone else.

Create your own module (if it's not exist yet). Rewrite Mage_Directory_Model_Resource_Country_Collection class:

<config>
    <modules>
        <Your_Module>
            <version>0.0.0.1</version>
        </Your_Module>
    </modules>
    <global>
        <models>
            <directory_resource>
                <rewrite>
                    <country_collection>Your_Module_Model_Resource_Directory_Country_Collection</country_collection>
                </rewrite>
            </directory_resource>
        </models>
    </global>
</config>

Create the following file in your Magento root dir:

/app/code/local/Your/Module/Model/Resource/Directory/Country/Collection.php

with the following content:

<?php

class Your_Module_Model_Resource_Directory_Country_Collection
    extends Mage_Directory_Model_Resource_Country_Collection
{

    protected function _initSelect()
    {
        parent::_initSelect();

        $this
            ->addOrder('country_id="US"','desc')
            ->addOrder('country_id', 'asc');

        return $this;
    }

}

After that, all country lists will be pulling US first, and then all other countries alphabetically.

I think that Alex B solution does not work anymore after SUPEE-6788 patch addressing possible SQL injection APPSEC-1063 quotes escape.

Mohammad Faisal overwrite caused some countries to dissapear after enabling Tablerates on our store.

I ended up with setting collection order with Zend_Db_Expr and removing Mage::helper('core/string')->ksortMultibyte($sort) in protected method.

Tested in Magento 1.9.3.2.

<?php

class Your_Module_Model_Resource_Directory_Country_Collection extends Mage_Directory_Model_Resource_Country_Collection {

/**
 * Convert items array to array for select options pushing most important countries to the top
 *
 * return items array
 * array(
 *      $index => array(
 *          'value' => mixed
 *          'label' => mixed
 *      )
 * )
 *
 * @param   string $valueField
 * @param   string $labelField
 * @return  array
 */
protected function _toOptionArray($valueField = 'id', $labelField = 'name', $additional = array())
{
    $res = array();
    $additional['value'] = $valueField;
    $additional['label'] = $labelField;

    $this->getSelect()->order(new Zend_Db_Expr('country_id = "NL" DESC'));
    $this->getSelect()->order(new Zend_Db_Expr('country_id = "BE" DESC'));
    $this->getSelect()->order(new Zend_Db_Expr('country_id = "DE" DESC'));
    $this->getSelect()->order(new Zend_Db_Expr('country_id = "FR" DESC'));
    $this->getSelect()->order('country_id', 'DESC');

    foreach ($this as $item) {
        foreach ($additional as $code => $field) {
            $data[$code] = $item->getData($field);
        }
        $res[] = $data;
    }

    return $res;
}

/**
 * Convert collection items to select options array
 *
 * @param string $emptyLabel
 * @return array
 */
public function toOptionArray($emptyLabel = ' ')
{
    $options = $this->_toOptionArray('country_id', 'name', array('title' => 'iso2_code'));

    $sort = array();
    foreach ($options as $data) {
        $name = Mage::app()->getLocale()->getCountryTranslation($data['value']);
        if (!empty($name)) {
            $sort[$name] = $data['value'];
        }
    }

    // Mage::helper('core/string')->ksortMultibyte($sort);
    $options = array();
    foreach ($sort as $label => $value) {
        $options[] = array(
            'value' => $value,
            'label' => $label
        );
    }

    if (count($options) > 0 && $emptyLabel !== false) {
        array_unshift($options, array('value' => '', 'label' => $emptyLabel));
    }

    return $options;
    }

}

I was also looking for the same and the other answer by Alex B was not working in my case. Also the code

$this->addOrder('country_id="US"','desc')
     ->addOrder('country_id', 'asc');

doesn't making any change in the country list. So instead on overriding the _initSelect() I choose toOptionArray() to override. and here's my code

public function toOptionArray($emptyLabel = '') {
    $options = parent::toOptionArray($emptyLabel);
    foreach ($options as $key => $option) {
        if ($option['value'] == 'IN') {  //check current country code
            unset($options[$key]);
            $options = addCountryToIndex($options, $option, 1);  
        }
    }
    return $options;
}

protected function addCountryToIndex($countries, $country, $index){
    $options = array_slice($countries, 0, $index, true) +
        array($index => $country) +
        array_slice($countries, $index, count($countries) - 1, true);
    return $options;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top