Skip to content

Commit e05a9d0

Browse files
author
Zsolt Gál
committed
Minor refactor to not use trait, extend readme
1 parent c802acc commit e05a9d0

File tree

6 files changed

+151
-52
lines changed

6 files changed

+151
-52
lines changed

README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,35 @@ $ruleSet->add(
2424
new Rule(
2525
'aboutOneDay', // rule name, which would be used as a translation key
2626
'23hour' // timespan, as a limit, without spaces between numerics and time. Check DefaultRuleSet for examples
27-
),
27+
),
2828
new Formatter(
29-
'days', // duration type, according to durations in \Technodelight\TimeAgo\Translation\SecondsDurationMap
29+
'day', // duration type, according to durations in \Technodelight\TimeAgo\Translation\SecondsDurationMap
3030
'floor' // strategy (function) to use for calculating the amount. In this example "days" are calculated with floor()
3131
)
3232
);
3333
$timeAgo = new Technodelight\TimeAgo(
3434
new DateTime('-1 hour'),
3535
new Technodelight\TimeAgo\Translator(
36-
new Technodelight\TimeAgo\Translation,
36+
new Technodelight\TimeAgo\Translation( // this only needs an array as an input
37+
[
38+
'aboutOneDay' => 'About one day'
39+
]
40+
),
3741
$ruleSet
3842
)
3943
);
4044
41-
$timeAgo->inWords(); // => 1 day ago
45+
$timeAgo->inWords(); // => About one day
4246
```
4347

44-
The example below shows how customisable is TimeAgo:
48+
The example below shows how customisable is TimeAgo:
4549

4650
```
4751
// with all dependencies injected:
4852
$translationLoader = new Technodelight\TimeAgo\TranslationLoader; // can load built-in translations
4953
$timeAgo = new Technodelight\TimeAgo(
5054
new DateTime('-1 hour'), // static datetime
51-
new Technodelight\TimeAgo\Translator( // this only needs an array as an input
55+
new Technodelight\TimeAgo\Translator(
5256
$translationLoader->load('hu') // use a fixed translation
5357
)
5458
);
@@ -60,7 +64,7 @@ $timeAgo->inWords(); // => körülbelül 1 órája
6064
6165
```
6266
In the above example you can pass any of the translations supplied with this repository. All credits goes to Jimmi Westerberg and to the contributors of his repository.
63-
67+
6468
By default, the `TimeAgo` uses the current system language as a guide to determine the required translation file, and it defaults to english if this information was not successfully resolved.
6569
Of course, you can pass your own translation when required:
6670

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Technodelight\TimeAgo\Translation;
4+
5+
class DefaultSecondsDurationMap implements SecondsDurationMap
6+
{
7+
/**
8+
* Durations mapped to values in seconds
9+
*
10+
* @var array [['duration' => 123]]
11+
*/
12+
private $secondsDurationMap = array(
13+
'sec' => 1,
14+
'min' => 60,
15+
'hour' => 3600,
16+
'day' => 86400,
17+
'month' => 2592000,
18+
'year' => 31104000,
19+
);
20+
21+
/**
22+
* Converts a definition like "1day" into seconds
23+
*
24+
* @param string $human
25+
* @return int
26+
*/
27+
public function inSeconds($human)
28+
{
29+
$parts = explode(' ', preg_replace('~-\s+~', '-', $human));
30+
$seconds = 0;
31+
foreach ($parts as $def) {
32+
$operand = '+';
33+
if (strpos($def, '-') !== false) {
34+
$def = substr($def, strpos($def, '-') + 1);
35+
$operand = '-';
36+
}
37+
sscanf($def, '%d%s', $amount, $duration);
38+
39+
$seconds += ($this->durationToSeconds($duration, $amount) * ($operand == '+' ? 1 : -1));
40+
}
41+
42+
return $seconds;
43+
}
44+
45+
/**
46+
* Returns an amount for a duration type
47+
*
48+
* @param string $duration
49+
* @return int
50+
*/
51+
public function amountForDuration($duration)
52+
{
53+
if (isset($this->secondsDurationMap[$duration])) {
54+
return $this->secondsDurationMap[$duration];
55+
}
56+
57+
return 0;
58+
}
59+
60+
/**
61+
* @param string $duration
62+
* @param int $amount
63+
* @return int
64+
*/
65+
private function durationToSeconds($duration, $amount)
66+
{
67+
return $amount * $this->secondsDurationMap[$duration];
68+
}
69+
}

src/Technodelight/TimeAgo/Translation/Formatter.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,44 @@
44

55
class Formatter
66
{
7-
use SecondsDurationMap;
8-
97
/**
108
* @var string
119
*/
1210
private $duration;
1311

1412
/**
15-
*
1613
* @var string
1714
*/
1815
private $strategy;
1916

20-
public function __construct($duration, $strategy = null)
17+
/**
18+
* @var SecondsDurationMap
19+
*/
20+
private $map;
21+
22+
/**
23+
* @param string $duration
24+
* @param callable $strategy a rounding function like 'round', 'floor' or 'ceil'
25+
* @param SecondsDurationMap|null $map
26+
*/
27+
public function __construct($duration, $strategy = null, SecondsDurationMap $map = null)
2128
{
2229
$this->duration = $duration;
23-
$this->strategy = $strategy ?: 'round';
30+
$this->strategy = is_callable($strategy) ? $strategy : 'round';
31+
$this->map = $map ?: new DefaultSecondsDurationMap;
2432
}
2533

2634
/**
27-
* @param int $seconds
35+
* Return amount of seconds rounded according to configured strategy
2836
*
37+
* @param int|float $seconds
2938
* @return int
3039
*/
3140
public function format($seconds)
3241
{
3342
return (int) call_user_func(
3443
$this->strategy,
35-
($seconds / $this->secondsDurationMap[$this->duration])
44+
($seconds / $this->map->amountForDuration($this->duration))
3645
);
3746
}
3847
}

src/Technodelight/TimeAgo/Translation/Rule.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
class Rule
66
{
7-
use SecondsDurationMap;
8-
97
/**
108
* @var string
119
*/
@@ -16,22 +14,39 @@ class Rule
1614
*/
1715
private $timespan;
1816

19-
public function __construct($name, $timespan)
17+
/**
18+
* @param string $name the name of the rule, used as translation key
19+
* @param string $timespan timespan definition, like '1hour 29sec'
20+
* @param SecondsDurationMap|null $map
21+
* @see SecondsDurationMap
22+
*/
23+
public function __construct($name, $timespan, SecondsDurationMap $map = null)
2024
{
25+
$map = $map ?: new DefaultSecondsDurationMap;
2126
$this->name = $name;
22-
$this->timespan = $this->inSeconds($timespan);
27+
$this->timespan = $map->inSeconds($timespan);
2328
}
2429

30+
/**
31+
* @return string
32+
*/
2533
public function name()
2634
{
2735
return $this->name;
2836
}
2937

38+
/**
39+
* @return int
40+
*/
3041
public function timespan()
3142
{
3243
return $this->timespan;
3344
}
3445

46+
/**
47+
* @param int|float $seconds
48+
* @return bool
49+
*/
3550
public function match($seconds)
3651
{
3752
return $seconds <= $this->timespan;

src/Technodelight/TimeAgo/Translation/RuleSet.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,29 @@
66

77
class RuleSet
88
{
9+
/**
10+
* @var Rule[]
11+
*/
912
private $rules = array();
1013

14+
/**
15+
* Add new rule to the set with formatter
16+
*
17+
* @param Rule $rule the rule which determines where to "cut"
18+
* @param Formatter $formatter the formatter which is responsible to render the "amount" of time
19+
* @return void
20+
*/
1121
public function add(Rule $rule, Formatter $formatter)
1222
{
1323
$this->rules[] = array($rule, $formatter);
1424
}
1525

26+
/**
27+
* Finds a matching rule for an amount of time
28+
*
29+
* @param int $seconds
30+
* @return Rule|null
31+
*/
1632
public function getMatchingRule($seconds)
1733
{
1834
$this->sortRulesByTimespan();
@@ -28,6 +44,13 @@ public function getMatchingRule($seconds)
2844
return $lastRule;
2945
}
3046

47+
/**
48+
* Finds a (configured) formatter for a given rule
49+
*
50+
* @param Rule $ruleToFind
51+
* @return Formatter
52+
* @throws LogicException when no formatter found
53+
*/
3154
public function formatterForRule(Rule $ruleToFind)
3255
{
3356
foreach ($this->rules as $ruleFormatterPair) {
@@ -37,7 +60,7 @@ public function formatterForRule(Rule $ruleToFind)
3760
}
3861
}
3962

40-
throw new LogicException('A formatter should have been available');
63+
throw new LogicException(sprintf('A formatter for rule %s was not found', $ruleToFind->name()));
4164
}
4265

4366
private function sortRulesByTimespan()

src/Technodelight/TimeAgo/Translation/SecondsDurationMap.php

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,21 @@
22

33
namespace Technodelight\TimeAgo\Translation;
44

5-
trait SecondsDurationMap
5+
interface SecondsDurationMap
66
{
77
/**
8-
* Durations mapped to values in seconds
8+
* Converts a definition like "1day" into seconds
99
*
10-
* @var array
10+
* @param string $human
11+
* @return int
1112
*/
12-
private $secondsDurationMap = array(
13-
'sec' => 1,
14-
'min' => 60,
15-
'hour' => 3600,
16-
'day' => 86400,
17-
'month' => 2592000,
18-
'year' => 31104000,
19-
);
13+
public function inSeconds($human);
2014

21-
private function inSeconds($human)
22-
{
23-
$parts = explode(' ', preg_replace('~-\s+~', '-', $human));
24-
$seconds = 0;
25-
foreach ($parts as $def) {
26-
$operand = '+';
27-
if (strpos($def, '-') !== false) {
28-
$def = substr($def, strpos($def, '-') + 1);
29-
$operand = '-';
30-
}
31-
sscanf($def, '%d%s', $amount, $duration);
32-
33-
$seconds += ($this->durationToSeconds($duration, $amount) * ($operand == '+' ? 1 : -1));
34-
}
35-
36-
return $seconds;
37-
}
38-
39-
private function durationToSeconds($duration, $amount)
40-
{
41-
return $amount * $this->secondsDurationMap[$duration];
42-
}
15+
/**
16+
* Returns an amount for a duration type
17+
*
18+
* @param string $duration
19+
* @return int
20+
*/
21+
public function amountForDuration($duration);
4322
}

0 commit comments

Comments
 (0)