Skip to content

Commit 3eb227e

Browse files
author
Norbert Orzechowicz
committed
Merge pull request #46 from doenietzomoeilijk/master
Refactor Number into separate languages
2 parents a68dc73 + 586674b commit 3eb227e

File tree

8 files changed

+171
-21
lines changed

8 files changed

+171
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ echo Number::ordinalize(0); // "0th"
7373
echo Number::ordinalize(1); // "1st"
7474
echo Number::ordinalize(2); // "2nd"
7575
echo Number::ordinalize(23); // "23rd"
76-
echo Number::ordinalize(1002); // "1002nd"
76+
echo Number::ordinalize(1002, 'nl'); // "1002e"
7777
echo Number::ordinalize(-111); // "-111th"
7878

7979
```
@@ -88,7 +88,7 @@ echo Number::ordinal(1); // "st"
8888
echo Number::ordinal(2); // "nd"
8989
echo Number::ordinal(23); // "rd"
9090
echo Number::ordinal(1002); // "nd"
91-
echo Number::ordinal(-111); // "th"
91+
echo Number::ordinal(-111, 'nl'); // "e"
9292
```
9393

9494
**Roman numbers**

src/Coduo/PHPHumanizer/Number.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,25 @@
99

1010
class Number
1111
{
12-
public static function ordinalize($number)
12+
/**
13+
* @param int|float $number
14+
* @param string $locale
15+
* @return string
16+
*/
17+
public static function ordinalize($number, $locale = 'en')
1318
{
14-
return $number.self::ordinal($number);
19+
return $number.self::ordinal($number, $locale);
1520
}
1621

17-
public static function ordinal($number)
22+
/**
23+
* @param int|float $number
24+
* @param string $locale
25+
* @return string
26+
*/
27+
public static function ordinal($number, $locale = 'en')
1828
{
19-
return (string) new Ordinal($number);
29+
$ordinal = new Ordinal($number, $locale);
30+
return (string) $ordinal;
2031
}
2132

2233
public static function binarySuffix($number, $locale = 'en')

src/Coduo/PHPHumanizer/Number/Ordinal.php

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,35 @@
22

33
namespace Coduo\PHPHumanizer\Number;
44

5+
use Coduo\PHPHumanizer\Number\Ordinal\Builder;
6+
use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;
7+
58
class Ordinal
69
{
710
/**
8-
* @var int|float
11+
* @type int|float
912
*/
1013
private $number;
1114

15+
/**
16+
* @type StrategyInterface
17+
*/
18+
private $strategy;
19+
1220
/**
1321
* @param int|float $number
22+
* @param string $locale
1423
*/
15-
public function __construct($number)
24+
public function __construct($number, $locale)
1625
{
1726
$this->number = $number;
27+
$this->strategy = Builder::build($locale);
1828
}
1929

2030
public function __toString()
2131
{
22-
$absNumber = abs((integer) $this->number);
23-
24-
if (in_array(($absNumber % 100), array(11, 12, 13))) {
25-
return 'th';
26-
}
27-
28-
switch ($absNumber % 10) {
29-
case 1: return 'st';
30-
case 2: return 'nd';
31-
case 3: return 'rd';
32-
default: return 'th';
33-
}
32+
return $this
33+
->strategy
34+
->ordinalSuffix($this->number);
3435
}
3536
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Coduo\PHPHumanizer\Number\Ordinal;
4+
5+
/**
6+
* Tries to find a proper strategy for ordinal numbers.
7+
*/
8+
class Builder
9+
{
10+
/**
11+
* @param string $locale
12+
* @return StrategyInterface
13+
* @throws \RuntimeException
14+
*/
15+
public static function build($locale)
16+
{
17+
// $locale should be xx or xx_YY
18+
if (!preg_match('/^([a-z]{2})(_([A-Z]{2}))?$/', $locale, $m)) {
19+
throw new \RuntimeException("Invalid locale specified: '$locale'.");
20+
}
21+
22+
$strategy = ucfirst($m[1]);
23+
if (!empty($m[3])) {
24+
$strategy .= "_$m[3]";
25+
}
26+
27+
$strategy = "\\Coduo\\PHPHumanizer\\Resources\\Ordinal\\{$strategy}Strategy";
28+
29+
if (class_exists($strategy)) {
30+
return new $strategy;
31+
}
32+
33+
// Debatable: should we fallback to English?
34+
// return self::build('en');
35+
throw new \RuntimeException("Strategy for locale $locale not found.");
36+
}
37+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Coduo\PHPHumanizer\Number\Ordinal;
4+
5+
interface StrategyInterface
6+
{
7+
/**
8+
* @param int|float $number
9+
* @return string
10+
*/
11+
public function ordinalSuffix($number);
12+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Coduo\PHPHumanizer\Resources\Ordinal;
4+
5+
use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;
6+
7+
class EnStrategy implements StrategyInterface
8+
{
9+
/** @inheritdoc */
10+
public function ordinalSuffix($number)
11+
{
12+
$absNumber = abs((integer) $number);
13+
14+
if (in_array(($absNumber % 100), array(11, 12, 13))) {
15+
return 'th';
16+
}
17+
18+
switch ($absNumber % 10) {
19+
case 1: return 'st';
20+
case 2: return 'nd';
21+
case 3: return 'rd';
22+
default: return 'th';
23+
}
24+
}
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Coduo\PHPHumanizer\Resources\Ordinal;
4+
5+
use Coduo\PHPHumanizer\Number\Ordinal\StrategyInterface;
6+
7+
class NlStrategy implements StrategyInterface
8+
{
9+
/** @inheritdoc */
10+
public function ordinalSuffix($number)
11+
{
12+
return "e";
13+
}
14+
}

tests/Coduo/PHPHumanizer/Tests/NumberTest.php

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ public function test_return_ordinal_suffix($expected, $number)
1717
$this->assertEquals($expected, Number::ordinal($number));
1818
}
1919

20+
/**
21+
* @dataProvider ordinalSuffixDutchProvider
22+
* @param $expected
23+
* @param $number
24+
*/
25+
public function test_return_ordinal_suffix_dutch($expected, $number)
26+
{
27+
$this->assertEquals($expected, Number::ordinal($number, 'nl'));
28+
}
29+
2030
/**
2131
* @dataProvider ordinalizeDataProvider
2232
* @depends test_return_ordinal_suffix
@@ -29,6 +39,18 @@ public function test_ordinalize_numbers($expected, $number)
2939
$this->assertEquals($expected, Number::ordinalize($number));
3040
}
3141

42+
/**
43+
* @dataProvider ordinalizeDataDutchProvider
44+
* @depends test_return_ordinal_suffix_dutch
45+
*
46+
* @param $expected
47+
* @param $number
48+
*/
49+
public function test_ordinalize_numbers_dutch($expected, $number)
50+
{
51+
$this->assertEquals($expected, Number::ordinalize($number, 'nl'));
52+
}
53+
3254
/**
3355
* @dataProvider binarySuffixDataProvider
3456
*
@@ -156,6 +178,20 @@ public function ordinalizeDataProvider()
156178
);
157179
}
158180

181+
/**
182+
* @return array
183+
*/
184+
public function ordinalizeDataDutchProvider()
185+
{
186+
return array(
187+
array('1e', 1),
188+
array('2e', 2),
189+
array('23e', 23),
190+
array('1002e', 1002),
191+
array('-111e', -111),
192+
);
193+
}
194+
159195
/**
160196
* @return array
161197
*/
@@ -170,6 +206,20 @@ public function ordinalSuffixProvider()
170206
);
171207
}
172208

209+
/**
210+
* @return array
211+
*/
212+
public function ordinalSuffixDutchProvider()
213+
{
214+
return array(
215+
array('e', 1),
216+
array('e', 2),
217+
array('e', 23),
218+
array('e', 1002),
219+
array('e', -111),
220+
);
221+
}
222+
173223
/**
174224
* @return array
175225
*/
@@ -293,4 +343,4 @@ public function arabicExceptionProvider()
293343
array("foobar"),
294344
);
295345
}
296-
}
346+
}

0 commit comments

Comments
 (0)