Comment puis-je utiliser PHP pour publier dynamiquement un fichier ical à lire par Google Agenda?

107

Toute recherche Google sur PHP ical affiche simplement phpicalendar et comment analyser ou lire des fichiers IN ical. Je veux juste écrire un fichier PHP qui extrait les événements de ma base de données et les écrit au format ical.

Mon problème est que je ne trouve nulle part qui réponde à deux questions:

  1. Quel est le format ical exact , y compris les en-têtes, le format de fichier, les pieds de page, etc.? En d'autres termes, que doit avoir exactement le fichier pour être correctement lu par Google Agenda, etc.?
  2. Si je construis ce fichier en utilisant une extension .php, comment le publier comme ical? Dois-je écrire dans un nouveau fichier .ics? Ou Google Agenda, etc. lira-t-il un fichier .php aussi longtemps que le contenu est dans le format correct? (Tout comme un fichier style.css.php sera lu comme un fichier CSS si le contenu est en fait CSS, etc.)

Toute aide que vous pouvez tous me donner ou me pointer sera grandement appréciée !!!

Rhodesjason
la source

Réponses:

129

Cela devrait être très simple si Google Agenda ne nécessite pas l' *.icsextension (ce qui nécessitera une réécriture d'URL sur le serveur).

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

C'est essentiellement tout ce dont vous avez besoin pour faire croire à un client que vous servez un fichier iCalendar, même s'il peut y avoir des problèmes concernant la mise en cache, l'encodage de texte, etc. Mais vous pouvez commencer à expérimenter avec ce code simple.

Stefan Gehrig
la source
1
Merci. Je pense que ces en-têtes sont ce qui me manquait. Je suppose qu'il y a quelques étapes finales pour préparer ce calendrier Google, car lorsque j'essaie de transmettre ce fichier à Google Agenda via l'URL, il est dit "Importation du calendrier à partir de l'URL ...", mais cela reste pour toujours. C'est peut-être une question différente à publier?
rhodesjason le
3
Exactement. J'ai mis à jour l'exemple ci-dessus - et j'ai également ajouté une propriété DTSTAMP qui indiquera au client quand les événements ont été mis à jour.
Stefan Gehrig
1
Ok Gehrig, tu es un génie. Ça a marché. Merci. (Pour autant que je
sache,
3
Si je ne me trompe pas. Les programmes utilisent l'UID pour voir si un événement est supprimé. Si un script php génère toujours un autre UID (-> mt_rand), les programmes penseront toujours que tout le contenu a changé. Tout a disparu et tout est nouveau. Personnellement, je m'en tiendrai au même UID si l'événement est le même dans la base de données et utilise simplement le recordID (et certaines informations sur l'hôte). Le DTSTAMP est là pour montrer que quelque chose a changé. Cela devrait suffire.
Seirddriezel
3
L'agenda Google nécessite l'extension * .ics. Si vous utilisez .htaccess, vous pouvez le faire en ajoutant RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky
19

Une note d'expérience personnelle en plus de la réponse de Stefan Gehrig et de la réponse de Dave None (et la réponse de mmmshuddup):

J'avais des problèmes de validation en utilisant à la fois \ n et PHP_EOL lorsque j'ai utilisé le validateur ICS à http://severinghaus.org/projects/icv/

J'ai appris que je devais utiliser \ r \ n pour le faire valider correctement, c'était donc ma solution:

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;

Cela a arrêté mes erreurs d'analyse et a validé correctement mes fichiers ICS.

Kane Ford
la source
Les informations d'en-tête sont la partie importante FYI pour quiconque regarde dans le futur. Pour la plupart, la plupart des applications et des programmes ne s'inquiètent pas des pauses NewLine. Seuls les validateurs semblent le faire. Mais le plus important est la partie en-tête. Nous avons essayé pendant un certain temps sans cela et avons eu de nombreux problèmes.
jfreak53
1
À quoi sert escapeString? J'ai supposé que cela devrait échapper à une chose ou deux, mais vous semblez l'utiliser htmlspecialcharsà la place.
Luc
1
Une solution rapide: date ('Ymd \ THis \ Z', $ horodatage). Devrait être un H au lieu de g.
Pedro Góes
6

Il existe un excellent package eluceo / ical qui vous permet de créer facilement des fichiers ics.

Voici un exemple d'utilisation de la documentation:

// 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
la source
4

http://www.kanzaki.com/docs/ical/ a une version légèrement plus lisible de l'ancienne spécification. Cela aide comme point de départ - beaucoup de choses sont toujours les mêmes.

Aussi sur mon site , j'ai

  1. Quelques listes de ressources utiles (voir la barre latérale en bas à droite) sur
    • ical Spec RFC 5545
    • Ressources de test ical
  2. Quelques notes enregistrées sur mon parcours de travail avec .icsces dernières années. En particulier, vous trouverez peut- être utile cette «feuille de triche» pour les événements répétitifs .

.ics zones nécessitant une manipulation soigneuse:

  • événements 'toute la journée'
  • types de dates (fuseau horaire, UTC ou local 'flottant') - nb pour comprendre la distinction
  • interopérabilité des règles de récurrence
Anmari
la source
2
  1. Format exact ical: http://www.ietf.org/rfc/rfc2445.txt
  2. Selon la spécification, il doit se terminer par .ics

Edit: en fait, je ne suis pas sûr - la ligne 6186 donne un exemple au format de dénomination .ics, mais elle indique également que vous pouvez utiliser des paramètres d'URL. Je ne pense pas que ce soit important, tant que le type MIME est correct.

Edit: Exemple de 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

Le type MIME est configuré sur le serveur.

lod3n
la source
1
J'ai essayé de lire cette spécification plusieurs fois, mais je ne peux pas en faire la tête ou la queue en ce qui concerne l'apparence du fichier ical. Pouvez-vous au moins m'indiquer certaines lignes où il commence à parler de ce que le fichier .ics devrait contenir en ce qui concerne l'en-tête, où mettre le type MIME, etc.?
rhodesjason
2

Assurez-vous de formater la chaîne comme ceci ou cela ne fonctionnera pas

 $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 Aucun
la source
1
il vaut mieux utiliser PHP_EOLau lieu de "\n".
Oui Barry
4
PHP_EOL est spécifique à l'environnement pour les lignes de fin, donc dans Windows, il sortira \r\ndonc gardez cela à l'esprit!
Chris