From 0e07183c69e4eaef625c9add3d7a0a91994fd2d4 Mon Sep 17 00:00:00 2001 From: Robert Rollins Date: Mon, 25 Aug 2014 12:17:21 -0700 Subject: [PATCH] While testing the patch from #2325649, I discovered a need to work around iCalcreator. iCalcreator knows that certain iCal properties (e.g. ATTENDEE) can have multiple entries in a single VEVENT. So when you access ATTENDEE for the first time, it gives you the first entry. Accessing it a second time gives back the second entry, or at least it tries to. If there is no second entry, iCalcreator returns False. Since Date iCal does not yet support multi-entry properties, I had to work around this functionality to ensure that hooks which add custom mappings don't run afoul of this process. --- libraries/ParserVcalendar.inc | 55 +++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/libraries/ParserVcalendar.inc b/libraries/ParserVcalendar.inc index 04d221c..c3f65b5 100644 --- a/libraries/ParserVcalendar.inc +++ b/libraries/ParserVcalendar.inc @@ -33,6 +33,17 @@ class ParserVcalendar { protected $totalComponents = 0; protected $lastComponentParsed = 0; + /** + * This is the list of iCal properties which are allowed to have more than + * one entry in a single VEVENT. If we ever support parsing more than just + * the first one, this listing will be useful. + */ + protected $multi_entry_properties = array( + 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', + 'EXDATE', 'EXRULE', 'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', + 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' + ); + /** * Constructor. */ @@ -181,6 +192,21 @@ class ParserVcalendar { return $this->lastComponentParsed; } + /** + * Handler that parses GEO fields. + * + * @return array + * The latitude and longitude values, keyed by 'lat' and 'lon'. + */ + public function parseGeofield($property_key, $vcalendar_component) { + $geo = array(); + if (!empty($vcalendar_component->geo['value'])) { + $geo['lat'] = $vcalendar_component->geo['value']['latitude']; + $geo['lon'] = $vcalendar_component->geo['value']['longitude']; + } + return $geo; + } + /** * Handler that parses text fields. * @@ -189,6 +215,15 @@ class ParserVcalendar { */ public function parseTextProperty($property_key, $vcalendar_component) { $text = $vcalendar_component->getProperty($property_key); + // In case someone writes a hook that adds a source for a multi-entry + // property and a parameter of that same property, we need to force + // iCalcreator to assume it has not accessed that property, yet. + // TODO: This is really just a hack. If/when multi-entry properties + // become supported, this will need to be redesigned. + if (in_array($property_key, $this->multi_entry_properties)) { + unset($vcalendar_component->propix[$property_key]); + } + if ($text === FALSE) { if ($property_key == 'SUMMARY') { $uid = $vcalendar_component->getProperty('UID'); @@ -202,21 +237,6 @@ class ParserVcalendar { return $text; } - /** - * Handler that parses GEO fields. - * - * @return array - * The latitude and longitude values, keyed by 'lat' and 'lon'. - */ - public function parseGeofield($property_key, $vcalendar_component) { - $geo = array(); - if (!empty($vcalendar_component->geo['value'])) { - $geo['lat'] = $vcalendar_component->geo['value']['latitude']; - $geo['lon'] = $vcalendar_component->geo['value']['longitude']; - } - return $geo; - } - /** * Handler that parses field parameters. * @@ -226,6 +246,11 @@ class ParserVcalendar { public function parsePropertyParameter($property_key, $vcalendar_component) { list($key, $attr) = explode(':', $property_key); $property = $vcalendar_component->getProperty($key, FALSE, TRUE); + // See parseTextProperty() for why this is here. + if (in_array($property_key, $this->multi_entry_properties)) { + unset($vcalendar_component->propix[$property_key]); + } + if ($property === FALSE) { // If the component doesn't have this property, return NULL. return NULL; -- GitLab