Git - Framework SuperObject

fso: / termdates.php [ Download ]

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
<?php

if ( !class_exists('FSO') )
    die('Framework SuperObject base class must be loaded to use its modules!');

/**
 * TermDates Class
 *
 * Class for converting between real dates and term/week dates.
 *
 * Adapted from the original code written by Rick Selby <rick@ystv.york.ac.uk>
 */
class TermDates extends FSO_Module
{
    const AUTUMN = 'aut';
    const SPRING = 'spr';
    const SUMMER = 'sum';

    private $termdb = null;     // database module to use
    private $yearWeeks = array();
    private $yearTerms = array();

    private $termTextAr = array(
        self::AUTUMN => 'Autumn',
        self::SPRING => 'Spring',
        self::SUMMER => 'Summer',
    );

    //  {{{ public function __construct( &$db )

    /**
     * Constructor
     *
     * Use database connection to load term data
     *
     * @param       FSO_DB_Module       $db
     * @return      void
     */
    public function __construct( &$db )
    {
        parent::__construct();
        $this->termdb =& $db;
        $result = $db->query('SELECT * FROM termDates ORDER BY year, week ASC');
        foreach ( $result->fetchAll(PDO::FETCH_ASSOC) as $row )
        {
            $this->yearWeeks[$row['year']][$row['week']] = $row['term'];
            $this->yearTerms[$row['year']][$row['term']] = $row['week'];
        }

        //  Set whether or not its termtime
        $term = $this->dateToTerm(time(), false);
        if ( empty($term) )
            define('TERMTIME', false);
        else
            define('TERMTIME', true);
    }

    //  }}}
    //  {{{ public function termText( $term )

    /**
     * Get the textual representation of a term name
     *
     * @param       string
     * @return      string
     */
    public function termText( $term )
    {
        return $this->termTextAr[$term];
    }

    //  }}}
    //  {{{ public function termArray()

    /**
     * Get the array of identifiers => real names for terms
     *
     * @return      array
     */
    public function termArray()
    {
        return $this->termTextAr;
    }

    //  }}}
    //  {{{ public function termToDate( $year, $term, $week, $day [, $hour = 0 [, $minute = 0]] )

    /**
     * Convert a year/term/week/day combination into a real date
     *
     *      year :  4-digit year representation
     *      term :  TermDates::AUTUMN, TermDates::SPRING or TermDates::SUMMER
     *      week :  1-10
     *      day  :  1 = Monday ... 7 = Sunday
     *
     * Returns a unix timestamp if inputs are valid
     */
    public function termToDate($year, $term, $week, $day, $hour = 0, $minute = 0)
    {
        if (!isset($this->yearTerms[$year][$term]))
            return false;

        $weekNum = $this->yearTerms[$year][$term] + ($week - 1);

        return $this->findDayOfWeek($year, $weekNum, $day, $hour, $minute);
    }

    //  }}}
    //  {{{ public function showTerm( [ $date = null ] )

    /**
     * Get the term that $date lies within (or the current date if not specified)
     *
     * @param       integer     $date
     * @return      string
     */
    public function showTerm($date = null)
    {
        $date = is_null($date) ? time() : $date;

        if ($termInfo = $this->dateToTerm($date, true))
            return $termInfo;
        else
            return $this->nextTerm($date);
    }

    //  }}}
    //  {{{ public function nextTerm( [ $date = null [, $tryNextYear = false] ] )

    /**
     * If we're in the holidays, this function will get the upcoming term details.
     * If we're in a term, it'll get the current term details. I believe.
     *
     * @param       integer     $date
     * @param       boolean     $tryNextYear
     * @return      array
     */
    public function nextTerm($date = null, $tryNextYear = false)
    {
        $date = is_null($date) ? time() : $date;

        $checkyear = date('Y', $date);
        $checkweek = date('W', $date);

        if ($this->yearWeeks[$checkyear])
        {
            $weeks = array_keys($this->yearWeeks[$checkyear]);
            $return = array();

            foreach ($weeks as $week)
                if (($week > $checkweek))
                {
                    $return['termText'] = $this->termText($this->yearWeeks[$checkyear][$week]);
                    $return['termRef'] = $this->yearWeeks[$checkyear][$week];
                    $return['year'] = $checkyear;

                    break;
                }

            if (sizeof($return) != 0)
                return $return;
            else
            {
                // only try one year ahead - we could recurse forever otherwise
                if (!$tryNextYear)
                    return $this->nextTerm(gmmktime (0,0,0,1,1,$checkyear+1), true);
                else
                    return false;
            }
        } else
            return false;
    }
    

    //  }}}
    //  {{{ public function lastTerm( [ $date = null [, $tryLastYear = false]] )

    /**
     * This will get the previous term details (see Officers Reports for use)
     *
     * @param       integer     $date
     * @param       boolean     $tryLastYear
     * @return      array
     */
    public function lastTerm($date = null, $tryLastYear = false)
    {
        $date = is_null($date) ? time() : $date;

        $checkyear = date('Y', $date);
        $checkweek = date('W', $date);

        if ($this->yearWeeks[$checkyear])
        {
            $weeks = array_keys($this->yearWeeks[$checkyear]);
            $return = array();

            foreach ($weeks as $week)
                if (($week + 10 <= $checkweek))
                {
                    $return['termText'] = $this->termText($this->yearWeeks[$checkyear][$week]);
                    $return['termRef'] = $this->yearWeeks[$checkyear][$week];
                    $return['year'] = $checkyear;
                }

            if (sizeof($return) != 0)
                return $return;
            else
            {
                // only try one year back - we could recurse forever otherwise
                if (!$tryLastYear)
                    return $this->lastTerm(gmmktime (0,0,0,12,31,$checkyear-1), true);
                else
                    return false;
            }
        } else
            return false;
    }
    

    //  }}}
    //  {{{ public function dateToTerm( $date [, $extraWeek = false] )

    /**
     * Convert a real date into an array of year/term/week details
     *
     * @param       integer     $date
     * @param       boolean     $extraWeek
     * @return      array
     */
    public function dateToTerm($date, $extraWeek = false)
    {
        $checkyear = date('Y', $date);
        $checkweek = date('W', $date);

        $weekRange = ($extraWeek ? 11 : 10);

        if ($this->yearWeeks[$checkyear])
        {
            $weeks = array_keys($this->yearWeeks[$checkyear]);
            $return = array();

            foreach ($weeks as $week)
                if (($week <= $checkweek) && ($week + $weekRange > $checkweek))
                {
                    $return['termText'] = $this->termText($this->yearWeeks[$checkyear][$week]);
                    $return['termRef'] = $this->yearWeeks[$checkyear][$week];
                    $return['year'] = date('Y', $date);
                    $termWeek = ($checkweek - $week + 1);
                    if (!$extraWeek || ($termWeek < 11))
                    {
                        $return['week'] = $termWeek;
                        $return['day'] = date('N', $date);
                    }
                    break;
                }

            if (sizeof($return) != 0)
                return $return;
            else
                return false;
        } else
            return false;
    }

    //  }}}
    //  {{{ public function findDayOfWeek( $year, $week, $day [, $hour = 0 [, $minute = 0 ]] )

    /**
     * Takes a year, week number, and day [mon, tues etc], and returns the timestamp for that day
     *
     * @param       integer     $year
     * @param       integer     $week
     * @param       integer     $day
     * @param       integer     $hour
     * @param       integer     $minute
     * @return      integer
     */
    public function findDayOfWeek($year, $week, $day, $hour = 0, $minute = 0)
    {
	    // day: 0=Sunday...6=Saturday
        // 1 	Monday 	0-53 	with more than 3 days this year

        // find out which day Jan 1st is
        $firstday = gmdate('N', strtotime($year.'-01-01'));

        /* if first day is Mon to Thurs - day 1 is in week 1)
                  Day | firstSunday
                --------------------
                Mon 1 |  0  (the 31st Dec)
                Tue 2 | -1  (the 30th Dec)
                Wed 3 | -2
                Thr 4 | -3
                Fri 5 |  3  (the 3rd Jan)
                Sat 6 |  2
                Sun 7 |  1
         */

        if ($firstday <= 4)
        {
            $firstSunday = 1 - $firstday;
        } else {
            $firstSunday = 8 - $firstday;
        }

        // get day in January for first day that we're looking for
        $firstWhichDay = $firstSunday + $day;
        // if the first day is still not a valid day, jump to week 2
        if ($firstWhichDay < 1)
        {
            // but if we want week one, it's not this year, so fail.
            if ($week == 1)
                return 0;

            // increment day and decrement week accordingly
            $firstWhichDay += 7;
            $week--;
        }

        // calculate seconds in a week
        $oneweek = 60*60*24*7;

        // do the calculation. 
        return strtotime($year.'-01-'.$firstWhichDay) // timestamp of the day in week 1
            + (($week - 1) * $oneweek) // plus number of seconds to get to correct week
            + (60 * 60 * $hour) // plus hours
            + (60 * $minute); // plus minutes
    }

    //  }}}
    
    //  {{{ compatibility stuff

    /**
     * The term* calls to make this version call-compatible with the original
     */
    public function termAutumn() { return self::AUTUMN; }
    public function termSpring() { return self::SPRING; }
    public function termSummer() { return self::SUMMER; }

    //  }}}
}

?>