Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
46.43% covered (danger)
46.43%
13 / 28
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
FormalityIndex
46.43% covered (danger)
46.43%
13 / 28
33.33% covered (danger)
33.33%
1 / 3
25.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFormalityIndex
92.31% covered (success)
92.31%
12 / 13
0.00% covered (danger)
0.00%
0 / 1
5.01
 loadIndexes
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace Wikimedia\Leximorph\Provider;
8
9use Psr\Log\LoggerInterface;
10use Wikimedia\Leximorph\Util\JsonLoader;
11
12/**
13 * FormalityIndex
14 *
15 * Loads and caches formality indexes from a JSON file.
16 *
17 * @since     1.45
18 * @author    Doğu Abaris (abaris@null.net)
19 * @license   https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
20 */
21class FormalityIndex {
22
23    private const string FORMALITY_INDEXES_PATH = __DIR__ . '/../data/formal-indexes.json';
24
25    /**
26     * @var array<string, int>|null
27     */
28    private static ?array $indexesCache = null;
29
30    /**
31     * @since 1.45
32     */
33    public function __construct(
34        private readonly string $langCode,
35        private readonly LoggerInterface $logger,
36        private readonly JsonLoader $jsonLoader,
37    ) {
38    }
39
40    /**
41     * Returns the formality index number for the given language code.
42     *
43     * If no entry is found or the entry is not a simple integer,
44     * we default to 0 (informal).
45     *
46     * @since 1.45
47     * @return int The formality index (1 for formal, 0 for informal).
48     */
49    public function getFormalityIndex(): int {
50        self::$indexesCache ??= $this->loadIndexes();
51        $indexesCache = self::$indexesCache;
52
53        if ( array_key_exists( $this->langCode, $indexesCache ) ) {
54            return $indexesCache[$this->langCode];
55        }
56
57        if ( str_contains( $this->langCode, '-' ) ) {
58            $parts = explode( '-', $this->langCode );
59            $suffix = array_pop( $parts );
60            if ( $suffix === 'formal' ) {
61                return 1;
62            } elseif ( $suffix === 'informal' ) {
63                return 0;
64            }
65
66            return $indexesCache[implode( '-', $parts )] ?? 0;
67        }
68
69        return 0;
70    }
71
72    /**
73     * Loads formal indexes from JSON.
74     *
75     * @since 1.45
76     * @return array<string, int> An associative array mapping language codes to formality indexes.
77     */
78    private function loadIndexes(): array {
79        $rawIndexes = $this->jsonLoader->load( self::FORMALITY_INDEXES_PATH, 'formality indexes' );
80        $indexes = [];
81
82        foreach ( $rawIndexes as $key => $value ) {
83            if ( is_string( $key ) && is_int( $value ) ) {
84                $indexes[$key] = $value;
85            } else {
86                $this->logger->error(
87                    'Invalid formality index entry. Expected string key and int value. ' .
88                    'Got key type {keyType}, value type {valueType}.',
89                    [
90                        'keyType' => gettype( $key ),
91                        'valueType' => gettype( $value ),
92                    ]
93                );
94            }
95        }
96
97        return $indexes;
98    }
99}