2012-09-27 68 views
0

我需要你的幫助。我正在用php函數編寫一個iCal .ics文件格式。似乎無法寫出有效的.ics文件?

如果我用iCal打開.ics文件,它表示應用程序說:「日曆無法讀取此日曆文件,也沒有事件添加到您的日曆中。

但是,如果我使用online .ics validator驗證文件,它說除了line endings之外,一切都應該是正常的。 validator這樣說:

您的日曆正在使用無效的換行格式。確保使用 \ r \ n結束行而不僅僅是\ n(RFC 2445§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; 
} 

?> 

你能看到這個問題嗎?什麼可能導致日曆不起作用?


UPDATE 嗯,我固定的行結束和日曆現在驗證罰款。所以在驗證時沒有錯誤,但我仍然無法在iCal中使用它。當我打開它時仍然表示日曆文件不可讀。這裏是我的腳本生成的實際文件... http://cl.ly/383D3M3q3P32

+0

你有沒有嘗試過用正確的行結尾? – TZHX

+0

那麼,行結局不是問題!我修復了行結尾,但該文件仍然無效!我更新了我的問題。 – matt

+0

修復問題時,請不要編輯問題,使當前答案無效。如果還有其他問題,請創建一個新問題。 –

回答

3

看你的iCal文件帶來了兩個議題:

  1. 如上mentionned,所有你的線需要有\ r \ n(即你需要確保
結束

BEGIN:VCALENDAR

VERSION:2.0

..

也結束了正確

2.you需要轉義逗號文本(請參見RFC5545§3.3.11:http://tools.ietf.org/html/rfc5545#section-3.3.11

你也可以運行那些通過網上的iCalendar驗證看到這個帖子答案:https://stackoverflow.com/a/4812081/1167333

+0

好吧,我更新了我的代碼,看起來像這樣... http://cl.ly/code/1i2P080v2s1G ...和輸出的日曆在所有這些validatars中驗證完美。 100分中的100分。但是我無法在我的「日曆」應用程序的Mac中打開它。同時在Mac OSX Mountain Lion中,「iCal」被重命名爲「Calendar」...輸出的文件如下所示:http://cl.ly/3c2w1Z462d2o「.ics」文件可以在舊版本的iCal中打開,但不會「他們看起來真的有效。沒有事件被添加,但日曆文件可以被讀取(所以打開它時沒有錯誤信息,但沒有添加事件) – matt

+0

問題不是你的代碼,而是底層數據:dtstart是* dtend後的*,參見: DTSTART:20121018T022000Z DTEND:20120904T162842Z 摘要:標題\,編號1? – oberron

3

你有wpse63611_esc_ical_text()函數來標準化輸出,但你只應用它到一些輸出片段。有趣的是,這樣的函數需要Unix風格的輸入("\n"),但整個機制依賴於將源代碼保存爲Windows風格("\r\n")。此外,您有時在相同的文本上調用該函數兩次。

我認爲根本問題是你並不真正知道行結尾是什麼。當你敲擊鍵盤的輸入鍵時,根據你的電腦是運行Windows還是某種Unix(如Linux或MacOS),你實際上會得到不同的字符。在Windows上,您實際上會獲得兩個個字符,在PHP中表示爲"\r\n"。在Unix上,您將獲得一個字符,在0123表示爲"\n"。如果你的編輯器足夠好,它將允許你用你選擇的行結束保存文件,不管你的計算機運行什麼。檢查「另存爲」對話框以獲取更多信息。

由於您實際上沒有輸入ICS文件,因此您需要確保PHP生成適當的字符。最簡單的方法是輸入和保存的源代碼,請你再轉換完整輸出一次:

$output = strtr($output, array(
    "\r\n" => "\r\n", 
    "\r" => "\r\n", 
    "\n" => "\r\n", 
)); 

你可能需要先清理你的代碼。

+0

謝謝,我已經更新了。它現在驗證罰款,每個.ics驗證器告訴我該文件是100%正確的。但是,必須丟失一些東西。 – matt

相關問題