Reputation: 44293
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
Upvotes: 0
Views: 6195
Reputation: 4775
looking at your ical file brings 2 topics:
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
Upvotes: 3
Reputation: 146450
You have the wpse63611_esc_ical_text()
function to normalize output but you only apply it to some output fragments. The funny thing is that such function expects Unix-style input ("\n"
) but the whole mechanism relies in saving your source code as Windows-style ("\r\n"
). Additionally, you sometimes call the function twice on the same text.
I believe the root problem is the you don't really know what a line ending is. When you hit your keyboard's Enter key, you'll actually get a different character depending on whether your computer runs Windows or some kind of Unix (such as Linux or MacOS). On Windows, you'll actually get two characters, represented as "\r\n"
in PHP. On Unix, you'll get one character, represented as "\n"
in PHP. If your editor is good enough, it'll allow you to save the file with the line ending of your choice, no matter what your computer runs. Check the "Save as" dialogue for further info.
Since you aren't actually typing the ICS file, you need to ensure that PHP generates the appropriate characters. The simplest way is to type and save the source code as you please and then convert the complete output once:
$output = strtr($output, array(
"\r\n" => "\r\n",
"\r" => "\r\n",
"\n" => "\r\n",
));
You'll probably need to clean up your code first.
Upvotes: 2