You are here

public function DateRRuleCalc::compute in Date 8

File

date_repeat/lib/Drupal/date_repeat/DateRRuleCalc.php, line 204
Code to compute the dates that match an iCal RRULE.

Class

DateRRuleCalc

Namespace

Drupal\date_repeat

Code

public function compute() {

  // Make sure we have something we can work with.
  if (!$this
    ->isValid()) {
    return FALSE;
  }
  if (empty($this->rrule['FREQ'])) {
    $this->rrule['FREQ'] = 'DAILY';
  }

  // These default values indicate there is no RRULE here.
  if ($this->rrule['FREQ'] == 'NONE' || isset($this->rrule['INTERVAL']) && $this->rrule['INTERVAL'] == 0) {
    return array();
  }

  // Get an integer value for the interval, if none given, '1'
  // is implied.
  if (empty($this->rrule['INTERVAL'])) {
    $this->rrule['INTERVAL'] = 1;
  }
  $interval = max(1, $this->rrule['INTERVAL']);

  // Make sure DAILY frequency isn't used in places it won't work;
  if (!empty($this->rrule['BYMONTHDAY']) && !in_array($this->rrule['FREQ'], array(
    'MONTHLY',
    'YEARLY',
  ))) {
    $this->rrule['FREQ'] = 'MONTHLY';
  }
  elseif (!empty($this->rrule['BYDAY']) && !in_array($this->rrule['FREQ'], array(
    'MONTHLY',
    'WEEKLY',
    'YEARLY',
  ))) {
    $this->rrule['FREQ'] = 'WEEKLY';
  }

  // Find the time period to jump forward between dates.
  switch ($this->rrule['FREQ']) {
    case 'DAILY':
      $jump_interval = 'P' . $interval . 'D';
      break;
    case 'WEEKLY':
      $jump_interval = 'P' . $interval . 'W';
      break;
    case 'MONTHLY':
      $jump_interval = 'P' . $interval . 'M';
      break;
    case 'YEARLY':
      $jump_interval = 'P' . $interval . 'Y';
      break;
  }
  $this->jump = new \DateInterval($jump_interval);

  // Make sure the rrule array has all the values we expect.
  $this
    ->complete_rrule();

  // The start date always goes into the results, whether or not
  // it meets the rules. RFC 2445 includes examples where the start
  // date DOES NOT meet the rules, but the expected results always
  // include the start date.
  $this->result[] = date_format($this->start_date, $this->default_format);

  // BYMONTHDAY will look for specific days of the month in one or
  // more months. This process is only valid when frequency is
  // monthly or yearly.
  if (!empty($this->rrule['BYMONTHDAY'])) {
    $this
      ->get_bymonthday_results();
  }
  elseif (empty($this->rrule['BYDAY'])) {
    $this
      ->get_other_results();
  }
  else {
    $this
      ->get_byday_results();
  }

  // Add additional dates, if any.
  foreach ($this->additions as $addition) {
    $date = new DrupalDateTime($addition . ' ' . $this->time_string, $this->timezone_name);
    $this->result[] = date_format($date, $this->default_format);
  }

  // Sort and return the result.
  sort($this->result);
  return $this->result;
}