Index: feedapi_mapper_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi_mapper/mappers/Attic/feedapi_mapper_date.inc,v
retrieving revision 1.1.2.3.2.1
diff -u -r1.1.2.3.2.1 feedapi_mapper_date.inc
--- feedapi_mapper_date.inc	8 Sep 2008 11:41:13 -0000	1.1.2.3.2.1
+++ feedapi_mapper_date.inc	8 Dec 2008 10:55:11 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: feedapi_mapper_date.inc,v 1.1.2.3.2.1 2008/09/08 11:41:13 alexb Exp $
+// $Id: feedapi_mapper_date.inc,v 1.1.2.2 2008/02/28 22:04:44 alexb Exp $
 
 /**
  * Implementation of hook_feedapi_mapper for date field from content.module (CCK),
@@ -9,43 +9,145 @@
  * @param string $field_name
  * @param string, number or array of string or number $feed_element
  * @param string or number as id $sub_field
- *
+ * 
  */
 function date_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = '') {
-  if (!$field = feedapi_mapper_content_is_cck_type($field_name, array('date', 'datestamp'))) {
+  if (!$field = feedapi_mapper_content_is_cck_type($field_name, array('date', 'datestamp', 'datetime'))) {
     // if not a date just return
     return;
   }
-
+  
   switch ($op) {
     case 'describe':
-      // Describe what we are doing in this mapper. This shows up as help text on the mapping page.
+      // Describe what we are doing in this mapper. This shows up as help text on the mapping page. 
       return t('Maps a date to a date CCK field.');
+    
     case 'list':
-      // just for sub_fields
+      // Here we are being asked to list sub fields we would like to map to.
+      // In this case, we only map to the CCK field or not, so we return just TRUE.
       return TRUE;
+    
     case 'map':
-      // Here is where the actual mapping happens.
-      include_once(drupal_get_path('module', 'date_api') .'/date.inc');
-      $items = $node->$field_name;
-      if (!is_array($feed_element)) {
-        // TODO TIMEZONE
-        // Don't know what type of date so first attempt to create a date from a string
-        $date = date_text_make_dbdate($feed_element, $field['type'], '', 'none', date_granularity_array($field));
-        if ($date->db->timestamp == '') {
-          // not from string, use the empty date object and try as a datestamp
-          date_set_date($date, $feed_element, 'none', 'db', DATE_UNIX);
-          // Note granularity is also done on submit
-        }
-      }
-
-      if ($field['type'] == DATE_ISO) {
-        $items[]['value'] = $date->db->iso;
+      include_once(drupal_get_path('module', 'date_api') .'/date_api_ical.inc');
+      
+      // A date created by the iCal parser will have an array of values
+      // and can be used to create complex, multiple values.
+      // A date created by an RSS feed may have only a simple date.
+      if (is_array($feed_element)) {
+        return feedapi_mapper_date_ical($node, $field, $feed_element);
       }
       else {
-        $items[]['value'] = $date->db->timestamp;
+        return feedapi_mapper_date_simple($node, $field, $feed_element);
       }
-      $node->$field_name = $items;
-      return $node;
   }
 }
+
+/**
+ * Create a date from a simple string date value.
+ */
+function feedapi_mapper_date_simple($node, $field, $feed_element) {
+  $field_name = $field['field_name'];
+  
+  // ISO 8601 dates will have +/-05:00 offset adjustments.
+  if (strstr($feed_element, '+')) {
+    $date_info = explode('+', $feed_element);
+    list($hours, $minutes) = explode(':', $date_info[1]);
+    $timezone = 'UTC';
+    $date = date_make_date(trim($date_info[0]), 'UTC');
+    date_modify($date, '-'. trim($hours) .' hours');
+    date_modify($date, '-'. trim($minutes) .' minutes');
+  }
+  elseif (strstr($feed_element, '-')) {
+    $date_info = explode('-', $feed_element);
+    list($hours, $minutes) = explode(':', $date_info[1]);
+    $timezone = 'UTC';
+    $date = date_make_date(trim($date_info[0]), 'UTC');
+    date_modify($date, '+'. trim($hours) .' hours');
+    date_modify($date, '+'. trim($minutes) .' minutes');
+  }
+  // Not an iCal date and not a ISO 8601 date, just use the value.
+  else {
+    $date = date_make_date($feed_element);
+    $timezone = date_default_timezone_name();
+  }
+
+  $db_tz = date_get_timezone_db($field['tz_handling'], $timezone);
+  $to_tz = date_get_timezone($field['tz_handling'], $timezone);
+  date_timezone_set($date, timezone_open($db_tz));
+  $format = date_type_format($field['type']);
+      
+  if ($formatted = date_format($date, $format)) {
+    // Create node field information.
+    $items = isset($node->$field_name) ? $node->$field_name : array();
+    $items[0]['value'] = $formatted;
+    $items[0]['value2'] = $items[0]['value'];
+    $items[0]['timezone'] = $to_tz;
+    date_timezone_set($date, timezone_open($to_tz));
+    $items[0]['offset'] = date_offset_get($date);
+    $items[0]['offset2'] = $items[0]['offset'];
+    $node->$field_name = $items;
+  }
+  return $node;
+}
+
+/**
+ * Create a date from an iCal feed.
+ */
+function feedapi_mapper_date_ical($node, $field, $feed_element) {
+  $field_name = $field['field_name'];
+  
+  $timezone = $feed_element['DTSTART']['tz'];
+  if (empty($timezone)) $timezone = date_default_timezone_name();
+  $date = date_make_date($feed_element['DTSTART']['datetime'], $timezone);
+        
+  $db_tz = date_get_timezone_db($field['tz_handling'], $timezone);
+  $to_tz = date_get_timezone($field['tz_handling'], $timezone);
+  date_timezone_set($date, timezone_open($db_tz));
+  $format = date_type_format($field['type']);
+      
+  if ($formatted = date_format($date, $format)) {
+    // Create node field information.
+    $items = isset($node->$field_name) ? $node->$field_name : array();
+    $items[0]['value'] = $formatted;
+    
+    $date2 = date_make_date($feed_element['DTEND']['datetime'], $timezone);
+    date_timezone_set($date2, timezone_open($db_tz));
+    $formatted2 = date_format($date2, $format);
+    $items[0]['value2'] = $formatted2;
+    $items[0]['timezone'] = $to_tz;
+    date_timezone_set($date, timezone_open($to_tz));
+    $items[0]['offset'] = date_offset_get($date);
+    $items[0]['offset2'] = $items[0]['offset'];
+    $node->$field_name = $items;
+        
+    if (array_key_exists('RRULE', $feed_element) && !empty($feed_element['RRULE']) && module_exists('date_repeat')) {
+          
+      include_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_calc.inc');
+      include_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
+
+      // Explode the RRULE into parts so we can analyze it.
+      $rrule = $feed_element['RRULE'] . (!empty($feed_element['EXDATE']) ? "/n". $feed_element['EXDATE'] : "");
+      $form_values = date_ical_parse_rrule($field, $rrule);
+          
+      // Set an maximum value for repeating dates.
+      // One year, 5 repeats for now, could be adjusted or made configurable later.
+      $max = date_now();
+      $max_repeats = 5;
+      
+      date_modify($max, '+1 year');
+      $until = date_format($max, 'Y-m-d H:i:s');
+      if (empty($form_values['UNTIL']) || $until < $form_values['UNTIL']['datetime']) {
+        $form_values['UNTIL'] = array('datetime' => $until, 'tz' => 'UTC');
+      }
+      $form_values['COUNT'] = $max_repeats;
+          
+      // Reconstruct the RRULE with our changes and build the repeats.
+      $rrule = date_api_ical_build_rrule($form_values);
+      $node_field = $items[0];
+      $values = date_repeat_build_dates($rrule, $form_values, $field, $node_field);
+      $node->$field_name = $values;
+
+    }
+  }
+  return $node;
+}

