]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/collation/CustomUppercaseCollation.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / collation / CustomUppercaseCollation.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @since 1.30
19  *
20  * @file
21  */
22
23 /**
24  * Resort normal UTF-8 order by putting a bunch of stuff in PUA
25  *
26  * This takes a bunch of characters (The alphabet) that should,
27  * be together, and converts them all to private-use-area characters
28  * so that they are all sorted in the right order relative to each
29  * other.
30  *
31  * This renumbers characters starting at U+F3000 (Chosen to avoid
32  * conflicts with other people using private use area)
33  *
34  * This does not support fancy things like secondary differences, etc.
35  *
36  * It is expected most people will subclass this and just override the
37  * constructor to hard-code an alphabet.
38  */
39 class CustomUppercaseCollation extends NumericUppercaseCollation {
40
41         /** @var array $alphabet Sorted array of letters */
42         private $alphabet;
43
44         /** @var array $puaSubset List of private use area codes */
45         private $puaSubset;
46
47         /**
48          * @note This assumes $alphabet does not contain U+F3000-U+F303F
49          *
50          * @param array $alphabet Sorted array of uppercase characters.
51          * @param Language $lang What language for number sorting.
52          */
53         public function __construct( array $alphabet, Language $lang ) {
54                 // It'd be trivial to extend this past 64, you'd just
55                 // need a bit of bit-fiddling. Doesn't seem necessary right
56                 // now.
57                 if ( count( $alphabet ) < 1 || count( $alphabet ) >= 64 ) {
58                         throw new UnexpectedValueException( "Alphabet must be < 64 items" );
59                 }
60                 $this->alphabet = $alphabet;
61
62                 $this->puaSubset = [];
63                 $len = count( $alphabet );
64                 for ( $i = 0; $i < $len; $i++ ) {
65                         $this->puaSubset[] = "\xF3\xB3\x80" . chr( $i + 128 );
66                 }
67                 parent::__construct( $lang );
68         }
69
70         private function convertToPua( $string ) {
71                 return str_replace( $this->alphabet, $this->puaSubset, $string );
72         }
73
74         public function getSortKey( $string ) {
75                 return $this->convertToPua( parent::getSortKey( $string ) );
76         }
77
78         public function getFirstLetter( $string ) {
79                 // In case a title has a PUA code in it, make it sort
80                 // under the header for the character it would replace
81                 // to avoid inconsistent behaviour. This class mostly
82                 // assumes that people will not use PUA codes.
83                 return parent::getFirstLetter(
84                         str_replace( $this->puaSubset, $this->alphabet, $string )
85                 );
86         }
87 }