Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic ical created from database not working

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!

like image 361
rhodesjason Avatar asked Sep 29 '09 21:09

rhodesjason


2 Answers

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/

like image 67
Jaymon Avatar answered Sep 30 '22 12:09

Jaymon


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;

?>
like image 23
Mohammad Avatar answered Sep 30 '22 12:09

Mohammad