Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.65% covered (success)
95.65%
22 / 23
88.89% covered (warning)
88.89%
8 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Provider
95.65% covered (success)
95.65%
22 / 23
88.89% covered (warning)
88.89%
8 / 9
15
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageCode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSpecMap
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSpecArgs
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
7
 getBidiProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFormalityIndexProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGrammarTransformationsProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageFallbacksProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPluralProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace Wikimedia\Leximorph;
8
9use CLDRPluralRuleParser\Evaluator;
10use Psr\Log\LoggerInterface;
11use Wikimedia\Leximorph\Provider\FormalityIndex;
12use Wikimedia\Leximorph\Provider\GrammarTransformations;
13use Wikimedia\Leximorph\Provider\LanguageFallbacks;
14use Wikimedia\Leximorph\Provider\PluralRules;
15use Wikimedia\Leximorph\Provider\TextDirection;
16use Wikimedia\Leximorph\Traits\SpecBasedFactoryTrait;
17use Wikimedia\Leximorph\Util\JsonLoader;
18use Wikimedia\Leximorph\Util\XmlLoader;
19
20/**
21 * Provider
22 *
23 * This class is responsible for instantiating Leximorph provider objects
24 * (Index, GrammarTransformations, LanguageFallbacks, and PluralRules)
25 * using Wikimedia’s ObjectFactory. The Provider holds a default language code
26 * that is injected into language-specific providers.
27 *
28 * Usage Example:
29 * <code>
30 *            $provider = new Provider( 'en', $logger );
31 *            $plural = $provider->getPluralProvider();
32 * </code>
33 *
34 * @newable
35 * @since     1.45
36 * @author    Doğu Abaris (abaris@null.net)
37 * @license   https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
38 */
39final class Provider {
40
41    use SpecBasedFactoryTrait;
42
43    /**
44     * Provider specifications.
45     *
46     * Each entry defines:
47     * - args: Default constructor arguments.
48     * - langDependent: Prepend the language code.
49     * - needsEvaluator: Inject a CLDR Evaluator instance.
50     * - needsLogger: Pass a logger instance.
51     * - needsJsonLoader: Inject a JsonLoader instance.
52     * - needsXmlLoader: Inject an XmlLoader instance.
53     * - needsSelf: Inject this Provider instance.
54     *
55     * @var array<class-string, array<string, mixed>>
56     */
57    private const array PROVIDER_SPECS = [
58        TextDirection::class => [
59            'args' => [],
60        ],
61        FormalityIndex::class => [
62            'args' => [],
63            'langDependent' => true,
64            'needsLogger' => true,
65            'needsJsonLoader' => true,
66        ],
67        GrammarTransformations::class => [
68            'args' => [],
69            'langDependent' => true,
70            'needsJsonLoader' => true,
71        ],
72        LanguageFallbacks::class => [
73            'args' => [],
74            'langDependent' => true,
75            'needsLogger' => true,
76            'needsJsonLoader' => true,
77        ],
78        PluralRules::class => [
79            'args' => [],
80            'langDependent' => true,
81            'needsEvaluator' => true,
82            'needsSelf' => true,
83            'needsLogger' => true,
84            'needsXmlLoader' => true,
85        ],
86    ];
87
88    /**
89     * Initializes a new Provider instance with a default language code and a logger.
90     *
91     * @param string $langCode The default language code to use.
92     * @param ?LoggerInterface $logger Optional logger; defaults to a NullLogger.
93     *
94     * @since 1.45
95     */
96    public function __construct( string $langCode, ?LoggerInterface $logger = null ) {
97        $this->langCode = $langCode;
98        $this->logger = $logger;
99    }
100
101    /**
102     * Get the current language code.
103     *
104     * @since 1.45
105     */
106    public function getLanguageCode(): string {
107        return $this->langCode;
108    }
109
110    /**
111     * Get the handler spec map.
112     *
113     * Returns an array of handler specs indexed by class name.
114     *
115     * @since 1.45
116     * @return array<class-string, array<string,mixed>>
117     */
118    protected function getSpecMap(): array {
119        return self::PROVIDER_SPECS;
120    }
121
122    /**
123     * @param array<string,mixed> $spec
124     *
125     * @since 1.45
126     * @return array<int,mixed>
127     */
128    protected function getSpecArgs( array $spec, LoggerInterface $logger ): array {
129        $args = [];
130        if ( $spec['langDependent'] ?? false ) {
131            $args[] = $this->langCode;
132        }
133        if ( $spec['needsEvaluator'] ?? false ) {
134            $args[] = new Evaluator();
135        }
136        if ( $spec['needsSelf'] ?? false ) {
137            $args[] = $this;
138        }
139        if ( $spec['needsLogger'] ?? false ) {
140            $args[] = $logger;
141        }
142        if ( $spec['needsJsonLoader'] ?? false ) {
143            $args[] = new JsonLoader( $logger );
144        }
145        if ( $spec['needsXmlLoader'] ?? false ) {
146            $args[] = new XmlLoader( $logger );
147        }
148
149        return $args;
150    }
151
152    /**
153     * @since 1.45
154     */
155    public function getBidiProvider(): TextDirection {
156        return $this->createFromSpec( TextDirection::class );
157    }
158
159    /**
160     * @since 1.45
161     */
162    public function getFormalityIndexProvider(): FormalityIndex {
163        return $this->createFromSpec( FormalityIndex::class );
164    }
165
166    /**
167     * @since 1.45
168     */
169    public function getGrammarTransformationsProvider(): GrammarTransformations {
170        return $this->createFromSpec( GrammarTransformations::class );
171    }
172
173    /**
174     * @since 1.45
175     */
176    public function getLanguageFallbacksProvider(): LanguageFallbacks {
177        return $this->createFromSpec( LanguageFallbacks::class );
178    }
179
180    /**
181     * @since 1.45
182     */
183    public function getPluralProvider(): PluralRules {
184        return $this->createFromSpec( PluralRules::class );
185    }
186}