ocPortal Developer's Guide: Calendar
» Return to Contents
sources/calendar.php
Global_functions_calendar.php
Function summary
|
void
|
init__calendar ()
|
|
string
|
get_week_number_for (TIME timestamp, boolean no_year)
|
|
array
|
date_from_week_of_year (integer year, integer week)
|
|
array
|
find_periods_recurrence (ID_TEXT timezone, BINARY do_timezone_conv, integer start_year, integer start_month, integer start_day, integer start_hour, integer start_minute, ?integer end_year, ?integer end_month, ?integer end_day, ?integer end_hour, ?integer end_minute, string recurrence, ?integer recurrences, ?TIME period_start, ?TIME period_end)
|
|
tempcode
|
nice_get_event_types (?AUTO_LINK it)
|
|
void
|
regenerate_event_reminder_jobs (AUTO_LINK id, boolean force)
|
|
string
|
date_range (TIME from, TIME to, boolean do_time)
|
|
array
|
calendar_matches (MEMBER member_id, boolean restrict, ?TIME period_start, ?TIME period_end, ?array filter, boolean do_rss)
|
|
tempcode
|
nice_get_events (?MEMBER only_owned, ?AUTO_LINK it, boolean edit_viewable_events)
|
|
?tempcode
|
detect_conflicts (MEMBER member_id, AUTO_LINK skip_id, ?integer start_year, ?integer start_month, ?integer start_day, ?integer start_hour, ?integer start_minute, ?integer end_year, ?integer end_month, ?integer end_day, ?integer end_hour, ?integer end_minute, string recurrence, ?integer recurrences)
|
|
integer
|
find_timezone_start_hour_in_utc (ID_TEXT timezone, integer year, integer month, integer day)
|
|
integer
|
find_timezone_start_minute_in_utc (ID_TEXT timezone, integer year, integer month, integer day)
|
|
integer
|
find_timezone_end_hour_in_utc (ID_TEXT timezone, integer year, integer month, integer day)
|
|
integer
|
find_timezone_end_minute_in_utc (ID_TEXT timezone, integer year, integer month, integer day)
|
|
TIME
|
cal_get_start_utctime_for_event (ID_TEXT timezone, integer year, integer month, integer day, ?integer hour, ?integer minute, boolean show_in_users_timezone)
|
|
TIME
|
cal_get_end_utctime_for_event (ID_TEXT timezone, integer year, integer month, integer day, ?integer hour, ?integer minute, boolean show_in_users_timezone)
|
|
TIME
|
cal_utctime_to_usertime (TIME utc_timestamp, ID_TEXT default_timezone, boolean show_in_users_timezone)
|
|
array
|
detect_happening_at (MEMBER member_id, AUTO_LINK skip_id, array our_times, boolean restrict, ?TIME period_start, ?TIME period_end)
|
void init__calendar()
Standard code module init function.
Parameters…
(No return value)
function init__calendar()
{
require_code('temporal2');
}
string get_week_number_for(TIME timestamp, boolean no_year)
Get the week number for a time.
Parameters…
| Name |
timestamp |
| Description |
The week number |
| Type |
TIME |
| Name |
no_year |
| Description |
Whether to do it contextually to the year, rather than including the year |
| Default value |
boolean-false |
| Type |
boolean |
Returns…
| Description |
The week number |
| Type |
string |
function get_week_number_for($timestamp,$no_year=false)
{
$format=$no_year?'W':'Y-W';
$w=intval(date('w'));
if ((get_option('ssw')=='0') || (($w!=0) && ($w!=6)))
{
return date($format,$timestamp);
}
if ($w==6) return date($format,$timestamp+60*60*24); // For SSW: If anything, the Saturday will get pushed forward because Sunday always exists in the first week now
return date($format,$timestamp-60*60*24); // For SSW: If anything, the Saturday will get pushed backwards because Sunday always exists in the first week now
}
array date_from_week_of_year(integer year, integer week)
Converts year+week to year+month+day. This is really complex. The first week of a year may actually start in December. The first day of the first week is a Monday or a Sunday, depending on configuration.
Parameters…
| Name |
year |
| Description |
Year # |
| Type |
integer |
| Name |
week |
| Description |
Week # |
| Type |
integer |
Returns…
| Description |
Month #,Day #,Year # |
| Type |
array |
function date_from_week_of_year($year,$week)
{
$basis=strval($year).'-'.str_pad(strval($week),2,'0',STR_PAD_LEFT);
$time=mktime(0,0,0,1,1,$year);
for ($i=0;$i<366;$i++)
{
$new_time=$time+60*60*24*$i;
$test=get_week_number_for($new_time);
if ($test==$basis)
{
$exploded=explode('-',date('m-d-Y',$new_time));
return array(intval($exploded[0]),intval($exploded[1]),intval($exploded[2]));
}
}
}
array find_periods_recurrence(ID_TEXT timezone, BINARY do_timezone_conv, integer start_year, integer start_month, integer start_day, integer start_hour, integer start_minute, ?integer end_year, ?integer end_month, ?integer end_day, ?integer end_hour, ?integer end_minute, string recurrence, ?integer recurrences, ?TIME period_start, ?TIME period_end)
Find a list of pairs specifying the times the event occurs, for 20 years into the future, in user-time.
Parameters…
| Name |
timezone |
| Description |
The timezone for the event (NULL: current user's timezone) |
| Type |
ID_TEXT |
| Name |
do_timezone_conv |
| Description |
Whether the time should be converted to the viewer's own timezone |
| Type |
BINARY |
| Name |
start_year |
| Description |
The year the event starts at. This and the below are in server time |
| Type |
integer |
| Name |
start_month |
| Description |
The month the event starts at |
| Type |
integer |
| Name |
start_day |
| Description |
The day the event starts at |
| Type |
integer |
| Name |
start_hour |
| Description |
The hour the event starts at |
| Type |
integer |
| Name |
start_minute |
| Description |
The minute the event starts at |
| Type |
integer |
| Name |
end_year |
| Description |
The year the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_month |
| Description |
The month the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_day |
| Description |
The day the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_hour |
| Description |
The hour the event ends at (NULL: not a multi day event / all day event) |
| Type |
?integer |
| Name |
end_minute |
| Description |
The minute the event ends at (NULL: not a multi day event / all day event) |
| Type |
?integer |
| Name |
recurrence |
| Description |
The event recurrence |
| Type |
string |
| Name |
recurrences |
| Description |
The number of recurrences (NULL: none/infinite) |
| Type |
?integer |
| Name |
period_start |
| Description |
The timestamp that found times must exceed. In user-time (NULL: now) |
| Default value |
|
| Type |
?TIME |
| Name |
period_end |
| Description |
The timestamp that found times must not exceed. In user-time (NULL: 20 years time) |
| Default value |
|
| Type |
?TIME |
Returns…
| Description |
A list of pairs for period times (timestamps, in user-time). Actually a series of pairs, 'window-bound timestamps' is first pair, then 'true coverage timestamps', then 'true coverage timestamps without timezone conversions' |
| Type |
array |
function find_periods_recurrence($timezone,$do_timezone_conv,$start_year,$start_month,$start_day,$start_hour,$start_minute,$end_year,$end_month,$end_day,$end_hour,$end_minute,$recurrence,$recurrences,$period_start=NULL,$period_end=NULL)
{
if ($recurrences===0) return array();
if (is_null($period_start)) $period_start=utctime_to_usertime(time());
if (is_null($period_end)) $period_end=utctime_to_usertime(time()+60*60*24*360*20);
$times=array();
$i=0;
$parts=explode(' ',$recurrence);
if (count($parts)!=1)
{
$recurrence=$parts[0];
$mask=$parts[1];
$mask_len=strlen($mask);
} else
{
$mask='1';
$mask_len=1;
}
$a=0;
$dif_day=0;
$dif_month=0;
$dif_year=0;
$dif=utctime_to_usertime()-utctime_to_usertime(mktime($start_hour,$start_minute,0,$start_month,$start_day,$start_year));
switch ($recurrence) // If a long way out of range, accelerate forward before steadedly looping forward till we might find a match (doesn't jump fully forward, due to possibility of timezones complicating things)
{
case 'daily':
$dif_day=1;
if ($dif>60*60*24*10)
$start_day+=$dif_day*intval(floor(floatval($dif)/(60.0*60.0*24.0)));
break;
case 'weekly':
$dif_day=7;
if ($dif>60*60*24*70)
$start_day+=$dif_day*intval(floor(floatval($dif)/(60.0*60.0*24.0)))-70;
break;
case 'monthly':
$dif_month=1;
if ($dif>60*60*24*31*10)
$start_month+=$dif_month*intval(floor(floatval($dif)/(60.0*60.0*24.0*31.0)))-10;
break;
case 'yearly':
$dif_year=1;
if ($dif>60*60*24*365*10)
$start_year+=$dif_year*intval(floor(floatval($dif)/(60.0*60.0*24.0*365.0)))-1;
break;
}
$_b=mixed();
$b=mixed();
do
{
/*
Consider this scenario...
An event ends at end of 1/1/2012 (23:59), which is 22:59 in UTC if they are in +1 timezone
Therefore the event, which is stored in UTC, needs a server time of 22:59 before going through cal_utctime_to_usertime
The server already has the day stored UTC which may be different to the day stored for the +1 timezone (in fact either the start or end day will be stored differently, assuming there is an end day)
*/
$_a=cal_get_start_utctime_for_event($timezone,$start_year,$start_month,$start_day,$start_hour,$start_minute,$do_timezone_conv==1);
$a=cal_utctime_to_usertime(
$_a,
$timezone,
$do_timezone_conv==1
);
if ((is_null($start_hour)) && (is_null($end_year) || is_null($end_month) || is_null($end_day))) // All day event with no end date, should be same as start date
{
$end_day=$start_day;
$end_month=$start_month;
$end_year=$start_year;
}
if (is_null($end_year) || is_null($end_month) || is_null($end_day))
{
$_b=NULL;
$b=NULL;
} else
{
$_b=cal_get_end_utctime_for_event($timezone,$end_year,$end_month,$end_day,$end_hour,$end_minute,$do_timezone_conv==1);
$b=cal_utctime_to_usertime(
$_b,
$timezone,
$do_timezone_conv==1
);
}
$starts_within=(($a>=$period_start) && ($a<$period_end));
$ends_within=(($b>$period_start) && ($b<=$period_end));
$spans=(($a<$period_start) && ($b>$period_end));
if (($starts_within || $ends_within || $spans) && (in_array($mask[$i%$mask_len],array('1','y'))))
{
$times[]=array(max($period_start,$a),min($period_end,$b),$a,$b,2*$_a-tz_time($_a,$timezone),is_null($_b)?NULL:(2*$_b-tz_time($_b,$timezone)));
}
$i++;
$start_day+=$dif_day;
$start_month+=$dif_month;
$start_year+=$dif_year;
if (!is_null($end_year) && !is_null($end_month) && !is_null($end_day))
{
$end_day+=$dif_day;
$end_month+=$dif_month;
$end_year+=$dif_year;
}
if ($i==300) break; // Let's be reasonable
}
while (($recurrence!='') && ($recurrence!='none') && ($a<$period_end) && ((is_null($recurrences)) || ($i<$recurrences)));
return $times;
}
tempcode nice_get_event_types(?AUTO_LINK it)
Get a list of event types, taking security into account against the current member.
Parameters…
| Name |
it |
| Description |
The event type to select by default (NULL: none) |
| Default value |
|
| Type |
?AUTO_LINK |
Returns…
| Description |
The list |
| Type |
tempcode |
function nice_get_event_types($it=NULL)
{
$type_list=new ocp_tempcode();
$types=$GLOBALS['SITE_DB']->query_select('calendar_types',array('id','t_title'));
foreach ($types as $type)
{
if (!has_category_access(get_member(),'calendar',strval($type['id']))) continue;
if (!has_submit_permission('low',get_member(),get_ip_address(),'cms_calendar',array('calendar',$type['id']))) continue;
if ($type['id']!=db_get_first_id())
$type_list->attach(form_input_list_entry(strval($type['id']),$type['id']==$it,get_translated_text($type['t_title'])));
else $first_type=$type;
}
if ((has_actual_page_access(get_member(),'admin_occle')) && (is_null($GLOBALS['CURRENT_SHARE_USER'])))
$type_list->attach(form_input_list_entry(strval(db_get_first_id()),db_get_first_id()==$it,get_translated_text($first_type['t_title'])));
return $type_list;
}
void regenerate_event_reminder_jobs(AUTO_LINK id, boolean force)
Regenerate all the calendar jobs for reminders for next occurance of an event (because the event was added or edited).
Parameters…
| Name |
id |
| Description |
The ID of the event |
| Type |
AUTO_LINK |
| Name |
force |
| Description |
Force evaluation even if it's in the past. Only valid for code events |
| Default value |
boolean-false |
| Type |
boolean |
(No return value)
function regenerate_event_reminder_jobs($id,$force=false)
{
$events=$GLOBALS['SITE_DB']->query_select('calendar_events',array('*'),array('id'=>$id),'',1);
if (!array_key_exists(0,$events)) return;
$event=$events[0];
$GLOBALS['SITE_DB']->query_delete('calendar_jobs',array('j_event_id'=>$id));
$period_start=$force?0:NULL;
$recurrences=find_periods_recurrence($event['e_timezone'],$event['e_do_timezone_conv'],$event['e_start_year'],$event['e_start_month'],$event['e_start_day'],is_null($event['e_start_hour'])?0:$event['e_start_hour'],is_null($event['e_start_minute'])?0:$event['e_start_minute'],$event['e_end_year'],$event['e_end_month'],$event['e_end_day'],is_null($event['e_end_hour'])?23:$event['e_end_hour'],is_null($event['e_end_minute'])?0:$event['e_end_minute'],$event['e_recurrence'],min(1,$event['e_recurrences']),$period_start);
if ((array_key_exists(0,$recurrences)) && ($recurrences[0][0]==$recurrences[0][2]/*really starts in window, not just spanning it*/))
{
if ($event['e_type']==db_get_first_id()) // Add system command job if necessary
{
$GLOBALS['SITE_DB']->query_insert('calendar_jobs',array(
'j_time'=>usertime_to_utctime($recurrences[0][0]),
'j_reminder_id'=>NULL,
'j_member_id'=>NULL,
'j_event_id'=>$id
));
} else
{
if (function_exists('set_time_limit')) @set_time_limit(0);
$start=0;
do
{
$reminders=$GLOBALS['SITE_DB']->query_select('calendar_reminders',array('*'),array('e_id'=>$id),'',500,$start);
foreach ($reminders as $reminder)
{
$GLOBALS['SITE_DB']->query_insert('calendar_jobs',array(
'j_time'=>usertime_to_utctime($recurrences[0][0])-$reminder['n_seconds_before'],
'j_reminder_id'=>$reminder['id'],
'j_member_id'=>$reminder['n_member_id'],
'j_event_id'=>$event['id']
));
}
$start+=500;
}
while (array_key_exists(0,$reminders));
}
}
}
string date_range(TIME from, TIME to, boolean do_time)
Create a neatly human-readable date range, using various user-friendly readability tricks.
Parameters…
| Name |
from |
| Description |
From time in user time |
| Type |
TIME |
| Name |
to |
| Description |
To time in user time |
| Type |
TIME |
| Name |
do_time |
| Description |
Whether time is included in this date range |
| Default value |
boolean-true |
| Type |
boolean |
Returns…
| Description |
Textual specially-formatted range |
| Type |
string |
function date_range($from,$to,$do_time=true)
{
if (($to-$from>60*60*24) || (!$do_time))
{
$_length=do_lang('DAYS',integer_format(intval(round(($to-$from)/(60*60*24.0)))));
if (!$do_time) return $_length;
$date=locale_filter(date(do_lang(($to-$from>60*60*24*5)?'calendar_date_range_single_long':'calendar_date_range_single'),$from));
$date2=locale_filter(date(do_lang(($to-$from>60*60*24*5)?'calendar_date_range_single_long':'calendar_date_range_single'),$to));
} else
{
// Duration between times
$_length=display_time_period($to-$from);
$pm_a=date('a',$from);
$pm_b=date('a',$to);
if ($pm_a==$pm_b)
{
$date=str_replace(do_lang('calendar_minute_no_seconds'),'',locale_filter(my_strftime(do_lang('calendar_minute_ampm_known'),$from)));
$date2=str_replace(do_lang('calendar_minute_no_seconds'),'',locale_filter(my_strftime(do_lang('calendar_minute'),$to)));
} else
{
$date=str_replace(do_lang('calendar_minute_no_seconds'),'',locale_filter(my_strftime(do_lang('calendar_minute'),$from)));
$date2=str_replace(do_lang('calendar_minute_no_seconds'),'',locale_filter(my_strftime(do_lang('calendar_minute'),$to)));
}
}
return do_lang('EVENT_TIME_RANGE',$date,$date2,$_length);
}
array calendar_matches(MEMBER member_id, boolean restrict, ?TIME period_start, ?TIME period_end, ?array filter, boolean do_rss)
Detect calendar matches in a time period, in user-time.
Parameters…
| Name |
member_id |
| Description |
The member to detect conflicts for |
| Type |
MEMBER |
| Name |
restrict |
| Description |
Whether to restrict only to viewable events for the current member |
| Type |
boolean |
| Name |
period_start |
| Description |
The timestamp that found times must exceed. In user-time (NULL: use find_periods_recurrence default) |
| Type |
?TIME |
| Name |
period_end |
| Description |
The timestamp that found times must not exceed. In user-time (NULL: use find_periods_recurrence default) |
| Type |
?TIME |
| Name |
filter |
| Description |
The type filter (NULL: none) |
| Default value |
|
| Type |
?array |
| Name |
do_rss |
| Description |
Whether to include RSS events in the results |
| Default value |
boolean-true |
| Type |
boolean |
Returns…
| Description |
A list of events happening, with time details |
| Type |
array |
function calendar_matches($member_id,$restrict,$period_start,$period_end,$filter=NULL,$do_rss=true)
{
if (is_null($period_start)) $period_start=utctime_to_usertime(time());
if (is_null($period_end)) $period_end=utctime_to_usertime(time()+60*60*24*360*20);
$matches=array();
$where='';
if ($restrict)
{
if ($where!='') $where.=' AND ';
$where.='(e_submitter='.strval((integer)$member_id).' OR e_is_public=1)';
}
if (!is_null($filter))
{
foreach ($filter as $a=>$b)
{
if ($b==0)
{
if ($where!='') $where.=' AND ';
$where.='e_type<>'.strval((integer)substr($a,4));
}
}
}
if ($where!='') $where.=' AND ';
$where.='(validated=1 OR e_is_public=0)';
if (addon_installed('syndication_blocks'))
{
// Determine what feeds to overlay
$feed_urls_todo=array();
for ($i=0;$i<10;$i++)
{
$feed_url=post_param('feed_'.strval($i),ocp_admirecookie('feed_'.strval($i),''));
require_code('users_active_actions');
ocp_setcookie('feed_'.strval($i),$feed_url);
if (($feed_url!='') && (preg_match('#^[\w\d\-\_]*$#',$feed_url)==0))
$feed_urls_todo[$feed_url]=NULL;
}
$_event_types=list_to_map('id',$GLOBALS['SITE_DB']->query_select('calendar_types',array('id','t_title','t_logo','t_external_feed')));
foreach ($_event_types as $j=>$_event_type)
{
if (($_event_type['t_external_feed']!='') && ((is_null($filter)) || (!array_key_exists($_event_type['id'],$filter)) || ($filter[$_event_type['id']]==1)) && (has_category_access(get_member(),'calendar',strval($_event_type['id']))))
$feed_urls_todo[$_event_type['t_external_feed']]=$_event_type['id'];
$_event_types[$j]['text_original']=get_translated_text($_event_type['t_title']);
}
$event_types=collapse_2d_complexity('text_original','t_logo',$_event_types);
// Overlay it
foreach ($feed_urls_todo as $feed_url=>$event_type)
{
$temp_file_path=ocp_tempnam('feed');
require_code('files');
$write_to_file=fopen($temp_file_path,'wb');
http_download_file($feed_url,1024*512,false,false,'ocPortal',NULL,NULL,NULL,NULL,NULL,$write_to_file);
if (($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE']=='text/calendar') || ($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE']=='application/octet-stream'))
{
$data=file_get_contents($temp_file_path);
require_code('calendar_ical');
$whole=end(explode('BEGIN:VCALENDAR',$data));
$events=explode('BEGIN:VEVENT',$whole);
$calendar_nodes=array();
foreach ($events as $key=>$items)
{
$nodes=explode("\n",$items);
foreach ($nodes as $childs)
{
if (preg_match('#^[^"]*:#',$childs)!=0)
$child=explode(':',$childs,2);
else $child=array($childs);
$matches2=array();
if (preg_match('#;TZID=(.*)#',$child[0],$matches2))
$calendar_nodes[$key]['TZID']=$matches2[1];
$child[0]=preg_replace('#;.*#','',$child[0]);
if (array_key_exists("1",$child) && $child[0]!=='PRODID' && $child[0]!=='VERSION' && $child[0]!=='END')
$calendar_nodes[$key][$child[0]]=str_replace(array('\n','\,'),array("\n",','),trim($child[1]," \t\""));
}
if ($key!=0)
{
list($full_url,$type,$recurrence,$recurrences,$seg_recurrences,$title,$content,$priority,$is_public,$start_year,$start_month,$start_day,$start_hour,$start_minute,$end_year,$end_month,$end_day,$end_hour,$end_minute,$timezone,$validated,$allow_rating,$allow_comments,$allow_trackbacks,$notes)=get_event_data_ical($calendar_nodes[$key]);
$is_public=1;
$event=array('e_recurrence'=>$recurrence,'e_content'=>$content,'e_title'=>$title,'e_id'=>$feed_url,'e_priority'=>$priority,'t_logo'=>'calendar/rss','e_recurrences'=>$recurrences,'e_seg_recurrences'=>$seg_recurrences,'e_is_public'=>$is_public,'e_start_year'=>$start_year,'e_start_month'=>$start_month,'e_start_day'=>$start_day,'e_start_hour'=>$start_hour,'e_start_minute'=>$start_minute,'e_end_year'=>$end_year,'e_end_month'=>$end_month,'e_end_day'=>$end_day,'e_end_hour'=>$end_hour,'e_end_minute'=>$end_minute,'e_timezone'=>$timezone);
if (!is_null($event_type)) $event['t_logo']=$_event_types[$event_type]['t_logo'];
if (!is_null($type))
{
$event['t_title']=$type;
if (array_key_exists($type,$event_types))
$event['t_logo']=$event_types[$type];
}
$their_times=find_periods_recurrence($timezone,0,$start_year,$start_month,$start_day,$start_hour,$start_minute,$end_year,$end_month,$end_day,$end_hour,$end_minute,$recurrence,$recurrences,$period_start,$period_end);
// Now search every combination to see if we can get a hit
foreach ($their_times as $their)
{
$matches[]=array($full_url,$event,$their[0],$their[1],$their[2],$their[3],$their[4],$their[5]);
}
}
}
} else
{
require_code('rss');
$rss=new rss($temp_file_path,true);
$content=new ocp_tempcode();
foreach ($rss->gleamed_items as $item)
{
if (array_key_exists('guid',$item)) $full_url=$item['guid'];
elseif (array_key_exists('comment_url',$item)) $full_url=$item['comment_url'];
elseif (array_key_exists('full_url',$item)) $full_url=$item['full_url'];
else $full_url='';
if ((array_key_exists('title',$item)) && (array_key_exists('clean_add_date',$item)) && ($full_url!=''))
{
$event=array('e_recurrence'=>'none','e_content'=>array_key_exists('news',$item)?$item['news']:'','e_title'=>$item['title'],'e_id'=>$full_url,'e_priority'=>'na','t_logo'=>'calendar/rss','e_recurrences'=>1,'e_seg_recurrences'=>'','e_is_public'=>1,'e_timezone'=>get_users_timezone());
if (!is_null($event_type)) $event['t_logo']=$_event_types[$event_type]['t_logo'];
if (array_key_exists('category',$item))
{
$event['t_title']=$item['category'];
if (array_key_exists($item['category'],$event_types))
$event['t_logo']=$event_types[$item['category']];
}
$from=utctime_to_usertime($item['clean_add_date']);
if (($from>=$period_start) && ($from<$period_end))
{
$event+=array('e_start_year'=>date('Y',$from),'e_start_month'=>date('m',$from),'e_start_day'=>date('D',$from),'e_start_hour'=>date('H',$from),'e_start_minute'=>date('i',$from),'e_end_year'=>NULL,'e_end_month'=>NULL,'e_end_day'=>NULL,'e_end_hour'=>NULL,'e_end_minute'=>NULL);
$matches[]=array($full_url,$event,$from,NULL,$from,NULL,$from,NULL);
}
}
}
}
unlink($temp_file_path);
}
}
if ($where!='') $where.=' AND ';
$where.='(((e_start_month>='.strval(intval(date('m',$period_start))-1).' OR e_start_year>'.date('Y',$period_start).') AND (e_end_month<='.strval(intval(date('m',$period_end))+1).' OR e_end_year<'.date('Y',$period_end).')) OR '.db_string_not_equal_to('e_recurrence','').')';
$where=' WHERE '.$where;
$event_count=$GLOBALS['SITE_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM '.$GLOBALS['SITE_DB']->get_table_prefix().'calendar_events e LEFT JOIN '.$GLOBALS['SITE_DB']->get_table_prefix().'calendar_types t ON e.e_type=t.id'.$where);
if ($event_count>2000)
{
attach_message(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'),'inform');
return array();
}
$events=$GLOBALS['SITE_DB']->query('SELECT *,e.id AS e_id FROM '.$GLOBALS['SITE_DB']->get_table_prefix().'calendar_events e LEFT JOIN '.$GLOBALS['SITE_DB']->get_table_prefix().'calendar_types t ON e.e_type=t.id'.$where);
foreach ($events as $event)
{
if (!has_category_access(get_member(),'calendar',strval($event['e_type']))) continue;
$their_times=find_periods_recurrence($event['e_timezone'],$event['e_do_timezone_conv'],$event['e_start_year'],$event['e_start_month'],$event['e_start_day'],$event['e_start_hour'],$event['e_start_minute'],$event['e_end_year'],$event['e_end_month'],$event['e_end_day'],$event['e_end_hour'],$event['e_end_minute'],$event['e_recurrence'],$event['e_recurrences'],$period_start,$period_end);
// Now search every combination to see if we can get a hit
foreach ($their_times as $their)
{
$matches[]=array($event['e_id'],$event,$their[0],$their[1],$their[2],$their[3],$their[4],$their[5]);
}
}
global $M_SORT_KEY;
$M_SORT_KEY=2;
usort($matches,'multi_sort');
return $matches;
}
tempcode nice_get_events(?MEMBER only_owned, ?AUTO_LINK it, boolean edit_viewable_events)
Get a list of events to edit.
Parameters…
| Name |
only_owned |
| Description |
Only show events owned by this member (NULL: no such limitation) |
| Type |
?MEMBER |
| Name |
it |
| Description |
Event to select by default (NULL: no specific default) |
| Type |
?AUTO_LINK |
| Name |
edit_viewable_events |
| Description |
Whether owned public events should be shown |
| Default value |
boolean-true |
| Type |
boolean |
Returns…
| Description |
The list |
| Type |
tempcode |
function nice_get_events($only_owned,$it,$edit_viewable_events=true)
{
$where=array();
if (!is_null($only_owned)) $where['e_submitter']=$only_owned;
if (!$edit_viewable_events) $where['e_is_public']=0;
if ($GLOBALS['SITE_DB']->query_value('calendar_events','COUNT(*)')>500) warn_exit(do_lang_tempcode('TOO_MANY_TO_CHOOSE_FROM'));
$events=$GLOBALS['SITE_DB']->query_select('calendar_events',array('id','e_title','e_type'),$where);
$list=new ocp_tempcode();
foreach ($events as $event)
{
if (!has_category_access(get_member(),'calendar',strval($event['e_type']))) continue;
$list->attach(form_input_list_entry(strval($event['id']),$event['id']==$it,get_translated_text($event['e_title'])));
}
return $list;
}
?tempcode detect_conflicts(MEMBER member_id, AUTO_LINK skip_id, ?integer start_year, ?integer start_month, ?integer start_day, ?integer start_hour, ?integer start_minute, ?integer end_year, ?integer end_month, ?integer end_day, ?integer end_hour, ?integer end_minute, string recurrence, ?integer recurrences)
Detect conflicts with an event at a certain time.
Parameters…
| Name |
member_id |
| Description |
The member to detect conflicts for |
| Type |
MEMBER |
| Name |
skip_id |
| Description |
The event ID that we are detecting conflicts with (we need this so we don't think we conflict with ourself) |
| Type |
AUTO_LINK |
| Name |
start_year |
| Description |
The year the event starts at. This and the below are in server time (NULL: default) |
| Type |
?integer |
| Name |
start_month |
| Description |
The month the event starts at (NULL: default) |
| Type |
?integer |
| Name |
start_day |
| Description |
The day the event starts at (NULL: default) |
| Type |
?integer |
| Name |
start_hour |
| Description |
The hour the event starts at (NULL: default) |
| Type |
?integer |
| Name |
start_minute |
| Description |
The minute the event starts at (NULL: default) |
| Type |
?integer |
| Name |
end_year |
| Description |
The year the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_month |
| Description |
The month the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_day |
| Description |
The day the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_hour |
| Description |
The hour the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
end_minute |
| Description |
The minute the event ends at (NULL: not a multi day event) |
| Type |
?integer |
| Name |
recurrence |
| Description |
The event recurrence |
| Type |
string |
| Name |
recurrences |
| Description |
The number of recurrences (NULL: none/infinite) |
| Type |
?integer |
Returns…
| Description |
Information about conflicts (NULL: none) |
| Type |
?tempcode |
function detect_conflicts($member_id,$skip_id,$start_year,$start_month,$start_day,$start_hour,$start_minute,$end_year,$end_month,$end_day,$end_hour,$end_minute,$recurrence,$recurrences)
{
$our_times=find_periods_recurrence(get_users_timezone(),1,$start_year,$start_month,$start_day,$start_hour,$start_minute,$end_year,$end_month,$end_day,$end_hour,$end_minute,$recurrence,$recurrences);
$conflicts=detect_happening_at($member_id,$skip_id,$our_times,!has_specific_permission(get_member(),'sense_personal_conflicts'));
$out=new ocp_tempcode();
$found_ids=array();
foreach ($conflicts as $conflict)
{
list($id,$event,,)=$conflict;
// Only show a conflict once
if (array_key_exists($id,$found_ids)) continue;
$found_ids[$id]=1;
$url=build_url(array('page'=>'_SELF','type'=>'view','id'=>$id),'_SELF');
$conflict=(($event['e_is_public']==1) || ($event['e_submitter']==get_member()))?make_string_tempcode(escape_html(get_translated_text($event['e_title']))):do_lang_tempcode('PRIVATE_HIDDEN');
$out->attach(do_template('CALENDAR_EVENT_CONFLICT',array('_GUID'=>'2e209eae2dfe2ee74df61c0f4ffe1651','URL'=>$url,'ID'=>strval($id),'TITLE'=>$conflict)));
}
if (!$out->is_empty()) return $out;
return NULL;
}
integer find_timezone_start_hour_in_utc(ID_TEXT timezone, integer year, integer month, integer day)
Find first hour in day for a timezone.
Parameters…
| Name |
timezone |
| Description |
Timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
Returns…
| Description |
Hour |
| Type |
integer |
function find_timezone_start_hour_in_utc($timezone,$year,$month,$day)
{
$t1=mktime(0,0,0,$month,$day,$year);
$t2=tz_time($t1,$timezone);
$t2-=2*($t2-$t1);
$ret=intval(date('H',$t2));
return $ret;
}
integer find_timezone_start_minute_in_utc(ID_TEXT timezone, integer year, integer month, integer day)
Find first minute in day for a timezone. Usually 0, but some timezones have 30 min offsets.
Parameters…
| Name |
timezone |
| Description |
Timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
Returns…
| Description |
Hour |
| Type |
integer |
function find_timezone_start_minute_in_utc($timezone,$year,$month,$day)
{
$t1=mktime(0,0,0,$month,$day,$year);
$t2=tz_time($t1,$timezone);
$t2-=2*($t2-$t1);
$ret=intval(date('i',$t2));
return $ret;
}
integer find_timezone_end_hour_in_utc(ID_TEXT timezone, integer year, integer month, integer day)
Find last hour in day for a timezone.
Parameters…
| Name |
timezone |
| Description |
Timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
Returns…
| Description |
Hour |
| Type |
integer |
function find_timezone_end_hour_in_utc($timezone,$year,$month,$day)
{
$t1=mktime(23,59,0,$month,$day,$year);
$t2=tz_time($t1,$timezone);
$t2-=2*($t2-$t1);
$ret=intval(date('H',$t2));
return $ret;
}
integer find_timezone_end_minute_in_utc(ID_TEXT timezone, integer year, integer month, integer day)
Find last minute in day for a timezone. Usually 59, but some timezones have 30 min offsets.
Parameters…
| Name |
timezone |
| Description |
Timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
Returns…
| Description |
Hour |
| Type |
integer |
function find_timezone_end_minute_in_utc($timezone,$year,$month,$day)
{
$t1=mktime(23,59,0,$month,$day,$year);
$t2=tz_time($t1,$timezone);
$t2-=2*($t2-$t1);
$ret=intval(date('i',$t2));
return $ret;
}
TIME cal_get_start_utctime_for_event(ID_TEXT timezone, integer year, integer month, integer day, ?integer hour, ?integer minute, boolean show_in_users_timezone)
Get the UTC start time for a specified UTC time event.
Parameters…
| Name |
timezone |
| Description |
The timezone it is in; used to derive $hour and $minute if those are NULL, such that they start the day correctly for this timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
| Name |
hour |
| Description |
Hour (NULL: start hour of day in the timezone expressed as UTC, for whatever day the given midnight day/month/year shifts to after timezone conversion) |
| Type |
?integer |
| Name |
minute |
| Description |
Minute (NULL: start minute of day in the timezone expressed as UTC, for whatever day the given midnight day/month/year shifts to after timezone conversion) |
| Type |
?integer |
| Name |
show_in_users_timezone |
| Description |
Whether the time should be converted to the viewer's own timezone instead. |
| Type |
boolean |
Returns…
| Description |
Timestamp |
| Type |
TIME |
function cal_get_start_utctime_for_event($timezone,$year,$month,$day,$hour,$minute,$show_in_users_timezone)
{
$_hour=is_null($hour)?0:$hour;
$_minute=is_null($minute)?0:$minute;
$timestamp=mktime(
$_hour,
$_minute,
0,
$month,
$day,
$year
);
if (is_null($hour))
{
$timestamp_day_end=mktime(
23,
59,
0,
$month,
$day,
$year
);
$timezoned_timestamp=tz_time($timestamp_day_end,$timezone);
$timezoned_timestamp_day_start=mktime(
0,
0,
0,
intval(date('m',$timezoned_timestamp)),
intval(date('d',$timezoned_timestamp)),
intval(date('Y',$timezoned_timestamp))
);
if (!$show_in_users_timezone) return $timezoned_timestamp_day_start;
return $timezoned_timestamp_day_start+($timestamp_day_end-$timezoned_timestamp);
}
if (!$show_in_users_timezone) // Move into timezone, as if that is UTC, as it won't get converted later
{
$timestamp=tz_time($timestamp,$timezone);
}
return $timestamp;
}
TIME cal_get_end_utctime_for_event(ID_TEXT timezone, integer year, integer month, integer day, ?integer hour, ?integer minute, boolean show_in_users_timezone)
Get the UTC end time for a specified UTC time event.
Parameters…
| Name |
timezone |
| Description |
Timezone |
| Type |
ID_TEXT |
| Name |
year |
| Description |
Year |
| Type |
integer |
| Name |
month |
| Description |
Month |
| Type |
integer |
| Name |
day |
| Description |
Day |
| Type |
integer |
| Name |
hour |
| Description |
Hour (NULL: end hour of day in the timezone expressed as UTC, for whatever day the given midnight day/month/year shifts to after timezone conversion) |
| Type |
?integer |
| Name |
minute |
| Description |
Minute (NULL: end minute of day in the timezone expressed as UTC, for whatever day the given midnight day/month/year shifts to after timezone conversion) |
| Type |
?integer |
| Name |
show_in_users_timezone |
| Description |
Whether the time should be converted to the viewer's own timezone instead. |
| Type |
boolean |
Returns…
| Description |
Timestamp |
| Type |
TIME |
function cal_get_end_utctime_for_event($timezone,$year,$month,$day,$hour,$minute,$show_in_users_timezone)
{
$_hour=is_null($hour)?23:$hour;
$_minute=is_null($minute)?59:$minute;
$timestamp=mktime(
$_hour,
$_minute,
0,
$month,
$day,
$year
);
if (is_null($hour))
{
$timestamp_day_start=mktime(
0,
0,
0,
$month,
$day,
$year
);
$timezoned_timestamp=tz_time($timestamp_day_start,$timezone);
$timezoned_timestamp_day_end=mktime(
23,
59,
0,
intval(date('m',$timezoned_timestamp)),
intval(date('d',$timezoned_timestamp)),
intval(date('Y',$timezoned_timestamp))
);
if (!$show_in_users_timezone) return $timezoned_timestamp_day_end;
return $timezoned_timestamp_day_end+($timestamp_day_start-$timezoned_timestamp);
}
if (!$show_in_users_timezone) // Move into timezone, as if that is UTC, as it won't get converted later
{
$timestamp=tz_time($timestamp,$timezone);
}
return $timestamp;
}
TIME cal_utctime_to_usertime(TIME utc_timestamp, ID_TEXT default_timezone, boolean show_in_users_timezone)
Put a timestamp into the correct timezone for being reported onto the calendar.
Parameters…
| Name |
utc_timestamp |
| Description |
Timestamp (proper UTC timestamp, not in user time) |
| Type |
TIME |
| Name |
default_timezone |
| Description |
The timezone associated with the event (the passed $utc_timestamp should NOT be relative to this timezone, that must be UTC) |
| Type |
ID_TEXT |
| Name |
show_in_users_timezone |
| Description |
Whether the time should be converted to the viewer's own timezone instead |
| Type |
boolean |
Returns…
| Description |
Altered timestamp |
| Type |
TIME |
function cal_utctime_to_usertime($utc_timestamp,$default_timezone,$show_in_users_timezone)
{
if (!$show_in_users_timezone) return $utc_timestamp;
return tz_time($utc_timestamp,get_users_timezone());
}
array detect_happening_at(MEMBER member_id, AUTO_LINK skip_id, array our_times, boolean restrict, ?TIME period_start, ?TIME period_end)
Detect conflicts with an event in certain time periods.
Parameters…
| Name |
member_id |
| Description |
The member to detect conflicts for |
| Type |
MEMBER |
| Name |
skip_id |
| Description |
The event ID that we are detecting conflicts with (we need this so we don't think we conflict with ourself) |
| Type |
AUTO_LINK |
| Name |
our_times |
| Description |
List of pairs specifying our happening time (in time order) |
| Type |
array |
| Name |
restrict |
| Description |
Whether to restrict only to viewable events for the current member |
| Default value |
boolean-true |
| Type |
boolean |
| Name |
period_start |
| Description |
The timestamp that found times must exceed. In user-time (NULL: use find_periods_recurrence default) |
| Default value |
|
| Type |
?TIME |
| Name |
period_end |
| Description |
The timestamp that found times must not exceed. In user-time (NULL: use find_periods_recurrence default) |
| Default value |
|
| Type |
?TIME |
Returns…
| Description |
A list of events happening, with time details |
| Type |
array |
function detect_happening_at($member_id,$skip_id,$our_times,$restrict=true,$period_start=NULL,$period_end=NULL)
{
if (count($our_times)==0) return array();
$conflicts=array();
$where=is_null($skip_id)?'':('id<>'.strval($skip_id));
if ($restrict)
{
if ($where!='') $where.=' AND ';
$where.='(e_submitter='.strval((integer)$member_id).' OR e_is_public=1)';
}
if ($where!='') $where.=' AND ';
$where.='(validated=1 OR e_is_public=0)';
$where.=' AND (((e_start_month>='.strval(intval(date('m',$our_times[0][0]))-1).' OR e_start_year>'.date('Y',$our_times[0][0]).') AND (e_end_month<='.strval(intval(date('m',$our_times[0][1]))+1).' OR e_end_year<'.date('Y',$our_times[0][1]).')) OR '.db_string_not_equal_to('e_recurrence','').')';
$where=' WHERE '.$where;
$table='calendar_events e';
$events=$GLOBALS['SITE_DB']->query('SELECT *,e.id AS e_id FROM '.$GLOBALS['SITE_DB']->get_table_prefix().$table.$where);
foreach ($events as $event)
{
if (!has_category_access(get_member(),'calendar',strval($event['e_type']))) continue;
$their_times=find_periods_recurrence(
$event['e_timezone'],
1,
$event['e_start_year'],
$event['e_start_month'],
$event['e_start_day'],
is_null($event['e_start_hour'])?find_timezone_start_hour_in_utc($event['e_timezone'],$event['e_start_year'],$event['e_start_month'],$event['e_start_day']):$event['e_start_hour'],
is_null($event['e_start_minute'])?find_timezone_start_minute_in_utc($event['e_timezone'],$event['e_start_year'],$event['e_start_month'],$event['e_start_day']):$event['e_start_minute'],
$event['e_end_year'],
$event['e_end_month'],
$event['e_end_day'],
is_null($event['e_end_hour'])?find_timezone_end_hour_in_utc($event['e_timezone'],$event['e_end_year'],$event['e_end_month'],$event['e_end_day']):$event['e_end_hour'],
is_null($event['e_end_minute'])?find_timezone_end_minute_in_utc($event['e_timezone'],$event['e_end_year'],$event['e_end_month'],$event['e_end_day']):$event['e_end_minute'],
$event['e_recurrence'],
$event['e_recurrences'],
$period_start,
$period_end
);
// Now search every combination to see if we can get a hit
foreach ($our_times as $our)
{
foreach ($their_times as $their)
{
$conflict=false;
if ((is_null($our[3])) && (is_null($their[3]))) // Has to be exactly the same
{
if ($our[2]==$their[2]) $conflict=true;
}
elseif ((is_null($our[3])) && (!is_null($their[3]))) // Ours has to occur within their period
{
if (($our[2]>=$their[2]) && ($our[2]<$their[3])) $conflict=true;
}
elseif ((!is_null($our[3])) && (is_null($their[3]))) // Theirs has to occur within our period
{
if (($their[2]>=$our[2]) && ($their[2]<$our[3])) $conflict=true;
}
elseif ((!is_null($our[3])) && (!is_null($their[3]))) // The two periods need to overlap
{
if (($our[2]>=$their[2]) && ($our[2]<$their[3])) $conflict=true;
if (($their[2]>=$our[2]) && ($their[2]<$our[3])) $conflict=true;
}
if ($conflict)
{
$conflicts[]=array($event['e_id'],$event,$their[2],$their[3]);
break 2;
}
}
}
}
return $conflicts;
}
0 reviews: Unrated (average)
There have been no comments yet