我需要你的帮助。我正在用php函数编写一个iCal .ics
文件格式。
如果我用iCal打开.ics
文件,它会说应用程序说:“日历无法读取此日历文件。您的日历中没有添加任何活动。”
但是,如果我使用online .ics validator验证文件,则表示除了line endings
之外一切正常。 validator说明了这一点:
您的日历使用的是无效的换行格式。一定要使用 \ r \ n结束行而不仅仅是\ n(RFC2445§4.1)。 恭喜;您的日历已经过验证!
但我不确定这是否是我的iCal无法读取文件的“真正”问题。 首先,我想知道如何更改此行结尾?
<?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;
}
?>
你能看到这个问题吗?什么可能导致日历不起作用?
更新 好吧,我修复了行结尾,现在日历验证正常。因此在验证时没有错误,但我仍然无法在iCal中使用它。当我打开它仍然说日历文件不可读。这是我的脚本生成的实际文件... http://cl.ly/383D3M3q3P32
答案 0 :(得分:3)
您有wpse63611_esc_ical_text()
函数来规范化输出,但您只将它应用于某些输出片段。有趣的是,这样的函数需要Unix风格的输入("\n"
),但整个机制依赖于将源代码保存为Windows风格("\r\n"
)。此外,有时您会在同一文本上调用该函数两次。
我认为根本问题是你真的不知道行结尾是什么。当您按下键盘的 Enter 键时,根据您的计算机是运行Windows还是某种Unix(如Linux或MacOS),您实际上会获得不同的字符。在Windows上,您实际上会得到两个字符,在PHP中表示为"\r\n"
。在Unix上,您将获得一个字符,在PHP中表示为"\n"
。如果您的编辑器足够好,它将允许您使用您选择的行结尾保存文件,无论您的计算机运行什么。查看“另存为”对话框以获取更多信息。
由于您实际上并未键入ICS文件,因此需要确保PHP生成相应的字符。最简单的方法是根据需要输入和保存源代码,然后转换完整输出一次:
$output = strtr($output, array(
"\r\n" => "\r\n",
"\r" => "\r\n",
"\n" => "\r\n",
));
您可能需要先清理代码。
答案 1 :(得分:3)
查看您的ics文件会带来两个主题:
BEGIN:VCALENDAR
VERSION:2.0
...
也正常结束
2.你需要在文本中删除逗号(参见RFC5545§3.3.11:http://tools.ietf.org/html/rfc5545#section-3.3.11)
你也可以通过在线icalendar验证器运行那些看到这个帖子的答案:https://stackoverflow.com/a/4812081/1167333