It is a shame that you can't use something like this:
'UPPER(User.first_name)' => 'ASC'
Which would be fairly basic.
I had this issue in a project, whereby I replaced the 'order' array with something like this:
'order' = "UPPER(first_name) ASC"
which successfully gave me the correct output.
Unfortunately, however, clicking the column header fields to sort my paginated table then replicated the issue, whereby my names were once again case-sensitive.
The solution that I came up with was to modify the PaginatorComponent of cakephp itself, so that my sort order would always be correct.
In the PaginatorComponent (/lib/Cake/Controller/Component/PaginatorComponent.php) I modified the validateSort function, replacing the following line:
$options['order'] = $order;
With the four lines below:
foreach($order as $order_field=>$order_direction){
$neworder['UPPER('.$order_field.')'] = $order_direction;
}
$options['order'] = $neworder;
It's not elegant, and is essentially just forcing the 'UPPER()' around the field name.
This worked in my particular situation whereby I need to always have case-insensitive queries.