Як я можу використовувати PHP для динамічного опублікування файлу, який читається у Календарі Google?


106

Будь-який пошук Google на PHP ical просто відображає phpicalendar та як розбирати чи читати IN ical файли. Я просто хочу написати файл PHP, який витягує події з моєї бази даних і записує їх у форматі iical.

Моя проблема полягає в тому, що я не можу ніде знайти, що відповість на два запитання:

  1. Який точний ical формат, включаючи заголовки, формат файлів, колонтитули тощо? Іншими словами, що саме повинен мати файл, щоб правильно його читати в Календарі Google тощо?
  2. Якщо я будую цей файл за допомогою розширення .php, як його опублікувати як ical? Чи потрібно писати у новий .ics файл? Або Google Календар тощо буде читати .php файл як ical, якщо вміст у правильному форматі? (Так само, як файл style.css.php буде читатися як файл CSS, якщо вміст насправді є CSS тощо)

Будемо дуже вдячні за будь-яку допомогу, яку ви всі можете надати або надати мені !!!

Відповіді:


128

Це повинно бути дуже простим, якщо Google Календар не вимагає розширення-розширення *.ics(що вимагає певного переписування URL-адреси на сервері).

$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;

Це, по суті, все, що потрібно змусити клієнта думати, що ви подаєте файл iCalendar, хоча можуть виникнути проблеми щодо кешування, кодування тексту тощо. Але ви можете почати експериментувати з цим простим кодом.


1
Дякую. Я думаю, що ці заголовки - це те, чого я бракував. Я припускаю, що для підготовки цього календаря Google є кілька останніх кроків, тому що коли я намагаюся подати цей файл до Календаря Google через URL, він говорить "Імпорт календаря з URL-адреси ...", але він зависає на це назавжди. Можливо, це інше питання, яке слід поставити?
rhodesjason

3
Саме так. Я оновив приклад вище - і також додав властивість DTSTAMP, яке повідомить клієнту, коли події були оновлені.
Стефан Гегріг

1
Гаразд Гегріге, ти геній. Це спрацювало. Дякую. (Наскільки я можу сказати, Google Календар також оновлюється майже одразу.)
rhodesjason

3
Якщо я не помиляюся Програми використовують UID, щоб побачити, чи видалено подію. Якщо php-скрипт завжди генерує інший UID (-> mt_rand), програми завжди будуть думати, що весь вміст змінився. Все зникло і все нове. Особисто я б дотримувався того ж UID, якщо подія однакова в базі даних і просто використовувати recordID (і деяку інформацію про хост). DTSTAMP є, щоб показати, що щось змінилося. Цього має бути достатньо.
Seirddriezel

3
У календарі Google НЕ потрібен розширення * .ics. Якщо ви використовуєте .htaccess, ви можете зробити це, додавши RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky

19

Довідка про особистий досвід, окрім відповіді Стефана Геріга та відповіді Дейва Ніко (та відповіді мммсхуддупа):

У мене виникли проблеми з валідацією, використовуючи і \ n, і PHP_EOL, коли я використовував валідатор ICS за адресою http://severinghaus.org/projects/icv/

Я дізнався, що мені потрібно використовувати \ r \ n, щоб змусити його правильно перевірити, тому це було моє рішення:

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;

Це зупинило мої помилки розбору та змусило мої ICS файли перевірити належним чином.


Інформація в заголовку - важлива частина FYI для кожного, хто дивиться в майбутнє. Здебільшого більшість програм і програм не турбуються про перерви в NewLine. Здається, тільки валідатори. Але найголовніше - це заголовна частина. Ми намагалися деякий час без цього і мали багато проблем.
jfreak53

1
Для чого таке escapeString? Я припускав, що він повинен уникнути речі чи двох, але ви, здається, використовуєте htmlspecialcharsдля цього.
Люк

1
Швидке виправлення: дата ('Ymd \ THis \ Z', $ timestamp). Повинна бути Н замість g.
Pedro Góes

6

Існує чудовий пакет eluceo / ical, який дозволяє легко створювати файли ics.

Ось приклад використання документів:

// 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/ має трохи більш читану версію старішої специфікації. Це допомагає як відправна точка - багато речей залишаються однаковими.

Також на своєму сайті у мене є

  1. Деякі списки корисних ресурсів (див. Бічну панель праворуч внизу) на
    • ical Spec RFC 5545
    • Ресурси ical тестування
  2. Деякі записки, записані в моїй подорожі, з якою працював .icsпротягом останніх кількох років. Зокрема, ви можете вважати корисним цей чит-лист, що повторюється .

.ics області, які потребують ретельного поводження:

  • події на цілий день
  • типи дат (часовий пояс, UTC або місцевий 'плаваючий') - nb, щоб зрозуміти відмінність
  • сумісність правил повторення

2
  1. Точний ical формат: http://www.ietf.org/rfc/rfc2445.txt
  2. Відповідно до специфікації, це має закінчитися в .ics

Редагувати: насправді я не впевнений - рядок 6186 дає приклад у форматі іменування .ics, але в ньому також зазначено, що ви можете використовувати параметри url. Я не думаю, що це має значення, якщо тип MIME правильний.

Редагувати: Приклад з 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

Тип MIME налаштований на сервері.


1
Я багато разів намагався прочитати цю специфікацію, але я не можу робити ні голови, ні хвости, наскільки виглядатиме файл ical. Чи можете ви принаймні вказати мені на деякі рядки, де він починає насправді говорити про те, що файл .ics повинен містити до заголовка, куди слід розмістити тип MIME тощо?
rhodesjason

2

Переконайтеся, що ви відформатували такий рядок або він не працює

 $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
краще використовувати PHP_EOLзамість "\n".
Так, Баррі

4
PHP_EOL - це специфічне для кінцевих рядків середовище, тому у Windows він виводитиме \r\nтак, майте це на увазі!
Кріс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.