Wie kann ich PHP verwenden, um eine von Google Kalender zu lesende Datei dynamisch zu veröffentlichen?

106

Jede Google-Suche auf PHP ical ruft nur phpicalendar auf und zeigt, wie IN ical-Dateien analysiert oder gelesen werden. Ich möchte nur eine PHP-Datei schreiben, die Ereignisse aus meiner Datenbank abruft und sie in einem bestimmten Format ausschreibt.

Mein Problem ist, dass ich nirgendwo etwas finden kann, das zwei Fragen beantwortet:

  1. Was ist das genaue Format, einschließlich Kopfzeilen, Dateiformat, Fußzeilen usw.? Mit anderen Worten, was muss die Datei genau haben, um von Google Kalender usw. richtig eingelesen zu werden?
  2. Wie veröffentliche ich diese Datei als ical, wenn ich sie mit der Erweiterung .php erstelle? Muss ich in eine neue .ics-Datei schreiben? Oder liest Google Kalender usw. eine .php-Datei so lange, wie der Inhalt im richtigen Format vorliegt? (Ähnlich wie eine style.css.php-Datei wird sie als CSS-Datei gelesen, wenn der Inhalt tatsächlich CSS usw. ist.)

Jede Hilfe, die Sie mir geben oder auf die Sie mich hinweisen können, wird sehr geschätzt !!!

Rhodesjason
quelle

Antworten:

128

Dies sollte sehr einfach sein, wenn Google Kalender die *.icsErweiterung- nicht benötigt (was ein Umschreiben der URL auf dem Server erfordert).

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

Das ist im Wesentlichen alles, was Sie benötigen, um einen Client glauben zu lassen, dass Sie eine iCalendar-Datei bereitstellen, auch wenn möglicherweise Probleme mit dem Caching, der Textcodierung usw. auftreten. Sie können jedoch mit diesem einfachen Code experimentieren.

Stefan Gehrig
quelle
1
Vielen Dank. Ich denke, diese Überschriften haben mir gefehlt. Ich gehe davon aus, dass es noch ein paar letzte Schritte gibt, um diesen Google Kalender fertig zu stellen. Wenn ich versuche, diese Datei über eine URL in den Google Kalender zu übertragen, wird dort "Kalender aus URL importieren ..." angezeigt, aber das bleibt für immer. Vielleicht ist das eine andere Frage zu posten?
Rhodesjason
3
Genau. Ich habe das obige Beispiel aktualisiert und eine DTSTAMP-Eigenschaft hinzugefügt, die einem Client mitteilt, wann die Ereignisse aktualisiert wurden.
Stefan Gehrig
1
Okay Gehrig, du bist ein Genie. Das hat funktioniert. Vielen Dank. (Soweit ich das
beurteilen
3
Wenn ich mich nicht irre. Programme verwenden die UID, um festzustellen, ob ein Ereignis gelöscht wurde. Wenn ein PHP-Skript immer eine andere UID generiert (-> mt_rand), denken Programme immer, dass sich der gesamte Inhalt geändert hat. Alles ist verschwunden und alles ist neu. Persönlich würde ich mich an dieselbe UID halten, wenn das Ereignis in der Datenbank identisch ist, und nur die recordID (und einige Hostinformationen) verwenden. Der DTSTAMP soll zeigen, dass sich etwas geändert hat. Das sollte genug sein.
Seirddriezel
3
Für den Google-Kalender ist die Erweiterung * .ics erforderlich. Wenn Sie .htaccess verwenden, können Sie es durch Hinzufügen von RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky
19

Ein Hinweis auf persönliche Erfahrungen zusätzlich zu der Antwort von Stefan Gehrig und der Antwort von Dave None (und der Antwort von mmmshuddup):

Ich hatte Validierungsprobleme mit \ n und PHP_EOL, als ich den ICS-Validator unter http://severinghaus.org/projects/icv/ verwendete.

Ich habe gelernt, dass ich \ r \ n verwenden muss, damit es ordnungsgemäß validiert wird. Dies war also meine Lösung:

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;

Dadurch wurden meine Analysefehler gestoppt und meine ICS-Dateien wurden ordnungsgemäß validiert.

Kane Ford
quelle
Die Header-Informationen sind der wichtige Teil zu Ihrer Information für alle, die in die Zukunft schauen. Die meisten Apps und Programme sorgen sich größtenteils nicht um die NewLine-Pausen. Nur die Validatoren scheinen es zu tun. Das Wichtigste ist jedoch der Header-Teil. Wir haben es eine Weile ohne versucht und hatten viele Probleme.
jfreak53
1
Wofür ist EscapeString? Ich nahm an, dass es ein oder zwei Dingen entkommen sollte, aber Sie scheinen htmlspecialcharsstattdessen dafür zu verwenden.
Luc
1
Eine schnelle Lösung: Datum ('Ymd \ THis \ Z', $ timestamp). Sollte ein H anstelle von g sein.
Pedro Góes
6

Es gibt ein ausgezeichnetes eluceo / ical- Paket, mit dem Sie einfach ics-Dateien erstellen können.

Hier ist ein Beispiel für die Verwendung aus Dokumenten:

// 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();
Ivan Yarych
quelle
4

http://www.kanzaki.com/docs/ical/ hat eine etwas besser lesbare Version der älteren Spezifikation. Es hilft als Ausgangspunkt - viele Dinge sind immer noch gleich.

Auch auf meiner Seite habe ich

  1. Einige Listen nützlicher Ressourcen (siehe Seitenleiste unten rechts)
    • ical Spec RFC 5545
    • Testressourcen
  2. Einige Notizen, die ich auf meiner Reise .icsin den letzten Jahren gemacht habe. Insbesondere kann dieses "Cheatsheet" für sich wiederholende Ereignisse nützlich sein.

.ics Bereiche, die einer sorgfältigen Behandlung bedürfen:

  • "ganztägige" Ereignisse
  • Datentypen (Zeitzone, UTC oder lokales 'Floating') - nb, um die Unterscheidung zu verstehen
  • Interoperabilität von Wiederholungsregeln
Anmari
quelle
2
  1. Genaues Format: http://www.ietf.org/rfc/rfc2445.txt
  2. Laut Spezifikation muss es in .ics enden

Bearbeiten: Eigentlich bin ich mir nicht sicher - Zeile 6186 enthält ein Beispiel im .ics-Namensformat, gibt aber auch an, dass Sie URL-Parameter verwenden können. Ich denke nicht, dass es wichtig ist, solange der MIME-Typ korrekt ist.

Bearbeiten: Beispiel aus 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

Der MIME-Typ ist auf dem Server konfiguriert.

lod3n
quelle
1
Ich habe viele Male versucht, diese Spezifikation zu lesen, aber ich kann mir keine Gedanken darüber machen, wie die ical-Datei aussehen wird. Können Sie mich zumindest auf einige Zeilen verweisen, in denen tatsächlich darüber gesprochen wird, was die .ics-Datei bis zum Header enthalten soll, wo der MIME-Typ abgelegt werden soll usw.?
Rhodesjason
2

Stellen Sie sicher, dass Sie die Zeichenfolge so formatieren, da sie sonst nicht funktioniert

 $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";
Dave Keine
quelle
1
es ist besser zu verwenden PHP_EOLals "\n".
Ja Barry
4
PHP_EOL ist umgebungsspezifisch für Endzeilen. In Windows wird es ausgegeben. \r\nDenken Sie also daran!
Chris