Search code examples
phpcodeignitersimplepie

Using multiple feeds in simplepie with codeigniter


I'm trying to get simplepie to loop through a few rss feeds using codeigniter but I can only get it to display the feed items from the last feed in the array.

I think it is to do with the foreach loop in the _get_feed function but everything I've tried has failed to fix it.

In my controller I have this

class Main extends Controller{

function index()
{
    $this->load->library( 'Simplepie' );

    $feed_urls = array
    (
        'http://feeds.feedburner.com/SputnikmusicNews',
        'http://feeds2.feedburner.com/nmecom/rss/newsxml',
    );

    foreach ($feed_urls as $feed_url)
    {
        $data = $this->_get_feed($feed_url);
    }

    $data['main_content'] = 'main_view';
    $this->load->view('includes/template', $data);
}

function _get_feed($url)
{
    $feed = new SimplePie();
    $feed->set_feed_url($url);
    $feed->init();

    $count = 0;

    foreach($feed->get_items() as $item)
    {
        $data['feed'][$count]['title'] = $item->get_title();
        $data['feed'][$count]['permalink'] = $item->get_permalink();
        $count ++;
    }       
    return $data;
}

}

Then in my view I have this

<?php foreach($feed as $item) : ?>
    <br />
    <a href="<?php echo $item['permalink']; ?>"><?php echo $item['title']; ?  ></a>
<?php endforeach; ?>

I'm aware that it's possible to give simplepie an array of feeds to parse with the set_feed_url function but I don't want to do this as it mixes all the feed items together.

I'd also like to know if placing the _get_feed function in the controller is ok in terms of best practises or would it be better off in a model as it is fetching data?


Solution

  • As far as I am aware your $data array was not global and therefore only had scope within the index function.

    As far as conventions go, I only use models for database connections, but I don't think there are any hard and fast rules.

    class Main extends Controller{
    
    function index()
    {
        $this->load->library( 'Simplepie' );
    
        $feed_urls = array
        (
            'http://feeds.feedburner.com/SputnikmusicNews',
            'http://feeds2.feedburner.com/nmecom/rss/newsxml',
        );
    
        foreach ($feed_urls as $feed_url)
        {
            $data['feed'][] = $this->_get_feed($feed_url);
        }
    
        $data['main_content'] = 'main_view';
        $this->load->view('includes/template', $data);
    }
    
    function _get_feed($url)
    {
        $feed = new SimplePie();
        $feed->set_feed_url($url);
        $feed->init();
    
        $count = 0;
    
        foreach($feed->get_items() as $item)
        {
            $return[$count]['title'] = $item->get_title();
            $return[$count]['permalink'] = $item->get_permalink();
            $count ++;
        }       
        return $return;
    }
    
    }
    

    This will give you:

    $data['feed'][0] = details from 1st url
    $data['feed'][1] = details from 2nd url
    

    So to access the title from the 1st article in the 1st feed:

    $data['feed'][0][0]['title']
    //or within the view
    $feed[0][0]['title'];
    

    If you wanted to merge the URL's together you would do something like:

    class Main extends Controller{
    
    function index()
    {
        $this->load->library( 'Simplepie' );
    
        $feed_urls = array
        (
            'http://feeds.feedburner.com/SputnikmusicNews',
            'http://feeds2.feedburner.com/nmecom/rss/newsxml',
        );
    
        foreach ($feed_urls as $feed_url)
        {
            $feed_info[] = $this->_get_feed($feed_url);
            $data['feed'][] = $this->_get_feed($feed_url);
        }
    
        foreach ($feed_info as $feed)
        {
            foreach($feed as $feed_item)
            {
                $data['feed'][] = array( 'title' => $feed_item->get_title(), 'permalink' => $feed_item->get_permalink() );
            }
        }
    
        $data['main_content'] = 'main_view';
        $this->load->view('includes/template', $data);
    }
    
    function _get_feed($url)
    {
        $feed = new SimplePie();
        $feed->set_feed_url($url);
        $feed->init();
    
        return $feed;
    }
    
    }