I built a site in PHP 5 and MySQL with a table that keeps track of scheduled photo shoots. I want to push out a feed of those scheduled "events" into an ical file.
I originally asked this question and got a good answer from S. Gehrig. I got a sample ical file working, and updating regularly in Google Calendar whenever I manually adjusted the file in Dreamweaver. However, now that I've added dynamic PHP pulling from the database, it won't work.
Here's the PHP:
<?php
require_once('../../_includes/initialize.php');
$ical = " BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN ";
$slots = Slot::find_all();
foreach($slots as $slot) {
$job = Job::find_by_id($slot->job_id);
$start_stamp = strtotime($slot->start);
$end_stamp = strtotime($slot->endtime);
$dtstart = gmdate('Ymd', $start_stamp).'T'. gmdate('His', $start_stamp) . "Z"; // converts to UTC time
$dtend = gmdate('Ymd', $end_stamp).'T'. gmdate('His', $end_stamp) . "Z"; // converts to UTC time
$summary = $job->title;
$ical .= " BEGIN:VEVENT
UID:" . $slot->id . "@homewoodphoto.jhu.edu
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:" . $dtstart . "
DTEND:" . $dtend . "
SUMMARY:" . $summary . "
END:VEVENT ";
}
$ical .= " END:VCALENDAR";
//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
echo $ical;
exit;
?>
The output of this file is exactly the same as the manual, hard-coded version that I have working, as far as I can tell. Can anyone see why this isn't working????
PS Here is the code of the file that IS working -- I just posted it on my server and subscribed via URL in Google Calendar. When I hardcoded in the 2nd event, it showed up shortly in Google Calendar on its own.
<?php
$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:20090925T170000Z
DTEND:20090928T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)); . "@yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:20090929T170000Z
DTEND:20090930T035959Z
SUMMARY:Camping Trip
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;
?>
HELP!
A commenter suggested I test by removing the headers and echoing the $ical var. Here are the results of that test, with line breaks added for your convenience:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:20090929T212141Z
DTSTART:20091001T230000Z
DTEND:20091001T230000Z
SUMMARY:little title
END:VEVENT
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:20090929T212141Z
DTSTART:20090926T230000Z
DTEND:20090927T010000Z
SUMMARY:A big photo shoot
END:VEVENT
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:20090929T212141Z
DTSTART:20091003T230000Z
DTEND:20091004T010000Z
SUMMARY:A big photo shoot
END:VEVENT
END:VCALENDAR
Thanks!
For people who stumble on this via a search it might not be clear how the problem was solved. Basically, the iCal specification requires \r\n for line breaks and no whitespace at the beginning of lines, which is what was fixed in the script to make it work.
When working with ical I've found the following 3 validators to be the most helpful:
most basic (misses whitespace): http://severinghaus.org/projects/icv/?url=
this one will catch whitespace: http://icalvalid.cloudapp.net/Default.aspx
this one will catch things the others didn't but is almost too strict: http://arnout.engelen.eu/icalendar-validator
Also, the best documentation on all the different elements: http://www.kanzaki.com/docs/ical/
Initial guess would be your array is not populated correctly. So to test it I would start with removing
//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
and changing $slots = Slot::find_all(); to
$slots = Slot::find_all();
print_r($slots);
to make sure your array of object is being set.
Then run it from either command line or browser to make sure it outputs as expected before submitting to google.
Try the following code to avoid white space:
<?php
require_once('../../_includes/initialize.php');
$ical = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//hacksw/handcal//NONSGML v1.0//EN";
$slots = Slot::find_all();
foreach($slots as $slot) {
$job = Job::find_by_id($slot->job_id);
$start_stamp = strtotime($slot->start);
$end_stamp = strtotime($slot->endtime);
$dtstart = gmdate('Ymd', $start_stamp).'T'. gmdate('His', $start_stamp) . "Z"; // converts to UTC time
$dtend = gmdate('Ymd', $end_stamp).'T'. gmdate('His', $end_stamp) . "Z"; // converts to UTC time
$summary = $job->title;
$ical .= "BEGIN:VEVENT\n";
$ical .= "UID:" . $slot->id . "@homewoodphoto.jhu.edu\n";
$ical .= "DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z\n";
$ical .= "DTSTART:" . $dtstart . "\n";
$ical .= "DTEND:" . $dtend . "\n";
$ical .= "SUMMARY:" . $summary . "\n";
$ical .= "END:VEVENT\n";
}
$ical .= "\nEND:VCALENDAR";
//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=homewoodphoto_master.ics');
echo $ical;
exit;
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With