Consuming Google Calendars with the Zend Framework

April 25, 2006

Tutorials, Zend Framework

A couple of weeks ago, Google jumped into the online calendar space by launching Google Calendar (um, beta). The application is chock-full of Ajaxy goodness and plenty of features, but I’m here to talk about what you can do with your calendar data behind the scenes. Using some handy tools from the Swiss Army Knife that is the Zend Framework, I’ll show you how to pull data from your Google Calendar into your site. Just for kicks, I’ll also throw in a caching layer to keep things fast and reduce the network traffic between your server and Google.

Our Tools

Since we don’t want to request the calendar feed from Google every time we run our script, we can use the Zend_Cache module to store the file locally, and only update it at a given interval. Zend_Cache is still in incubation, but in my testing I found it plenty stable to handle this task. Zend_Cache is developed by the author of PEAR’s Cache_Lite package.

Lucky for us, Google Calendar exports data in Atom format. That means we can use the Zend_Feed module to parse our cached XML file into a PHP object. No fussy XML wrangling today, so sorry.

The Code

For this example, I’ll assume you have a Google Calendar with some data in it, and that you know your feed’s URL. To find the URL, log into your calendar and click "Settings." Then click the "Calendars" tab followed by the name of the calendar you want to import. You should see two XML icons on the Calendar Details page. You can use either one, but the public feed will must be shared, and will contain different information based on what you decide to make public.

You can download the code example here.

Let’s take a look at the code. First, I’ll include the necessary Framework modules, define a helper function for date formatting, set my calendar URL, and set my cache options:

<?php 

require_once 'Zend/Feed.php';
require_once 'Zend/Cache.php';

function format_atom_datetime($atom_date,$format='m/d/Y h:i:s a'){
    $pattern = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/";
    preg_match($pattern,$atom_date,$match);
    return date($format,gmmktime($match[4],$match[5],$match[6],$match[2],$match[3],$match[1]));
}

//your calendar feed URL
$feed_url = 'http://www.google.com/calendar/feeds/...';

//set cache options
$frontendOptions = array(
    'lifeTime' => 3600 // cache lifetime of 1 hour
);
$backendOptions = array(
    'cacheDir' => '/tmp/'
);

Next, I’ll check the cache to see if we have our file saved. If there isn’t one, or if it’s stale, we fetch it from Google and save it.

//grab the file from cache, or fetch it from Google and cache it
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
if (!($xml = $cache->get('GoogleCalendar'))) {
if (!($xml = @file_get_contents($feed_url))){
echo "Oops. Can't grab this Calendar from Google. Check your feed URL and calendar permissions";
exit;
}
$cache->save($xml);
}

Note, if you want to save several different calendars, make sure you use a different cache identifier for each. I chose "GoogleCalendar" for my single feed.

Now that we have the XML feed stored in the variable $xml, we can create a Zend_Feed object:

//read the xml into a Zend_Feed object
try {
$cal = Zend_Feed::importString($xml);
} catch (Zend_Feed_Exception $e) {
echo "Oops. Can't import this feed: {$e->getMessage()}\n";
exit;
}

Now it’s just a matter of displaying our calendar information on the page. Examine the Zend_Feed manual and the raw feed itself to see what fields you can pull and display. In my example I’m using a minimalistic output. You’ll notice a little weirdness from Google–for example all of my events seem to be located in "America/Los_Angeles" despite the actual location I set.

//display each event
echo "<dl>\n";
foreach ($cal as $item) {
echo "<dt>".$item->title()."</dt>\n";
echo "<dd>Posted By ".$item->author->name()."</dd>\n";
echo "<dd>".$item->content()."</dd>\n";
echo "<dd>Published: ".format_atom_datetime($item->published())."</dd>\n";
echo "<dd>Last Updated: ".format_atom_datetime($item->updated())."</dd>\n";
}
echo "</dl>\n";

That’s all there is to it! Post a comment and let us know the cool stuff you are doing with Google Calendars on your own site.

, ,

6 Responses to “Consuming Google Calendars with the Zend Framework”

  1. _____anonymous_____ Says:

    Why doesn’t this work for me? Is the code out dated?

  2. vishap Says:

    this is a very interesting article. wow. And its very useful for me now, because I plan to us this calender.

    BIG thanks

    Markus

    (even if google just broke down Oo )

  3. _____anonymous_____ Says:

    "you might want to consider using Zend_Http_Client in your example instead of file_get_contents(). That way you can introduce another easy to use ZF component and have an example that will work for people on hosts with allow_url_fopen disabled."

    Indeed, considering allow_url_fopen is generally considered a serious security problem in php5. The cURL lib or HTTP Client lib would have been much better ideas.

  4. _____anonymous_____ Says:

    Okay, you are either a good writer or this is very simple, no?

    I think that I could pull this off, if I had a Google calendar or any reason to display it…..

  5. admin Says:

    I had this weekend free till you published this. Now I’ve got to spend the weekend playing with GCal! :)

    Great article, thanks.

    =C=

  6. gneustaetter Says:

    you might want to consider using Zend_Http_Client in your example instead of file_get_contents(). That way you can introduce another easy to use ZF component and have an example that will work for people on hosts with allow_url_fopen disabled.