Come posso utilizzare PHP per pubblicare dinamicamente un file ical che deve essere letto da Google Calendar?


106

Qualsiasi ricerca Google su PHP ical fa apparire solo phpicalendar e come analizzare o leggere i file IN ical. Voglio solo scrivere un file PHP che prenda gli eventi dal mio database e li scriva in formato ical.

Il mio problema è che non riesco a trovare da nessuna parte che risponda a due domande:

  1. Qual è il formato ical esatto , inclusi intestazioni, formato file, piè di pagina, ecc.? In altre parole, cosa deve avere esattamente il file per poter essere letto correttamente da Google Calendar, ecc.?
  2. Se creo questo file utilizzando un'estensione .php, come lo pubblico come ical? Devo scrivere su un nuovo file .ics? O Google Calendar ecc. Leggerà un file .php come ical purché i contenuti siano nel formato corretto? (In modo molto simile a un file style.css.php verrà letto come file CSS se i contenuti sono effettivamente CSS, ecc.)

Qualsiasi aiuto che tutti voi potete dare o indicarmi sarà molto apprezzato !!!

Risposte:


128

Questo dovrebbe essere molto semplice se Google Calendar non richiede l' *.icsestensione (che richiederà una riscrittura dell'URL nel server).

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

Questo è essenzialmente tutto ciò di cui hai bisogno per far credere a un cliente che stai servendo un file iCalendar, anche se potrebbero esserci alcuni problemi relativi alla cache, alla codifica del testo e così via. Ma puoi iniziare a sperimentare con questo semplice codice.


1
Grazie. Penso che quelle intestazioni siano ciò che mi mancava. Presumo che ci siano alcuni passaggi finali per rendere pronto questo Google Calendar, poiché quando provo a inviare questo file a Google Calendar tramite URL, viene visualizzato il messaggio "Importing calendar from url ...", ma si blocca per sempre. Forse è una domanda diversa da pubblicare?
rhodesjason,

3
Esattamente. Ho aggiornato l'esempio sopra e ho anche aggiunto una proprietà DTSTAMP che indicherà a un client quando gli eventi sono stati aggiornati.
Stefan Gehrig

1
Va bene Gehrig, sei un genio. Ha funzionato. Grazie. (Per quanto ne so, anche Google Calendar si aggiorna quasi immediatamente.)
rhodesjason

3
Se non erro. I programmi utilizzano l'UID per vedere se un evento viene eliminato. Se uno script php genera sempre un altro UID (-> mt_rand), i programmi penseranno sempre che l'intero contenuto sia cambiato. Tutto è svanito e tutto è nuovo. Personalmente mi atterrei allo stesso UID se l'evento è lo stesso nel database e userei solo il recordID (e alcune informazioni sull'host). Il DTSTAMP è lì per mostrare che qualcosa è cambiato. Dovrebbe bastare.
Seirddriezel

3
Google Calendar RICHIEDE l'estensione * .ics. Se stai usando .htaccess, puoi farlo aggiungendo RewriteEngine on RewriteRule ^calendar.ics$ my_php_script.php [QSA]
Fanky

19

Una nota di esperienza personale in aggiunta alla risposta di Stefan Gehrig e di Dave None (e la risposta di mmmshuddup):

Avevo problemi di convalida utilizzando sia \ ne PHP_EOL quando ho utilizzato il validatore ICS su http://severinghaus.org/projects/icv/

Ho imparato che dovevo usare \ r \ n per farlo convalidare correttamente, quindi questa era la mia soluzione:

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;

Ciò ha bloccato i miei errori di analisi e ha reso i miei file ICS convalidati correttamente.


Le informazioni di intestazione sono la parte importante FYI per chiunque guardi in futuro. Per la maggior parte, la maggior parte delle app e dei programmi non si preoccupano delle interruzioni di NewLine. Solo i validatori lo fanno sembra. Ma la cosa più importante è la parte dell'intestazione. Abbiamo provato per un po 'senza di essa e abbiamo avuto molti problemi.
jfreak53

1
A cosa serve escapeString? Ho pensato che dovrebbe sfuggire a una o due cose, ma sembra che tu lo usi htmlspecialcharsinvece.
Luc

1
Una soluzione rapida: data ('Ymd \ THis \ Z', $ timestamp). Dovrebbe essere una H invece di g.
Pedro Góes

6

C'è un eccellente pacchetto eluceo / ical che ti permette di creare facilmente file ics.

Ecco un esempio di utilizzo da documenti:

// 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/ ha una versione leggermente più leggibile delle specifiche precedenti. Aiuta come punto di partenza: molte cose sono sempre le stesse.

Anche sul mio sito ho

  1. Alcuni elenchi di risorse utili (vedi barra laterale in basso a destra) su
    • Specifiche tecniche RFC 5545
    • Risorse per test ical
  2. Alcune note registrati durante il mio viaggio di lavoro .icsnegli ultimi anni. In particolare, potresti trovare utile questo "cheatsheet" di eventi ripetuti .

.ics aree che richiedono un'attenta gestione:

  • eventi "tutto il giorno"
  • tipi di date (fuso orario, UTC o "mobile" locale) - nb per capire la distinzione
  • interoperabilità delle regole di ricorrenza

2
  1. Formato ical esatto: http://www.ietf.org/rfc/rfc2445.txt
  2. Secondo le specifiche, deve finire in .ics

Modifica: in realtà non ne sono sicuro: la riga 6186 fornisce un esempio in formato di denominazione .ics, ma afferma anche che è possibile utilizzare parametri URL. Non penso sia importante, a patto che il tipo MIME sia corretto.

Modifica: esempio da 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

Il tipo MIME è configurato sul server.


1
Ho provato a leggere quella specifica molte volte ma non riesco a farne testa o croce per quanto riguarda l'aspetto del file ical. Puoi almeno indicarmi alcune righe in cui inizia a parlare effettivamente di ciò che il file .ics dovrebbe contenere per quanto riguarda l'intestazione, dove mettere il tipo MIME, ecc.?
rhodesjason,

2

Assicurati di formattare la stringa in questo modo o non funzionerà

 $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
è meglio usare PHP_EOLinvece di "\n".
Sì Barry

4
PHP_EOL è specifico dell'ambiente per le righe finali, quindi in Windows verrà generato, \r\nquindi tienilo a mente!
Chris
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.