Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Number into separate languages #46

Merged
merged 7 commits into from
Nov 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ echo Number::ordinalize(0); // "0th"
echo Number::ordinalize(1); // "1st"
echo Number::ordinalize(2); // "2nd"
echo Number::ordinalize(23); // "23rd"
echo Number::ordinalize(1002); // "1002nd"
echo Number::ordinalize(1002, 'nl'); // "1002e"
echo Number::ordinalize(-111); // "-111th"

```
Expand All @@ -88,7 +88,7 @@ echo Number::ordinal(1); // "st"
echo Number::ordinal(2); // "nd"
echo Number::ordinal(23); // "rd"
echo Number::ordinal(1002); // "nd"
echo Number::ordinal(-111); // "th"
echo Number::ordinal(-111, 'nl'); // "e"
```

**Roman numbers**
Expand Down
19 changes: 15 additions & 4 deletions src/Coduo/PHPHumanizer/Number.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@

class Number
{
public static function ordinalize($number)
/**
* @param int|float $number
* @param string $locale
* @return string
*/
public static function ordinalize($number, $locale = 'en')
{
return $number.self::ordinal($number);
return $number.self::ordinal($number, $locale);
}

public static function ordinal($number)
/**
* @param int|float $number
* @param string $locale
* @return string
*/
public static function ordinal($number, $locale = 'en')
{
return (string) new Ordinal($number);
$ordinal = new Ordinal($number, $locale);
return (string) $ordinal;
}

public static function binarySuffix($number, $locale = 'en')
Expand Down
29 changes: 15 additions & 14 deletions src/Coduo/PHPHumanizer/Number/Ordinal.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,35 @@

namespace Coduo\PHPHumanizer\Number;

use Coduo\PHPHumanizer\Number\Ordinal\Builder;
use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;

class Ordinal
{
/**
* @var int|float
* @type int|float
*/
private $number;

/**
* @type StrategyInterface
*/
private $strategy;

/**
* @param int|float $number
* @param string $locale
*/
public function __construct($number)
public function __construct($number, $locale)
{
$this->number = $number;
$this->strategy = Builder::build($locale);
}

public function __toString()
{
$absNumber = abs((integer) $this->number);

if (in_array(($absNumber % 100), array(11, 12, 13))) {
return 'th';
}

switch ($absNumber % 10) {
case 1: return 'st';
case 2: return 'nd';
case 3: return 'rd';
default: return 'th';
}
return $this
->strategy
->ordinalSuffix($this->number);
}
}
37 changes: 37 additions & 0 deletions src/Coduo/PHPHumanizer/Number/Ordinal/Builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Coduo\PHPHumanizer\Number\Ordinal;

/**
* Tries to find a proper strategy for ordinal numbers.
*/
class Builder
{
/**
* @param string $locale
* @return StrategyInterface
* @throws \RuntimeException
*/
public static function build($locale)
{
// $locale should be xx or xx_YY
if (!preg_match('/^([a-z]{2})(_([A-Z]{2}))?$/', $locale, $m)) {
throw new \RuntimeException("Invalid locale specified: '$locale'.");
}

$strategy = ucfirst($m[1]);
if (!empty($m[3])) {
$strategy .= "_$m[3]";
}

$strategy = "\\Coduo\\PHPHumanizer\\Resources\\Ordinal\\{$strategy}Strategy";

if (class_exists($strategy)) {
return new $strategy;
}

// Debatable: should we fallback to English?
// return self::build('en');
throw new \RuntimeException("Strategy for locale $locale not found.");
}
}
12 changes: 12 additions & 0 deletions src/Coduo/PHPHumanizer/Number/Ordinal/StrategyInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Coduo\PHPHumanizer\Number\Ordinal;

interface StrategyInterface
{
/**
* @param int|float $number
* @return string
*/
public function ordinalSuffix($number);
}
25 changes: 25 additions & 0 deletions src/Coduo/PHPHumanizer/Resources/Ordinal/EnStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Coduo\PHPHumanizer\Resources\Ordinal;

use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;

class EnStrategy implements StrategyInterface
{
/** @inheritdoc */
public function ordinalSuffix($number)
{
$absNumber = abs((integer) $number);

if (in_array(($absNumber % 100), array(11, 12, 13))) {
return 'th';
}

switch ($absNumber % 10) {
case 1: return 'st';
case 2: return 'nd';
case 3: return 'rd';
default: return 'th';
}
}
}
14 changes: 14 additions & 0 deletions src/Coduo/PHPHumanizer/Resources/Ordinal/NlStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Coduo\PHPHumanizer\Resources\Ordinal;

use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;

class NlStrategy implements StrategyInterface
{
/** @inheritdoc */
public function ordinalSuffix($number)
{
return "e";
}
}
52 changes: 51 additions & 1 deletion tests/Coduo/PHPHumanizer/Tests/NumberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ public function test_return_ordinal_suffix($expected, $number)
$this->assertEquals($expected, Number::ordinal($number));
}

/**
* @dataProvider ordinalSuffixDutchProvider
* @param $expected
* @param $number
*/
public function test_return_ordinal_suffix_dutch($expected, $number)
{
$this->assertEquals($expected, Number::ordinal($number, 'nl'));
}

/**
* @dataProvider ordinalizeDataProvider
* @depends test_return_ordinal_suffix
Expand All @@ -29,6 +39,18 @@ public function test_ordinalize_numbers($expected, $number)
$this->assertEquals($expected, Number::ordinalize($number));
}

/**
* @dataProvider ordinalizeDataDutchProvider
* @depends test_return_ordinal_suffix_dutch
*
* @param $expected
* @param $number
*/
public function test_ordinalize_numbers_dutch($expected, $number)
{
$this->assertEquals($expected, Number::ordinalize($number, 'nl'));
}

/**
* @dataProvider binarySuffixDataProvider
*
Expand Down Expand Up @@ -156,6 +178,20 @@ public function ordinalizeDataProvider()
);
}

/**
* @return array
*/
public function ordinalizeDataDutchProvider()
{
return array(
array('1e', 1),
array('2e', 2),
array('23e', 23),
array('1002e', 1002),
array('-111e', -111),
);
}

/**
* @return array
*/
Expand All @@ -170,6 +206,20 @@ public function ordinalSuffixProvider()
);
}

/**
* @return array
*/
public function ordinalSuffixDutchProvider()
{
return array(
array('e', 1),
array('e', 2),
array('e', 23),
array('e', 1002),
array('e', -111),
);
}

/**
* @return array
*/
Expand Down Expand Up @@ -293,4 +343,4 @@ public function arabicExceptionProvider()
array("foobar"),
);
}
}
}