DateiCalFeedsParser.inc 6.54 KB
Newer Older
Robert Rollins's avatar
Robert Rollins committed
1 2
<?php
/**
3
 * @file
4
 * DateiCalFeedsParser is Date iCal's Feeds parser plugin.
Robert Rollins's avatar
Robert Rollins committed
5 6
 */

7 8 9 10 11 12 13 14 15 16 17 18 19
class DateiCalFeedsParser extends FeedsParser {
  
  /**
   * Implements FeedsParser::getMappingSources().
   */
  public function getMappingSources() {
    return parent::getMappingSources() + self::getiCalMappingSources();
  }
  
  /**
   * Implements FeedsParser::parse().
   */
  public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {
20 21 22
    $library = libraries_load('iCalcreator');
    if (!$library['loaded']) {
      throw new DateIcalException(t('Unable to load the iCalcreator library. Please ensure that it is properly installed.'));
23
    }
24
    $state = $source->state(FEEDS_PARSE);
25 26 27 28 29 30 31 32 33 34 35 36
    
    // Read the iCal feed into memory.
    $ical_feed_contents = $fetcher_result->getRaw();
    
    // Parse the feed into an iCalcreator vcalendar object.
    $calendar = new vcalendar();
    if ($calendar->parse($ical_feed_contents) === FALSE) {
      $plugin = $source->importer->config['fetcher']['plugin_key'];
      $url = $source->config[$plugin]['source'];
      throw new DateIcalException(t('Parsing the data from %url failed. Please ensure that this URL leads to a valid iCal feed.', array('%url' => $url)));
    }
    
37 38 39 40 41
    // Total hack to get around iCalcreator's mistreatment of UID "0".
    if (empty($calendar->components[0]->uid) || empty($calendar->components[0]->uid['value'])) {
      $calendar->components[0]->uid = array('value' => 'zero', 'params' => NULL);
    }
    
42 43 44 45 46
    // Allow modules to alter the vcalendar object before we interpret it.
    $context = array(
      'source' => $source,
      'fetcher_result' => $fetcher_result,
    );
47
    drupal_alter('date_ical_import_vcalendar', $calendar, $context);
48
    
Robert Rollins's avatar
Robert Rollins committed
49 50
    // We've got a vcalendar object created from the feed data. Now we need to
    // convert that vcalendar into an array of Feeds-compatible data arrays.
51
    // ParserVcalendar->parse() does that.
52
    require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'date_ical') . '/libraries/ParserVcalendar.inc';
53 54
    $parser = new ParserVcalendar($calendar, $source, $fetcher_result, $source->getConfigFor($this));
    
55
    // Using the stored progress pointer (or 0 if it's not set),
56 57 58 59 60 61 62 63
    // determine which section of the feed to parse, then parse it.
    $offset = isset($state->pointer) ? $state->pointer : 0;
    $limit = $source->importer->getLimit();
    $rows = $parser->parse($offset, $limit);
    
    // Report progress.
    $state->total = $parser->getTotalComponents();
    // We need to add 1 to the index of the last parsed componenent so that
64
    // the subsequent batch starts on the first unparsed component.
65 66
    $state->pointer = $parser->getLastComponentParsed() + 1;
    $state->progress($state->total, $state->pointer);
67

68
    return new FeedsParserResult($rows);
69 70
  }
  
Robert Rollins's avatar
Robert Rollins committed
71
  /**
72
   * Defines the default configuration settings for an actual import.
Robert Rollins's avatar
Robert Rollins committed
73 74 75 76 77 78 79 80
   */
  public function sourceDefaults() {
    return array(
      'indefinite_count' => $this->config['indefinite_count'],
    );
  }
  
  /**
81
   * Defines the default settings shown on the configuration form.
Robert Rollins's avatar
Robert Rollins committed
82 83 84 85 86 87 88 89
   */
  public function configDefaults() {
    return array(
      'indefinite_count' => '52',
    );
  }
  
  /**
90
   * Builds the configuration form.
Robert Rollins's avatar
Robert Rollins committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
   */
  public function configForm(&$form_state) {
    $form = array();
    $form['indefinite_count'] = array(
      '#title' => t('Indefinite COUNT'),
      '#type' => 'select',
      '#options' => array(
        '31' => '31',
        '52' => '52',
        '90' => '90',
        '365' => '365',
      ),
      '#description' => t('Indefinitely repeating events are not supported. The repeat count will instead be set to this number.'),
      '#default_value' => $this->config['indefinite_count'],
    );
    return $form;
  }
  
  /**
   * Creates the list of mapping sources offered by DateiCalFeedsParser.
   */
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
  public static function getiCalMappingSources() {
    $sources = array();
    $sources['SUMMARY'] = array(
      'name' => t('Summary/Title'),
      'description' => t('The SUMMARY property. A short summary (usually the title) of the event.'),
      'date_ical_parse_handler' => 'parseTextProperty',
    );
    $sources['DESCRIPTION'] = array(
      'name' => t('Description'),
      'description' => t('The DESCRIPTION property. A more complete description of the event than what is provided by the Summary.'),
      'date_ical_parse_handler' => 'parseTextProperty',
    );
    $sources['DTSTART'] = array(
      'name' => t('Date: Start'),
      'description' => t('The DTSTART property. The start time of each event in the feed.'),
      'date_ical_parse_handler' => 'parseDateTimeProperty',
    );
    $sources['DTEND'] = array(
      'name' => t('Date: End'),
      'description' => t('THE DTEND or DURATION property. The end time (or duration) of each event in the feed.'),
      'date_ical_parse_handler' => 'parseDateTimeProperty',
    );
    $sources['RRULE'] = array(
      'name' => t('Repeat Rule'),
      'description' => t('The RRULE property. Describes when and how often this event should repeat.
        The date field for the target node must be configured to support repeating dates, using the Date Repeat Field module (a submodule of Date).'),
      'date_ical_parse_handler' => 'parseRepeatProperty',
    );
    $sources['UID'] = array(
      'name' => 'UID',
      'description' => t('The UID property. Each event must have a UID if you wish for the import process to be able to update previously-imported nodes.
        If used, this field MUST be set to Unique.'),
      'date_ical_parse_handler' => 'parseTextProperty',
    );
    $sources['URL'] = array(
      'name' => 'URL',
      'description' => t('The URL property. Some feeds specify a URL for the event using this property.'),
      'date_ical_parse_handler' => 'parseTextProperty',
    );
    $sources['LOCATION'] = array(
      'name' => t('Location'),
      'description' => t('The LOCATION property. Can be mapped to a text field, or the title of a referenced node.'),
      'date_ical_parse_handler' => 'parseTextProperty',
    );
    $sources['LOCATION:ALTREP'] = array(
      'name' => t('Location: ALTREP'),
      'description' => t('The ALTREP value of the LOCATION property. Additional location information, usually a URL to a page with more info.'),
      'date_ical_parse_handler' => 'parsePropertyParameter',
    );
    $sources['CATEGORIES'] = array(
      'name' => t('Categories'),
      'description' => t('The CATEGORIES property. Catagories that describe the event, which can be imported into taxonomy terms.'),
      'date_ical_parse_handler' => 'parseMultivalueProperty',
    );
    return $sources;
  }
}