Addshore has uploaded a new change for review.
https://gerrit.wikimedia.org/r/281261
Change subject: Split Collation.php
......................................................................
Split Collation.php
Change-Id: I6abfecf91cdce83dd34b1e8aa8e0b35315f62742
---
M autoload.php
A includes/collation/Collation.php
A includes/collation/CollationCkb.php
A includes/collation/CollationEt.php
R includes/collation/IcuCollation.php
A includes/collation/IdentityCollation.php
A includes/collation/UppercaseCollation.php
7 files changed, 300 insertions(+), 202 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/61/281261/1
diff --git a/autoload.php b/autoload.php
index fd4f873..54a0ba0 100644
--- a/autoload.php
+++ b/autoload.php
@@ -240,9 +240,9 @@
'CliInstaller' => __DIR__ . '/includes/installer/CliInstaller.php',
'CloneDatabase' => __DIR__ . '/includes/db/CloneDatabase.php',
'CodeContentHandler' => __DIR__ .
'/includes/content/CodeContentHandler.php',
- 'Collation' => __DIR__ . '/includes/Collation.php',
- 'CollationCkb' => __DIR__ . '/includes/Collation.php',
- 'CollationEt' => __DIR__ . '/includes/Collation.php',
+ 'Collation' => __DIR__ . '/includes/collation/Collation.php',
+ 'CollationCkb' => __DIR__ . '/includes/collation/CollationCkb.php',
+ 'CollationEt' => __DIR__ . '/includes/collation/CollationEt.php',
'CommandLineInc' => __DIR__ . '/maintenance/commandLine.inc',
'CommandLineInstaller' => __DIR__ . '/maintenance/install.php',
'CompareParserCache' => __DIR__ . '/maintenance/compareParserCache.php',
@@ -564,8 +564,8 @@
'IPSet' => __DIR__ . '/includes/compat/IPSetCompat.php',
'IPTC' => __DIR__ . '/includes/media/IPTC.php',
'IRCColourfulRCFeedFormatter' => __DIR__ .
'/includes/rcfeed/IRCColourfulRCFeedFormatter.php',
- 'IcuCollation' => __DIR__ . '/includes/Collation.php',
- 'IdentityCollation' => __DIR__ . '/includes/Collation.php',
+ 'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
+ 'IdentityCollation' => __DIR__ .
'/includes/collation/IdentityCollation.php',
'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
'ImageCleanup' => __DIR__ . '/maintenance/cleanupImages.php',
'ImageGallery' => __DIR__ .
'/includes/gallery/TraditionalImageGallery.php',
@@ -1375,7 +1375,7 @@
'UploadStashNotLoggedInException' => __DIR__ .
'/includes/upload/UploadStash.php',
'UploadStashWrongOwnerException' => __DIR__ .
'/includes/upload/UploadStash.php',
'UploadStashZeroLengthFileException' => __DIR__ .
'/includes/upload/UploadStash.php',
- 'UppercaseCollation' => __DIR__ . '/includes/Collation.php',
+ 'UppercaseCollation' => __DIR__ .
'/includes/collation/UppercaseCollation.php',
'UsageException' => __DIR__ . '/includes/api/ApiMain.php',
'User' => __DIR__ . '/includes/user/User.php',
'UserArray' => __DIR__ . '/includes/user/UserArray.php',
diff --git a/includes/collation/Collation.php b/includes/collation/Collation.php
new file mode 100644
index 0000000..84d1f24
--- /dev/null
+++ b/includes/collation/Collation.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * Database row sorting.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+abstract class Collation {
+ private static $instance;
+
+ /**
+ * @return Collation
+ */
+ static function singleton() {
+ if ( !self::$instance ) {
+ global $wgCategoryCollation;
+ self::$instance = self::factory( $wgCategoryCollation );
+ }
+ return self::$instance;
+ }
+
+ /**
+ * @throws MWException
+ * @param string $collationName
+ * @return Collation
+ */
+ static function factory( $collationName ) {
+ switch ( $collationName ) {
+ case 'uppercase':
+ return new UppercaseCollation;
+ case 'identity':
+ return new IdentityCollation;
+ case 'uca-default':
+ return new IcuCollation( 'root' );
+ case 'xx-uca-ckb':
+ return new CollationCkb;
+ case 'xx-uca-et':
+ return new CollationEt;
+ default:
+ $match = [];
+ if ( preg_match( '/^uca-([a-z@=-]+)$/',
$collationName, $match ) ) {
+ return new IcuCollation( $match[1] );
+ }
+
+ # Provide a mechanism for extensions to hook in.
+ $collationObject = null;
+ Hooks::run( 'Collation::factory', [
$collationName, &$collationObject ] );
+
+ if ( $collationObject instanceof Collation ) {
+ return $collationObject;
+ }
+
+ // If all else fails...
+ throw new MWException( __METHOD__ . ": unknown
collation type \"$collationName\"" );
+ }
+ }
+
+ /**
+ * Given a string, convert it to a (hopefully short) key that can be
used
+ * for efficient sorting. A binary sort according to the sortkeys
+ * corresponds to a logical sort of the corresponding strings. Current
+ * code expects that a line feed character should sort before all
others, but
+ * has no other particular expectations (and that one can be changed if
+ * necessary).
+ *
+ * @param string $string UTF-8 string
+ * @return string Binary sortkey
+ */
+ abstract function getSortKey( $string );
+
+ /**
+ * Given a string, return the logical "first letter" to be used for
+ * grouping on category pages and so on. This has to be coordinated
+ * carefully with convertToSortkey(), or else the sorted list might jump
+ * back and forth between the same "initial letters" or other
pathological
+ * behavior. For instance, if you just return the first character, but
"a"
+ * sorts the same as "A" based on getSortKey(), then you might get a
+ * list like
+ *
+ * == A ==
+ * * [[Aardvark]]
+ *
+ * == a ==
+ * * [[antelope]]
+ *
+ * == A ==
+ * * [[Ape]]
+ *
+ * etc., assuming for the sake of argument that $wgCapitalLinks is
false.
+ *
+ * @param string $string UTF-8 string
+ * @return string UTF-8 string corresponding to the first letter of
input
+ */
+ abstract function getFirstLetter( $string );
+
+}
diff --git a/includes/collation/CollationCkb.php
b/includes/collation/CollationCkb.php
new file mode 100644
index 0000000..da1a562
--- /dev/null
+++ b/includes/collation/CollationCkb.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Workaround for the lack of support of Sorani Kurdish / Central Kurdish
language ('ckb') in ICU.
+ *
+ * Uses the same collation rules as Persian / Farsi ('fa'), but different
characters for digits.
+ */
+class CollationCkb extends IcuCollation {
+ function __construct() {
+ // This will set $locale and collators, which affect the actual
sorting order
+ parent::__construct( 'fa' );
+ // Override the 'fa' language set by parent constructor, which
affects #getFirstLetterData()
+ $this->digitTransformLanguage = Language::factory( 'ckb' );
+ }
+}
diff --git a/includes/collation/CollationEt.php
b/includes/collation/CollationEt.php
new file mode 100644
index 0000000..d80bce3
--- /dev/null
+++ b/includes/collation/CollationEt.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Workaround for incorrect collation of Estonian language ('et') in ICU (bug
54168).
+ *
+ * 'W' and 'V' should not be considered the same letter for the purposes of
collation in modern
+ * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21
'LATIN LETTER SMALL
+ * CAPITAL W' for sortkey generation, which is collated like 'W' and is not
tailored to have the
+ * same primary weight as 'V' in Estonian.
+ */
+class CollationEt extends IcuCollation {
+ function __construct() {
+ parent::__construct( 'et' );
+ }
+
+ private static function mangle( $string ) {
+ return str_replace(
+ [ 'w', 'W' ],
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ $string
+ );
+ }
+
+ private static function unmangle( $string ) {
+ // Casing data is lost…
+ return str_replace(
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ 'W',
+ $string
+ );
+ }
+
+ function getSortKey( $string ) {
+ return parent::getSortKey( self::mangle( $string ) );
+ }
+
+ function getFirstLetter( $string ) {
+ return self::unmangle( parent::getFirstLetter( self::mangle(
$string ) ) );
+ }
+}
diff --git a/includes/Collation.php b/includes/collation/IcuCollation.php
similarity index 73%
rename from includes/Collation.php
rename to includes/collation/IcuCollation.php
index 7a3623d..fee4cd0 100644
--- a/includes/Collation.php
+++ b/includes/collation/IcuCollation.php
@@ -1,7 +1,5 @@
<?php
/**
- * Database row sorting.
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -19,139 +17,6 @@
*
* @file
*/
-
-abstract class Collation {
- private static $instance;
-
- /**
- * @return Collation
- */
- static function singleton() {
- if ( !self::$instance ) {
- global $wgCategoryCollation;
- self::$instance = self::factory( $wgCategoryCollation );
- }
- return self::$instance;
- }
-
- /**
- * @throws MWException
- * @param string $collationName
- * @return Collation
- */
- static function factory( $collationName ) {
- switch ( $collationName ) {
- case 'uppercase':
- return new UppercaseCollation;
- case 'identity':
- return new IdentityCollation;
- case 'uca-default':
- return new IcuCollation( 'root' );
- case 'xx-uca-ckb':
- return new CollationCkb;
- case 'xx-uca-et':
- return new CollationEt;
- default:
- $match = [];
- if ( preg_match( '/^uca-([a-z@=-]+)$/',
$collationName, $match ) ) {
- return new IcuCollation( $match[1] );
- }
-
- # Provide a mechanism for extensions to hook in.
- $collationObject = null;
- Hooks::run( 'Collation::factory', [
$collationName, &$collationObject ] );
-
- if ( $collationObject instanceof Collation ) {
- return $collationObject;
- }
-
- // If all else fails...
- throw new MWException( __METHOD__ . ": unknown
collation type \"$collationName\"" );
- }
- }
-
- /**
- * Given a string, convert it to a (hopefully short) key that can be
used
- * for efficient sorting. A binary sort according to the sortkeys
- * corresponds to a logical sort of the corresponding strings. Current
- * code expects that a line feed character should sort before all
others, but
- * has no other particular expectations (and that one can be changed if
- * necessary).
- *
- * @param string $string UTF-8 string
- * @return string Binary sortkey
- */
- abstract function getSortKey( $string );
-
- /**
- * Given a string, return the logical "first letter" to be used for
- * grouping on category pages and so on. This has to be coordinated
- * carefully with convertToSortkey(), or else the sorted list might jump
- * back and forth between the same "initial letters" or other
pathological
- * behavior. For instance, if you just return the first character, but
"a"
- * sorts the same as "A" based on getSortKey(), then you might get a
- * list like
- *
- * == A ==
- * * [[Aardvark]]
- *
- * == a ==
- * * [[antelope]]
- *
- * == A ==
- * * [[Ape]]
- *
- * etc., assuming for the sake of argument that $wgCapitalLinks is
false.
- *
- * @param string $string UTF-8 string
- * @return string UTF-8 string corresponding to the first letter of
input
- */
- abstract function getFirstLetter( $string );
-}
-
-class UppercaseCollation extends Collation {
- private $lang;
-
- function __construct() {
- // Get a language object so that we can use the generic UTF-8
uppercase
- // function there
- $this->lang = Language::factory( 'en' );
- }
-
- function getSortKey( $string ) {
- return $this->lang->uc( $string );
- }
-
- function getFirstLetter( $string ) {
- if ( $string[0] == "\0" ) {
- $string = substr( $string, 1 );
- }
- return $this->lang->ucfirst( $this->lang->firstChar( $string )
);
- }
-}
-
-/**
- * Collation class that's essentially a no-op.
- *
- * Does sorting based on binary value of the string.
- * Like how things were pre 1.17.
- */
-class IdentityCollation extends Collation {
-
- function getSortKey( $string ) {
- return $string;
- }
-
- function getFirstLetter( $string ) {
- global $wgContLang;
- // Copied from UppercaseCollation.
- // I'm kind of unclear on when this could happen...
- if ( $string[0] == "\0" ) {
- $string = substr( $string, 1 );
- }
- return $wgContLang->firstChar( $string );
- }
-}
class IcuCollation extends Collation {
const FIRST_LETTER_VERSION = 2;
@@ -296,7 +161,7 @@
const RECORD_LENGTH = 14;
- function __construct( $locale ) {
+ public function __construct( $locale ) {
if ( !extension_loaded( 'intl' ) ) {
throw new MWException( 'An ICU collation was requested,
' .
'but the intl extension is not available.' );
@@ -316,7 +181,7 @@
$this->primaryCollator->setStrength( Collator::PRIMARY );
}
- function getSortKey( $string ) {
+ public function getSortKey( $string ) {
// intl extension produces non null-terminated
// strings. Appending '' fixes it so that it doesn't generate
// a warning on each access in debug php.
@@ -326,14 +191,14 @@
return $key;
}
- function getPrimarySortKey( $string ) {
+ public function getPrimarySortKey( $string ) {
MediaWiki\suppressWarnings();
$key = $this->primaryCollator->getSortKey( $string ) . '';
MediaWiki\restoreWarnings();
return $key;
}
- function getFirstLetter( $string ) {
+ public function getFirstLetter( $string ) {
$string = strval( $string );
if ( $string === '' ) {
return '';
@@ -361,7 +226,7 @@
return $this->getLetterByIndex( $min );
}
- function getFirstLetterData() {
+ public function getFirstLetterData() {
if ( $this->firstLetterData !== null ) {
return $this->firstLetterData;
}
@@ -512,21 +377,21 @@
return $data;
}
- function getLetterByIndex( $index ) {
+ public function getLetterByIndex( $index ) {
if ( $this->firstLetterData === null ) {
$this->getFirstLetterData();
}
return $this->firstLetterData['chars'][$index];
}
- function getSortKeyByLetterIndex( $index ) {
+ public function getSortKeyByLetterIndex( $index ) {
if ( $this->firstLetterData === null ) {
$this->getFirstLetterData();
}
return $this->firstLetterData['keys'][$index];
}
- function getFirstLetterCount() {
+ public function getFirstLetterCount() {
if ( $this->firstLetterData === null ) {
$this->getFirstLetterData();
}
@@ -591,58 +456,5 @@
} else {
return false;
}
- }
-}
-
-/**
- * Workaround for the lack of support of Sorani Kurdish / Central Kurdish
language ('ckb') in ICU.
- *
- * Uses the same collation rules as Persian / Farsi ('fa'), but different
characters for digits.
- */
-class CollationCkb extends IcuCollation {
- function __construct() {
- // This will set $locale and collators, which affect the actual
sorting order
- parent::__construct( 'fa' );
- // Override the 'fa' language set by parent constructor, which
affects #getFirstLetterData()
- $this->digitTransformLanguage = Language::factory( 'ckb' );
- }
-}
-
-/**
- * Workaround for incorrect collation of Estonian language ('et') in ICU (bug
54168).
- *
- * 'W' and 'V' should not be considered the same letter for the purposes of
collation in modern
- * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21
'LATIN LETTER SMALL
- * CAPITAL W' for sortkey generation, which is collated like 'W' and is not
tailored to have the
- * same primary weight as 'V' in Estonian.
- */
-class CollationEt extends IcuCollation {
- function __construct() {
- parent::__construct( 'et' );
- }
-
- private static function mangle( $string ) {
- return str_replace(
- [ 'w', 'W' ],
- 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
- $string
- );
- }
-
- private static function unmangle( $string ) {
- // Casing data is lost…
- return str_replace(
- 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
- 'W',
- $string
- );
- }
-
- function getSortKey( $string ) {
- return parent::getSortKey( self::mangle( $string ) );
- }
-
- function getFirstLetter( $string ) {
- return self::unmangle( parent::getFirstLetter( self::mangle(
$string ) ) );
}
}
diff --git a/includes/collation/IdentityCollation.php
b/includes/collation/IdentityCollation.php
new file mode 100644
index 0000000..9a99f1a
--- /dev/null
+++ b/includes/collation/IdentityCollation.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Collation class that's essentially a no-op.
+ *
+ * Does sorting based on binary value of the string.
+ * Like how things were pre 1.17.
+ */
+class IdentityCollation extends Collation {
+
+ public function getSortKey( $string ) {
+ return $string;
+ }
+
+ public function getFirstLetter( $string ) {
+ global $wgContLang;
+ // Copied from UppercaseCollation.
+ // I'm kind of unclear on when this could happen...
+ if ( $string[0] == "\0" ) {
+ $string = substr( $string, 1 );
+ }
+ return $wgContLang->firstChar( $string );
+ }
+}
diff --git a/includes/collation/UppercaseCollation.php
b/includes/collation/UppercaseCollation.php
new file mode 100644
index 0000000..c589a76
--- /dev/null
+++ b/includes/collation/UppercaseCollation.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class UppercaseCollation extends Collation {
+
+ private $lang;
+
+ public function __construct() {
+ // Get a language object so that we can use the generic UTF-8
uppercase
+ // function there
+ $this->lang = Language::factory( 'en' );
+ }
+
+ public function getSortKey( $string ) {
+ return $this->lang->uc( $string );
+ }
+
+ public function getFirstLetter( $string ) {
+ if ( $string[0] == "\0" ) {
+ $string = substr( $string, 1 );
+ }
+ return $this->lang->ucfirst( $this->lang->firstChar( $string )
);
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/281261
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6abfecf91cdce83dd34b1e8aa8e0b35315f62742
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Addshore <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits