function amr_create_date_time($datetimestring, $tzobj) { // date time create with exception trap to avoid fatal errors try { $dt = new DateTime($datetimestring, $tzobj); } catch (Exception $e) { $text = '<br />Unable to create DateTime object from ' . $datetimestring . ' <br />' . $e->getMessage(); amr_tell_admin_the_error($text); return false; } return $dt; }
function amr_generate_repeats(&$event, $astart, $aend, $limit) { /* takes an event and some parameters and generates the repeat events */ $repeats = array(); // and array of dates $newevents = array(); // an array of events if (isset($event['DTSTART'])) { if (is_object($event['DTSTART'])) { $dtstart = $event['DTSTART']; $dt = empty($event['DTSTART']) ? '' : $event['DTSTART']->format('c'); /* begin setting up the event key that will help us check for modifocations - semingly duplicates! - overwrite for repeats */ } else { if (ICAL_EVENTS_DEBUG) { echo '<r><b>DTSTART is not an object</b>' . $event['DTSTART']; } return false; /* it is set, but it is not an aobject ? */ } } else { /* possibly an undated, non repeating VTODO or Vjournal- no repeating to be done if no DTSTART, and no RDATE */ $dt = '-nodtstart'; if (!isset($event['RDATE'])) { if (isset($event['UID'])) { $newevents[$event['UID']] = $event; } else { amr_tell_admin_the_error('There is an invalid event. It has no UID:' . print_r($event, true)); } return $newevents; /* possibly an undated, non repeating VTODO or Vjournal- no repeating to be done if no DTSTART, and no RDATE */ } else { echo 'This event is invalid. It has no DTSTART, but does have RDATE. Not allowed according to ical spec.'; return false; /***check for repeating RDATEs if no start date */ } } /* To handle modifications, use a key to the events, so can match any later mods with a repeating event we may have generated */ $seq = empty($event['SEQUENCE']) ? '0' : $event['SEQUENCE']; /* begin setting up the event key that will help us check for modifications - semingly duplicates!*/ if (!isset($event['UID'])) { $event['UID'] = 'NoUID'; } /* there is no repeating rule, so just copy over */ if (isset($event['RECURRENCE-ID'])) { /* a modification or exceptions to a repeating instance ? */ // $recdate = $dt; if (isset($_GET['debugexc'])) { echo '<br />RECURRENCE-ID:'; var_dump($event['RECURRENCE-ID']); } if (is_array($event['RECURRENCE-ID'])) { /* just take first, should only be one */ $recdateobj = $event['RECURRENCE-ID'][0]; $recdate = $recdateobj->format('YmdHis'); // purely identifies specifc instances of a repeating rule are affected by the exception/modification //20140721 - lost the month in ymd somehow - added back if (isset($_GET['debugexc'])) { echo '<br /> Flag recurrence modification for ' . $recdate; } } else { if (is_object($event['RECURRENCE-ID'])) { /* Then it is a date instance which has been modified . We need to overwrite the appropriate repeating dates. This is done later? *** */ $recdateobj = $event['RECURRENCE-ID']; $recdate = $recdateobj->format('YmdHis'); if (isset($_GET['debugexc'])) { echo '<br />RecurrenceID date to check against event rrule.'; echo $recdate; } } else { /**** should deal with THISANDFUTURE or THISANDPRIOR EG: RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z */ echo '<br>THISAND.... modification to repeating event encountered. This cannot be dealt with yet'; var_dump($event['RECURRENCE-ID']); } } if (amr_event_should_be_shown($event, $astart, $aend) or amr_falls_between($recdateobj, $astart, $aend) or amr_is_same_day($recdateobj, $astart) or amr_is_same_day($recdateobj, $aend)) { $key = $event['UID'] . ' ' . $recdate . ' ' . $seq . '999'; /* By virtue of being a recurrence id it should override a non recurrence (ie normal) even if they have the same sequence */ $newevents[$key] = $event; /* so we drop the old events used to generate the repeats */ $newevents[$key]['EventDate'] = new Datetime(); //if cloning dont need tz $newevents[$key]['EventDate'] = clone $dtstart; if (!amr_create_enddate($newevents[$key])) { if (ICAL_EVENTS_DEBUG) { echo ' ** No end date - is it an alarm? '; } } } else { if (isset($_GET['debugexc'])) { echo '<br /> ' . $recdate . ' not in range and ' . $dtstart->format('c') . ' not in range'; // debug_print_event ($event); } return false; /* the modification and the instance that it relates to are not in our date range */ } } else { /* It is not a recurrence id, may be a repeating, or solo */ if (isset($dtstart)) { if (amr_is_before($dtstart, $aend)) { /* If the start is after our end limit, then skip this event */ //var_dump($event); if (isset($event['RRULE']) or isset($event['RDATE'])) { /* if have, must use dtstart in case we are dependent on it's characteristics,. We can exclude too early dates later on */ $repeats = amr_repeat_anevent($event, $astart, $aend, $limit); /**** try for a more efficient start? */ if (isset($_GET['rdebug']) or ICAL_EVENTS_DEBUG) { if (count($repeats) > 0) { echo '<br>Create repeats: ' . count($repeats); } } /* now need to convert back to a full event by copying the event data for each repeat */ if (is_array($repeats) and count($repeats) > 0) { foreach ($repeats as $i => $r) { $repkey = $event['UID'] . ' ' . $r->format('YmdHis') . ' ' . $seq; /* Don't use timezone - some recurrence id's maybe created with universal dates */ if (isset($newevents[$repkey])) { // error_log('Unexpected Duplication of Repeating Event '.$repkey.' - error in ical file or error in plugin?'); // only happened on weird rrule - may be valid anyway so as not to miss anything } $newevents[$repkey] = $event; // copy the event data over - note objects will point to same object unless we clone Use duration or new /clone Enddate $newevents[$repkey]['EventDate'] = new Datetime(); //if cloning dont need tz $newevents[$repkey]['EventDate'] = clone $r; // if (ICAL_EVENTS_DEBUG) {echo '<br>Created '.$newevents[$repkey]['EventDate']->format('YmdHis l'); } if (!amr_create_enddate($newevents[$repkey])) { if (ICAL_EVENTS_DEBUG) { echo ' ** No end date created, maybe just a start? '; } } } } } else { $key = $event['UID'] . ' ' . $dt . ' ' . $seq; /* No Recurrence id and no RRULE or RDATE */ $newevents[$key] = $event; // copy the event data over - note objects will point to same object - is this an issue? Use duration or new /clone Enddate $newevents[$key]['EventDate'] = new Datetime(); //if cloning dont need tz $newevents[$key]['EventDate'] = clone $dtstart; if (isset($newevents[$key]['DURATION'])) { amr_create_enddate($newevents[$key]); //changed because EndDate not same as DTEND if all day } } } } else { // no starting date $key = $event['UID'] . ' ' . $dt . ' ' . $seq; $newevents[$key] = $event; $newevents[$key]['EventDate'] = ''; } } if (ICAL_EVENTS_DEBUG) { echo '<br />number of newevents = ' . count($newevents); } return $newevents; }
function amr_parseVALUE($VALUE, $text, $tzobj) { /* amr parsing a value like VALUE=PERIOD:19960403T020000Z/19960403T040000Z, 19960404T010000Z/PT3H VALUE=DATE:19970101,19970120,19970217,19970421,.. 19970526,19970704,19970901,19971014,19971128,19971129,19971225 VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Berlin:20061223 */ //if (ICAL_EVENTS_DEBUG) {echo '<br />For value: '.$VALUE.' '.$text;} if (empty($text)) { if (ICAL_EVENTS_DEBUG) { echo '<br />For value: ' . $VALUE . ' text is blank'; } return false; } switch ($VALUE) { case 'DATE-TIME': if (!($d = amr_parseDateTime($text, $tzobj))) { return false; } else { return $d; } case 'DATE': if (!($d = amr_parseDate($text, $tzobj))) { return false; } else { return $d; } case 'PERIOD': if (!($d = amr_parsePeriod($text, $tzobj))) { return false; } else { return $d; } default: /* something like DATE;TZID=/mozilla.org/20070129_1/Europe/Berlin */ $p = explode(';', $VALUE); if (!($p[0] === 'DATE')) { if (ICAL_EVENTS_DEBUG) { echo 'Error: Unexpected data in file '; print_r($p); } return false; } else { if (substr($p[1], 0, 4) === 'TZID') { /* then we have a weird TZ */ $tzobj = amr_deal_with_tzpath_in_date(substr($p[1], 5)); /* pass the rest of the string over for tz extraction */ if (!($d = amr_parseDate($text, $tzobj))) { amr_tell_admin_the_error('Fail parse tz date' . $p[1]); return false; } else { return $d; } } else { if (ICAL_EVENTS_DEBUG) { echo 'Error: Unexpected data in file '; print_r($p[1]); } return false; } } return false; } }