You are here

public function ParserVcalendar::parse in Date iCal 7.3

Parses the vcalendar object into an array of event data arrays.

Parameters

int $offset: Specifies which section of the feed to start parsing at.

int $limit: Specifies how many components to parse on this run.

Return value

array An array of parsed event data keyed by our mapping source property keys.

File

libraries/ParserVcalendar.inc, line 70
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 parse($offset, $limit) {

  // Sometimes, the feed will set a timezone for every event in the calendar
  // using the non-standard X-WR-TIMEZONE property. Date iCal uses this
  // timezone only if the date property is not in UTC and has no TZID.
  $xtimezone = $this->calendar
    ->getProperty('X-WR-TIMEZONE');
  if (!empty($xtimezone[1])) {

    // Allow modules to alter the timezone string before it gets converted
    // into a DateTimeZone.
    $context = array(
      'property_key' => NULL,
      'calendar_component' => NULL,
      'calendar' => $this->calendar,
      'feeeds_source' => $this->source,
      'feeds_fetcher_result' => $this->fetcherResult,
    );
    drupal_alter('date_ical_import_timezone', $xtimezone[1], $context);
    $this->xtimezone = $this
      ->_tzid_to_datetimezone($xtimezone[1]);
  }

  // Collect the timezones into an array, for easier access.
  while ($component = $this->calendar
    ->getComponent('VTIMEZONE')) {
    $this->timezones[] = $component;
  }

  // This context array is used by date_ical_import_component_alter() and
  // date_ical_import_parsed_data_alter().
  $context2 = array(
    'calendar' => $this->calendar,
    'source' => $this->source,
    'fetcher_result' => $this->fetcherResult,
  );

  // Collect each component, so we can batch them properly in the next loop.
  $raw_components = array();
  $types = array(
    'VEVENT',
    'VTODO',
    'VJOURNAL',
    'VFREEBUSY',
    'VALARM',
  );
  foreach ($types as $type) {
    while ($vcalendar_component = $this->calendar
      ->getComponent($type)) {

      // Allow modules to alter the vcalendar component before we parse it
      // into a Feeds-compatible data array.
      drupal_alter('date_ical_import_component', $vcalendar_component, $context2);
      $raw_components[] = $vcalendar_component;
    }
  }

  // Store this for use by DateiCalFeedsParser's batch processing code.
  $this->totalComponents = count($raw_components);

  // Parse each raw component in the current batch into a Feeds-compatible
  // event data array.
  $events = array();
  $batch = array_slice($raw_components, $offset, $limit, TRUE);
  foreach ($batch as $ndx => $raw_component) {
    $this->parsed_data = array();
    foreach ($this->mapping_sources as $property_key => $data) {
      $handler = NULL;
      if (isset($data['date_ical_parse_handler'])) {
        $handler = $data['date_ical_parse_handler'];
      }
      else {

        // This is not one of our sources, so if we don't recognize and
        // support it, we'll have to pass a warning to the user.
        if ($property_key == 'geofield') {
          $handler = 'parseGeofield';
        }
        else {

          // We can safely ignore certain sources.
          $known_unknowns = array(
            'Blank source 1',
            // "Black Source 1" is from Feeds Tamper.
            'parent:nid',
            // Defined in FeedsParser
            'parent:uid',
          );
          if (!in_array($property_key, $known_unknowns)) {

            // Only warn the user if this mapping source is in use.
            foreach ($this->source->importer->processor->config['mappings'] as $mapping) {
              if ($mapping['source'] == $property_key) {
                drupal_set_message(t('Date iCal does not recognize the "@name" Mapping Source, and must skip it.', array(
                  '@name' => $data['name'],
                )), 'warning', FALSE);
                break;
              }
            }
          }
        }
      }
      if ($handler) {
        $this->parsed_data[$property_key] = $this
          ->{$handler}($property_key, $raw_component);
      }
      if ($property_key == 'geofield' && !empty($this->parsed_data['geofield'])) {

        // To make our data readable by geofield_feeds_combined_source(), we
        // need to put it into the format output by Simplepie 1.3.
        $this->parsed_data['location_latitude'] = array(
          $this->parsed_data['geofield']['lat'],
        );
        $this->parsed_data['location_longitude'] = array(
          $this->parsed_data['geofield']['lon'],
        );
      }
    }

    // Allow modules to alter the final parsed data before we send it to the
    // Feeds processor.
    drupal_alter('date_ical_import_post_parse', $this->parsed_data, $context2);

    // Skip this event if it's earlier than the user's specified skip time.
    if (!$this
      ->_skip_current_event()) {
      $events[] = $this->parsed_data;
    }

    // The indices of the original $raw_components array are preserved in
    // $batch, so using the $ndx value here lets us communicate our progress
    // through the full collection of components.
    $this->lastComponentParsed = $ndx;
  }
  return $events;
}