Reverses order of components when looping through during the calendar… #65
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adjustment to allow Outlook v15 to recognize timezones when using explicit timezone with definition
I ran into an issue generating ics files with explicit timezone definitions where invites would recognize the timezone in mac Calendar and google calendar but fail to recognize the timezone in Outlook v15 (at least. I have not tested to see if other versions of outlook have this same issue).
To cut to the chase, the error came when the
VEVENT
definition came before theVTIMEZONE
definition. If the order is reversed, Outlook will recognize the timezone.The change needed to the code is adding a
reverse_array
to loop foreach-ing over the Calendar classes components:The way example 5 is written out, the timezone is set as a property of the Calendar class, but the event is set directly as a component.
When the render method is fired on the calendar, it builds the property bag first which adds the the Calendar timezone property to the components array and then later iterates over the components. This means with the current structure the timezone will always come after the events added previously to the array of components.
Since we can always count on the events being added by the user directly via addComponents we know we can reverse the order of the components to make sure the timezones are defined before the events.
Duplicating the problem
Here is the sample code I used to troubleshoot the issue. It's basically example5 with the event date and timezones changed.
setTzName('CDT'); $vTimezoneRuleDst->setDtStart(new \DateTime('1970-03-08 02:00:00', $dtz)); $vTimezoneRuleDst->setTzOffsetFrom('-0600'); $vTimezoneRuleDst->setTzOffsetTo('-0500'); $dstRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule(); $dstRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY); $dstRecurrenceRule->setByMonth(3); $dstRecurrenceRule->setByDay('2SU'); $vTimezoneRuleDst->setRecurrenceRule($dstRecurrenceRule); // 3. Create timezone rule object for Standard Time $vTimezoneRuleStd = new \Eluceo\iCal\Component\TimezoneRule(\Eluceo\iCal\Component\TimezoneRule::TYPE_STANDARD); $vTimezoneRuleStd->setTzName('CST'); $vTimezoneRuleStd->setDtStart(new \DateTime('1970-11-01 03:00:00', $dtz)); $vTimezoneRuleStd->setTzOffsetFrom('-0500'); $vTimezoneRuleStd->setTzOffsetTo('-0600'); $stdRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule(); $stdRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY); $stdRecurrenceRule->setByMonth(11); $stdRecurrenceRule->setByDay('1SU'); $vTimezoneRuleStd->setRecurrenceRule($stdRecurrenceRule); // 4. Create timezone definition and add rules $vTimezone = new \Eluceo\iCal\Component\Timezone($tz); $vTimezone->addComponent($vTimezoneRuleDst); $vTimezone->addComponent($vTimezoneRuleStd); $vCalendar->setTimezone($vTimezone); // 5. Create an event $vEvent = new \Eluceo\iCal\Component\Event(); $vEvent->setDtStart(new \DateTime('2016-02-12 17:00:00', $dtz)); $vEvent->setDtEnd(new \DateTime('2016-02-12 18:30:00', $dtz)); $vEvent->setSummary('Beer-o-clock'); // 6. Adding Timezone $vEvent->setUseTimezone(true); // 7. Add event to calendar $vCalendar->addComponent($vEvent); // 8. Set headers header('Content-Type: text/calendar; charset=utf-8'); header('Content-Disposition: attachment; filename="eow-test.ics"'); // 9. Output echo $vCalendar->render(); ``` If you generate the ics file from this before the `array_reverse` change and then open it in Outlook v15 it will use the events time with the user's local timezone. ![](http://i.imgur.com/fPkYt34.png) Once you add the `array_reverse` in, the timezone generated from the same code will be recognized. ![](http://i.imgur.com/zjNhchq.png) This is my first real pull request, so sorry if this is too much or too little detail.