Commit 5926f795 authored by Robert Rollins's avatar Robert Rollins

Added hook_date_ical_timezone_alter().

This hook allows modules to fix broken timezone strings in the iCal feeds they import.

Also cleaned up the way that timezone strings are handled by the parser, especially under error conditions.
parent 30ee5618
......@@ -154,3 +154,28 @@ function hook_date_ical_feeds_object_alter(&$value, &$context) {
// ...
}
}
/**
* Alter the timezone string before it gets converted into a DateTimeZone object.
* This is useful for when an iCal feed you're trying to import uses deprecated
* timezone names, like "Eastern Standard Time", rather than "America/New_York".
*
* @param $tz_string
* The timezone sting to be altered (e.g. "America/Los_Angeles").
* @param $context
* An associative array of context, with the following keys and values:
* - 'property_key': Inernal, parser-specific identifier for this property.
* - 'property': "RAW" value of this property.
* - 'item': The DateIcalComponentInterface object that holds the unparsed component.
* - 'parser_result': The parsed result of the whole Calendar.
* - 'feeds_source': Contains all the metadata about the configuration of this Feed.
*/
function hook_date_ical_timezone_alter(&$tz_string, &$context) {
// Example of what might be done with this alter hook:
if ($tz_string == 'Eastern Standard Time') {
// "Eastern Standard Time" is a deprecated timezone string, which PHP doesn't
// recognize. It's (essentially) equivalent to "America/New_York", though,
// which PHP is fine with.
$tz_string = 'America/New_York';
}
}
......@@ -126,8 +126,12 @@ class DateIcalIcalcreatorParser extends DateIcalFeedsParser {
}
}
// DEV NOTES:
// Due to the way that the loop after this one manipulates the $components array, and work that gets done in here
// is overriden. However, we probably *should* be using this, somehow, since I think it was in the old version
// in order to handle non-standard VTIMEZONES. Maybe?
$components = array();
while ($component = $calendar->getComponent('TIMEZONE')) {
while ($component = $calendar->getComponent('VTIMEZONE')) {
$components[$component->getProperty('tzid')] = new DateIcalIcalcreatorComponent($component);
}
$result->timezones = $components;
......@@ -274,26 +278,24 @@ class DateIcalIcalcreatorParser extends DateIcalFeedsParser {
if (strtoupper($date_array['tz']) == 'Z') {
$date_array['tz'] = 'UTC';
}
$tz = new DateTimeZone($date_array['tz']);
}
else {
// If there was no timezone in the date array itself, add one if we have one.
if (!empty($property['params']['TZID'])) {
// Use the timezone from this DATE-TIME component
try {
$tz = new DateTimeZone($property['params']['TZID']);
// note: these should relate to the DateIcalParserResult::$timezones but see comment on property.
}
catch (Exception $e) {
$source->log('parse', 'DATE-TIME TZID "%tzid" not recognized by PHP: %error',
array('%tzid' => $property['params']['TZID'], '%error' => $e->getMessage()), WATCHDOG_NOTICE);
}
// Allow modules to alter the timezone string before it gets converted into a DateTimeZone.
drupal_alter('date_ical_timezone', $date_array['tz'], $context);
try {
$tz = new DateTimeZone($date_array['tz']);
}
elseif (!empty($result->timezone)) {
// Use the timezone that was detected for the entire iCal feed.
$tz = $result->timezone;
catch (Exception $e) {
$source->log('parse', '"%tzid" is not recognized by PHP as a valid timezone, so UTC was used instead. Try implementing hook_date_ical_timezone_alter() to fix this problem.',
array('%tzid' => $date_array['tz']), WATCHDOG_WARNING);
drupal_set_message(t('"%tzid" is not recognized by PHP as a valid timezone, so UTC was used instead. Try implementing hook_date_ical_timezone_alter() to fix this problem.',
array('%tzid' => $date_array['tz'])), 'warning');
}
}
// If there was no timezone in the date array itself, add one if we have one.
else if (!empty($result->timezone)) {
// Use the timezone that was detected for the entire iCal feed.
$tz = $result->timezone;
}
// If this iCal object has no DTEND, but it does have a DURATION, emulate DTEND as DTSTART + DURATION.
// Again, this mechanism requires that dtstart be parsed before dtend in the source->target mapping.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment