Repository::locale_for()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ICanBoogie\CLDR;
4
5
use ICanBoogie\Accessor\AccessorTrait;
6
use ICanBoogie\CLDR\Core\Locale;
7
use ICanBoogie\CLDR\Core\LocaleData;
8
use ICanBoogie\CLDR\Core\LocaleId;
9
use ICanBoogie\CLDR\General\Lists\ListFormatter;
10
use ICanBoogie\CLDR\General\Lists\ListPattern;
11
use ICanBoogie\CLDR\Numbers\CurrencyFormatter;
12
use ICanBoogie\CLDR\Numbers\NumberFormatter;
13
use ICanBoogie\CLDR\Numbers\NumberPattern;
14
use ICanBoogie\CLDR\Numbers\Symbols;
15
use ICanBoogie\CLDR\Provider\ResourceNotFound;
16
use ICanBoogie\CLDR\Supplemental\Plurals;
17
use ICanBoogie\CLDR\Supplemental\Supplemental;
18
use ICanBoogie\CLDR\Supplemental\Territory\Territory;
19
use ICanBoogie\CLDR\Supplemental\Territory\TerritoryCode;
20
21
use function array_shift;
22
use function explode;
23
24
/**
25
 * Representation of the CLDR.
26
 *
27
 * @property-read Supplemental $supplemental
28
 * @uses self::get_supplemental()
29
 * @property-read NumberFormatter $number_formatter
30
 * @uses self::get_number_formatter()
31
 * @property-read CurrencyFormatter $currency_formatter
32
 * @uses self::get_currency_formatter()
33
 * @property-read ListFormatter $list_formatter
34
 * @uses self::get_list_formatter()
35
 * @property-read Plurals $plurals
36
 * @uses self::get_plurals()
37
 *
38
 * @link https://github.com/unicode-org/cldr-json/tree/47.0.0
39
 */
40
final class Repository
41
{
42
    /**
43
     * @uses get_supplemental
44
     * @uses get_number_formatter
45
     * @uses get_currency_formatter
46
     * @uses get_list_formatter
47
     * @uses get_list_formatter
48
     * @uses get_plurals
49
     */
50
    use AccessorTrait;
51
52
    /**
53
     * @var array<string>
54
     */
55
    public array $available_locales;
56
57
    public function __construct(
58
        public readonly Provider $provider
59
    ) {
60
        $this->available_locales = LocaleData::AVAILABLE_LOCALES;
61
    }
62
63
    private Supplemental $supplemental;
64
65
    private function get_supplemental(): Supplemental
66
    {
67
        return $this->supplemental ??= new Supplemental($this);
68
    }
69
70
    private NumberFormatter $number_formatter;
71
72
    private function get_number_formatter(): NumberFormatter
73
    {
74
        return $this->number_formatter ??= new NumberFormatter();
75
    }
76
77
    private CurrencyFormatter $currency_formatter;
78
79
    private function get_currency_formatter(): CurrencyFormatter
0 ignored issues
show
Unused Code introduced by
The method get_currency_formatter() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
80
    {
81
        return $this->currency_formatter ??= new CurrencyFormatter($this->get_number_formatter());
82
    }
83
84
    private ListFormatter $list_formatter;
85
86
    private function get_list_formatter(): ListFormatter
0 ignored issues
show
Unused Code introduced by
The method get_list_formatter() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
87
    {
88
        return $this->list_formatter ??= new ListFormatter();
89
    }
90
91
    private Plurals $plurals;
92
93
    private function get_plurals(): Plurals
0 ignored issues
show
Unused Code introduced by
The method get_plurals() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
94
    {
95
        return $this->plurals ??= new Plurals($this->get_supplemental()['plurals']);
96
    }
97
98
    /**
99
     * Fetches the data available at the specified path.
100
     *
101
     * @param string|null $data_path Path to the data to extract.
102
     *
103
     * @throws ResourceNotFound
104
     *
105
     * @phpstan-ignore-next-line
106
     */
107
    public function fetch(string $path, ?string $data_path = null): array
108
    {
109
        $data = $this->provider->provide($path);
110
111
        if ($data_path) {
112
            $data_path = explode('/', $data_path);
113
114
            while ($data_path) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data_path of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
115
                $p = array_shift($data_path);
116
                $data = $data[$p];
117
            }
118
        }
119
120
        return $data;
121
    }
122
123
    /**
124
     * Format a number with the specified pattern.
125
     *
126
     * Note, if the pattern contains '%', the number will be multiplied by 100 first. If the
127
     * pattern contains '‰', the number will be multiplied by 1000.
128
     *
129
     * @param float|int|numeric-string $number
0 ignored issues
show
Documentation Bug introduced by
The doc comment float|int|numeric-string at position 4 could not be parsed: Unknown type name 'numeric-string' at position 4 in float|int|numeric-string.
Loading history...
130
     *     The number to format.
131
     * @param string|NumberPattern $pattern
132
     *     The pattern used to format the number.
133
     */
134
    public function format_number(
135
        float|int|string $number,
136
        NumberPattern|string $pattern,
137
        ?Symbols $symbols = null,
138
    ): string {
139
        return $this->number_formatter->format($number, $pattern, $symbols);
140
    }
141
142
    /**
143
     * Format a number with the specified pattern.
144
     *
145
     * @param float|int|numeric-string $number
0 ignored issues
show
Documentation Bug introduced by
The doc comment float|int|numeric-string at position 4 could not be parsed: Unknown type name 'numeric-string' at position 4 in float|int|numeric-string.
Loading history...
146
     *      The number to format.
147
     *
148
     * @see CurrencyFormatter::format()
149
     */
150
    public function format_currency(
151
        float|int|string $number,
152
        NumberPattern|string $pattern,
153
        ?Symbols $symbols = null,
154
        string $currencySymbol = CurrencyFormatter::DEFAULT_CURRENCY_SYMBOL
155
    ): string {
156
        return $this->currency_formatter->format($number, $pattern, $symbols, $currencySymbol);
157
    }
158
159
    /**
160
     * Formats variable-length lists of scalars.
161
     *
162
     * @param scalar[] $list
163
     *
164
     * @see ListFormatter::format()
165
     */
166
    public function format_list(array $list, ListPattern $list_pattern): string
167
    {
168
        return $this->list_formatter->format($list, $list_pattern);
169
    }
170
171
    /**
172
     * @param string|LocaleId $id
173
     *     A locale ID; for example, fr-BE.
174
     */
175
    public function locale_for(string|LocaleId $id): Locale
176
    {
177
        if (!$id instanceof LocaleId) {
178
            $id = LocaleId::of($id);
179
        }
180
181
        return new Locale($this, $id);
182
    }
183
184
    /**
185
     * @param string|TerritoryCode $code
186
     *     A territory code; for example, CA.
187
     */
188
    public function territory_for(string|TerritoryCode $code): Territory
189
    {
190
        if (!$code instanceof TerritoryCode) {
191
            $code = TerritoryCode::of($code);
192
        }
193
194
        return new Territory($this, $code);
195
    }
196
}
197