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    /**
24     * Path to formal indexes JSON file.
25     */
26    private const FORMALITY_INDEXES_PATH = __DIR__ . '/../data/formal-indexes.json';
27
28    /**
29     * Cached formality indexes.
30     *
31     * @var array<string, int>|null
32     */
33    private static ?array $indexesCache = null;
34
35    /**
36     * Initializes the FormalityIndex.
37     *
38     * @param string $langCode The language code.
39     * @param LoggerInterface $logger The logger instance to use.
40     * @param JsonLoader $jsonLoader The json loader to load data
41     *
42     * @since 1.45
43     */
44    public function __construct(
45        private readonly string $langCode,
46        private readonly LoggerInterface $logger,
47        private readonly JsonLoader $jsonLoader,
48    ) {
49    }
50
51    /**
52     * Returns the formality index number for the given language code.
53     *
54     * If no entry is found or the entry is not a simple integer,
55     * we default to 0 (informal).
56     *
57     * @since 1.45
58     * @return int The formality index (1 for formal, 0 for informal).
59     */
60    public function getFormalityIndex(): int {
61        self::$indexesCache ??= $this->loadIndexes();
62        $indexesCache = self::$indexesCache;
63
64        if ( array_key_exists( $this->langCode, $indexesCache ) ) {
65            return $indexesCache[$this->langCode];
66        }
67
68        if ( str_contains( $this->langCode, '-' ) ) {
69            $parts = explode( '-', $this->langCode );
70            $suffix = array_pop( $parts );
71            if ( $suffix === 'formal' ) {
72                return 1;
73            } elseif ( $suffix === 'informal' ) {
74                return 0;
75            }
76
77            return $indexesCache[implode( '-', $parts )] ?? 0;
78        }
79
80        return 0;
81    }
82
83    /**
84     * Loads formal indexes from JSON.
85     *
86     * @since 1.45
87     * @return array<string, int> An associative array mapping language codes to formality indexes.
88     */
89    private function loadIndexes(): array {
90        $rawIndexes = $this->jsonLoader->load( self::FORMALITY_INDEXES_PATH, 'formality indexes' );
91        $indexes = [];
92
93        foreach ( $rawIndexes as $key => $value ) {
94            if ( is_string( $key ) && is_int( $value ) ) {
95                $indexes[$key] = $value;
96            } else {
97                $this->logger->error(
98                    'Invalid formality index entry. Expected string key and int value. ' .
99                    'Got key type {keyType}, value type {valueType}.',
100                    [
101                        'keyType' => gettype( $key ),
102                        'valueType' => gettype( $value ),
103                    ]
104                );
105            }
106        }
107
108        return $indexes;
109    }
110}