示例#1
0
  private function add_rrule($rrule_string) {
    $rules = explode(';', $rrule_string);
    $this->recur = TRUE;
    if ($this->occurrences === NULL) {
      $this->occurrences = Array();
    }

    // read attributes from rrule_string
    $limit_type = '';
    $limit = '';

    $incrementors = Array(
      'SECONDLY' => 'increment_second',
      'MINUTELY' => 'increment_minute',
      'HOURLY' => 'increment_hour',
      'DAILY' => 'increment_day',	
      'WEEKLY' => 'increment_week',
      'MONTHLY' => 'increment_month',
      'YEARLY' => 'increment_year',
      );

    $occurs_by_list = Array();

    foreach ($rules as $rule) {
      $namevalue = explode('=', $rule);
      $rulename = $namevalue[0];
      $rulevalue = $namevalue[1];
      switch ($rulename) {
      case 'FREQ': // always present
	$this->incrementor = $incrementors[$rulevalue];
	break;
      case 'INTERVAL':
	$this->interval = $rulevalue;
      case 'UNTIL':
	$limit_type = 'UNTIL';
	$this->until = ICalendar::ical2unix($rulevalue);
	break;
      case 'COUNT':
	$limit_type = 'COUNT';
	$limit = $rulevalue;
	break;
      case (substr($rulename, 0, 2) == 'BY'):
	$occurs_by_list[$rulename] = explode(',', $rulevalue);
	break;
      }
    }
    // finished reading attributes from rrule_string

    $occursByTypes = Array(
      'BYMONTH' => Array('func' => 'increment_month', 'format' => 'n'),
      'BYWEEKNO' => Array('func' => 'increment_week', 'format' => 'W'),
      'BYYEARDAY' => Array('func' => 'increment_day', 'format' => 'z'),
      'BYMONTHDAY' => Array('func'=> 'increment_day', 'format' => 'j'),
      'BYDAY' => Array('func' => 'increment_day', 'format' => 'w'),
      'BYHOUR' => Array('func' => 'increment_hour', 'format' => 'G'),
      'BYMINUTE' => Array('func' => 'increment_minute', 'format' => 'i'),
      'BYSECOND' => Array('func' => 'increment_second', 'format' => 's'),
      );

    // create the first occurrence set
    $occur_unit = Array($this->range->get_start());
    foreach ($occursByTypes as $byfreq => $attribs) {
      // we loop through occurByTypes so we can be sure to
      // act on each "by frequency" rule in order of decreasing grain size

      if (array_key_exists($byfreq, $occurs_by_list)) {
	$new_occur_unit = Array();

	// every "when" within the "by frequency"
	// e.g. MO,TU,WE for BYDAY
	// needs to be a separate element of the occurrence set
	foreach($occurs_by_list[$byfreq] as $when) {
	  $occurs_when = ($byfreq == 'BYDAY') ? ICalendar::$dayIndex[$when] : $when;

	  // if the set of occurrences already has multiple elements
	  // they will be multiplied
	  // e.g. MO,TU for BYDAY and 1,2,3 for BYMONTH
	  // yields 6 elements in the occurence set
	  foreach ($occur_unit as $start) {	    
	    $count = 0; // for debugging below
	    while (intval(date($attribs['format'], $start)) != $occurs_when) {
	      $start = call_user_func($attribs['func'], $start);

	      // haven't seen this happen yet but who knows
	      if ($count > 366) {
		throw new ICalendarException("maximum loop count exceeded");
	      }
	      $count += 1;
	    }
	    $new_occur_unit[] = $start;
	  }
	}
	$occur_unit = $new_occur_unit;
      }
    }

    // BYSETPOS limits us to particular indices of the occurrence set
    if (array_key_exists('BYSETPOS', $occurs_by_list)) {
      $new_occur_unit = Array();
      $setposlist = $occurs_by_list['BYSETPOS'];
      foreach ($setposlist as $setpos) {
	if ($setpos < 0) {
	  $setpos = count($occur_unit) + $setpos;
	} else {
	  $setpos = $setpos - 1;
	}
	$new_occur_unit[] = $occur_unit[$setpos];
      }
      $occur_unit = $new_occur_unit;
    }

    $this->occurrences = $occur_unit;

    // duplicate the occurrence set for COUNT limits
    // this is approximate
    if ($limit_type == 'COUNT') {
      $num_increments = $limit / count($this_occurrences);
      $end = end($occur_unit);
      while ($num_increments > 0) {
	$end = $this->incrementor($end);
	$num_increments -= 1;
      }
      $this->until = $end;
    }
  }