11 replies [Last post]
canuckistani@drupal.org's picture
Offline
Joined: 06/17/2009
Juice: 6

I'm using the list of countries from this post:

http://www.ubercart.org/comment/39958/Re_Not_sure_about_list

I wanted to sort these so that an arbitrary set of countries is sorted at the top, with a separator; here is the function I used to do that, called from inside modulname_form_uc_cart_checkout_form_alter:

<?php
function _sort_countries($countries) {
   
$top_countries = array(
       
"US" =>"United States",
       
"GB" =>"United Kingdom",
       
"MX" =>"Mexico",
       
"JP" =>"Japan",
       
"DE" =>"Germany",
       
"FR" =>"France",
       
"CN" =>"China",
       
"CA" =>"Canada",
       
"BR" =>"Brazil",
    );
   
   
$flipped = array_flip($top_countries);

   

$top = array();
   
$bottom = array();
   
    foreach (
$countries as $key => $country) {
        if (
array_key_exists($country, $flipped)) {
           
$top[$key] = $country;
        } else {
           
$bottom[$key] = $country;
        }
    }
   
// we asort because things get sorted already?
   
arsort($top);
   
$merged = array_merge(array_flip($top),
                          array(
'----' => ''),
                         
array_flip($bottom));
   
    return
array_flip($merged);
}
?>

Obviously this is not sophisticated enough to allow non-devs to do custom sorting of the list via a UI, but it was sufficient for my purposes, and it may be enough to allow you to add some additional usability to your site if the vast majority of your users are from a small subset of countries.Note the various array gymnastics I had to go through in order to preserve the original array keys. =)

Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
looks like exactly what I'm trying to achieve...

Thanks to cauckistani for posting this, but can anyone tell me if this is for UC1 or UC2 please?

I'm trying to get this to work by creating a new module but seeing as I've not done this before I'm struggling a bit. After looking around at creating modules I've managed to start off with;

<?php
// Hook Form Alter for sorting country lists in UC Checkout

function uc_country_list_form_alter(&$form, $form_state, $form_id) {
 
// Normally a switch is used because you may want to alter more than
  // one form and it is easy to add a new case for each form.
 
switch ($form_id) {
   
// This is our form ID.
   
case 'uc_cart_checkout_form':
       
// Do stuff
       
break;
    }
}
?>

...and tried to drop the given code in where I have // Do stuff but it doesn't do anything - on a slightly positive note...it doesn't break anything either. I know it's trying to at least modify the correct form because

<?php
$form
['panes']['delivery']['delivery_country']['#title'] = t('MyNewTitle');
?>

replaces the Country label with MyNewTitle

Any help getting this sorted would be massively appreciated. Thanks in advance.

canuckistani's picture
Offline
Joined: 04/02/2009
Juice: 14
Re: Quick function for sorting countries list

The code is being used in an Ubercart 2 site, specifically https://store.activestate.com . I don't work there anymore, but I'm very sure they're still using this.

As for how to use the code I provided, you should copy it into your custom module as a separate utility function and call it inside your form_alter on the correct part of the $form array. Here is my form_alter for this in all it's glory:

<?php
/**
* implementation of hook_FORMID_form_alter
*/

function uc_something_form_uc_cart_checkout_form_alter(&$form, &$form_state) {
    if (isset(
$form['panes']['delivery'])) {
       
$delivery = $form['panes']['delivery'];
       
$delivery['delivery_country']['#options'] = _sort_countries($delivery['delivery_country']['#options']);
       
$form['panes']['delivery'] = $delivery;
    }
   
// because collapsible panes are for weenies
   
foreach ($form['panes'] as $k => $v) {
        unset(
$v['#collapsible']);
        unset(
$v['#collapsed']);
       
$form['panes'][$k] = $v;
    }
}
?>
Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
Thanks!!!

Hi canuckistani,

Thanks so much for your help - I've managed to get it working (on both delivery and billing addresses Smiling). It's also given me an insight into how to go about module creation...so double thanks!!

Out of interest, is there a way to 'unsort' $top so that the values get returned in the order listed while $bottom remain sorted alphabetically?

autopoietic's picture
Offline
Joined: 07/28/2009
Juice: 52
Re: Thanks!!!

Just dropped in here, but it looks like you could just remove arsort($top); and the $top would remain sorted as it was initially.

canuckistani's picture
Offline
Joined: 04/02/2009
Juice: 14
Re: Re: Thanks!!!

Yeah, I forget why I did that Eye-wink. Probably a marketing request.

Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
Hmmmmm

I'm sure i tried that and it still returned alphabetically - I'll go in and try it again and will get back to you.

autopoietic's picture
Offline
Joined: 07/28/2009
Juice: 52
try just inserting the top countries

Sticking my oar in again without testing anything...

maybe you could just use the $top_countries array straight in the array_merge, as the '$top' array should be equivalent but flipped twice, which I suppose had the side-effect of sorting the array:

<?php
$merged
= array_merge(
 
array_flip($top_countries),
  array(
'----' => ''),
 
array_flip($bottom));
  
return
array_flip($merged);
?>
Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
worked a treat

Brilliant, thanks for that autopoietic - it worked!

The site this is going on is for an artist who is going around the world with his installations in various cities and I thought it would be a nice touch to list the countries where he had been in order at the top of the form...so for me, this is now the perfect solution.

Thanks again

autopoietic's picture
Offline
Joined: 07/28/2009
Juice: 52
Re: worked a treat

No problem, rock on Brizl

Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
(No subject)

Laughing out loud

Axel_Pressbutton's picture
Offline
Joined: 11/30/2008
Juice: 123
Ah....

Maybe not - the countries are listed in the correct order but they no longer pull in the aut-generated Stat/Province values.

I noticed that the original code still pulls in the correct option values e.g. United Kingdom whereas the revised code returns United Kingdom

I guess I could try adding the numbers in the array instead of the identifying letters.....but have a feeling that may mess things up more.

Update: Yes, it appears to work OK if I use the numeric values e.g.

<?php
function _sort_countries($countries) {
   
$top_countries = array(
       
"826" => "United Kingdom",
       
"724" => "Spain",
       
"840" => "United States"
   
);
?>

...not ideal, but it'll do for now.