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
|
<?php
/**
* @version $Header: /cvsroot/bitweaver/_bit_calendar/Calendar.php,v 1.32 2006/02/02 14:39:46 hash9 Exp $
* @package calendar
*/
/**
* Required setup
*/
include_once( KERNEL_PKG_PATH . 'BitDate.php' );
// set week offset - start with a day other than monday
define( 'WEEK_OFFSET', !empty( $gBitUser->mUserPrefs['calendar_week_offset'] ) ? $gBitUser->mUserPrefs['calendar_week_offset'] : $gBitSystem->getPreference( 'calendar_week_offset', 0 ) );
/**
* @package calendar
*/
class Calendar extends LibertyContent {
function Calendar() {
LibertyContent::LibertyContent();
global $gBitSystem;
$this->mDate = new BitDate(0);
}
/**
* get a full list of content for a given time period
* return array of items
*
* The output array will be a set of UTC tagged pages covering the period
* defined in the $pListHash. Items identified from the list will be tagged to
* the day identified in the selected timestamp from which the list was built.
* If the user has selected a local time display, then the day will be the actual
* UTC day that the item is in, rather than the UTC day of the item. In this way
* the display view provides a list of locally correct entries for each day.
**/
function getList( $pListHash ) {
$ret = array();
if( $this->prepGetList( $pListHash ) ) {
include_once( LIBERTY_PKG_PATH.'LibertyContent.php' );
$content = new LibertyContent();
$content->prepGetList( $pListHash );
$res = $content->getContentList( $pListHash );
$offset = $this->mDate->get_display_offset();
foreach( $res['data'] as $item ) {
// shift all time data by user timezone offset
// and then display as a simple UTC time
$item['timestamp'] = $item[$pListHash['calendar_sort_mode']] + $offset;
$item['created'] = $item['created'] + $offset;
$item['last_modified'] = $item['last_modified'] + $offset;
$item['event_time'] = $item['event_time'] + $offset;
$dstart = $this->mDate->gmmktime( 0, 0, 0, $this->mDate->date( "m", $item['timestamp'], true ), $this->mDate->date( "d", $item['timestamp'], true ), $this->mDate->date( "Y", $item['timestamp'], true ) );
$ret[$dstart][] = $item;
}
}
return $ret;
}
/**
* calculate the start and stop time for the current display page
**/
function doRangeCalculations( $pDateHash ) {
$focus = $this->mDate->getdate( $pDateHash['focus_date'] );
if( $pDateHash['view_mode'] == 'month' ) {
$view_start = $this->mDate->mktime( 0, 0, 0, $focus['mon'], 1, $focus['year'] );
$view_end = $this->mDate->mktime( 0, 0, 0, $focus['mon'] + 1, 1, $focus['year'] ) - 1;
} elseif( $pDateHash['view_mode'] == 'week' or $pDateHash['view_mode'] == 'weeklist') {
if ( $focus['wday'] == 0 ) {
$wd = 7 + WEEK_OFFSET;
} else {
$wd = $focus['wday'] + WEEK_OFFSET;
}
// if we are moving out from the selected week, move us back in
if( $wd > 7 ) {
$wd -= 7;
}
// for some very odd reason, which i can't work out, we need to add a day here
$view_start = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] - $wd + 1, $focus['year'] );
$view_end = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] - $wd + 8, $focus['year'] ) - 1;
} else {
$view_start = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] , $focus['year'] );
$view_end = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] + 1, $focus['year'] ) - 1;
}
// this is where we adjust the start and stop times to user local time settings
// The range is adjusted backwards so that it covers the correct window
$view_start = $view_start - $this->mDate->get_display_offset();
$view_end = $view_end - $this->mDate->get_display_offset();
$start_year = $this->mDate->date( 'Y', $view_start );
if ( $start_year < 1902 ) {
$view_start_iso = $view_start = $this->mDate->date( 'Y-m-d', $view_start );
$view_end_iso = $view_end = $this->mDate->date( 'Y-m-d', $view_start );
$view_start = 0;
$view_end = 0;
}
$ret = array(
'view_start' => $view_start,
'view_end' => $view_end,
);
// Insert ISO dates if they are set - Used for dates pre 1902
if ( !empty($view_start_iso) ) {
$ret['view_start_iso'] = $view_start_iso;
$ret['view_end_iso'] = $view_end_iso;
}
return $ret;
}
/**
* prepare ListHash to ensure errorfree usage
**/
function prepGetList( &$pListHash ) {
if( !empty( $pListHash['focus_date'] ) ) {
$calDates = $this->doRangeCalculations( $pListHash );
$pListHash['start'] = $calDates['view_start'];
$pListHash['stop'] = $calDates['view_end'];
}
if( !empty( $pListHash['sort_mode'] ) ) {
$pListHash['calendar_sort_mode'] = preg_replace( "/(_asc$|_desc$)/i", "", $pListHash['sort_mode'] );
}
return TRUE;
}
function buildDay( $pDateHash ) {
global $gBitSystem, $gBitUser;
$focus = $this->mDate->getdate( $pDateHash['focus_date'] );
$ret = array();
if( $pDateHash['view_mode'] == 'day' ) {
// calculare what the visible day view range is
$day_start = isset( $gBitUser->mUserPrefs['calendar_day_start'] ) ? $gBitUser->mUserPrefs['calendar_day_start'] : $gBitSystem->getPreference( 'calendar_day_start', 0 );
$day_end = isset( $gBitUser->mUserPrefs['calendar_day_end'] ) ? $gBitUser->mUserPrefs['calendar_day_end'] : $gBitSystem->getPreference( 'calendar_day_end', 24 );
$start_time = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'], $focus['year'] ) + ( 60 * 60 * $day_start );
$stop_time = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] + 1, $focus['year'] ) - ( 60 * 60 * ( 24 - $day_end ) );
$hours_count = ( $stop_time - $start_time ) / ( 60 * 60 );
// allow for custom time intervals
$hour_fraction = !empty( $gBitUser->mUserPrefs['calendar_hour_fraction'] ) ? $gBitUser->mUserPrefs['calendar_hour_fraction'] : $gBitSystem->getPreference( 'calendar_hour_fraction', 1 );
$row_count = $hours_count * $hour_fraction;
$start_time_info = $this->mDate->getdate( $start_time );
$hour = $start_time_info['hours'] - 1;
$mins = 0;
for( $i = 0; $i < $row_count; $i++ ) {
if( !( $i % $hour_fraction ) ) {
// set vars
$hour++;
$mins = 0;
}
$ret[$i]['time'] = $this->mDate->gmmktime( $hour, $mins, 0, $focus['mon'], $focus['mday'], $focus['year'] );
$mins += 60 / $hour_fraction;
}
// calendar data is added below
}
return $ret;
}
/**
* build an array of unix UTC timestamps relating to the current
* calendar focus. This provides a fixed basis from which to apply local
* offsets provided by tz_offset information. Daylight saving information
* is not available via this route!
**/
function buildCalendarNavigation( $pDateHash ) {
$focus = $this->mDate->getdate( $pDateHash['focus_date'] );
$today = $this->mDate->getdate( mktime() );
$ret = array(
'before' => array(
'day' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] - 1, $focus['year'] ),
'week' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] - 7, $focus['year'] ),
'month' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'] - 1, $focus['mday'], $focus['year'] ),
'year' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'], $focus['year'] - 1 ),
),
'after' => array(
'day' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] + 1, $focus['year'] ),
'week' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'] + 7, $focus['year'] ),
'month' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'] + 1, $focus['mday'], $focus['year'] ),
'year' => $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $focus['mday'], $focus['year'] + 1 ),
),
'focus_month' => $focus['mon'],
'focus_year' => $focus['year'],
'focus_date' => $focus[0],
'today' => $this->mDate->gmmktime( 0, 0, 0, $today['mon'], $today['mday'], $today['year'] ),
'display_focus_date' => $focus[0],
);
return $ret;
}
/**
* build a two dimensional array of unix timestamps
* The timestamps are either UTC or display local time depending on the
* setting of the current users display time offset
* mktime SHOULD NOT BE USED since it offsets the times based on server
* timezone and daylight saving, but the USERS daylight saving information
* is not available, which will cause some problems!
**/
function buildCalendar( $pDateHash ) {
global $gBitSmarty;
$focus = $this->mDate->getdate( $pDateHash['focus_date'] );
$prev_month_end = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], 0, $focus['year'] );
$next_month_begin = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'] + 1, 1, $focus['year'] );
$prev_month_end_info = $this->mDate->getdate( $prev_month_end );
$prev_month = $prev_month_end_info['mon'];
$prev_month_year = $prev_month_end_info['year'];
// Build a two-dimensional array of UNIX timestamps.
$cal = array();
// Start the first row with the final day( s ) of the previous month.
$week = array();
$month_begin = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], WEEK_OFFSET, $focus['year'] );
$month_begin_day_of_week = $this->mDate->dayOfWeek( $focus['year'], $focus['mon'], WEEK_OFFSET );
$days_in_prev_month = $this->mDate->daysInMonth( $prev_month, $prev_month_year );
// Fill out the first row with the last day( s ) of the previous month.
for( $day_of_week = 0; $day_of_week < $month_begin_day_of_week; $day_of_week++ ) {
$_day = $days_in_prev_month - $month_begin_day_of_week + $day_of_week + 1;
$week[]['day'] = $this->mDate->gmmktime( 0, 0, 0, $prev_month, $_day, $prev_month_year );
}
// Fill in the days of the selected month.
$days_in_month = $this->mDate->daysInMonth( $focus['mon'], $focus['year'] );
for( $i = 1; $i <= $days_in_month; $i++ ) {
if( $day_of_week == 7 ) {
$calendar[$this->mDate->weekOfYear( $focus['year'], $focus['mon'], $i )] = $week;
// re-initialize $day_of_week and $week
$day_of_week = 0;
$week = array();
}
$week[]['day'] = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'], $i, $focus['year'] );
$day_of_week++;
}
// Fill out the last row with the first day( s ) of the next month.
for( $j = 1; $day_of_week < 7; $j++, $day_of_week++ ) {
$week[]['day'] = $this->mDate->gmmktime( 0, 0, 0, $focus['mon'] + 1, $j, $focus['year'] );
}
$week_num = $this->mDate->weekOfYear( $focus['year'], $focus['mon'], $days_in_month + $j );
$calendar[$week_num] = $week;
// Modify offset to fix roll over on week numbers
// This is required because the week numbers are calculated for Sunday
// Offseting the result in BitDate is the real solution
if ( WEEK_OFFSET == 7 ) $offset = $focus['mday'] + 1;
else $offset = $focus['mday'] + 1 + WEEK_OFFSET;
// this week number has to be calculated, since the cal start can be configured
$week_num = $this->mDate->weekOfYear( $focus['year'], $focus['mon'], $offset );
// if we only want to see a weeks / days worth of data, nuke all xs data
if( $pDateHash['view_mode'] == 'week' or $pDateHash['view_mode'] == 'weeklist' ) {
$cal = $calendar[$week_num];
$calendar = array();
$calendar[$week_num] = $cal;
} elseif( $pDateHash['view_mode'] == 'day' ) {
$calendar = array();
$calendar[$week_num][]['day'] = $pDateHash['focus_date'];
}
return $calendar;
}
}
?>
|