How To Use: Custom Classes & Interfaces?

Hello all,

I have a feeling this is a simple task, yet I can’t find an explanation anywhere on how to do this with the Yii framework. I searched the wiki and the forums and can not find a simple answer.

I have a file called ‘FeedManager.php’ that contains this code:


<?php


interface IFeedManager{

    function getFeed($RawFeed);

}




class FeedManager{

    

   public $feed = null;

   private $rawFeed = null;

   private $feedXML = null;

   private $feedURL = null;

   private $format = null;

   private $manager = null;

   private $error = null;

   private $ready = false;


    public function  __construct($url) {

        $this->feedURL = $url;

    }


    public function getFormat(){

        return $this->format;

    }


    public function getError(){

        return $this->error;

    }


    public function getFeed(){

        

        // Grab the XML for the feed

        $this->feedXML = $this->CurlGrabPage($this->feedURL);

        if($this->feedXML !== null):


            // Determine the Feed Format

            $this->format = $this->detectFeedFormat();


            if($this->format !== null):

                switch ($this->format):


                    case "RSS" :

                        $this->manager = new RSSFeedManager();

                        break;


                    case "Atom" :

                        $this->manager = new AtomFeedManager();

                        break;


                endswitch;


                // Load Feed XML into a Feed Object i.e. rawFeed

                $this->loadFeedFromXML();


                // Get properly formatted feed

                $this->feed = $this->manager->getFeed($this->rawFeed);


                if($this->feed !== null):

                    $this->ready = true;    // Feed is ready for use

                    $this->feed = $this->manager->getFeed($url);

                else:

                    $this->error = "Could not format the the feed";

                    //$this->error = "Could not format the the feed by ".$this->format." specification";

                endif;

            else:

                $this->error = "Could not detect the Feed format";

            endif;

        else:

            $this->error = "Failed to detect Feed at: ".$this->feedURL;

        endif;

        

        

    }


    private function detectFeedFormat(){


        if(preg_match('#<rss.*?>#', $this->feedXML))

            return "RSS";

        elseif(preg_match('#<feed.*?>#', $this->feedXML))

            return "Atom";

        else

            return null;


    }


    private function CurlGrabPage($url, $proxy=null, $proxystatus=false){


        $ch = curl_init();

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        if ($proxystatus):

            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

            curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);

            curl_setopt($ch, CURLOPT_PROXY, $proxy);

        endif;

        curl_setopt($ch, CURLOPT_URL, $url);

        ob_start();      // prevent any output

        $contents = curl_exec ($ch); // execute the curl command

        ob_end_clean();  // stop preventing output

        curl_close ($ch);

        return $contents;


    }


    private function loadFeedFromXML(){

        $this->rawFeed = simplexml_load_string($this->feedXML);

    }


}


class RSSFeedManager extends IFeedManager{

    public function getFeed($RawFeed){

        if($RawFeed !== null):

            $Feed->title = $RawFeed->channel->title;

            $Feed->link = $RawFeed->channel->link;

            $Feed->logo->title = $RawFeed->channel->image->title;

            $Feed->logo->url = $RawFeed->channel->image->url;

            $Feed->logo->link = $RawFeed->channel->image->link;

            $Feed->author->name = $RawFeed->channel->copyright;

            $Feed->author->email = $RawFeed->channel->webMaster;

            $itemCount = 0;

            foreach($RawFeed->channel->item as $item):

                $Feed->entry[$itemCount]->title = $item->title;

                $Feed->entry[$itemCount]->link = $item->link;

                $Feed->entry[$itemCount]->category = $item->category;

                $Feed->entry[$itemCount]->date = date("d/m/Y @ H:i", strtotime($item->pubDate));

                $Feed->entry[$itemCount]->content = $item->description;

                $itemCount++;

            endforeach;

            return $Feed;

        endif;

        return null;

    }

}


class AtomFeedManager extends IFeedManager{

    public function getFeed($RawFeed){

        if($RawFeed !== null):

            $Feed->title = $RawFeed->title;

            $Feed->link = $RawFeed->channel->link;

            $Feed->logo->title = $RawFeed->title;

            $Feed->logo->url = $RawFeed->logo;

            foreach($RawFeed->link as $link):

                    if($link->attributes()->type == 'text/html'):

                        $Feed->logo->link = $link->attributes()->href; break;

                    endif;

            endforeach;

            $Feed->author->name = $RawFeed->author->name;

            $Feed->author->email = $RawFeed->author->email;

            $itemCount = 0;

            foreach($RawFeed->entry as $item):

                    $Feed->entry[$itemCount]->title = $item->title;

                    $Feed->entry[$itemCount]->link = $item->link->attributes()->href;

                    $Feed->entry[$itemCount]->category = $item->category->attributes()->term;

                    $Feed->entry[$itemCount]->date = date("d/m/Y @ H:i", strtotime($item->updated));

                    $Feed->entry[$itemCount]->content = $item->content;

                    $itemCount++;

            endforeach;

            return $Feed;

        endif;

        return null;


    }

}


?>

I am consitently getting an internal server error when trying to use the FeedManager object, when I moved the AtomFeedManager & RSSFeedManager classes from the file, I could at least use the object, but not the full functionality. How Yii includes these classes for use isn’t clear to me.

How can I structure the above classes and interface in a way Yii will let me use a ‘FeedManager’ object in my controllers? i.e.


<?php


$FeedManager = new FeedManager($url);


?>

Thanks,

Chris

The subclasses extend from the interface instead of from the base class. Just save the file in the protected/components directory and your example should work (at least be loaded).

You probably should enable debugging or examine the log file to get the detailed error message ("Fatal error: Class RSSFeedManager cannot extend from interface IFeedManager").

Edit: There’s more to it, FeedManager instantiates the other classes. Perhaps you meant implements instead of extends. But once the code is fixed, I can’t see any reasom it shouldn’t work with Yii.

/Tommy

Hello tri,

Thanks for your response, although I am still struggling to understand why it’s not working.

I have the file ‘FeedManager.php’ under /protected/components/, which is obviously preloaded by Yii. In the FeedManager.php file I have:


<?php


interface IFeedManager{

    function getFeed($RawFeed);

}


class AtomFeedManager extends IFeedManager{

    public function getFeed($RawFeed){

        .....


    }

}


class RSSFeedManager extends IFeedManager{

    public function getFeed($RawFeed){

        .....

    }

}


class FeedManager{


    .........


}


?>

I am currently testing the business logic in a view file, to which I use the simple code:


<?php


$url = "http://feeds.bbci.co.uk/news/rss.xml";

$Feed = new FeedManager($url);


?>


<div>Hello</div>

I have written a simple Hello to indicate when there’s been no errors with the FeedManager object, I tried enabling CWebLogRoute in the config file but I can’t determine the problem, the resulting page is a blank screen.

When I uncomment the ‘new FeedManager($url)’, it loads the Hello.

The FeedManager object works in a normal PHP script with an include, but I can’t incorporate it into Yii?

Your help is appreciated,

Thanks,

Chris

I still don’t understand how it can work with extends IFeedManager instead of implements.

You have to move the FeedManager class to the bottom of the script since it refer to the other two classes. Or (not needed but like Yii components) save each class in a file with same name as the class.

Really? Did you rearrange the code before posting here? When loaded correctly, there’s also at least one more error inside the example code.

/Tommy