/** * Get a TZID string from this VEVENT/VTODO/... component if we can * @param vComponent $comp * @return The TZID value we found, or null */ private static function GetTZID(vComponent $comp) { $p = $comp->GetProperty('DTSTART'); if (!isset($p) && $comp->GetType() == 'VTODO') { $p = $comp->GetProperty('DUE'); } if (!isset($p)) { return null; } return $p->GetParameterValue('TZID'); }
/** * Given a dav_id and an original vCalendar, pull out each of the VALARMs * and write the values into the calendar_alarm table. * * @param int $dav_id The dav_id of the caldav_data we're processing * @param vComponent The VEVENT or VTODO containing the VALARM * @return null */ function write_alarms($dav_id, vComponent $ical) { $qry = new AwlQuery('DELETE FROM calendar_alarm WHERE dav_id = ' . $dav_id); $qry->Exec('PUT', __LINE__, __FILE__); $alarms = $ical->GetComponents('VALARM'); if (count($alarms) < 1) { return; } $qry->SetSql('INSERT INTO calendar_alarm ( dav_id, action, trigger, summary, description, component, next_trigger ) VALUES( ' . $dav_id . ', :action, :trigger, :summary, :description, :component, :related::timestamp with time zone + :related_trigger::interval )'); $qry->Prepare(); foreach ($alarms as $v) { $trigger = array_merge($v->GetProperties('TRIGGER')); if ($trigger == null) { continue; } // Bogus data. $trigger = $trigger[0]; $related = null; $related_trigger = '0M'; $trigger_type = $trigger->GetParameterValue('VALUE'); if (!isset($trigger_type) || $trigger_type == 'DURATION') { switch ($trigger->GetParameterValue('RELATED')) { case 'DTEND': $related = $ical->GetProperty('DTEND'); break; case 'DUE': $related = $ical->GetProperty('DUE'); break; default: $related = $ical->GetProperty('DTSTART'); } $duration = $trigger->Value(); if (!preg_match('{^-?P(:?\\d+W)?(:?\\d+D)?(:?T(:?\\d+H)?(:?\\d+M)?(:?\\d+S)?)?$}', $duration)) { continue; } $minus = substr($duration, 0, 1) == '-'; $related_trigger = trim(preg_replace('#[PT-]#', ' ', $duration)); if ($minus) { $related_trigger = preg_replace('{(\\d+[WDHMS])}', '-$1 ', $related_trigger); } else { $related_trigger = preg_replace('{(\\d+[WDHMS])}', '$1 ', $related_trigger); } } else { if ($trigger_type == 'DATE-TIME') { $related = $trigger; } else { if (false === strtotime($trigger->Value())) { continue; } // Invalid date. $related = $trigger; } } $related_date = new RepeatRuleDateTime($related); $qry->Bind(':action', $v->GetPValue('ACTION')); $qry->Bind(':trigger', $trigger->Render()); $qry->Bind(':summary', $v->GetPValue('SUMMARY')); $qry->Bind(':description', $v->GetPValue('DESCRIPTION')); $qry->Bind(':component', $v->Render()); $qry->Bind(':related', $related_date->UTC()); $qry->Bind(':related_trigger', $related_trigger); $qry->Exec('PUT', __LINE__, __FILE__); } }
/** * Return a date range for this component. * @param vComponent $comp * @throws Exception (1) When DTSTART is not present but the RFC says MUST and (2) when we get an unsupported component * @return RepeatRuleDateRange */ function getComponentRange(vComponent $comp) { $dtstart_prop = $comp->GetProperty('DTSTART'); $duration_prop = $comp->GetProperty('DURATION'); if (isset($duration_prop)) { if (!isset($dtstart_prop)) { throw new Exception('Invalid ' . $comp->GetType() . ' containing DURATION without DTSTART', 0); } $dtstart = new RepeatRuleDateTime($dtstart_prop); $dtend = clone $dtstart; $dtend->modify(new Rfc5545Duration($duration_prop->Value())); } else { $completed_prop = null; switch ($comp->GetType()) { case 'VEVENT': if (!isset($dtstart_prop)) { throw new Exception('Invalid VEVENT without DTSTART', 0); } $dtend_prop = $comp->GetProperty('DTEND'); break; case 'VTODO': $completed_prop = $comp->GetProperty('COMPLETED'); $dtend_prop = $comp->GetProperty('DUE'); break; case 'VJOURNAL': if (!isset($dtstart_prop)) { $dtstart_prop = $comp->GetProperty('DTSTAMP'); } $dtend_prop = $dtstart_prop; default: throw new Exception('getComponentRange cannot handle "' . $comp->GetType() . '" components', 0); } if (isset($dtstart_prop)) { $dtstart = new RepeatRuleDateTime($dtstart_prop); } else { $dtstart = null; } if (isset($dtend_prop)) { $dtend = new RepeatRuleDateTime($dtend_prop); } else { $dtend = null; } if (isset($completed_prop)) { $completed = new RepeatRuleDateTime($completed_prop); if (!isset($dtstart) || isset($dtstart) && $completed < $dtstart) { $dtstart = $completed; } if (!isset($dtend) || isset($dtend) && $completed > $dtend) { $dtend = $completed; } } } return new RepeatRuleDateRange($dtstart, $dtend); }