Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverses order of components when looping through during the calendar… #65

Closed
wants to merge 1 commit into from

Conversation

chris-schmitz
Copy link

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 the VTIMEZONE 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:

    /** @var $component Component */
    foreach (array_reverse($this->components) as $component) {
        foreach ($component->build() as $l) {
            $lines[] = $l;
        }
    }

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.

… build process.

This allows Outlook v15 to recognize timezone when creating explicit
timezones rules.
@markuspoerschke
Copy link
Owner

markuspoerschke commented Apr 26, 2016

I think simply reversing the order of the component is not reliable. Therefore I fixed the order of the timezone components to render them always at the beginning: 388f5c0

@chris-schmitz Do you think that helps resolving your issue? (Thanks for this detailed issue report by the way)

@chris-schmitz
Copy link
Author

I think that will resolve the issue. I'll update, check, and let you know.

No prob regarding the detail. Thanks for building a package that created the invites for me :)

@chris-schmitz
Copy link
Author

@markuspoerschke Yep, that resolved my issue. Thanks for making that change!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants