aboutsummaryrefslogtreecommitdiffstats
path: root/functions/parse/end_vevent.php
diff options
context:
space:
mode:
authorJim Hu <jimhu@users.sourceforge.net>2008-12-15 17:25:27 +0000
committerJim Hu <jimhu@users.sourceforge.net>2008-12-15 17:25:27 +0000
commitcb1509c1c670974f54ed67d2076fef39e0d20812 (patch)
tree7f7f64c60ad63cf884cf5562565f46cffd3f9597 /functions/parse/end_vevent.php
parent99cfde6479207ba9349d8c4a093ef14a1026154d (diff)
downloadphpicalendar-cb1509c1c670974f54ed67d2076fef39e0d20812.tar.gz
phpicalendar-cb1509c1c670974f54ed67d2076fef39e0d20812.tar.bz2
phpicalendar-cb1509c1c670974f54ed67d2076fef39e0d20812.zip
big changes to recurrence; trying to get closer to the spec
Diffstat (limited to 'functions/parse/end_vevent.php')
-rw-r--r--functions/parse/end_vevent.php391
1 files changed, 112 insertions, 279 deletions
diff --git a/functions/parse/end_vevent.php b/functions/parse/end_vevent.php
index 33175cf..5cf2c35 100644
--- a/functions/parse/end_vevent.php
+++ b/functions/parse/end_vevent.php
@@ -3,12 +3,14 @@
What happens in this file:
1. Initialization: add information not present by default
-2.
+ a. duration
+ b. class
+ c. uid
+ d. adjust start_time and end_time
+2. Build recur_data array
+3. Add occurrences to master_array
*/
-if (!isset($url)) $url = '';
-if (!isset($type)) $type = '';
-
// Handle DURATION
if (!isset($end_unixtime)) {
if(!isset($the_duration)) $the_duration = 0;
@@ -36,13 +38,6 @@ if (!isset($uid)) {
$uid_valid = true;
}
-if (!isset($summary)) $summary = '';
-if (!isset($description)) $description = '';
-if (!isset($status)) $status = '';
-if (!isset($class)) $class = '';
-if (!isset($location)) $location = '';
-
-
# adjust event start and end times
if (isset($start_time) && isset($end_time)) {
// Mozilla style all-day events or just really long events
@@ -112,26 +107,8 @@ if (isset($allday_start) && $allday_start != '') {
$rrule_array['END_TIME'] = $end_time;
# $rrule_array['END'] = 'end';
}
-
-$start_date_time = strtotime($start_date);
-if (!isset($fromdate)){
- #this should happen if not in one of the rss views
- $this_month_start_time = strtotime($this_year.$this_month.'01');
- if ($current_view == 'year' || ($save_parsed_cals == 'yes' && !$is_webcal)|| $current_view == 'print' && $printview == 'year') {
- $start_range_time = strtotime($this_year.'-01-01 -2 weeks');
- $end_range_time = strtotime($this_year.'-12-31 +2 weeks');
- } else {
- $start_range_time = strtotime('-1 month -2 day', $this_month_start_time);
- $end_range_time = strtotime('+2 month +2 day', $this_month_start_time);
- }
-}else{
- $start_range_time = strtotime($fromdate);
- $end_range_time = strtotime($todate)+60*60*24;
-}
-
-$freq_type = 'year';
-$interval = 1;
+$freq_type = 'none';
# Load $rrule_array
foreach ($rrule_array as $key => $val) {
switch($key) {
@@ -157,7 +134,7 @@ foreach ($rrule_array as $key => $val) {
if (strlen($until) == 8) $until = $until.'235959';
$abs_until = $until;
ereg ('([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})', $until, $regs);
- $until = mktime($regs[4],$regs[5],$regs[6],$regs[2],$regs[3],$regs[1]);
+ $until_unixtime = mktime($regs[4],$regs[5],@$regs[6],$regs[2],$regs[3],$regs[1]);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = localizeDate($dateFormat_week,$until);
break;
case 'INTERVAL':
@@ -167,47 +144,39 @@ foreach ($rrule_array as $key => $val) {
}
break;
case 'BYSECOND':
- $bysecond = $val;
- $bysecond = split (',', $bysecond);
+ $bysecond = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $bysecond;
break;
case 'BYMINUTE':
- $byminute = $val;
- $byminute = split (',', $byminute);
+ $byminute = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $byminute;
break;
case 'BYHOUR':
- $byhour = $val;
- $byhour = split (',', $byhour);
+ $byhour = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $byhour;
break;
case 'BYDAY':
- $byday = $val;
- $byday = split (',', $byday);
+ $byday = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $byday;
break;
case 'BYMONTHDAY':
- $bymonthday = $val;
- $bymonthday = split (',', $bymonthday);
+ $bymonthday = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $bymonthday;
break;
case 'BYYEARDAY':
- $byyearday = $val;
- $byyearday = split (',', $byyearday);
+ $byyearday = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $byyearday;
break;
case 'BYWEEKNO':
- $byweekno = $val;
- $byweekno = split (',', $byweekno);
+ $byweekno = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $byweekno;
break;
case 'BYMONTH':
- $bymonth = $val;
- $bymonth = split (',', $bymonth);
+ $bymonth = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $bymonth;
break;
case 'BYSETPOS':
- $bysetpos = $val;
+ $bysetpos = split (',', $val);
$recur_array[($start_date)][($hour.$minute)][$uid]['recur'][$key] = $bysetpos;
break;
case 'WKST':
@@ -216,243 +185,98 @@ foreach ($rrule_array as $key => $val) {
break;
}
}
-/*
-Load $recur_array
-$recur_array is an array of unix times for instances of an event. This code handles repeats.
-Note that dates with exceptions are counted as instances.
-RDATE is currently not supported
-*/
# $recur is the recurrence info that goes into the master array for this VEVENT
-$recur = $recur_array[($start_date)][($hour.$minute)][$uid]['recur'];
-
-// if $until isn't set yet, we set it to the end of our range we're looking at
-if (!isset($until)) $until = $end_range_time;
-if (!isset($abs_until)) $abs_until = date('YmdHis', $end_range_time);
-$end_date_time = $until;
-
-// If the $end_range_time is less than the $start_date_time, or $start_range_time is greater
-// than $end_date_time, we may as well forget the whole thing
-// It doesn't do us any good to spend time adding data we aren't even looking at
-// this will prevent the year view from taking way longer than it needs to
-if ($end_range_time >= $start_date_time && $start_range_time_tmp <= $end_date_time) {
-
- // if the beginning of our range is less than the start of the item, we may as well set it equal to it
- if ($start_range_time < $start_date_time){
- $start_range_time = $start_date_time;
- }
- if ($end_range_time > $end_date_time) $end_range_time = $end_date_time;
-
- // initialize the time we will increment
- $next_range_time = $start_range_time;
-
- // start at the $start_range and go until we hit the end of our range.
- if(!isset($wkst)) $wkst='SU';
- $wkst3char = two2threeCharDays($wkst);
+$recur = @$recur_array[($start_date)][($hour.$minute)][$uid]['recur'];
- # set first instance if it's in range
- $recur_data = array();
- if ($start_unixtime < $mArray_end && $end_unixtime > $mArray_begin){
- $recur_data[] = $start_unixtime;
- }
- /*
- The while loop below increments $next_range_time by $freq type. For the larger freq types, there is only
- one $next_range_time per repeat, but the BYXXX rules may write more than one event in that repeat cycle
- $next_date_time handles those instances within a $freq_type
- */
- #echo "<br><br>$summary<br>next range time:".date("Ymd his",$next_range_time)." <br>start range time ".date("Ymd his",$start_range_time)." <br>end range time ".date("Ymd his",$end_range_time);
- while (($next_range_time >= $start_range_time) && ($next_range_time <= $end_range_time)) {
- # pick the right compare function from date_functions.php
- # $diff is the number of occurrences between start_date and next_range_time
- $func = $freq_type.'Compare';
- $diff = $func(date('Ymd',$next_range_time), $start_date);
- $rcount = $diff;
- if(count($byday) > 1) $rcount = $diff * count($byday);
- if ($rcount < $count && $diff % $interval == 0) {
- $year = date('Y', $next_range_time);
- $month = date('m', $next_range_time);
- switch ($rrule_array['FREQ']) {
- case 'DAILY':
- $recur_data[] = $next_range_time;
- break;
- case 'WEEKLY':
- // Populate $byday with the default day if it's not set.
- if (!isset($byday)) $byday[] = strtoupper(substr(date('D', $start_date_time), 0, 2));
- $the_sunday = dateOfWeek(date("Ymd",$next_range_time), $wkst3char);
- foreach($byday as $key=>$day) {
- $day = two2threeCharDays($day);
- #need to find the first day of the appropriate week.
- if ($key == 0){
- $next_date_time = strtotime("next $day",strtotime($the_sunday)) + (12 * 60 * 60);
- }else{
- $next_date_time = strtotime("next $day",$next_date_time) + (12 * 60 * 60);
- }
- $recur_data[] = $next_date_time; #echo "<br>$key $day ".strtotime("Ymd his", $next_date_time);
- }
- break;
- case 'MONTHLY':
- if (empty($bymonth)) $bymonth = array(1,2,3,4,5,6,7,8,9,10,11,12);
- if (!empty($bysetpos)){
- /* bysetpos code from dustinbutler
- start on day 1 or last day.
- if day matches any BYDAY the count is incremented.
- SETPOS = 4, need 4th match
- SETPOS = -1, need 1st match
- */
- if ($bysetpos > 0) {
- $next_day = '+1 day';
- $day = 1;
- } else {
- $next_day = '-1 day';
- $day = $totalDays[$month];
- }
- $day = mktime(0, 0, 0, $month, $day, $year);
- $countMatch = 0;
- while ($countMatch != abs($bysetpos)) {
- /* Does this day match a BYDAY value? */
- $thisDay = $day;
- $textDay = strtoupper(substr(date('D', $thisDay), 0, 2));
- if (in_array($textDay, $byday)) {
- $countMatch++;
- }
- $day = strtotime($next_day, $thisDay);
- }
- if(in_array(date("m", $next_date_time), $bymonth)) $recur_data[] = $next_date_time;
- }elseif (count($bymonthday) > 0 && empty($byday)) {
- foreach($bymonthday as $day) {
- if ($day < 0) $day = ((date('t', $next_range_time)) + ($day)) + 1;
- if (checkdate($month,$day,$year)) {
- $next_date_time = mktime(0,0,0,$month,$day,$year);
- if(in_array(date("m", $next_date_time), $bymonth)) $recur_data[] = $next_date_time;
- }
- }
- } else {
- foreach($byday as $day) {
- /* set $byday_arr
- [0] => byday string, e.g. 4TH
- [1] => sign/modifier
- [2] => 4 number
- [3] => TH day abbr
- */
- ereg ('([-\+]{0,1})?([0-9]{1})?([A-Z]{2})', $day, $byday_arr);
- $on_day = two2threeCharDays($byday_arr[3]);
- $next_date_time = strtotime($byday_arr[1].$byday_arr[2].$on_day, $next_range_time);
- if(empty($bymonthday) && in_array(date("m", $next_date_time), $bymonth)) $recur_data[] = $next_date_time;
-
- if (isset($bymonthday) && (!empty($bymonthday))) {
- // This supports MONTHLY where BYDAY and BYMONTH are both set
- foreach($bymonthday as $day) {
- if (checkdate($month,$day,$year)) {
- $next_date_time = mktime(0,0,0,$month,$day,$year);
- $daday = strtolower(strftime("%a", $next_date_time));
- if ($daday == $on_day && in_array($month, $bymonth)) {
- if(in_array(date("m", $next_date_time), $bymonth)) $recur_data[] = $next_date_time;
- }
- }
- }
- }
- } # end foreach $byday
- }
- break;
- case 'YEARLY':
- if ((!isset($bymonth)) || (sizeof($bymonth) == 0)) $bymonth = array(date('m', $start_date_time));
- foreach($bymonth as $month) {
- if (isset($bysetpos)){
- /* bysetpos code from dustinbutler
- start on day 1 or last day.
- if day matches any BYDAY the count is incremented.
- SETPOS = 4, need 4th match
- SETPOS = -1, need 1st match
- */
- if ($bysetpos > 0) {
- $next_day = '+1 day';
- $day = 1;
- } else {
- $next_day = '-1 day';
- $day = date("t",$month);
- }
- $day = mktime(12, 0, 0, $month, $day, $year);
- $countMatch = 0;
- while ($countMatch != abs($bysetpos)) {
- /* Does this day match a BYDAY value? */
- $thisDay = $day;
- $textDay = strtoupper(substr(date('D', $thisDay), 0, 2));
- if (in_array($textDay, $byday)) {
- $countMatch++;
- }
- $day = strtotime($next_day, $thisDay);
- }
- $recur_data[] = $thisDay;
- }
- if ((isset($byday)) && (is_array($byday))) {
- $checkdate_time = mktime(0,0,0,$month,1,$year);
- foreach($byday as $day) {
- ereg ('([-\+]{0,1})?([0-9]{1})?([A-Z]{2})', $day, $byday_arr);
- if ($byday_arr[2] != '') {
- $nth = $byday_arr[2]-1;
- } else {
- $nth = 0;
- }
- $on_day = two2threeCharDays($byday_arr[3]);
- $on_day_num = two2threeCharDays($byday_arr[3],false);
- if ($byday_arr[1] == '-') {
- $last_day_tmp = date('t',$checkdate_time);
- $checkdate_time = strtotime(date('Y-m-'.$last_day_tmp, $checkdate_time));
- $last_tmp = (date('w',$checkdate_time) == $on_day_num) ? '' : 'last ';
- $next_date_time = strtotime($last_tmp.$on_day.' -'.$nth.' week', $checkdate_time);
- } else {
- $next_date_time = strtotime($on_day.' +'.$nth.' week', $checkdate_time);
- }
- }
- } else {
- $day = date('d', $start_date_time);
- $next_date_time = mktime(0,0,0,$month,$day,$year+1);
- //echo date('Ymd',$next_date_time).$summary.'<br>';
- }
- if (isset($next_date_time) && $next_date_time != '') $recur_data[] = $next_date_time;
- }
- if (isset($byyearday)) {
- foreach ($byyearday as $yearday) {
- ereg ('([-\+]{0,1})?([0-9]{1,3})', $yearday, $byyearday_arr);
- if ($byyearday_arr[1] == '-') {
- $ydtime = mktime(0,0,0,12,31,$this_year);
- $yearnum = $byyearday_arr[2] - 1;
- $next_date_time = strtotime('-'.$yearnum.' days', $ydtime);
- } else {
- $ydtime = mktime(0,0,0,1,1,$this_year);
- $yearnum = $byyearday_arr[2] - 1;
- $next_date_time = strtotime('+'.$yearnum.' days', $ydtime);
- }
- if (isset($next_date_time) && $next_date_time != '') $recur_data[] = $next_date_time;
- }
- }
- break;
- default:
- // anything else we need to end the loop
- $next_range_time = $end_range_time + 100;
- } # end switch
- }
- $next_range_time = strtotime('+'.$interval.' '.$freq_type, $next_range_time);
- } #end while loop
-} # end if time compare
+/* ============================ Load $recur_data ============================
+$recur_data is an array of unix times for instances of an event. This code handles repeats.
+Note that dates with exceptions are counted as instances.
+RDATE is currently not supported
+A. Set up the time range to scan for events.
+If COUNT is not set (default is 1,000,000) then we don't have to start at start_date; we can start at the minimum interval for the view.
+variables ending in date are in phpical date format: YYYYMMDD
+variables ending with time are in phpical time format: HHMM
+variables ending in unixtime are in unixtime
-#foreach($recur_data as $time) echo "<br>".date("Ymd his",$time);
+mArray_begin and mArray_end are set in initialization by date_range.php and may be overwritten by rss_common.php. These should be the default for start_range and end_range unixtimes. Conditions where overwrite these:
+ COUNT < 1,000,000 - we have to count occurrences; reset next_range_unixtime starting value
+ $until_unixtime < $mArray_end - stop iterating early
+ !isset($rrule_array['FREQ']) - only iterate once, set the end_range_unixtime to the end_date_unixtime
+Note that start_range_unixtime and end_range_unixtime are not the same as start_date_unixtime and end_date_unixtime */
+$next_range_unixtime = $mArray_begin;
+$end_range_unixtime = $mArray_end+60*60*24;
+$start_date_unixtime = strtotime($start_date);
+if($count < 1000000) $next_range_unixtime = $start_date_unixtime;
+if(isset($until) && $end_range_unixtime > $until_unixtime) $end_range_unixtime = $until_unixtime;
+if(!isset($rrule_array['FREQ'])){
+ $end_range_unixtime = strtotime($end_date);
+ $count = 1;
+}
+// if the beginning of our range is less than the start of the item, we may as well set it equal to it
+if ($next_range_unixtime < $start_date_unixtime) $next_range_unixtime = $start_date_unixtime;
+
+// convert wkst to a 3 char day for strtotime to work
+$wkst3char = two2threeCharDays($wkst);
+/* The while loop below increments $next_range_time by $freq type. For the larger freq types, there is only
+one $next_range_time per repeat, but the BYXXX rules may write more than one event in that repeat cycle
+$next_date_time handles those instances within a $freq_type */
+#echo "<pre>$summary\n\tstart mArray time:".date("Ymd his",$mArray_begin)."\n\tstart range time:".date("Ymd his",$next_range_unixtime)."\n\tend range time ".date("Ymd his",$end_range_unixtime)."</pre>";
+$recur_data = array();
+while ($next_range_unixtime <= $end_range_unixtime) {
+ $year = date('Y', $next_range_unixtime);
+ $month = date('m', $next_range_unixtime);
+ # pick the right compare function from date_functions.php
+ # $diff is the number of occurrences between start_date and next_range_time
+ $func = $freq_type.'Compare';
+ $diff = $func(date('Ymd',$next_range_time), $start_date);
+ switch ($freq_type){
+ case 'day':
+ add_recur($next_range_unixtime);
+ break;
+ case 'week':
+ add_recur(expand_byday($next_range_unixtime));
+ break;
+ case 'month':
+ $next_date_unixtime = mktime(12,0,0,$month,date('d',$start_unixtime),$year); echo "month".date("Ymd his",$next_date_unixtime);
+ add_recur(($next_date_unixtime));
+ break;
+ case 'year':
+ $next_date_unixtime = mktime(12,0,0,date('m',$start_unixtime),date('d',$start_unixtime),$year); echo "year:$hour,$min,0,".date('m',$start_unixtime).",".date('d',$start_unixtime).",$year".date("Ymd his",$next_date_unixtime);print_r($datetime);
+ add_recur(($next_date_unixtime));
+ break;
+ default:
+ add_recur($start_unixtime);
+ break 2;
+ }
+ $next_range_unixtime = strtotime('+'.$interval.' '.$freq_type, $next_range_unixtime);
+} #end while loop
+$recur_data = array_unique($recur_data);
+sort($recur_data);
+echo "<pre>$summary recur_data:";
+#var_dump($recur_data);
+foreach($recur_data as $time) echo "\n".date("Ymd his",$time);
+echo "</pre>";
+if ($count < count($recur_data)){
+ $arr = array_slice($recur_data,0,$count);
+ $recur_data =$arr;
+}
# use recur_data array to write the master array
// use the same code to write the data instead of always changing it 5 times
-$recur_data_hour = @substr($start_time,0,2);
-$recur_data_minute = @substr($start_time,2,2);
-foreach($recur_data as $recur_data_time) {
- $recur_data_year = date('Y', $recur_data_time);
- $recur_data_month = date('m', $recur_data_time);
- $recur_data_day = date('d', $recur_data_time);
+$recur_data_hour = @substr($start_unixtime,0,2);
+$recur_data_minute = @substr($start_unixtime,2,2);
+foreach($recur_data as $recur_data_unixtime) {
+ $recur_data_year = date('Y', $recur_data_unixtime);
+ $recur_data_month = date('m', $recur_data_unixtime);
+ $recur_data_day = date('d', $recur_data_unixtime);
$recur_data_date = $recur_data_year.$recur_data_month.$recur_data_day;
- if (($recur_data_time >= $start_date_time) && ($recur_data_time <= $end_date_time) && ($count_to != $count) && !in_array($recur_data_date, $except_dates)) {
+ if ( !in_array($recur_data_date, $except_dates) ) {
if (isset($allday_start) && $allday_start != '') {
- $start_time2 = $recur_data_time;
- $end_time2 = strtotime('+'.$diff_allday_days.' days', $recur_data_time);
+ $start_time2 = $recur_data_unixtime;
+ $end_time2 = strtotime('+'.$diff_allday_days.' days', $recur_data_unixtime);
while ($start_time2 < $end_time2) {
$start_date2 = date('Ymd', $start_time2);
$master_array[($start_date2)][('-1')][$uid] = array (
@@ -473,7 +297,7 @@ foreach($recur_data as $recur_data_time) {
$start_unixtime_tmp = mktime($recur_data_hour,$recur_data_minute,0,$recur_data_month,$recur_data_day,$recur_data_year);
$end_unixtime_tmp = $start_unixtime_tmp + $length;
- if (($end_time >= $bleed_time) && ($bleed_check == '-1')) {
+ if (($end_time >= $phpiCal_config->bleed_time) && ($bleed_check == '-1')) {
$start_tmp = strtotime(date('Ymd',$start_unixtime_tmp));
$end_date_tmp = date('Ymd',$end_unixtime_tmp);
while ($start_tmp < $end_unixtime_tmp) {
@@ -530,8 +354,6 @@ foreach($recur_data as $recur_data_time) {
if (!isset($end_time_tmp1)) $end_time_tmp1 = $end_time;
// Let's double check the until to not write past it
- $until_check = $recur_data_date.$hour.$minute.'00';
- if ($abs_until > $until_check) {
$master_array[($recur_data_date)][($hour.$minute)][$uid] = array (
'event_start' => $start_time,
'event_end' => $end_time_tmp1,
@@ -555,7 +377,7 @@ foreach($recur_data as $recur_data_time) {
$master_array[($recur_data_date)][($hour.$minute)][$uid]['display_end'] = $display_end_tmp;
}
checkOverlap($recur_data_date, ($hour.$minute), $uid);
- }
+
}
}
}
@@ -580,5 +402,16 @@ if (is_array($except_dates)) {
// Clear event data now that it's been saved.
unset($start_time, $start_time_tmp, $end_time, $end_time_tmp, $start_unixtime, $start_unixtime_tmp, $end_unixtime, $end_unixtime_tmp, $summary, $length, $description, $status, $class, $location, $organizer, $attendee);
-
+//If you want to see the values in the arrays, uncomment below.
+//print '<pre>';
+//print_r($master_array);
+//print_r($overlap_array);
+//print_r($day_array);
+//print_r($rrule_array);
+//print_r($byday_arr);
+//print_r($recurrence_delete);
+//print_r($cal_displaynames);
+//print_r($cal_filelist);
+//print_r($tz_array);
+//print '</pre>';
?> \ No newline at end of file

© 2014-2024 Faster IT GmbH | imprint | privacy policy