[code]<?php

/*
 * Rss reader/parser
 * @author Ruud Verbij, ruudverbij@gmail.com
 * @version 1.0
 * @usage at the bottom
 */

class rssReader {
    private $url;
    private $source;
    private $titel;
    private $eersteItem;
    private $aantalItems;
    private $extraOptiesArray;

    private $titels;
    private $inhouds;
    private $links;
    private $pubDates;
    private $categorys;
    private $extraOpties;

    /*
     * Constructor
     * @param url = url to rss file
     * @require url != null
     */
    function __construct($url) {
        // setting private vars
        $this->url = $url;
        $this->source = file_get_contents($url);

        // search rss-feed title
        $beginTitel = strpos($this->source,"<title>")+7;
        $eindTitel  = strpos($this->source,"</title>",$beginTitel);
        $this->titel = substr($this->source,$beginTitel,$eindTitel-$beginTitel);

        // finding first item
        $this->eersteItem = strpos($this->source,"<item>",0) + 6; 

        // finding number of items in the rss-file
        $this->aantalItems = substr_count($this->source,"<item>");
    }

    /*
     * @return index of first Item
     */
    function getFirstItem() {
        return $this->eersteItem;
    }

    private function getSource() {
        return $this->source;
    }

    /*
     * Sets extra search options to parse
     * @param $extraSearchOptions -> array with Integer index
     */
    function setExtraSearchOptions($extraSearchOptions) {
        $this->extraOptiesArray = $extraSearchOptions;
    }

    /*
     * Parsing the rss-file
     * @param titel,link,descr,pubDate,category booleans
     * searching for if boolean is set true
     * @require all true values are present in each item in the rss-feed
     */
    function parse($title = false,$link = false,$descr = false,$pubDate = false,$category = false,$extra = false) {
        $beginZoektocht = $this->getFirstItem() - 6;

        // for each item
        for($i = 0; $i < $this->aantalItems; $i++) {
            // localising item
            $beginZoektocht = strpos($this->getSource(),"<item>",$beginZoektocht);
            
            // check what should be called
            if($title)
                $this->titelZoeken($beginZoektocht);
            if($link)
                $this->linkZoeken($beginZoektocht);
            if($descr)
                $this->descrZoeken($beginZoektocht);
            if($pubDate)
                $this->pubDateZoeken($beginZoektocht);
            if($category)
                $this->categoryZoeken($beginZoektocht);
            if($extra)
                $this->extraZoeken($beginZoektocht);

            $beginZoektocht = strpos($this->getSource(),"</item>",$beginZoektocht+1);
        }   
    }

    private function extraZoeken($begin) {
        for($i=0;$i<count($this->extraOptiesArray);$i++) {
            $tekst = $this->extraOptiesArray[$i];
            $beginZoektocht = strpos($this->getSource(),"<".$tekst.">",$begin)+strlen($tekst)+2;
            $eindZoektocht  = strpos($this->getSource(),"</".$tekst.">",$beginZoektocht);
            $this->extraOpties[$tekst][] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        }
    }


    private function categoryZoeken($begin) {
        $beginZoektocht = strpos($this->getSource(),"<category>",$begin) + 10;
        $eindZoektocht  = strpos($this->getSource(),"</category>",$beginZoektocht);
        $this->categorys[] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        return $eindZoektocht;
    }

    private function pubDateZoeken($begin) {
        $beginZoektocht = strpos($this->getSource(),"<pubDate>",$begin) + 9;
        $eindZoektocht  = strpos($this->getSource(),"</pubDate>",$beginZoektocht);
        $this->pubDates[] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        return $eindZoektocht;
    }

    private function descrZoeken($begin) {
        $beginZoektocht = strpos($this->getSource(),"<description>",$begin) + 13;
        $eindZoektocht  = strpos($this->getSource(),"</description>",$beginZoektocht);
        $this->inhouds[] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        return $eindZoektocht;
    }

    private function titelZoeken($begin) {
        $beginZoektocht = strpos($this->getSource(),"<title>",$begin) + 7;
        $eindZoektocht  = strpos($this->getSource(),"</title>",$beginZoektocht);
        $this->titels[] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        return $eindZoektocht;
    }

    private function linkZoeken($begin) {
        $beginZoektocht = strpos($this->getSource(),"<link>",$begin) + 6;
        $eindZoektocht  = strpos($this->getSource(),"</link>",$beginZoektocht);
        $this->links[] = substr($this->getSource(),$beginZoektocht,$eindZoektocht-$beginZoektocht);
        return $eindZoektocht;
    }

    /*
     * set number of items to process
     * does not require $aantal <= getCountItems(), will be checked
     */
    function setCountItems($aantal) {
        if($aantal <= $this->getCountItems())
            $this->aantalItems = $aantal;
    }

    /*
     * @return number of items processed
     */
    function getCountItems() {
        return $this->aantalItems;
    }

    /*
     * @return rss-feeds title
     */
    function getRssTitle() {
        return $this->titel;
    }

    /*
     * @return items extra[$stringKey] of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     * if $stringKey hasnt been parsed; returns false
     */
    function getExtra($which,$stringKey) {
        if(in_array($stringKey,$this->extraOptiesArray)) {
            if($which < $this->getCountItems()) {
                return $this->extraOpties[$stringKey][$which];
            }
            else
                return $this->extraOpties[$stringKey][$this->getCountItems() - 1];
        }
        else
           return false;
    }

    /*
     * @return items title of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getTitle($which) {
        if($which < $this->getCountItems())
            return $this->titels[$which];
        else
            return $this->titels[$this->getCountItems() -1];
    }

    /*
     * @return items description of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getDescription($which) {
        if($which < $this->getCountItems())
            return $this->inhouds[$which];
        else
            return $this->inhouds[$this->getCountItems() -1];
    }

    /*
     * @return items link of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getLink($which) {
        if($which < $this->getCountItems())
            return $this->links[$which];
        else
            return $this->links[$this->getCountItems() -1];
    }

    /*
     * @return items pubDate of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getPubDate($which) {
        if($which < $this->getCountItems())
            return $this->pubDates[$which];
        else
            return $this->pubDates[$this->getCountItems() -1];
    }

    /*
     * @return items category of 'which'-item
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getCategory($which) {
        if($which < $this->getCountItems())
            return $this->categorys[$which];
        else
            return $this->categorys[$this->getCountItems() -1];
    }

    /*
     * @return item which as array with keys title,description,link,pubDate and category, if set true
     * if $which >= $this->getCountItems() -> $which = $this->getCountItems()-1
     */
    function getItem($which,$title = false,$description = false,$link = false,$pubDate = false,$category = false,$extra=false) {
        $which = ($which > $this->getCountItems()) ? $this->getCountItems()-1 : $which;
        $result[] = "";

        if($title)
            $result['title'] = $this->getTitle($which);

        if($description)
            $result['description'] = $this->getDescription($which);

        if($link)
            $result['link'] = $this->getLink($which);

        if($pubDate)
            $result['pubDate'] = $this->getPubDate($which);

        if($category)
            $result['category'] = $this->getCategory($which);

        if($extra)
            for($i=0;$i<count($this->extraSearchOptions);$i++)
                $result[$extraSearchOptions[$i]] = $this->getExtra($which,$extraSearchOptions[$i]);

        return $result;
    }

    /*
     * html_entity_decode for all descriptions
     * no return
     */
    function decodeDescription() {
        for($i = 0; $i < $this->getCountItems(); $i++)
            $this->inhouds[$i] = html_entity_decode($this->getDescription($i));
    }

    /*
     * strips descriptions (removes <CDATA and ]]>), specially for nu.nl
     */
    function stripDescription($tekst = "") {
        if(empty($tekst)) {
            for($i = 0; $i < $this->getCountItems(); $i++) {
                $beginInhoud  = strpos($this->getDescription($i),"CDATA")+6;
                $eindigInhoud = strpos($this->getDescription($i),"]]>");
                $this->inhouds[$i] = substr($this->getDescription($i),$beginInhoud,$eindigInhoud-$beginInhoud);
            }
        } else {
            $beginInhoud  = strpos($tekst,"CDATA")+6;
            $eindigInhoud = strpos($tekst,"]]>");
            return substr($tekst,$beginInhoud,$eindigInhoud-$beginInhoud);
        }
    }

    /*
     * limits $what at length $length
     * if($wrap), words are finished if needed untill a whitespace has been reached
     * integer $dots says how many dots have to be add if new.length < old.length
     * returns new string
     */
    static function limit($what,$length,$wrap = false,$dots = 0) {
        $lengteNu = strlen($what);
        if(($lengteNu > $length) && $wrap) {
            $length = strpos($what," ",$length);
            if($length <= 0)
                       $length = $lengteNu;
        }
        $what = substr($what,0,$length);
        if($lengteNu > $length)
            $what .= str_repeat(".",$dots);
        return $what;
    }
}
?>
<-- ************************************************ -->
<?php
/* usage1: setting extra search options yourself */
$rss = new rssReader('http://www.nu.nl/deeplink_rss2/index.jsp?r=Algemeen');
$extraOptions = array('title','description','link');
$rss->setExtraSearchOptions($extraOptions);
$rss->parse(false,false,false,false,false,true);
$rss->setCountItems(4);

echo $rss->getRssTitle() . "<br>";
for($i=0;$i<$rss->getCountItems();$i++) {
    echo "<a href=\"".$rss->getExtra($i,'link')."\"><b>".$rss->getExtra($i,'title')."</b></a><br>";
    echo $rss->limit($rss->stripDescription($rss->getExtra($i,'description')),100,true,3) . "<br>";
}
?>
<hr>
Will do the same as
<hr>
<?php
/* usage2: using buildin search options */
$rss = new rssReader('http://www.nu.nl/deeplink_rss2/index.jsp?r=Algemeen');
$rss->parse(true, true, true);
$rss->decodeDescription();
$rss->stripDescription();
$rss->setCountItems(4);

echo $rss->getRssTitle() . "<br>";
for($i=0;$i<$rss->getCountItems();$i++) {
    $items[] = $rss->getItem($i,true,true,true);
    echo "<a href=\"$items[$i]['link']\"><b>".$items[$i]['title']."</b></a><br>";
    echo $rss->limit($items[$i]['description'],100,true,3) . "<br>";
}
?>[/code]