Index: trunk/phase3/maintenance/updateCollation.php |
— | — | @@ -57,11 +57,10 @@ |
58 | 58 | $dbw->begin(); |
59 | 59 | foreach ( $res as $row ) { |
60 | 60 | $title = Title::newFromRow( $row ); |
61 | | - $rawSortkey = $title->getCategorySortkey(); |
62 | 61 | if ( $row->cl_collation == 0 ) { |
63 | 62 | # This is an old-style row, so the sortkey needs to be |
64 | 63 | # converted. |
65 | | - if ( $row->cl_sortkey == $rawSortkey ) { |
| 64 | + if ( $row->cl_sortkey == $title->getCategorySortkey() ) { |
66 | 65 | $prefix = ''; |
67 | 66 | } else { |
68 | 67 | # Custom sortkey, use it as a prefix |
— | — | @@ -82,7 +81,8 @@ |
83 | 82 | $dbw->update( |
84 | 83 | 'categorylinks', |
85 | 84 | array( |
86 | | - 'cl_sortkey' => $wgContLang->convertToSortkey( $prefix . $rawSortkey ), |
| 85 | + 'cl_sortkey' => $wgContLang->convertToSortkey( |
| 86 | + $title->getCategorySortkey( $prefix ) ), |
87 | 87 | 'cl_sortkey_prefix' => $prefix, |
88 | 88 | 'cl_collation' => $wgCollationVersion, |
89 | 89 | 'cl_type' => $type, |
Index: trunk/phase3/includes/CategoryPage.php |
— | — | @@ -312,7 +312,7 @@ |
313 | 313 | $count = 0; |
314 | 314 | foreach ( $res as $row ) { |
315 | 315 | $title = Title::newFromRow( $row ); |
316 | | - $rawSortkey = $row->cl_sortkey_prefix . $title->getCategorySortkey(); |
| 316 | + $rawSortkey = $title->getCategorySortkey( $row->cl_sortkey_prefix ); |
317 | 317 | |
318 | 318 | if ( ++$count > $this->limit ) { |
319 | 319 | # We've reached the one extra which shows that there |
Index: trunk/phase3/includes/LinksUpdate.php |
— | — | @@ -457,7 +457,7 @@ |
458 | 458 | # order or such. |
459 | 459 | $prefix = $sortkey; |
460 | 460 | $sortkey = $wgContLang->convertToSortkey( |
461 | | - $prefix . $this->mTitle->getCategorySortkey() ); |
| 461 | + $this->mTitle->getCategorySortkey( $prefix ) ); |
462 | 462 | } |
463 | 463 | |
464 | 464 | $arr[] = array( |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -4139,20 +4139,29 @@ |
4140 | 4140 | } |
4141 | 4141 | |
4142 | 4142 | /** |
4143 | | - * Returns what the default sort key for categories would be, if |
4144 | | - * {{defaultsort:}} isn't used. This is the same as getText() for |
4145 | | - * categories, and for everything if $wgCategoryPrefixedDefaultSortkey is |
4146 | | - * false; otherwise it's the same as getPrefixedText(). |
| 4143 | + * Returns the raw sort key to be used for categories, with the specified |
| 4144 | + * prefix. This will be fed to Language::convertToSortkey() to get a |
| 4145 | + * binary sortkey that can be used for actual sorting. |
4147 | 4146 | * |
| 4147 | + * @param $prefix string The prefix to be used, specified using |
| 4148 | + * {{defaultsort:}} or like [[Category:Foo|prefix]]. Empty for no |
| 4149 | + * prefix. |
4148 | 4150 | * @return string |
4149 | 4151 | */ |
4150 | | - public function getCategorySortkey() { |
| 4152 | + public function getCategorySortkey( $prefix = '' ) { |
4151 | 4153 | global $wgCategoryPrefixedDefaultSortkey; |
4152 | 4154 | if ( $this->getNamespace() == NS_CATEGORY |
4153 | 4155 | || !$wgCategoryPrefixedDefaultSortkey ) { |
4154 | | - return $this->getText(); |
| 4156 | + $unprefixed = $this->getText(); |
4155 | 4157 | } else { |
4156 | | - return $this->getPrefixedText(); |
| 4158 | + $unprefixed = $this->getPrefixedText(); |
4157 | 4159 | } |
| 4160 | + if ( $prefix !== '' ) { |
| 4161 | + # Separate with a null byte, so the unprefixed part is only used as |
| 4162 | + # a tiebreaker when two pages have the exact same prefix -- null |
| 4163 | + # sorts before everything else (hopefully). |
| 4164 | + return "$prefix\0$unprefixed"; |
| 4165 | + } |
| 4166 | + return $unprefixed; |
4158 | 4167 | } |
4159 | 4168 | } |
Index: trunk/phase3/languages/Language.php |
— | — | @@ -2938,10 +2938,10 @@ |
2939 | 2939 | /** |
2940 | 2940 | * Given a string, convert it to a (hopefully short) key that can be used |
2941 | 2941 | * for efficient sorting. A binary sort according to the sortkeys |
2942 | | - * corresponds to a logical sort of the corresponding strings. Applying |
2943 | | - * this to cl_sortkey_prefix concatenated with the page title (possibly |
2944 | | - * with namespace prefix, depending on $wgCategoryPrefixedDefaultSortkey) |
2945 | | - * gives you cl_sortkey. |
| 2942 | + * corresponds to a logical sort of the corresponding strings. Current |
| 2943 | + * code expects that a null character should sort before all others, but |
| 2944 | + * has no other particular expectations (and that one can be changed if |
| 2945 | + * necessary). |
2946 | 2946 | * |
2947 | 2947 | * @param string $string UTF-8 string |
2948 | 2948 | * @return string Binary sortkey |
— | — | @@ -2988,6 +2988,9 @@ |
2989 | 2989 | * @return string UTF-8 string corresponding to the first letter of input |
2990 | 2990 | */ |
2991 | 2991 | public function firstLetterForLists( $string ) { |
| 2992 | + if ( $string[0] == "\0" ) { |
| 2993 | + $string = substr( $string, 1 ); |
| 2994 | + } |
2992 | 2995 | return strtoupper( mb_substr( $string, 0, 1 ) ); |
2993 | 2996 | } |
2994 | 2997 | } |