Categories


Loading feed
Loading feed
Loading feed

Zend Framework, JSON, and Del.icio.us


Del.icio.us is a social linking site to store web links. Some one afternoon while messing around Zend Framework I had the idea that it might be nice to add my Del.icio.us links to my homepage. This sounds easy enough as Del.icio.us makes available an RSS feed for this purpose. However, there is one problem; Zend_Feed does not seem to be able to parse this particular RSS feed. The reason is that Del.icio.us makes use of some extended namespaces for its RSS feed. Normally this would not be a problem as we could simply write a new class to extend Zend_Feed to read this file. However, this is a quicker and simpler way. Enter JSON.

Del.icio.us not only makes links available via a JSON, but also tags and other information. In addition, the Zend Framework has built in support JSON objects. Sounds like a match made in heaven.

JSON Connection

To begin we need to have a URL to use for the web service on Del.icio.us. Information on Del.icio.us's JSON support can be found at http://del.icio.us/help/json/. One important item to note here is we need the raw JSON object, so we must specify that in our URL. For these examples, our user will be exampleuser. Given this, our URL will look like:

http://del.icio.us/feeds/json/exampleuser?raw

Creating the controller

To create the controller we need to open an HTTP connection to the JSON feed. To do this, we will set up a standard Zend Framework controller using Zend_Http_Client to fetch the feed and Zend_Json to parse the JSON object in to a PHP array. Our controller would look like:

<?php

class linkController extends Zend_Controller_Action
{
    public function indexAction()
    {
        // It is assumed that this registry entry has been setup in your bootstrap index.php
        $view = Zend::registry('view'); 
        $http = new Zend_Http_Client('http://del.icio.us/feeds/json/exampleuser?raw');
        $response = $http->get();
        if ($response->isSuccessful()) 
        {
            $view->delicious = Zend_Json::decode($response->getBody());
        }
        echo $view->render('link.php');
}

    public function noRouteAction()
    {
        $this->_redirect('/');
    }
}

?>

Creating the view

Next all we need to have a working system is to create a view to go with that controller to display the data. Our view would then contain something like:

<h2>My Del.icio.us Links</h2>
<dl> 
<?php
foreach ($this->delicious as $item) 
{
	echo '<dt><a href="' . $item["u"] . '" target="_blank">' . $item["d"] . '</a></dt>';
        echo '<dd>' . $item["n"] . '<br />Tagged as: ';
        foreach ($item["t"] as $key => $tag) 
        {
            if ($key > 0) {
                echo ', ';
            }
            echo $tag;
        }
        echo '</dd>';
}
?>

</dl>

Caching the results

Now that we have a working controller and view, we should probably cache the results. In order to not abuse the Del.icio.us service we do not want to ping them for every request the page gets. Instead we only want to check for updates every X minutes. First, we need to set up where we are going to store this cache. In this example, we are going to use a database as the site already makes use of one. In this example we are creating a table called feeds, and added a blank row for the Del.icio.us data.

CREATE TABLE `feeds` (
  `feed_name` varchar(25) NOT NULL default '',
  `feed_data` text NOT NULL,
  `feed_updated` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`feed_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `feeds` (`feed_name`,`feed_data`,`feed_updated`) VALUES ('delicious','',0);

Once we have out table and row, we can update the controller to check the state of the feed, by querying the database using Zend_DB, before calling the Del.icio.us JSON interface, and update it if out cache is more than 30 minutes old.

<?php

class linkController extends Zend_Controller_Action
{
    public function indexAction()
    {
        // It is assumed that these registry entries have been setup in your bootstrap index.php
        $view = Zend::registry('view'); 
        $db = Zend::registry('db');     
        $select = $db->select();
        $select->from('feeds', '*');
        $select->where("feed_name=?", "delicious");
        $sql = $select->__toString(); 
        $result = $db->fetchRow($sql);
    	
        if ($result["feed_updated"] < time()) 
        { 
            $http = new Zend_Http_Client('http://del.icio.us/feeds/json/exampleuser?raw');
            $response = $http->get();
            if ($response->isSuccessful())
            {
                $set = array (
                    'feed_data' => base64_encode($response->getBody()),
                    'feed_updated' => time() + 1800,
                );
                $where = $db->quoteInto('feed_name = ?', 'delicious');
                $rows_affected = $db->update('feeds', $set, $where);				
                $view->delicious = Zend_Json::decode($response->getBody());
            }			
        } else {
            $view->delicious = Zend_Json::decode(base64_decode($result["feed_data"]));
        }		 	
        echo $view->render('link.php');
    }

    public function noRouteAction()
    {
        $this->_redirect('/');
    }
}

?>

Wrap Up

There you have it a working server side JSON connection to Del.icio.us. I hope you find this example useful. Here is an example of this in production on my personal home page at http://www.jasonwhittenburg.com/link/

Download Example Code for Zend Framework, JSON, and Del.icio.us

Comments


Monday, September 18, 2006
ZEND CACHE
4:34AM PDT · gneustaetter
Tuesday, September 19, 2006
EXCELLENT STUFF!
12:20AM PDT · rushy2uk
BASE 64 ENCODING?
2:12AM PDT · lkagan2000
Wednesday, September 20, 2006
ZEND_CACHE
3:26AM PDT · jwhittenburg
Saturday, December 2, 2006
JUST TWO SMALL NOTES...
1:42AM PST · sevencorvina
Thursday, December 7, 2006
ZEND_HTTP_CLIENT API CHANGE
6:43AM PST · shahar