Completed
Pull Request — master (#4)
by James Ekow Abaka
03:06 queued 36s
created

DateHelper::sentence()   C

Complexity

Conditions 12
Paths 18

Size

Total Lines 117
Code Lines 90

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 90
nc 18
nop 2
dl 0
loc 117
ccs 18
cts 18
cp 1
crap 12
rs 5.7915
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * Ntentan Framework
4
 * Copyright (c) 2008-2015 James Ekow Abaka Ainooson
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining
7
 * a copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sublicense, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 * 
14
 * The above copyright notice and this permission notice shall be
15
 * included in all copies or substantial portions of the Software.
16
 * 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
24
 * 
25
 */
26
27
namespace ntentan\honam\engines\php\helpers;
28
29
use ntentan\honam\engines\php\Helper;
30
31
/**
32
 * A view helper for formatting dates.
33
 *
34
 * @author James Ekow Abaka Ainooson
35
 */
36
class DateHelper extends Helper
37
{
38
    /**
39
     * The UNIX timestamp which represents the most recently parsed date.
40
     * @var integer
41
     */
42
    private $timestamp;
43
    
44
    /**
45
     * Internal utility method for selecting a timestamp. This method returns
46
     * the DatesHelper::timestamp variable if the date parameter is null. This
47
     * method makes it possible for the helper methods to use either the
48
     * internally stored timestamp (which is stored by the DatesHelper::parse
49
     * method) or the date passed directly to the helper method.
50
     *
51
     * @param string $date
52
     * @return integer
53
     */
54 1
    private function selectTimestamp($date = null)
55
    {
56 1
        return $date === null ? $this->timestamp : strtotime($date);
57
    }
58
59
    /**
60
     * Parse a time in string format and store. Once parsed, all calls to helper
61
     * methods which do not specify their own dates use the last date which was
62
     * parsed.
63
     * 
64
     * @param string $time
65
     * @return DateHelper
66
     */
67 1
    public function help($time)
68
    {
69 1
        $this->timestamp = strtotime($time);
70 1
        return $this;
71
    }
72
73
    /**
74
     * A wrapper arround the PHP date() method. This method however takes the
75
     * dates in various string formats.
76
     *
77
     * @param string $format
78
     * @param string $date
79
     * @return string
80
     */
81 1
    public function format($format = 'jS F, Y', $date = null)
82
    {
83 1
        return date($format, $this->selectTimestamp($date));
84
    }
85
86
    /**
87
     * Returns date in the format 12:00 am
88
     * 
89
     * @param string $date
90
     * @return string
91
     */
92 1
    public function time($date = null)
93
    {
94 1
        return date("g:i a", $this->selectTimestamp($date));
95
    }
96
97
    /**
98
     * Provides a nice sentence to represents the date in age terms eg. Three Years,
99
     * Two days or now. The first argument is a boolean which qualifies the date
100
     * with a relativity word (like ago) which gives the date a sense of passing
101
     * time. For example the outputs with this argument could be
102
     * (two days ago, one month ago, now, yesterday, three minutes ago ...)
103
     *
104
     * ````php
105
     * <?php
106
     * $helpers->date('2015-01-01')->sentence(true);
107
     * ````
108
     * 
109
     * @param boolean $ago
110
     * @param string $referenceDate
111
     * @return string
112
     */
113 1
    public function sentence($ago = false, $referenceDate = null)
114
    {
115 1
        $timestamp = $this->selectTimestamp();
116 1
        $now = $referenceDate === null ? time() : strtotime($referenceDate);
117 1
        $elapsed = $now - $timestamp;
118
        
119 1
        $future = $elapsed < 0;
120 1
        $elapsed = abs($elapsed);
121 1
        $englishDate = '';
122
        
123
        $timeFrames = array(
124
            array(
125 1
                'min' => 0,
126
                'max' => 10,
127
                'scale' => 'now',
128
                'plurals' => false,
129
                'divisor' => 1,
130
                'has_future' => false,
131
                'show_elapsed' => false
132
            ),
133
            array(
134
                'min' => 10,
135
                'max' => 60,
136
                'scale' => 'second',
137
                'plurals' => true,
138
                'divisor' => 1,
139
                'has_future' => false,
140
                'show_elapsed' => true
141
            ),            
142
            array(
143
                'min' => 60,
144
                'max' => 3600,
145
                'scale' => 'minute',
146
                'plurals' => true,
147
                'divisor' => 60,
148
                'has_future' => false,
149
                'show_elapsed' => true
150
            ),                        
151
            array(
152
                'min' => 3600,
153
                'max' => 86400,
154
                'scale' => 'hour',
155
                'plurals' => true,
156
                'divisor' => 3600,
157
                'has_future' => false,
158
                'show_elapsed' => true
159
            ),    
160
            array(
161
                'min' => 86400,
162
                'max' => 172800,
163
                'scale' => array('yesterday', 'tomorrow'),
164
                'has_future' => true,
165
                'plurals' => false,
166
                'divisor' => 86400,
167
                'show_elapsed' => false
168
            ),  
169
            array(
170
                'min' => 172800,
171
                'max' => 604800,
172
                'scale' => 'day',
173
                'plurals' => true,
174
                'divisor' => 86400,
175
                'has_future' => false,
176
                'show_elapsed' => true
177
            ),              
178
            array(
179
                'min' => 604800,
180
                'max' => 2419200,
181
                'scale' => 'week',
182
                'plurals' => true,
183
                'divisor' => 604800,
184
                'has_future' => false,
185
                'show_elapsed' => true
186
            ),              
187
            array(
188
                'min' => 2419200,
189
                'max' => 31536000,
190
                'scale' => 'month',
191
                'plurals' => true,
192
                'divisor' => 2419200,
193
                'has_future' => false,
194
                'show_elapsed' => true
195
            ),   
196
            array(
197
                'min' => 31536000,
198
                'max' => 0,
199
                'scale' => 'year',
200
                'plurals' => true,
201
                'divisor' => 31536000,
202
                'has_future' => false,
203
                'show_elapsed' => true
204
            ),               
205
        );
206
        
207 1
        foreach($timeFrames as $timeFrame)
208
        {
209 1
            if(($elapsed >= $timeFrame['min'] && $elapsed < $timeFrame['max']) || ($elapsed >= $timeFrame['min'] && $timeFrame['max'] === 0))
210
            {
211 1
                $value = floor($elapsed / $timeFrame['divisor']);
212 1
                $englishDate = $this->getEnglishDate($timeFrame, $value, $future);
213 1
                break;
214
            }
215
        }
216
217 1
        if($englishDate != 'now' && $englishDate != 'yesterday' && $englishDate != 'today' && $ago)
218
        {
219 1
            if($future) 
220
            {
221 1
                $englishDate = 'in '. $englishDate;
222
            }
223
            else 
224
            {
225 1
                $englishDate .= ' ago';
226
            }
227
        }
228
229 1
        return $englishDate;
230
    }
231
    
232 1
    private function getEnglishDate($timeFrame, $value, $future)
233
    {
234 1
        return ($timeFrame['show_elapsed'] ?  "$value " : '') .
235 1
            ($timeFrame['has_future'] ? ($future ? $timeFrame['scale'][1] : $timeFrame['scale'][0]) : "{$timeFrame['scale']}") . 
236 1
            ($timeFrame['plurals'] && $value > 1 ? 's' : '');        
237
    }
238
    
239 1
    public function __toString() {
240 1
        return $this->format();
241
    }
242
}
243