Skip to content

Commit

Permalink
Merge pull request #46 from doenietzomoeilijk/master
Browse files Browse the repository at this point in the history
Refactor Number into separate languages
  • Loading branch information
Norbert Orzechowicz committed Nov 19, 2015
2 parents a68dc73 + 586674b commit 3eb227e
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 21 deletions.
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"),
);
}
}
}

0 comments on commit 3eb227e

Please sign in to comment.