4
4
5
5
namespace Bakame \Laravel \Intl ;
6
6
7
+ use Bakame \Laravel \Intl \Options \DateType ;
8
+ use Bakame \Laravel \Intl \Options \NumberAttribute ;
9
+ use Bakame \Laravel \Intl \Options \NumberStyle ;
10
+ use Bakame \Laravel \Intl \Options \NumberType ;
11
+ use Bakame \Laravel \Intl \Options \TimeType ;
7
12
use DateTimeInterface ;
8
13
use DateTimeZone ;
9
14
use Exception ;
19
24
20
25
final class Formatter
21
26
{
22
- private const DATE_FORMATS = [
23
- 'none ' => IntlDateFormatter::NONE ,
24
- 'short ' => IntlDateFormatter::SHORT ,
25
- 'medium ' => IntlDateFormatter::MEDIUM ,
26
- 'long ' => IntlDateFormatter::LONG ,
27
- 'full ' => IntlDateFormatter::FULL ,
28
- ];
29
-
30
- private const NUMBER_TYPES = [
31
- 'default ' => NumberFormatter::TYPE_DEFAULT ,
32
- 'int32 ' => NumberFormatter::TYPE_INT32 ,
33
- 'int64 ' => NumberFormatter::TYPE_INT64 ,
34
- 'double ' => NumberFormatter::TYPE_DOUBLE ,
35
- 'currency ' => NumberFormatter::TYPE_CURRENCY ,
36
- ];
37
-
38
- private const NUMBER_STYLES = [
39
- 'decimal ' => NumberFormatter::DECIMAL ,
40
- 'currency ' => NumberFormatter::CURRENCY ,
41
- 'percent ' => NumberFormatter::PERCENT ,
42
- 'scientific ' => NumberFormatter::SCIENTIFIC ,
43
- 'spellout ' => NumberFormatter::SPELLOUT ,
44
- 'ordinal ' => NumberFormatter::ORDINAL ,
45
- 'duration ' => NumberFormatter::DURATION ,
46
- ];
47
-
48
- private const NUMBER_ATTRIBUTES = [
49
- 'grouping_used ' => NumberFormatter::GROUPING_USED ,
50
- 'decimal_always_shown ' => NumberFormatter::DECIMAL_ALWAYS_SHOWN ,
51
- 'max_integer_digit ' => NumberFormatter::MAX_INTEGER_DIGITS ,
52
- 'min_integer_digit ' => NumberFormatter::MIN_INTEGER_DIGITS ,
53
- 'integer_digit ' => NumberFormatter::INTEGER_DIGITS ,
54
- 'max_fraction_digit ' => NumberFormatter::MAX_FRACTION_DIGITS ,
55
- 'min_fraction_digit ' => NumberFormatter::MIN_FRACTION_DIGITS ,
56
- 'fraction_digit ' => NumberFormatter::FRACTION_DIGITS ,
57
- 'multiplier ' => NumberFormatter::MULTIPLIER ,
58
- 'grouping_size ' => NumberFormatter::GROUPING_SIZE ,
59
- 'rounding_mode ' => NumberFormatter::ROUNDING_MODE ,
60
- 'rounding_increment ' => NumberFormatter::ROUNDING_INCREMENT ,
61
- 'format_width ' => NumberFormatter::FORMAT_WIDTH ,
62
- 'padding_position ' => NumberFormatter::PADDING_POSITION ,
63
- 'secondary_grouping_size ' => NumberFormatter::SECONDARY_GROUPING_SIZE ,
64
- 'significant_digits_used ' => NumberFormatter::SIGNIFICANT_DIGITS_USED ,
65
- 'min_significant_digits_used ' => NumberFormatter::MIN_SIGNIFICANT_DIGITS ,
66
- 'max_significant_digits_used ' => NumberFormatter::MAX_SIGNIFICANT_DIGITS ,
67
- 'lenient_parse ' => NumberFormatter::LENIENT_PARSE ,
68
- ];
69
-
70
- private const NUMBER_ROUNDING_ATTRIBUTES = [
71
- 'ceiling ' => NumberFormatter::ROUND_CEILING ,
72
- 'floor ' => NumberFormatter::ROUND_FLOOR ,
73
- 'down ' => NumberFormatter::ROUND_DOWN ,
74
- 'up ' => NumberFormatter::ROUND_UP ,
75
- 'halfeven ' => NumberFormatter::ROUND_HALFEVEN ,
76
- 'halfdown ' => NumberFormatter::ROUND_HALFDOWN ,
77
- 'halfup ' => NumberFormatter::ROUND_HALFUP ,
78
- ];
79
-
80
- private const NUMBER_PADDING_ATTRIBUTES = [
81
- 'before_prefix ' => NumberFormatter::PAD_BEFORE_PREFIX ,
82
- 'after_prefix ' => NumberFormatter::PAD_AFTER_PREFIX ,
83
- 'before_suffix ' => NumberFormatter::PAD_BEFORE_SUFFIX ,
84
- 'after_suffix ' => NumberFormatter::PAD_AFTER_SUFFIX ,
85
- ];
86
-
87
27
private Configuration $ configuration ;
88
28
private DateResolver $ dateResolver ;
89
29
/** @var array<IntlDateFormatter> */
@@ -193,7 +133,7 @@ public function getCountryTimezones(string $country): array
193
133
*/
194
134
public function formatCurrency ($ amount , string $ currency , array $ attrs = [], string $ locale = null ): string
195
135
{
196
- $ formatter = $ this ->createNumberFormatter ($ locale , 'currency ' , $ attrs );
136
+ $ formatter = $ this ->createNumberFormatter ($ locale , NumberStyle:: fromName ( 'currency ' ) , $ attrs );
197
137
if (false === $ ret = $ formatter ->formatCurrency ($ amount , $ currency )) {
198
138
// @codeCoverageIgnoreStart
199
139
throw FailedFormatting::dueToNumberFormatter ('Unable to format the given number as a currency. ' );
@@ -214,15 +154,9 @@ public function formatNumber(
214
154
string $ type = 'default ' ,
215
155
string $ locale = null
216
156
): string {
217
- if (!isset (self ::NUMBER_TYPES [$ type ])) {
218
- throw FailedFormatting::dueToUnknownNumberType ($ type , self ::NUMBER_TYPES );
219
- }
220
-
221
- /** @var string $style */
222
- $ style = $ style ?? array_search ($ this ->configuration ->style , self ::NUMBER_STYLES , true );
223
-
157
+ $ style = null === $ style ? $ this ->configuration ->style : NumberStyle::fromName ($ style );
224
158
$ formatter = $ this ->createNumberFormatter ($ locale , $ style , $ attrs );
225
- if (false === $ ret = $ formatter ->format ($ number , self :: NUMBER_TYPES [ $ type] )) {
159
+ if (false === $ ret = $ formatter ->format ($ number , NumberType:: fromName ( $ type)-> value )) {
226
160
// @codeCoverageIgnoreStart
227
161
throw FailedFormatting::dueToNumberFormatter ('Unable to format the given number. ' );
228
162
// @codeCoverageIgnoreEnd
@@ -300,23 +234,15 @@ private function createDateFormatter(
300
234
DateTimeZone $ timezone ,
301
235
string $ calendar
302
236
): IntlDateFormatter {
303
- if (null !== $ dateFormat && !isset (self ::DATE_FORMATS [$ dateFormat ])) {
304
- throw FailedFormatting::dueToUnknownDateFormat ($ dateFormat , self ::DATE_FORMATS );
305
- }
306
-
307
- if (null !== $ timeFormat && !isset (self ::DATE_FORMATS [$ timeFormat ])) {
308
- throw FailedFormatting::dueToUnknownTimeFormat ($ timeFormat , self ::DATE_FORMATS );
309
- }
310
-
237
+ $ dateType = null !== $ dateFormat ? DateType::fromName ($ dateFormat ) : $ this ->configuration ->dateType ;
238
+ $ timeType = null !== $ timeFormat ? TimeType::fromName ($ timeFormat ) : $ this ->configuration ->timeType ;
311
239
$ locale = $ locale ?? Locale::getDefault ();
312
240
$ calendar = 'gregorian ' === strtolower ($ calendar ) ? IntlDateFormatter::GREGORIAN : IntlDateFormatter::TRADITIONAL ;
313
- $ dateFormatValue = self ::DATE_FORMATS [$ dateFormat ] ?? $ this ->configuration ->dateType ;
314
- $ timeFormatValue = self ::DATE_FORMATS [$ timeFormat ] ?? $ this ->configuration ->timeType ;
315
241
$ pattern = $ pattern ?? $ this ->configuration ->datePattern ;
316
242
317
- $ hash = $ locale .'| ' .$ dateFormatValue .'| ' .$ timeFormatValue .'| ' .$ timezone ->getName ().'| ' .$ calendar .'| ' .$ pattern ;
243
+ $ hash = $ locale .'| ' .$ dateType -> value .'| ' .$ timeType -> value .'| ' .$ timezone ->getName ().'| ' .$ calendar .'| ' .$ pattern ;
318
244
if (!isset ($ this ->dateFormatters [$ hash ])) {
319
- $ dateFormatter = new IntlDateFormatter ($ locale , $ dateFormatValue , $ timeFormatValue , $ timezone , $ calendar );
245
+ $ dateFormatter = new IntlDateFormatter ($ locale , $ dateType -> value , $ timeType -> value , $ timezone , $ calendar );
320
246
if (null !== $ pattern ) {
321
247
$ dateFormatter ->setPattern ($ pattern );
322
248
}
@@ -329,18 +255,14 @@ private function createDateFormatter(
329
255
/**
330
256
* @param array<string, string|float|int> $attrs
331
257
*/
332
- private function createNumberFormatter (?string $ locale , string $ style , array $ attrs = []): NumberFormatter
258
+ private function createNumberFormatter (?string $ locale , NumberStyle $ style , array $ attrs = []): NumberFormatter
333
259
{
334
- if (!isset (self ::NUMBER_STYLES [$ style ])) {
335
- throw FailedFormatting::dueToUnknownStyle ($ style , self ::NUMBER_STYLES );
336
- }
337
-
338
260
$ locale = $ locale ?? Locale::getDefault ();
339
261
340
262
ksort ($ attrs );
341
- $ hash = $ locale .'| ' .$ style .'| ' .json_encode ($ attrs );
263
+ $ hash = $ locale .'| ' .$ style-> value .'| ' .json_encode ($ attrs );
342
264
if (!isset ($ this ->numberFormatters [$ hash ])) {
343
- $ newNumberFormatter = new NumberFormatter ($ locale , self :: NUMBER_STYLES [ $ style] );
265
+ $ newNumberFormatter = new NumberFormatter ($ locale , $ style-> value );
344
266
$ this ->addDefaultAttributes ($ newNumberFormatter );
345
267
$ this ->setNumberFormatterAttributes ($ newNumberFormatter , $ attrs );
346
268
$ this ->numberFormatters [$ hash ] = $ newNumberFormatter ;
@@ -355,29 +277,7 @@ private function createNumberFormatter(?string $locale, string $style, array $at
355
277
private function setNumberFormatterAttributes (NumberFormatter $ numberFormatter , array $ attrs ): void
356
278
{
357
279
foreach ($ attrs as $ name => $ value ) {
358
- if (!isset (self ::NUMBER_ATTRIBUTES [$ name ])) {
359
- throw FailedFormatting::dueToUnknownNumberFormatterAttributeName ($ name , self ::NUMBER_ATTRIBUTES );
360
- }
361
-
362
- if ('rounding_mode ' === $ name ) {
363
- if (!isset (self ::NUMBER_ROUNDING_ATTRIBUTES [$ value ])) {
364
- throw FailedFormatting::dueToUnknownNumberFormatterRoundingMode ($ value , self ::NUMBER_ROUNDING_ATTRIBUTES );
365
- }
366
-
367
- $ value = self ::NUMBER_ROUNDING_ATTRIBUTES [$ value ];
368
- } elseif ('padding_position ' === $ name ) {
369
- if (!isset (self ::NUMBER_PADDING_ATTRIBUTES [$ value ])) {
370
- throw FailedFormatting::dueToUnknownNumberFormatterPaddingPosition ($ value , self ::NUMBER_PADDING_ATTRIBUTES );
371
- }
372
-
373
- $ value = self ::NUMBER_PADDING_ATTRIBUTES [$ value ];
374
- }
375
-
376
- if (is_string ($ value )) {
377
- throw FailedFormatting::dueToInvalidNumberFormatterAttributeValue ($ name , $ value );
378
- }
379
-
380
- $ numberFormatter ->setAttribute (self ::NUMBER_ATTRIBUTES [$ name ], $ value );
280
+ NumberAttribute::from ($ name , $ value )->addTo ($ numberFormatter );
381
281
}
382
282
}
383
283
0 commit comments