Формат 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 также не работает