Integrating iCal in PHP

iCal is a file format which allows the sharing of generic calendar information. A lot of sites such as HomeAway and AirBnB generate iCal files so you can synchronise bookings across platforms on which your properties may be advertised.

If one of these platforms is your own website, you may need to read the external files (from HomeAway etc) and enter the information into your database to keep it up to date. Reading and/or writing these files is actually pretty straightforward – you just need to know the correct format.

First of all, let’s take a look at what a basic iCal file looks like:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//UniqueID, Inc.//EN
BEGIN:VEVENT
UID:3093bdc35333dafc24a4e9ffad352f6f
DTSTAMP:20160615T110419Z
DTSTART:20170811
DTEND:20170818
SUMMARY:Booking for John Smith
END:VEVENT
BEGIN:VEVENT
UID:6c5e65585905ee04d06df38aa2245319
DTSTAMP:20160615T110419Z
DTSTART:20170804
DTEND:20170811
SUMMARY:Booking for Joe Bloggs
END:VEVENT
END:VCALENDAR

(A handy guide to the specification of each attribute is here http://www.kanzaki.com/docs/ical/)

Writing

To create this, simply loop through the data you wish to include (i.e. each of the bookings for your property) and build a string to iCal specification. Don’t forget to set the correct headers before you echo out the string; these tell the program reading your file that it is in iCal format.

$ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//[YOUR WEBSITE], Inc.//EN";

$query = mysqli_query("SELECT * FROM booking_dates");
while($row = mysqli_fetch_object($query)){
    $ical .= "
BEGIN:VEVENT
UID:" .md5(uniqid(mt_rand(), true))
DTSTAMP:".gmdate("Ymd")."T".gmdate("His")."Z
DTSTART:".date("Ymd", strtotime($row->start_date))."
DTEND:".date("Ymd", strtotime($row->end_date))."
SUMMARY:Booking for $row->name
END:VEVENT";
}

$ical .= "
END:VCALENDAR";

header("Content-type: text/calendar; charset=utf-8");
header("Content-Disposition: inline; filename=calendar.ics");
echo $ical;

Reading

A very useful function I found (thanks Steffen Behn http://stackoverflow.com/a/13844260) simplifies this immensely.

function icsToArray($paramUrl){
    $icsFile = file_get_contents($paramUrl);

    $icsData = explode("BEGIN:", $icsFile);

    foreach($icsData as $key => $value){
        $icsDatesMeta[$key] = explode("\n", $value);
    }

    foreach($icsDatesMeta as $key => $value){
        foreach($value as $subKey => $subValue){
            if($subValue != ""){
                if($key != 0 && $subKey == 0){
                    $icsDates[$key]["BEGIN"] = trim($subValue);
                }else{
                    $subValueArr = explode(":", $subValue, 2);
                    $icsDates[$key][$subValueArr[0]] = trim($subValueArr[1]);
                }
            }
        }
    }

    return $icsDates;
}

Use the above function as such:

$icspath = "http://path-to-file.ics";
$ics = icsToArray($icspath);
foreach($ics as $a){
    if($a['BEGIN'] == "VEVENT"){
        $start_date = date("Y-m-d", strtotime($a['DTSTART']));
        $end_date = date("Y-m-d", strtotime($a['DTEND']));
        $summary = $a['SUMMARY'];
    }
}

Then you can do with the data as you wish. In the above example I’ve converted the dates to standard “Y-m-d” format and assigned the various data to variables. You would then most likely input this into your database in order to keep your calendar up to date with the source of the ics file.

And that’s it!

This code is free to use at your own discretion. It comes without warranty. Please feel free to feedback any edits.


We'd love to hear from you!

If you think Bronco has the skills to take your business forward then what are you waiting for?

Get in Touch Today!

Discussion

Write a comment...
  • harshal

    Thanks.!

  • Denish

    So Helpful!!!
    Thank you very much

Add a Comment