The case transformation options for arguments don't work properly with special characters. strtoupper/strtolower/ucfirst/ucwords only transform alphabetic characters that belong the the system locale (though I can't actually get that to work on my Ubuntu server using sv_SE.utf-8 and taxonomy terms containing Swedish characters). Since it's likely that a multi-language site needs to transform characters that span across multiple locales I think it would be better to use the mb_* family of functions instead.

The patch also removes a duplicate occurence of case 'upper':

  function case_transform($string, $option) {
    switch ($this->options[$option]) {
      default:
        return $string;
      case 'upper':
        return mb_strtoupper($string);
      case 'lower':
        return mb_strtolower($string);
      case 'ucfirst':
        return mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1);
      case 'ucwords':
        return mb_convert_case($string, MB_CASE_TITLE);
    }
  }
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

merlinofchaos’s picture

Status: Needs review » Fixed

Minor note: I prefer patches generated from the base 'views' directory to make it easy to apply.

Committed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

mr.baileys’s picture

Version: 6.x-2.1 » 6.x-2.x-dev
Status: Closed (fixed) » Needs review
FileSize
1.1 KB

This fix causes problems on installations where the PHP mbstring extension is not active, and the mb_* calls are not defined:

PHP Fatal error:  Call to undefined function mb_strtolower() in <drupal-root>\sites\all\modules\views\handlers\views_handler_argument_string.inc on line 188

Drupal has a number of unicode functions that degrade gracefully if the mbstring extension is not present, so I'd suggest replacing the mb_* calls with their drupal_* counterparts. There is no matching function for mb_convert_case, so I've added a check to determine which function to run:

function case_transform($string, $option) {
  global $multibyte;
	
  switch ($this->options[$option]) {
    default:
      return $string;
    case 'upper':
      return drupal_strtoupper($string);
    case 'lower':
      return drupal_strtolower($string);
    case 'ucfirst':
      return drupal_strtoupper(drupal_substr($string, 0, 1)) . drupal_substr($string, 1);
    case 'ucwords':
      if ($multibyte == UNICODE_MULTIBYTE) {
        return mb_convert_case($string, MB_CASE_TITLE);
      } else {
        return ucwords($string);
      }
  }
}
hawk259’s picture

Yes, this broke on my system. Thanks for the new patch!

dragonwize’s picture

Priority: Normal » Critical

bump

merlinofchaos’s picture

Status: Needs review » Fixed

Thanks! Committed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.