Search code examples
phpicalendarline-endings

Can't seem to write a valid .ics file?


I need your help. I'm writing a iCal .ics File-format with a php function.

If I open the .ics file with iCal it says the application says: "Calendar can’t read this calendar file. No events have been added to your calendar."

However if I validate the file with an online .ics validator it says everything should be fine except the line endings. The validator says this:

Your calendar is using an invalid newline format. Make sure to use \r\n to end lines rather than just \n (RFC 2445 §4.1). Congratulations; your calendar validated!

But I'm not sure if this is the "real" problem why my iCal can't read the file. First off, I wonder how to change this line endings?

<?php

function wpse63611_events_feed_output(){
    $filename = urlencode( 'My-Events-' . date('Y') . '.ics' );

    // Start collecting output
    ob_start();

    header( 'Content-Description: File Transfer' );
    header( 'Content-Disposition: attachment; filename=' . $filename );
    header( 'Content-type: text/calendar' );
    header( "Pragma: 0" );
    header( "Expires: 0" );
?>
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//<?php  get_bloginfo('name'); ?>//NONSGML Events //EN
CALSCALE:GREGORIAN
X-WR-CALNAME:<?php echo get_bloginfo('name');?> - Events
<?php
    if ( have_posts() ):
        $now = new DateTime();
        $datestamp =$now->format('Ymd\THis\Z');
        while( have_posts() ): the_post();
            global $post;
            $uid = md5(uniqid(mt_rand(), true))."@mydomain.com";
            $start = unixToiCal(get_event_date($post, true, true), 2.0);
            $end = unixToiCal(get_event_end_date($post, true, true), 2.0);
            $summary = wpse63611_esc_ical_text(get_the_title());
            $description = apply_filters('the_excerpt_rss',  get_the_content());
            $description = wpse63611_esc_ical_text($description); ?>
BEGIN:VEVENT
UID:<?php echo $uid; ?>
<?php echo "\r\n"; ?>
DTSTAMP:<?php echo $datestamp; ?>
<?php echo "\r\n"; ?>
DTSTART:<?php echo $start; ?>
<?php echo "\r\n"; ?>
DTEND:<?php echo $end; ?>
<?php echo "\r\n"; ?>
SUMMARY:<?php echo $summary; ?>
<?php echo "\r\n"; ?>
DESCRIPTION:<?php echo $description; ?>
<?php echo "\r\n"; ?>
END:VEVENT
<?php endwhile; endif; ?>
END:VCALENDAR
<?php
    // Collect output and echo 
    $eventsical = ob_get_contents();
    ob_end_clean();
    echo $eventsical;
    exit();
}

function unixToiCal( $uStamp = 0, $tzone = 0.0 ) {
    $uStampUTC = $uStamp + ($tzone * 3600);       
    $stamp  = date("Ymd\THis\Z", $uStampUTC);
    return $stamp;       
}

function wpse63611_esc_ical_text( $text='' ) {
    $text = str_replace("\\", "", $text);
    $text = str_replace("\r", "\r\n ", $text);
    $text = str_replace("\n", "\r\n ", $text);
    return $text;
}

?>

Can you see any problem with this? What could cause the calendar not to work?


UPDATE Well, I fixed the line endings and the calendar validates fine now. So no errors when validating it, but I still can't get it working in iCal. When I open it it still says the calendar file is not readable. Here is the actual file that is generated by my script … http://cl.ly/383D3M3q3P32


Solution

  • looking at your ical file brings 2 topics:

    1. as mentionned above, all your lines need to be ended by \r\n (i.e. you need to ensure

    BEGIN:VCALENDAR

    VERSION:2.0

    ..

    are also ended properly

    2.you need to escape commas in text (see RFC5545 §3.3.11: https://www.rfc-editor.org/rfc/rfc5545#section-3.3.11 )

    you can also run those through online icalendar validators see this post answer: https://stackoverflow.com/a/4812081/1167333