Làm cách nào tôi có thể sử dụng PHP để xuất bản động một tệp ical để Lịch Google đọc?


106

Bất kỳ tìm kiếm nào của Google trên ical PHP chỉ hiển thị phpicalendar và cách phân tích cú pháp hoặc đọc các tệp IN ical. Tôi chỉ muốn viết một tệp PHP lấy các sự kiện từ cơ sở dữ liệu của tôi và ghi chúng ra định dạng ical.

Vấn đề của tôi là tôi không thể tìm thấy bất kỳ nơi nào có thể trả lời hai câu hỏi:

  1. Là gì chính xác định dạng ical, bao gồm tiêu đề, định dạng tập tin, footers, vv? Nói cách khác, chính xác thì tệp phải có những gì để được Lịch Google đọc đúng cách, v.v.?
  2. Nếu tôi tạo tệp này bằng phần mở rộng .php, làm cách nào để xuất bản tệp đó dưới dạng ical? Tôi có phải ghi vào tệp .ics mới không? Hay Lịch Google, v.v. sẽ đọc tệp .php dưới dạng ical miễn là nội dung ở đúng định dạng? (Giống như tệp style.css.php sẽ được đọc dưới dạng tệp CSS nếu nội dung thực sự là CSS, v.v.)

Bất kỳ sự giúp đỡ nào mà tất cả các bạn có thể cho hoặc chỉ cho tôi sẽ được đánh giá rất cao !!!

Câu trả lời:


128

Điều này sẽ rất đơn giản nếu Lịch Google không yêu cầu *.ics-extension (sẽ yêu cầu viết lại một số URL trong máy chủ).

$ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "@yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR";

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=calendar.ics');
echo $ical;
exit;

Về cơ bản, đó là tất cả những gì bạn cần để khiến khách hàng nghĩ rằng bạn đang cung cấp tệp iCalendar, mặc dù có thể có một số vấn đề liên quan đến bộ nhớ đệm, mã hóa văn bản, v.v. Nhưng bạn có thể bắt đầu thử nghiệm với mã đơn giản này.


1
Cảm ơn. Tôi nghĩ rằng những tiêu đề đó là những gì tôi đã thiếu. Tôi cho rằng có một vài bước cuối cùng để làm cho Lịch Google này sẵn sàng, vì khi tôi cố gắng cung cấp tệp này vào Lịch Google qua URL, nó cho biết "Đang nhập lịch từ url ..." nhưng mãi mãi không thấy. Có lẽ đó là một câu hỏi khác để đăng?
rhodesjason 23/09/09

3
Chính xác. Tôi đã cập nhật ví dụ ở trên - và tôi cũng đã thêm thuộc tính DTSTAMP sẽ cho khách hàng biết khi nào các sự kiện đã được cập nhật.
Stefan Gehrig 24/09/09

1
Được rồi Gehrig, bạn là một thiên tài. Điều đó đã hiệu quả. Cảm ơn. (Cho đến nay như tôi có thể nói với Google Calendar được cập nhật gần như ngay lập tức, quá.)
rhodesjason

3
Nếu tôi không nhầm. Các chương trình sử dụng UID để xem liệu một sự kiện có bị xóa hay không. Nếu php-script luôn tạo một UID khác (-> mt_rand), các chương trình sẽ luôn nghĩ rằng toàn bộ nội dung đã thay đổi. Mọi thứ biến mất và mọi thứ đều mới. Cá nhân tôi sẽ gắn bó với cùng một UID nếu sự kiện giống nhau trong cơ sở dữ liệu và chỉ sử dụng recordID (và một số thông tin máy chủ). DTSTAMP ở đó để cho thấy điều gì đó đã thay đổi. Như vậy là đủ.
Seirddriezel

3
Lịch Google KHÔNG yêu cầu đuôi * .ics. Nếu bạn đang sử dụng .htaccess, bạn có thể làm cho nó bằng cách thêm RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky

19

Một lưu ý về kinh nghiệm cá nhân ngoài câu trả lời của Stefan Gehrig và câu trả lời của Dave None (và câu trả lời của mmmshuddup):

Tôi đã gặp sự cố xác thực khi sử dụng cả \ n và PHP_EOL khi tôi sử dụng trình xác thực ICS tại http://severshaus.org/projects/icv/

Tôi biết rằng tôi phải sử dụng \ r \ n để làm cho nó xác thực đúng cách, vì vậy đây là giải pháp của tôi:

function dateToCal($timestamp) {
  return date('Ymd\Tgis\Z', $timestamp);
}

function escapeString($string) {
  return preg_replace('/([\,;])/','\\\$1', $string);
}    

    $eol = "\r\n";
    $load = "BEGIN:VCALENDAR" . $eol .
    "VERSION:2.0" . $eol .
    "PRODID:-//project/author//NONSGML v1.0//EN" . $eol .
    "CALSCALE:GREGORIAN" . $eol .
    "BEGIN:VEVENT" . $eol .
    "DTEND:" . dateToCal($end) . $eol .
    "UID:" . $id . $eol .
    "DTSTAMP:" . dateToCal(time()) . $eol .
    "DESCRIPTION:" . htmlspecialchars($title) . $eol .
    "URL;VALUE=URI:" . htmlspecialchars($url) . $eol .
    "SUMMARY:" . htmlspecialchars($description) . $eol .
    "DTSTART:" . dateToCal($start) . $eol .
    "END:VEVENT" . $eol .
    "END:VCALENDAR";

    $filename="Event-".$id;

    // Set the headers
    header('Content-type: text/calendar; charset=utf-8');
    header('Content-Disposition: attachment; filename=' . $filename);

    // Dump load
    echo $load;

Điều đó đã ngăn các lỗi phân tích cú pháp của tôi và làm cho các tệp ICS của tôi được xác thực đúng cách.


Thông tin tiêu đề là phần quan trọng của FYI đối với bất kỳ ai đang tìm kiếm trong tương lai. Đối với hầu hết các ứng dụng và chương trình không lo lắng về lỗi NewLine. Dường như chỉ có những người xác nhận mới làm điều đó. Nhưng điều quan trọng nhất là phần tiêu đề. Chúng tôi đã cố gắng trong một thời gian mà không có nó và đang gặp nhiều vấn đề.
jfreak53

1
EscapeString để làm gì? Tôi cho rằng nó sẽ thoát khỏi một hoặc hai điều nhưng bạn dường như sử dụng htmlspecialcharscho điều đó thay thế.
Lục

1
Cách sửa nhanh: date ('Ymd \ THis \ Z', $ timestamp). Nên là H thay vì g.
Pedro Góes

6

Có một gói eluceo / ical tuyệt vời cho phép bạn dễ dàng tạo các tệp ics.

Đây là một ví dụ sử dụng từ tài liệu:

// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');

// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');

// Adding Timezone (optional)
$vEvent->setUseTimezone(true);

// 3. Add event to calendar
$vCalendar->addComponent($vEvent);

// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');

// 5. Output
echo $vCalendar->render();


4

http://www.kanzaki.com/docs/ical/ có một phiên bản dễ đọc hơn của thông số cũ hơn. Nó giúp ích như một điểm khởi đầu - nhiều thứ vẫn giống nhau.

Cũng trên trang web của tôi , tôi có

  1. Một số danh sách tài nguyên hữu ích (xem thanh bên dưới cùng bên phải) trên
    • ical Spec RFC 5545
    • Tài nguyên kiểm tra ical
  2. Một số ghi chép về hành trình làm việc của tôi .icstrong vài năm qua. Đặc biệt, bạn có thể thấy 'bảng cheatsheet' các sự kiện lặp lại này rất hữu ích.

.ics các khu vực cần xử lý cẩn thận:

  • sự kiện 'cả ngày'
  • loại ngày (múi giờ, UTC hoặc địa phương 'thả nổi') - nb để hiểu sự phân biệt
  • khả năng tương tác của các quy tắc lặp lại

2
  1. Định dạng ical chính xác: http://www.ietf.org/rfc/rfc2445.txt
  2. Theo thông số kỹ thuật, nó phải kết thúc bằng .ics

Chỉnh sửa: thực sự tôi không chắc - dòng 6186 đưa ra một ví dụ ở định dạng đặt tên .ics, nhưng nó cũng cho biết bạn có thể sử dụng các tham số url. Tôi không nghĩ điều đó quan trọng, miễn là kiểu MIME là đúng.

Chỉnh sửa: Ví dụ từ wikipedia: http://en.wikipedia.org/wiki/ICalendar

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR

Loại MIME được cấu hình trên máy chủ.


1
Tôi đã cố gắng đọc thông số kỹ thuật đó nhiều lần nhưng tôi không thể hiểu được đầu hoặc đuôi của nó đến mức tệp ical sẽ trông như thế nào. Ít nhất bạn có thể chỉ cho tôi một số dòng nơi nó bắt đầu thực sự nói về những gì tệp .ics nên chứa bao gồm tiêu đề, nơi đặt kiểu MIME, v.v. không?
rhodesjason 23/09/09

2

Đảm bảo rằng bạn định dạng chuỗi như thế này nếu không nó sẽ không hoạt động

 $content = "BEGIN:VCALENDAR\n".
            "VERSION:2.0\n".
            "PRODID:-//hacksw/handcal//NONSGML v1.0//EN\n".
            "BEGIN:VEVENT\n".
            "UID:".uniqid()."\n".
            "DTSTAMP:".$time."\n".
            "DTSTART:".$time."\n".
            "DTEND:".$time."\n".
            "SUMMARY:".$summary."\n".
            "END:VEVENT\n".
            "END:VCALENDAR";

1
tốt hơn là sử dụng PHP_EOLthay vì "\n".
Có Barry

4
PHP_EOL là môi trường cụ thể cho các dòng cuối, vì vậy trong windows, nó sẽ xuất ra, \r\nvì vậy hãy ghi nhớ điều đó!
Chris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.