diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83ffe96..da8b1f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,8 @@
# Changelog
-All Notable changes to `bakame/laravel-intl-formatter` will be documented in this file
+All Notable changes to `bakame/intl-formatter` will be documented in this file
-## [0.1.0] - 2022-06-04
+## [0.1.0] - 2022-06-05
**Initial release!**
diff --git a/README.md b/README.md
index 3975a58..2441c94 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-Laravel Intl Formatter
+Intl Formatter
=======================================
[![Author](http://img.shields.io/badge/author-@nyamsprod-blue.svg?style=flat-square)](https://twitter.com/nyamsprod)
@@ -8,8 +8,8 @@ Laravel Intl Formatter
[![Total Downloads](https://img.shields.io/packagist/dt/bakame/intl-formatter.svg?style=flat-square)](https://packagist.org/packages/bakame/intl-formatter)
[![Sponsor development of this project](https://img.shields.io/badge/sponsor%20this%20package-%E2%9D%A4-ff69b4.svg?style=flat-square)](https://github.com/sponsors/nyamsprod)
-The package can be used in any Laravel based application to quickly handle internationalization
-by providing helper functions in Blade templates or Laravel codebase.
+The package can be used in any PHP application to quickly handle internationalization
+by providing classes to format locale, language, timezones, currency and dates.
System Requirements
-------
diff --git a/phpunit.xml b/phpunit.xml
index 1552064..efe6f4c 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -27,7 +27,7 @@
-
+
src
diff --git a/src/Configuration.php b/src/Configuration.php
index 02fa820..99a4612 100644
--- a/src/Configuration.php
+++ b/src/Configuration.php
@@ -5,7 +5,10 @@
namespace Bakame\Intl;
use Bakame\Intl\Options\DateType;
+use Bakame\Intl\Options\NumberAttribute;
use Bakame\Intl\Options\NumberStyle;
+use Bakame\Intl\Options\SymbolAttribute;
+use Bakame\Intl\Options\TextAttribute;
use Bakame\Intl\Options\TimeType;
final class Configuration
@@ -22,24 +25,24 @@ final class Configuration
public ?string $numberPattern;
/**
* @readonly
- * @var array
+ * @var array
*/
public array $attributes;
/**
* @readonly
- * @var array
+ * @var array
*/
public array $textAttributes;
/**
* @readonly
- * @var array
+ * @var array
*/
public array $symbolAttributes;
/**
- * @param array $attributes
- * @param array $textAttributes
- * @param array $symbolAttributes
+ * @param array $attributes
+ * @param array $textAttributes
+ * @param array $symbolAttributes
*/
public function __construct(
DateType $dateType,
@@ -64,16 +67,16 @@ public function __construct(
/**
* @param array{
* date:array{
- * dateType:int,
- * timeType:int,
+ * dateFormat:string,
+ * timeFormat:string,
* pattern?:?string
* },
* number:array{
- * style:int,
+ * style:string,
* pattern?:?string,
- * attributes?:array,
- * textAttributes?:array,
- * symbolAttributes?:array
+ * attributes?:array,
+ * textAttributes?:array,
+ * symbolAttributes?:array
* }
* } $settings
*/
@@ -100,14 +103,59 @@ public static function fromApplication(array $settings): self
}
return new self(
- DateType::from($settings['date']['dateType']),
- TimeType::from($settings['date']['timeType']),
- NumberStyle::from($settings['number']['style']),
+ DateType::fromName($settings['date']['dateFormat']),
+ TimeType::fromName($settings['date']['timeFormat']),
+ NumberStyle::fromName($settings['number']['style']),
$settings['date']['pattern'],
$settings['number']['pattern'],
- $settings['number']['attributes'],
- $settings['number']['textAttributes'],
- $settings['number']['symbolAttributes'],
+ self::filterNumberAttributes($settings['number']['attributes']),
+ self::filterTextAttributes($settings['number']['textAttributes']),
+ self::filterSymboAttributes($settings['number']['symbolAttributes']),
);
}
+
+ /**
+ * @param array $attributes
+ *
+ * @return array
+ */
+ private static function filterNumberAttributes(array $attributes): array
+ {
+ $res = [];
+ foreach ($attributes as $name => $value) {
+ $res[] = NumberAttribute::from($name, $value);
+ }
+
+ return $res;
+ }
+
+ /**
+ * @param array $attributes
+ *
+ * @return array
+ */
+ private static function filterTextAttributes(array $attributes): array
+ {
+ $res = [];
+ foreach ($attributes as $name => $value) {
+ $res[] = TextAttribute::from($name, $value);
+ }
+
+ return $res;
+ }
+
+ /**
+ * @param array $attributes
+ *
+ * @return array
+ */
+ private static function filterSymboAttributes(array $attributes): array
+ {
+ $res = [];
+ foreach ($attributes as $name => $value) {
+ $res[] = SymbolAttribute::from($name, $value);
+ }
+
+ return $res;
+ }
}
diff --git a/src/ConfigurationTest.php b/src/ConfigurationTest.php
new file mode 100644
index 0000000..c4fe332
--- /dev/null
+++ b/src/ConfigurationTest.php
@@ -0,0 +1,101 @@
+attributes);
+ self::assertSame(NumberFormatter::GROUPING_USED, $config->attributes[0]->name);
+ self::assertSame(2, $config->attributes[0]->value);
+ self::assertCount(0, $config->textAttributes);
+ self::assertCount(0, $config->symbolAttributes);
+ self::assertNull($config->datePattern);
+ self::assertEmpty($config->numberPattern);
+ self::assertSame(IntlDateFormatter::FULL, $config->dateType->value);
+ self::assertSame(IntlDateFormatter::SHORT, $config->timeType->value);
+ self::assertSame(NumberFormatter::CURRENCY, $config->style->value);
+ }
+
+ /** @test */
+ public function it_can_be_instantiated_with_only_required_properties_via_settings(): void
+ {
+ $config = Configuration::fromApplication([
+ 'date' => [
+ 'dateFormat' => 'full',
+ 'timeFormat' => 'short',
+ ],
+ 'number' => [
+ 'style' => 'currency',
+ ],
+ ]);
+
+ self::assertCount(0, $config->attributes);
+ self::assertCount(0, $config->textAttributes);
+ self::assertCount(0, $config->symbolAttributes);
+ self::assertNull($config->datePattern);
+ self::assertNull($config->numberPattern);
+ self::assertSame(IntlDateFormatter::FULL, $config->dateType->value);
+ self::assertSame(IntlDateFormatter::SHORT, $config->timeType->value);
+ self::assertSame(NumberFormatter::CURRENCY, $config->style->value);
+ }
+
+ /** @test */
+ public function it_fails_load_configuration_with_invalid_attribute_name(): void
+ {
+ $this->expectException(FailedFormatting::class);
+
+ Configuration::fromApplication([
+ 'date' => [
+ 'dateFormat' => 'full',
+ 'timeFormat' => 'short',
+ ],
+ 'number' => [
+ 'style' => 'currency',
+ 'attributes' => [
+ 'foobar' => 1,
+ ],
+ ],
+ ]);
+ }
+
+ /** @test */
+ public function it_fails_load_configuration_with_invalid_attribute_value(): void
+ {
+ $this->expectException(FailedFormatting::class);
+
+ Configuration::fromApplication([
+ 'date' => [
+ 'dateFormat' => 'full',
+ 'timeFormat' => 'short',
+ ],
+ 'number' => [
+ 'style' => 'currency',
+ 'attributes' => [
+ 'grouping_used' => '2',
+ ],
+ ],
+ ]);
+ }
+}
diff --git a/src/Formatter.php b/src/Formatter.php
index cf26ad8..99fefcb 100644
--- a/src/Formatter.php
+++ b/src/Formatter.php
@@ -283,16 +283,16 @@ private function setNumberFormatterAttributes(NumberFormatter $numberFormatter,
private function addDefaultAttributes(NumberFormatter $numberFormatter): void
{
- foreach ($this->configuration->attributes as $attribute => $value) {
- $numberFormatter->setAttribute($attribute, $value);
+ foreach ($this->configuration->attributes as $attribute) {
+ $attribute->addTo($numberFormatter);
}
- foreach ($this->configuration->textAttributes as $attribute => $value) {
- $numberFormatter->setTextAttribute($attribute, $value);
+ foreach ($this->configuration->textAttributes as $textAttribute) {
+ $textAttribute->addTo($numberFormatter);
}
- foreach ($this->configuration->symbolAttributes as $attribute => $value) {
- $numberFormatter->setSymbol($attribute, $value);
+ foreach ($this->configuration->symbolAttributes as $symbolAttribute) {
+ $symbolAttribute->addTo($numberFormatter);
}
if (null !== $this->configuration->numberPattern) {
diff --git a/src/FormatterTest.php b/src/FormatterTest.php
index d238049..ca065c4 100644
--- a/src/FormatterTest.php
+++ b/src/FormatterTest.php
@@ -7,8 +7,6 @@
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
-use IntlDateFormatter;
-use NumberFormatter;
use PHPUnit\Framework\TestCase;
/**
@@ -25,11 +23,11 @@ protected function setUp(): void
$this->formatter = new Formatter(
Configuration::fromApplication([
'date' => [
- 'dateType' => IntlDateFormatter::FULL,
- 'timeType' => IntlDateFormatter::FULL,
+ 'dateFormat' => 'full',
+ 'timeFormat' => 'full',
],
'number' => [
- 'style' => NumberFormatter::DECIMAL,
+ 'style' => 'decimal',
],
]),
SystemDateResolver::fromSystem()
@@ -41,14 +39,14 @@ public function it_can_be_instantiated_with_a_different_configuration(): void
{
$configuration = Configuration::fromApplication([
'date' => [
- 'dateType' => IntlDateFormatter::FULL,
- 'timeType' => IntlDateFormatter::FULL,
+ 'dateFormat' => 'full',
+ 'timeFormat' => 'full',
],
'number' => [
- 'style' => NumberFormatter::DECIMAL,
- 'attributes' => [NumberFormatter::FRACTION_DIGITS => 1],
- 'textAttributes' => [NumberFormatter::POSITIVE_PREFIX => '++'],
- 'symbolAttributes' => [NumberFormatter::DECIMAL_SEPARATOR_SYMBOL => 'x'],
+ 'style' => 'decimal',
+ 'attributes' => ['fraction_digit' => 1],
+ 'textAttributes' => ['positive_prefix' => '++'],
+ 'symbolAttributes' => ['decimal_separator' => 'x'],
],
]);
diff --git a/src/Options/DateType.php b/src/Options/DateType.php
index 4e1aa69..eda38eb 100644
--- a/src/Options/DateType.php
+++ b/src/Options/DateType.php
@@ -6,15 +6,34 @@
use IntlDateFormatter;
-final class DateType extends PseudoEnum
-{
- protected const CONSTANTS = [
- 'none' => IntlDateFormatter::NONE,
- 'short' => IntlDateFormatter::SHORT,
- 'medium' => IntlDateFormatter::MEDIUM,
- 'long' => IntlDateFormatter::LONG,
- 'full' => IntlDateFormatter::FULL,
- ];
+if (7 < PHP_MAJOR_VERSION && extension_loaded('intl')) {
+ final class DateType extends PseudoEnum
+ {
+ protected const CONSTANTS = [
+ 'none' => IntlDateFormatter::NONE,
+ 'short' => IntlDateFormatter::SHORT,
+ 'medium' => IntlDateFormatter::MEDIUM,
+ 'long' => IntlDateFormatter::LONG,
+ 'full' => IntlDateFormatter::FULL,
+ 'relative_short' => IntlDateFormatter::RELATIVE_SHORT,
+ 'relative_medium' => IntlDateFormatter::RELATIVE_MEDIUM,
+ 'relative_long' => IntlDateFormatter::RELATIVE_LONG,
+ 'relative_full' => IntlDateFormatter::RELATIVE_FULL,
+ ];
- protected static string $description = 'date format';
+ protected static string $description = 'date format';
+ }
+} else {
+ final class DateType extends PseudoEnum
+ {
+ protected const CONSTANTS = [
+ 'none' => IntlDateFormatter::NONE,
+ 'short' => IntlDateFormatter::SHORT,
+ 'medium' => IntlDateFormatter::MEDIUM,
+ 'long' => IntlDateFormatter::LONG,
+ 'full' => IntlDateFormatter::FULL,
+ ];
+
+ protected static string $description = 'date format';
+ }
}
diff --git a/src/Options/SymbolAttribute.php b/src/Options/SymbolAttribute.php
new file mode 100644
index 0000000..20ccc38
--- /dev/null
+++ b/src/Options/SymbolAttribute.php
@@ -0,0 +1,58 @@
+ NumberFormatter::DECIMAL_SEPARATOR_SYMBOL,
+ 'grouping_separator' => NumberFormatter::GROUPING_SEPARATOR_SYMBOL,
+ 'pattern_separator' => NumberFormatter::PATTERN_SEPARATOR_SYMBOL,
+ 'percent' => NumberFormatter::PERCENT_SYMBOL,
+ 'zero_digit' => NumberFormatter::ZERO_DIGIT_SYMBOL,
+ 'digit' => NumberFormatter::DIGIT_SYMBOL,
+ 'minus_sign' => NumberFormatter::MINUS_SIGN_SYMBOL,
+ 'plus_sign' => NumberFormatter::PLUS_SIGN_SYMBOL,
+ 'currency' => NumberFormatter::CURRENCY_SYMBOL,
+ 'intl_currency' => NumberFormatter::INTL_CURRENCY_SYMBOL,
+ 'monetary_separator' => NumberFormatter::MONETARY_SEPARATOR_SYMBOL,
+ 'exponential' => NumberFormatter::EXPONENTIAL_SYMBOL,
+ 'permill' => NumberFormatter::PERMILL_SYMBOL,
+ 'pad_escape' => NumberFormatter::PAD_ESCAPE_SYMBOL,
+ 'infinity' => NumberFormatter::INFINITY_SYMBOL,
+ 'nan' => NumberFormatter::NAN_SYMBOL,
+ 'significant_digit' => NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL,
+ 'monetary_grouping_separator' => NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL,
+ ];
+
+ /** @readonly */
+ public int $name;
+
+ /** @readonly */
+ public string $value;
+
+ private function __construct(int $name, string $value)
+ {
+ $this->value = $value;
+ $this->name = $name;
+ }
+
+ public static function from(string $name, string $value): self
+ {
+ if (!isset(self::ATTRIBUTES[$name])) {
+ throw FailedFormatting::dueToUnknownNumberFormatterAttributeName($name, self::ATTRIBUTES);
+ }
+
+ return new self(self::ATTRIBUTES[$name], $value);
+ }
+
+ public function addTo(NumberFormatter $numberFormatter): void
+ {
+ $numberFormatter->setSymbol($this->name, $this->value);
+ }
+}
diff --git a/src/Options/TextAttribute.php b/src/Options/TextAttribute.php
new file mode 100644
index 0000000..f7c341b
--- /dev/null
+++ b/src/Options/TextAttribute.php
@@ -0,0 +1,48 @@
+ NumberFormatter::POSITIVE_PREFIX,
+ 'positive_suffix' => NumberFormatter::POSITIVE_SUFFIX,
+ 'negative_prefix' => NumberFormatter::NEGATIVE_PREFIX,
+ 'negative_suffix' => NumberFormatter::NEGATIVE_SUFFIX,
+ 'padding_character' => NumberFormatter::PADDING_CHARACTER,
+ 'currency_code' => NumberFormatter::CURRENCY_CODE,
+ 'default_ruleset' => NumberFormatter::DEFAULT_RULESET,
+ 'public_rulesets' => NumberFormatter::PUBLIC_RULESETS,
+ ];
+
+ /** @readonly */
+ public string $value;
+
+ /** @readonly */
+ public int $name;
+
+ private function __construct(int $name, string $value)
+ {
+ $this->value = $value;
+ $this->name = $name;
+ }
+
+ public static function from(string $name, string $value): self
+ {
+ if (!isset(self::ATTRIBUTES[$name])) {
+ throw FailedFormatting::dueToUnknownNumberFormatterAttributeName($name, self::ATTRIBUTES);
+ }
+
+ return new self(self::ATTRIBUTES[$name], $value);
+ }
+
+ public function addTo(NumberFormatter $numberFormatter): void
+ {
+ $numberFormatter->setTextAttribute($this->name, $this->value);
+ }
+}