Beispiel #1
0
 function PHPTest()
 {
     $result = '';
     $start = microtime(true);
     $rule = new RepeatRule($this->dtstart, $this->recur);
     $i = 0;
     while ($date = $rule->next()) {
         if ($i++ % 4 == 0) {
             $result .= "\n";
         }
         $result .= "   " . $date->format('Y-m-d H:i:s');
         if ($i >= $this->result_limit) {
             break;
         }
     }
     $this->PHP_time = microtime(true) - $start;
     return $result;
 }
Beispiel #2
0
/**
* Return a RepeatRuleDateRange from the earliest start to the latest end of the event.
* 
* @todo: This should probably be made part of the VCalendar object when we move the RRule.php into AWL.
*
* @param object $vResource A vComponent which is a VCALENDAR containing components needing expansion
* @return RepeatRuleDateRange Representing the range of time covered by the event. 
*/
function getVCalendarRange($vResource)
{
    global $c;
    $components = $vResource->GetComponents();
    $dtstart = null;
    $duration = null;
    $earliest_start = null;
    $latest_end = null;
    $has_repeats = false;
    foreach ($components as $k => $comp) {
        if ($comp->GetType() == 'VTIMEZONE') {
            continue;
        }
        $range = getComponentRange($comp);
        $dtstart = $range->from;
        if (!isset($dtstart)) {
            continue;
        }
        $duration = $range->getDuration();
        $rrule = $comp->GetProperty('RRULE');
        $limited_occurrences = true;
        if (isset($rrule)) {
            $rule = new RepeatRule($dtstart, $rrule);
            $limited_occurrences = $rule->hasLimitedOccurrences();
        }
        if ($limited_occurrences) {
            $instances = array();
            $instances[$dtstart->FloatOrUTC()] = $dtstart;
            if (!isset($range_end)) {
                $range_end = new RepeatRuleDateTime();
                $range_end->modify('+150 years');
            }
            $instances += rrule_expand($dtstart, 'RRULE', $comp, $range_end);
            $instances += rdate_expand($dtstart, 'RDATE', $comp, $range_end);
            foreach (rdate_expand($dtstart, 'EXDATE', $comp, $range_end) as $k => $v) {
                unset($instances[$k]);
            }
            if (count($instances) < 1) {
                if (empty($earliest_start) || $dtstart < $earliest_start) {
                    $earliest_start = $dtstart;
                }
                $latest_end = null;
                break;
            }
            $instances = array_keys($instances);
            asort($instances);
            $first = new RepeatRuleDateTime($instances[0]);
            $last = new RepeatRuleDateTime($instances[count($instances) - 1]);
            $last->modify($duration);
            if (empty($earliest_start) || $first < $earliest_start) {
                $earliest_start = $first;
            }
            if (empty($latest_end) || $last > $latest_end) {
                $latest_end = $last;
            }
        } else {
            if (empty($earliest_start) || $dtstart < $earliest_start) {
                $earliest_start = $dtstart;
            }
            $latest_end = null;
            break;
        }
    }
    return new RepeatRuleDateRange($earliest_start, $latest_end);
}
Beispiel #3
0
/**
* Expand the event instances for an RRULE property
*
* @param object $dtstart A RepeatRuleDateTime which is the master dtstart
* @param string $property RDATE or EXDATE, depending...
* @param array $component A vComponent which is a VEVENT, VTODO or VJOURNAL
* @param array $range_end A date after which we care less about expansion
*
* @return array An array keyed on the UTC dates, referring to the component
*/
function rrule_expand($dtstart, $property, $component, $range_end)
{
    $expansion = array();
    $recur = $component->GetProperty($property);
    if (!isset($recur)) {
        return $expansion;
    }
    $recur = $recur->Value();
    $this_start = $component->GetProperty('DTSTART');
    if (isset($this_start)) {
        $timezone = $this_start->GetParameterValue('TZID');
        $this_start = new RepeatRuleDateTime($this_start->Value(), $timezone);
    } else {
        $this_start = clone $dtstart;
    }
    //  print_r( $this_start );
    //  printf( "RRULE: %s\n", $recur );
    $rule = new RepeatRule($this_start, $recur);
    $i = 0;
    $result_limit = 1000;
    while ($date = $rule->next()) {
        //    printf( "[%3d] %s\n", $i, $date->UTC() );
        $expansion[$date->UTC()] = $component;
        if ($i++ >= $result_limit || $date > $range_end) {
            break;
        }
    }
    //  print_r( $expansion );
    return $expansion;
}
Beispiel #4
0
/**
* Expand the instances for a STANDARD or DAYLIGHT component of a VTIMEZONE 
*
* @param object $vResource is a VCALENDAR with a VTIMEZONE containing components needing expansion
* @param object $range_start A RepeatRuleDateTime which is the beginning of the range for events.
* @param object $range_end A RepeatRuleDateTime which is the end of the range for events.
* @param int $offset_from The offset from UTC in seconds at the onset time.
*
* @return array of onset datetimes with UTC from/to offsets
*/
function expand_timezone_onsets(vCalendar $vResource, RepeatRuleDateTime $range_start, RepeatRuleDateTime $range_end)
{
    global $c;
    $vtimezones = $vResource->GetComponents();
    $vtz = $vtimezones[0];
    $components = $vtz->GetComponents();
    $instances = array();
    $dtstart = null;
    $is_date = false;
    $has_repeats = false;
    $zone_tz = $vtz->GetPValue('TZID');
    foreach ($components as $k => $comp) {
        if (DEBUG_EXPAND) {
            printf("Starting TZ expansion for component '%s' in timezone '%s'\n", $comp->GetType(), $zone_tz);
            foreach ($instances as $k => $v) {
                print ' : ' . $k;
            }
            print "\n";
        }
        $dtstart_prop = $comp->GetProperty('DTSTART');
        if (!isset($dtstart_prop)) {
            continue;
        }
        $dtstart = new RepeatRuleDateTime($dtstart_prop);
        $dtstart->setTimeZone('UTC');
        $offset_from = $comp->GetPValue('TZOFFSETFROM');
        $offset_from = $offset_from / 100 * 3600 + abs($offset_from) % 100 * 60 * ($offset_from < 0 ? -1 : 0);
        $offset_from *= -1;
        $offset_from = "{$offset_from} seconds";
        dbg_error_log('tz/update', "%s of offset\n", $offset_from);
        $dtstart->modify($offset_from);
        $is_date = $dtstart->isDate();
        $instances[$dtstart->UTC('Y-m-d\\TH:i:s\\Z')] = $comp;
        $rrule = $comp->GetProperty('RRULE');
        $has_repeats = isset($rrule);
        if (!$has_repeats) {
            continue;
        }
        $recur = $comp->GetProperty('RRULE');
        if (isset($recur)) {
            $recur = $recur->Value();
            $this_start = clone $dtstart;
            $rule = new RepeatRule($this_start, $recur, $is_date);
            $i = 0;
            $result_limit = 1000;
            while ($date = $rule->next()) {
                $instances[$date->UTC('Y-m-d\\TH:i:s\\Z')] = $comp;
                if ($i++ >= $result_limit || $date > $range_end) {
                    break;
                }
            }
            if (DEBUG_EXPAND) {
                print "After rrule_expand";
                foreach ($instances as $k => $v) {
                    print ' : ' . $k;
                }
                print "\n";
            }
        }
        $properties = $comp->GetProperties('RDATE');
        if (count($properties)) {
            foreach ($properties as $p) {
                $timezone = $p->GetParameterValue('TZID');
                $rdate = $p->Value();
                $rdates = explode(',', $rdate);
                foreach ($rdates as $k => $v) {
                    $rdate = new RepeatRuleDateTime($v, $timezone, $is_date);
                    if ($return_floating_times) {
                        $rdate->setAsFloat();
                    }
                    $instances[$rdate->UTC('Y-m-d\\TH:i:s\\Z')] = $comp;
                    if ($rdate > $range_end) {
                        break;
                    }
                }
            }
            if (DEBUG_EXPAND) {
                print "After rdate_expand";
                foreach ($instances as $k => $v) {
                    print ' : ' . $k;
                }
                print "\n";
            }
        }
    }
    ksort($instances);
    $onsets = array();
    $start_utc = $range_start->UTC('Y-m-d\\TH:i:s\\Z');
    $end_utc = $range_end->UTC('Y-m-d\\TH:i:s\\Z');
    foreach ($instances as $utc => $comp) {
        if ($utc > $end_utc) {
            if (DEBUG_EXPAND) {
                printf("We're done: {$utc} is out of the range.\n");
            }
            break;
        }
        if ($utc < $start_utc) {
            continue;
        }
        $onsets[$utc] = array('from' => $comp->GetPValue('TZOFFSETFROM'), 'to' => $comp->GetPValue('TZOFFSETTO'), 'name' => $comp->GetPValue('TZNAME'), 'type' => $comp->GetType());
    }
    return $onsets;
}