Simple CakePHP RSS Helper

For a project I’m currently building with CakePHP I needed to integrate some contents of an RSS feed into a part of the layout. Using a simple custom-made helper, I got the job done pretty quickly. Here is how it works.

For those of you not yet familiar with setting up helpers in CakePHP, take a look at the Cookbook’s article on it.

Now here is my RSS helper in whole:

<?php
class RssHelper extends AppHelper {
 
    var $helpers = array('Xml');
 
    function parseRss($limit = 3) {
        // Parse the RSS feed
        $xml = new Xml('http://example.com/rss-feed.xml');
        $data = $xml->toArray();
 
        // Filter any non-news items
        $items = $this->filterItems($data);
 
        // Prepare output array
        $output = array();
 
        // Loop over the results
        for($i = 0;$i < $limit;$i++) {
            $output[] = $items[$i];
        }
 
        // Return the filtered and limited items list
        return $output;
    }
 
    function filterItems($data) {
        // Prepare results array
        $results = array();
 
        // Filter any non-news items
        foreach($data['Rss']['Channel']['Item'] as $item) {
            if($item['category'] == 'News') {
                $results[] = $item;
            }
        }
 
        return $results;
    }
 
}
?>

At first, because we’re dealing with an XML source, we’re going to use the Xml helper that comes with CakePHP.  This will help us greatly, because it can quickly and efficiently parse the XML from the RSS feed.

In the helper I have created two functions: parseRss and filterItems. The parseRss function is used to subtract the actual data that we’re interested in from the XML source. The first step is to define a new Xml object to the Xml helper. You can use the RSS url as a parameter.

Next, we use the XmlHelper’s handy toArray function in order to give us one large data array with the same structure as the XML of the RSS feed.

Now, the filterItems function comes to use. In my case, I had a mixed RSS feed, but I was only interested in the News category. The function loops over all the children of the <Rss><Channel><Item> node and checks wheter it’s category is actually ‘News’. If it is, it’s added to our $results array. Once all the items have been parsed, the $results array is being returned. In our case, since we called the function from the parseRss function, the execution will continue there.

Now that we have a filtered list, we also want to limit the list to an amount that will fit nicely into our layout. In order to achieve this, a new array called $output is created. It will contain as much items as the set $limit -which defaults to 3- allows.

Finally, a for-loop keeps fetching items until the $limit is reached. It will then stop and return the $output array. This array can be used in our layout to display the news items from the RSS feed.

That covers the helper, all nice and simple. In order to be able to call it, don’t forget to add it to the $helpers list of your controller. In my case, I call it from my layout, which requires me to add it to the AppController. So I have this in my app/app_controller.php file:

<?php
class AppController extends Controller {
 
    var $helpers = array('Rss');
 
}
?>

To call it from the view should look something like this:

<dl id="news" class="box">
<?php
$news = $this->Rss->parseRss(5);
foreach($news as $item):
?>
    <dt><?php echo date('d-m-Y H:i', strtotime($item['pubDate'])); ?></dt>;
    <dd><?php echo $this->Html->link($item['title'], $item['origLink'], array('target' => '_blank')); ?></dd>
<?php endforeach; ?>
</dl>

This would produce a definition list with the news items. From there, you can extract any data you like. In my case, I extract the pubDate, title and origLink elements and pass them to the view.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">