/** * @param string $locale */ function __construct($locale = null) { if (!$locale) { $locale = \Locale::getDefault(); } $this->collator = new \Collator($locale); $this->collator->setAttribute(\Collator::NUMERIC_COLLATION, \Collator::ON); }
public function __construct($locale) { if (!extension_loaded('intl')) { throw new MWException('An ICU collation was requested, ' . 'but the intl extension is not available.'); } $this->locale = $locale; // Drop everything after the '@' in locale's name $localeParts = explode('@', $locale); $this->digitTransformLanguage = Language::factory($locale === 'root' ? 'en' : $localeParts[0]); $this->mainCollator = Collator::create($locale); if (!$this->mainCollator) { throw new MWException("Invalid ICU locale specified for collation: {$locale}"); } $this->primaryCollator = Collator::create($locale); $this->primaryCollator->setStrength(Collator::PRIMARY); // If the special suffix for numeric collation is present, turn on numeric collation. if (substr($locale, -5, 5) === '-u-kn') { $this->useNumericCollation = true; // Strip off the special suffix so it doesn't trip up fetchFirstLetterData(). $this->locale = substr($this->locale, 0, -5); $this->mainCollator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); $this->primaryCollator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); } }
/** * Locale aware sorting, the key associations are kept, values are sorted alphabetically. * * @param array $arr array to be sorted (reference) * @param int $sortflag One of collatorlib::SORT_NUMERIC, collatorlib::SORT_STRING, collatorlib::SORT_NATURAL, collatorlib::SORT_REGULAR * optionally "|" collatorlib::CASE_SENSITIVE * @return bool True on success */ public static function asort(array &$arr, $sortflag = collatorlib::SORT_STRING) { if (empty($arr)) { // nothing to do return true; } $original = null; $casesensitive = (bool) ($sortflag & collatorlib::CASE_SENSITIVE); $sortflag = $sortflag & ~collatorlib::CASE_SENSITIVE; if ($sortflag != collatorlib::SORT_NATURAL and $sortflag != collatorlib::SORT_STRING) { $casesensitive = false; } if (self::ensure_collator_available()) { if ($sortflag == collatorlib::SORT_NUMERIC) { $flag = Collator::SORT_NUMERIC; } else { if ($sortflag == collatorlib::SORT_REGULAR) { $flag = Collator::SORT_REGULAR; } else { $flag = Collator::SORT_STRING; } } if ($sortflag == collatorlib::SORT_NATURAL) { $original = $arr; if ($sortflag == collatorlib::SORT_NATURAL) { foreach ($arr as $key => $value) { $arr[$key] = self::naturalise((string) $value); } } } if ($casesensitive) { self::$collator->setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST); } else { self::$collator->setAttribute(Collator::CASE_FIRST, Collator::OFF); } $result = self::$collator->asort($arr, $flag); if ($original) { self::restore_array($arr, $original); } return $result; } // try some fallback that works at least for English if ($sortflag == collatorlib::SORT_NUMERIC) { return asort($arr, SORT_NUMERIC); } else { if ($sortflag == collatorlib::SORT_REGULAR) { return asort($arr, SORT_REGULAR); } } if (!$casesensitive) { $original = $arr; foreach ($arr as $key => $value) { $arr[$key] = textlib::strtolower($value); } } if ($sortflag == collatorlib::SORT_NATURAL) { $result = natsort($arr); } else { $result = asort($arr, SORT_LOCALE_STRING); } if ($original) { self::restore_array($arr, $original); } return $result; }
/** * @ignore */ public static function collatorObject($caseInsensitive, $naturalOrder, $locale, $collationFlags) { // Is public to be accessible by other classes, such as CArray. assert('is_bool($caseInsensitive) && is_bool($naturalOrder) && is_cstring($locale) && ' . 'is_bitfield($collationFlags)', vs(isset($this), get_defined_vars())); assert('CULocale::isValid($locale) || CString::equalsCi($locale, "root")', vs(isset($this), get_defined_vars())); $coll = new Collator($locale); // Case sensitivity. if (!$caseInsensitive) { $coll->setStrength(Collator::TERTIARY); } else { $coll->setStrength(Collator::SECONDARY); } // Natural order. if (!$naturalOrder) { // To be sure. $coll->setAttribute(Collator::NUMERIC_COLLATION, Collator::OFF); } else { $coll->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); } // Accents. if (CBitField::isBitSet($collationFlags, self::COLLATION_IGNORE_ACCENTS)) { $coll->setStrength(Collator::PRIMARY); if (!$caseInsensitive) { $coll->setAttribute(Collator::CASE_LEVEL, Collator::ON); } } // Invisible characters, some punctuation and symbols. if (CBitField::isBitSet($collationFlags, self::COLLATION_IGNORE_NONWORD)) { $coll->setAttribute(Collator::ALTERNATE_HANDLING, Collator::SHIFTED); } // Case order. if (!CBitField::isBitSet($collationFlags, self::COLLATION_UPPERCASE_FIRST)) { // To be sure. $coll->setAttribute(Collator::CASE_FIRST, Collator::OFF); } else { $coll->setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST); } // "French" collation. if (CBitField::isBitSet($collationFlags, self::COLLATION_FRENCH)) { $coll->setAttribute(Collator::FRENCH_COLLATION, Collator::ON); } return $coll; }