Parsing tags with Zend Feed

Consuming a feed with Zend Feed is quite simple if you don’t want to do something fancy. It could look something like this:

$cur_headlines = Zend_Feed::import("http://localhost/dailydev/dzone_new_links.xml");
foreach($cur_headlines as $item){
  $arr = array(
    "title" => $item->title(), 
    "link" => $item->link(), 
    "description" => $item->description()
  );
}

Easy enough, the array above could be inserted in a database for example. But what if we want to save tag information? An item in the Dzone feed we use in this example could look like this:

.
.
.
<title>Good Unix Tutorials</title>
<link>http://feeds.dzone.com/~r/dzone/upcoming/~3/188060046/good_unix_tutorials.html</link>
<description>I have compiled a list of the best unix tutorials. If you know any good one you can add them to the list.</description>
<category>books</category>
<category>how-to</category>
<category>tools</category>
<category>unix-linux</category>
.
.
.

Zend Feed makes use of the DOM functions in PHP5, calling $item->category() above will not generate the proper results, we will get an array with DOMElements back instead of an array of strings, the same goes for $item->category. However, using getDOM() and getElementsByTagName() will give us a DOMNodeList which we can loop through:

function getTags(&$item){
	$tag_obj = Common::loadModel('tag');
	$item_cat = is_array($item->category()) ? $item->getDOM()->getElementsByTagName('category') : $item->category();
	$tags = ",";
	if(is_object($item_cat)){
		foreach($item_cat as $cat){
			$tags .= "{$cat->nodeValue},";
			$tag_obj->insertTag($cat->nodeValue);
		}
	}else if(!empty($item_cat)){
		$tags .= "$item_cat,";
		$tag_obj->insertTag($item_cat);
	}
	
	return $tags;
}

This example uses functionality covered in the series on writing a cms/community with the Zend Framework and Smarty, so I won’t explain it.

Let’s check out our tag model:

class Tag extends ExtModel{
	protected $_name        = 'tags';
	protected $_primary 	= 'id';
	
	function insertTag($value){
		$row = $this->createRow();
		$row->value = $value;
		$row->popularity = 1;
		
		try{
			$new_id = $row->save();
		}catch(Zend_Db_Statement_Exception $e){}
		
		if(empty($new_id)){
			$old_data = $this->fetchRow("value = '$value'");
			$old_data->popularity += 1;
			$old_data->save(); 
		}
	}
}

The above might be a little confusing without the SQL:

CREATE TABLE `tags` (
  `id` bigint(12) NOT NULL auto_increment,
  `value` varchar(250) character set utf8 NOT NULL,
  `popularity` bigint(12) NOT NULL default '1',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `value` (`value`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

Now the try catch statement makes more sense, as you can see we have a unique key on value which contains the tag itself. This makes the save function fail which generates an exception that we have to catch - if the tag is already in the database. If we haven’t got a new id as the result we know that the insert failed. We will update the old info instead.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • blogmarks
  • Reddit
  • Simpy
  • StumbleUpon
  • Technorati
  • DZone
  • Ma.gnolia

Related Posts

Tags: , , ,

Leave a Reply