You are here

public function ParserVcalendar::parseRepeatProperty in Date iCal 7.3

Handler that parses RRULE, RDATE, EXRULE, and EXDATE together.

Return value

string The RRULE, RDATE, EXRULE, and EXDATE values concatinated with |.

File

libraries/ParserVcalendar.inc, line 449
Defines a class that parses iCalcreator vcalendar objects into Feeds-compatible data arrays.

Class

ParserVcalendar
@file Defines a class that parses iCalcreator vcalendar objects into Feeds-compatible data arrays.

Code

public function parseRepeatProperty($property_key, $vcalendar_component) {
  if ($vcalendar_component
    ->getProperty($property_key) === FALSE) {
    return NULL;
  }
  $uid = $vcalendar_component
    ->getProperty('UID');
  $count = $this->config['indefinite_count'];

  // Due to a few bugs and limitations with Date Repeat, we need to massage
  // the RRULE a bit.
  if (count($vcalendar_component->rrule) > 1) {

    // TODO: Is Date Repeat still limited to 1 RRULE with Feeds 2.0-beta1?
    $msg = 'The event with UID %uid has multiple RRULEs, but the Date Repeat module only supports one. Only the first RRULE in the event will be used.
        If your events need to have a complex repeat pattern, using RDATEs should help.';
    watchdog('date_ical', $msg, array(
      '%uid' => $uid,
    ), 'warning');
    drupal_set_message('At least one of the events in this iCal feed has multiple RRULEs, but the Date Repeat module only supports one.
        Only the first RRULE in an event will be used.', 'warning', FALSE);

    // Date Repeat will get extremely confused if it's sent multiple RRULE
    // values, so we need to manually pare it down to only the first one.
    $vcalendar_component->rrule = array(
      $vcalendar_component->rrule[0],
    );
  }
  foreach ($vcalendar_component->rrule as &$rrule_data) {

    // RRULEs must have an INTERVAL, or Date Repeat will throw errors.
    // TODO: Is this still true with Feeds 2.0-beta1?
    if (!isset($rrule_data['value']['INTERVAL'])) {
      $rrule_data['value']['INTERVAL'] = '1';
    }
    if (!isset($rrule_data['value']['COUNT']) && !isset($rrule_data['value']['UNTIL'])) {
      $msg = "The event with UID %uid has an indefinitely repeating RRULE, which the Date Repeat module doesn't support.\n          As a workaround, Date iCal set the repeat count to @count. This value can be customized in the iCal parser settings.";
      watchdog('date_ical', $msg, array(
        '%uid' => $uid,
        '@count' => $count,
      ), WATCHDOG_WARNING);
      if (!empty($this->config['indefinite_message_display'])) {
        drupal_set_message(t("At least one of the events in this iCal feed has an indefinitely repeating RRULE, which the Date Repeat module doesn't support.<br>\n              As a workaround, Date iCal set the repeat count to @count. This value can be customized in the iCal parser settings.", array(
          '@count' => $count,
        )), 'warning', FALSE);
      }
      if (isset($this->config['indefinite_count'])) {
        $rrule_data['value']['COUNT'] = $this->config['indefinite_count'];
      }
      else {

        // Somehow, it's possible for the config values to have no setting, even though we've given them a default.
        // So make really sure we set the COUNT to *something*.
        $rrule_data['value']['COUNT'] = 52;
      }
    }
  }

  # Due to a bug in iCalcreator 2.20.2, any repeat property that's too long to fit on one line will be returned

  # verbatim, including the endline and the single-space indentation that starts the second line. Thus, we need to

  # remove those things ourselves.
  $rrule = trim(preg_replace('/\\s/', '', $vcalendar_component
    ->createRrule()));
  $rdate = trim(preg_replace('/\\s/', '', $vcalendar_component
    ->createRdate()));
  $exrule = trim(preg_replace('/\\s/', '', $vcalendar_component
    ->createExrule()));

  // Modules such as Date Repeat, as well as our parsing functions, generally
  // expect a single EXDATE entry for optimal operation. If we have multiple
  // entries in the data, we should concatenate them here.
  $parsed_exdate = trim(preg_replace('/\\s/', '', $vcalendar_component
    ->createExdate()));

  // First, get the individual contents of any definitions. It's OK even if
  // there is only one.
  $exdate_parts = explode('EXDATE;', $parsed_exdate);
  array_shift($exdate_parts);

  // First element always blank.
  // Extended parameters such as VALUE and TZID are set in the first EXDATE
  // The other ones must not repeat them. We skip the first entry when
  // enforcing this, obviously.
  $skip = TRUE;
  foreach ($exdate_parts as &$exdate_part) {
    if ($skip) {
      $skip = FALSE;
      continue;
    }

    // This strips off the part before the colon, since we only want the value
    // from the first EXDATE entry. end() wants a real array, hence why two
    // lines.
    $exdate_part_parts = explode(':', $exdate_part);
    $exdate_part = end($exdate_part_parts);
  }

  // Combine the parts back together with an EXDATE; specifier in front.
  $exdate = !empty($exdate_parts) ? 'EXDATE;' . implode(',', $exdate_parts) : '';
  return "{$rrule}|{$rdate}|{$exrule}|{$exdate}";
}