2009-09-23 11 views
96

Toute recherche Google sur PHP ical ne fait qu'appeler phpicalendar et comment analyser ou lire des fichiers INIQUE. Je veux juste écrire un fichier PHP qui extrait les événements de ma base de données et les écrit au format ical.Comment puis-je utiliser PHP pour publier dynamiquement un fichier ical à lire par Google Agenda?

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

  1. Quel est le format ical exacte , y compris les en-têtes, le format de fichier, pieds de page, etc.? En d'autres termes, qu'est-ce que le fichier doit avoir, exactement, pour être correctement lu par Google Agenda, etc.?
  2. Si je compile ce fichier en utilisant une extension .php, comment puis-je le publier en tant que ical? Dois-je écrire dans un nouveau fichier .ics? Ou Google Agenda, etc., lira-t-il un fichier .php aussi longtemps que le contenu sera au bon format? (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 donner ou pointer vers moi sera grandement appréciée !!!

Répondre

117

Cela devrait être très simple si Google Agenda ne nécessite pas l'extension *.ics (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 que vous devez faire un client pense que vous servez un fichier iCalendar, même si il pourrait y avoir des problèmes en ce qui concerne la mise en cache, l'encodage de texte et ainsi de suite. Mais vous pouvez commencer à expérimenter avec ce code simple.

+1

Merci. Je pense que ces en-têtes sont ce qui me manquait. Je suppose qu'il y a quelques étapes finales dans la préparation de ce calendrier Google, car lorsque j'essaie d'envoyer ce fichier à Google Agenda via une URL, il est écrit "Importer un calendrier depuis l'url ..." mais reste bloqué pour toujours. Peut-être que c'est une question différente à poster? – rhodesjason

+0

Avez-vous essayé d'accéder au script depuis votre navigateur? Est-ce qu'il vous invite à télécharger "caneldar.ics"? Pouvez-vous importer le fichier dans iCal ou Outlook par exemple? –

+0

Oui, cela fonctionne bien, et Entourage le charge bien aussi. J'ai juste besoin de la possibilité de créer un fichier que Google Calendar (GC) pingera encore et encore pour actualiser, afin qu'il reste à jour avec un calendrier d'événements dans ma base de données. À l'heure actuelle, GC ne l'acceptera pas. – rhodesjason

2
  1. Format ical exact: http://www.ietf.org/rfc/rfc2445.txt
  2. Selon les spécifications, il doit .ics

Edit: en fait je ne suis pas sûr - ligne 6186 donne un exemple en nommant ics format, mais il indique également que vous pouvez utiliser les paramètres 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 

type MIME est configuré sur le serveur.

+0

J'ai essayé de lire que spec plusieurs fois, mais je ne peux pas faire des têtes ou queues aussi loin que ce que le fichier ical ressemblera. Pouvez-vous au moins me diriger vers quelques lignes où il commence réellement à parler de ce que le fichier .ics devrait contenir aussi loin que l'en-tête, où placer le type MIME, etc? – rhodesjason

+1

Bien sûr, voir ci-dessus. – lod3n

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.

également sur my site, je

  1. Certaines listes de ressources utiles (voir en bas la barre latérale à droite) sur
    • ical Spec RFC 5545
    • Ressources ical Test
  2. Some notes enregistré sur mon voyage de travail avec .ics au cours des dernières années. En particulier, vous pouvez trouver ce repeating events 'cheatsheet' utile.

.ics zones qui nécessitent une manipulation minutieuse:

  • 'toute la journée' événements
  • types de dates (fuseau horaire, UTC ou locale 'flottante') - nb de comprendre la distinction
  • interopérabilité des règles de récurrence
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"; 
+1

il est préférable d'utiliser' PHP_EOL' au lieu de '" \ n "'. –

+3

PHP_EOL est spécifique à l'environnement pour les lignes de fin, donc dans windows il va sortir '\ r \ n' alors gardez ça à l'esprit! – Chris

15

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

J'avais des problèmes de validation utilisant à la fois \ n et PHP_EOL quand je l'ICS validateur à http://severinghaus.org/projects/icv/

J'ai appris que je devais utiliser \ r \ n afin de l'obtenir pour valider correctement, donc ce fut 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; 

qui a arrêté mes erreurs d'analyse et m Ade mes fichiers ICS valident correctement.

+0

L'information d'en-tête est la partie importante FYI à 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 le font. Mais la chose la plus importante est la partie en-tête. Nous avons essayé pendant un certain temps sans cela et avions beaucoup de problèmes. – jfreak53

+1

A quoi sert escapeString? J'ai supposé qu'il devrait échapper à une chose ou deux, mais vous semblez utiliser 'htmlspecialchars' pour cela. – Luc

+0

Une solution rapide: date ('Ymd \ THis \ Z', $ timestamp). Devrait être un H au lieu de g. –

4

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

Voici un exemple d'utilisation de documents:

// 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(); 
Questions connexes