Merge "docs: Fix typo"
[mediawiki.git] / includes / collation / CollationFactory.php
blob2340e2fd607b26a3a0700e59129f948f7c93a1fa
1 <?php
3 /**
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * http://www.gnu.org/copyleft/gpl.html
19 * @file
22 namespace MediaWiki\Collation;
24 use Collation;
25 use InvalidArgumentException;
26 use MediaWiki\Config\ServiceOptions;
27 use MediaWiki\HookContainer\HookContainer;
28 use MediaWiki\HookContainer\HookRunner;
29 use MediaWiki\MainConfigNames;
30 use Wikimedia\ObjectFactory\ObjectFactory;
32 /**
33 * Common factory to construct collation classes.
35 * @since 1.37
37 class CollationFactory {
38 /**
39 * @internal For use by ServiceWiring
41 public const CONSTRUCTOR_OPTIONS = [
42 MainConfigNames::CategoryCollation,
45 private const CORE_COLLATIONS = [
46 'uppercase' => [
47 'class' => \UppercaseCollation::class,
48 'services' => [
49 'LanguageFactory',
52 'numeric' => [
53 'class' => \NumericUppercaseCollation::class,
54 'services' => [
55 'LanguageFactory',
56 'ContentLanguage',
59 'identity' => [
60 'class' => \IdentityCollation::class,
61 'services' => [
62 'ContentLanguage',
65 'uca-default' => [
66 'class' => \IcuCollation::class,
67 'services' => [
68 'LanguageFactory',
70 'args' => [
71 'root',
74 'uca-default-u-kn' => [
75 'class' => \IcuCollation::class,
76 'services' => [
77 'LanguageFactory',
79 'args' => [
80 'root-u-kn',
83 'xx-uca-ckb' => [
84 'class' => \CollationCkb::class,
85 'services' => [
86 'LanguageFactory',
89 'uppercase-ab' => [
90 'class' => \AbkhazUppercaseCollation::class,
91 'services' => [
92 'LanguageFactory',
95 'uppercase-ba' => [
96 'class' => \BashkirUppercaseCollation::class,
97 'services' => [
98 'LanguageFactory',
103 /** @var ServiceOptions */
104 private $options;
106 /** @var ObjectFactory */
107 private $objectFactory;
109 /** @var HookRunner */
110 private $hookRunner;
113 * @param ServiceOptions $options
114 * @param ObjectFactory $objectFactory
115 * @param HookContainer $hookContainer
117 public function __construct(
118 ServiceOptions $options,
119 ObjectFactory $objectFactory,
120 HookContainer $hookContainer
122 $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
123 $this->options = $options;
124 $this->objectFactory = $objectFactory;
125 $this->hookRunner = new HookRunner( $hookContainer );
128 public function getCategoryCollation(): Collation {
129 return $this->makeCollation( $this->getDefaultCollationName() );
132 public function getDefaultCollationName(): string {
133 return $this->options->get( MainConfigNames::CategoryCollation );
136 public function makeCollation( string $collationName ): Collation {
137 if ( isset( self::CORE_COLLATIONS[$collationName] ) ) {
138 return $this->instantiateCollation( self::CORE_COLLATIONS[$collationName] );
141 if ( preg_match( '/^uca-([A-Za-z@=-]+)$/', $collationName, $match ) ) {
142 return $this->instantiateCollation( [
143 'class' => \IcuCollation::class,
144 'services' => [
145 'LanguageFactory',
147 'args' => [
148 $match[1],
150 ] );
151 } elseif ( preg_match( '/^remote-uca-([A-Za-z@=-]+)$/', $collationName, $match ) ) {
152 return $this->instantiateCollation( [
153 'class' => \RemoteIcuCollation::class,
154 'services' => [
155 'ShellboxClientFactory'
157 'args' => [
158 $match[1]
160 ] );
163 // Provide a mechanism for extensions to hook in.
164 $collationObject = null;
165 $this->hookRunner->onCollation__factory( $collationName, $collationObject );
167 if ( !$collationObject instanceof Collation ) {
168 throw new InvalidArgumentException( __METHOD__ . ": unknown collation type \"$collationName\"" );
171 return $collationObject;
175 * @param array $spec
176 * @return Collation
178 private function instantiateCollation( $spec ): Collation {
179 return $this->objectFactory->createObject(
180 $spec,
182 'assertClass' => Collation::class