Формат iCal для календаря Google Calendar/Yahoo не работает

Я создал файл календаря (.ics) из моего приложения с целью потребления в приложении "Календарь", например "Календарь Google". Я запустил файл ниже через валидатор, но похоже, что ни Google, ни Yahoo Calendars не хотят играть в мяч. Клиент моего локального Mac-календаря работает на 100%. Может ли кто-нибудь увидеть что-нибудь очевидное о файле ниже, который потенциально может задохнуться в Календаре Google? Или любые дополнительные поля, в которых они нуждаются? Я также получаю 500 ошибок из календаря Yahoo. Вырывая волосы в этот момент.

Я пробовал с информацией о часовом поясе и без нее, и это, похоже, не имеет большого значения.

Выход заголовка

        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); 
        header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); 
        header('Cache-Control: no-store, no-cache, must-revalidate' );
        header('Cache-Control: post-check=0, pre-check=0', false );
        header('Pragma: no-cache' );
        header('Content-type: text/calendar;');
        header('Content-Disposition: inline; filename="calendar.ics"');
        header("Content-Description: File Transfer");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . strlen($generated));

UTC times или TZID Я экспериментировал и, похоже, не имел никакого значения. Если у кого-то есть действительно простой пример URL-адреса.ИК-событий, которые, похоже, работают с "кросс-календарем", это очень понравилось бы. В качестве альтернативы, если кто-то может предоставить некоторые достойные библиотеки для этой цели, которые не являются болью для интеграции в проект CakePHP, этого было бы достаточно.

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//MS//NONSGML//EN
X-WR-CALNAME:Holidays
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:1075
DTSTART;TZID=Europe/London:20150114T080000
DTEND;TZID=Europe/London:20150114T170000
DTSTAMP:20150114T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Stat Holiday (1.0 days)
LAST-MODIFIED:20150114T080000Z
LOCATION:
SUMMARY: Statutory Day
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1076
DTSTART;TZID=Europe/London:20150116T080000
DTEND;TZID=Europe/London:20150116T170000
DTSTAMP:20150116T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Stat Holiday (1.0 days)
LAST-MODIFIED:20150116T080000Z
LOCATION:
SUMMARY: Statutory Day
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1079
DTSTART;TZID=Europe/London:20151020T123000
DTEND;TZID=Europe/London:20151020T170000
DTSTAMP:20151020T123000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151020T123000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1080
DTSTART;TZID=Europe/London:20151021T080000
DTEND;TZID=Europe/London:20151021T123000
DTSTAMP:20151021T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday (3.0 days) test
LAST-MODIFIED:20151021T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1081
DTSTART;TZID=Europe/London:20151022T080000
DTEND;TZID=Europe/London:20151022T170000
DTSTAMP:20151022T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151022T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:1082
DTSTART;TZID=Europe/London:20151023T080000
DTEND;TZID=Europe/London:20151023T170000
DTSTAMP:20151023T080000Z
CREATED:20151019T211433Z
DESCRIPTION:Holiday Request (3.0 days) test
LAST-MODIFIED:20151023T080000Z
LOCATION:
SUMMARY:admin Leave
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

Ответ 1

Используя комбинацию ответов на SO (Ошибки Календаря Google при импорте файла .ics) и некоторый исходный код из https://gist.github.com/jakebellacera/635416

Мой рабочий код, протестированный в нескольких инструментах:

<?php

//test
//
$summary = "test";
$datestart=time();
$dateend = $datestart + 3600;
$address = "Amsterdam";
$description = "testing ical format";
$filename = "test.ics";

// Variables used in this script:
//   $summary     - text title of the event
//   $datestart   - the starting date (in seconds since unix epoch)
//   $dateend     - the ending date (in seconds since unix epoch)
//   $address     - the event address
//   $uri         - the URL of the event (add http://)
//   $description - text description of the event
//   $filename    - the name of this file for saving (e.g. my-event-name.ics)
//
// Notes:
//  - the UID should be unique to the event, so in this case I'm just using
//    uniqid to create a uid, but you could do whatever you'd like.
//
//  - iCal requires a date format of "yyyymmddThhiissZ". The "T" and "Z"
//    characters are not placeholders, just plain ol' characters. The "T"
//    character acts as a delimeter between the date (yyyymmdd) and the time
//    (hhiiss), and the "Z" states that the date is in UTC time. Note that if
//    you don't want to use UTC time, you must prepend your date-time values
//    with a TZID property. See RFC 5545 section 3.3.5
//
//  - The Content-Disposition: attachment; header tells the browser to save/open
//    the file. The filename param sets the name of the file, so you could set
//    it as "my-event-name.ics" or something similar.
//
//  - Read up on RFC 5545, the iCalendar specification. There is a lot of helpful
//    info in there, such as formatting rules. There are also many more options
//    to set, including alarms, invitees, busy status, etc.
//
//      https://www.ietf.org/rfc/rfc5545.txt
// 1. Set the correct headers for this file
header('Content-type: text/calendar; charset=utf-8');
header("Content-Disposition:inline;filename=".$filename);
// 2. Define helper functions
// Converts a unix timestamp to an ics-friendly format
// NOTE: "Z" means that this timestamp is a UTC timestamp. If you need
// to set a locale, remove the "\Z" and modify DTEND, DTSTAMP and DTSTART
// with TZID properties (see RFC 5545 section 3.3.5 for info)
//
// Also note that we are using "H" instead of "g" because iCalendar Time format
// requires 24-hour time (see RFC 5545 section 3.3.12 for info).
function dateToCal($timestamp) {
  return date('Ymd\THis\Z', $timestamp);
}
// Escapes a string of characters
function escapeString($string) {
  return preg_replace('/([\,;])/','\\\$1', $string);
}
// 3. Echo out the ics file contents
$iCal="BEGIN:VCALENDAR\r
VERSION:2.0\r
PRODID:-//hacksw/handcal//NONSGML v1.0//EN\r
CALSCALE:GREGORIAN\r
BEGIN:VEVENT\r
DTSTAMP:".dateToCal(time())."\r
DTSTART:".dateToCal($datestart)."\r
DTEND:".dateToCal($dateend)."\r
UID:".uniqid()."\r
LOCATION:".escapeString($address)."\r
DESCRIPTION:".escapeString($description)."\r
SUMMARY:".escapeString($summary)."\r
END:VEVENT\r
END:VCALENDAR";
file_put_contents($filename,$iCal);
print file_get_contents($filename);
unlink($filename);
exit;
?>

Кажется важным, чтобы конечные строки были правильными (так что\r\n).

Ответ 2

Ваш файл верен, я сам загрузил его в календари Google, поэтому он должен работать, однако, если вы не остановите script после файлового эха, например:

    //somewhere else in the script
    echo "this will break the file";
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); 
    header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); 
    header('Cache-Control: no-store, no-cache, must-revalidate' );
    header('Cache-Control: post-check=0, pre-check=0', false );
    header('Pragma: no-cache' );
    header('Content-type: text/calendar;');
    header('Content-Disposition: inline; filename="calendar.ics"');
    header("Content-Description: File Transfer");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . strlen($generated));
    echo $generated;
    exit;//or return 200 or whatever
    echo "this could break the file except there is an exit;";//for example.

Вы могли бы по существу отправить неверный файл.

Ответ 3

В файле .ics я добавил одну строку

METHOD:REQUEST

и yahoo начали работать. В моем случае я отправил письма в hotmail, gmail и yahoo с файлом .ics, и yahoo не работал без этой строки. С

METHOD:PUBLISH

yahoo также не работает