Magento Country Reorder
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 hel开发者_StackOverflow中文版p me out of this.
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'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.
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;
}
精彩评论