<?php

/**
  * BLOG:CMS: PHP/MySQL Personal Content Management System (CMS)
  * http://blogcms.com/
  * ----------------------------------------------------------------
  *
  * Copyright (C) 2003-2005 Radek HULÁN
  * http://hulan.cz/contact/
  *
  * Based on: 
  * ----------------------------------------------------------------
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) 
  * Copyright (C) 2002-2003 The Nucleus Group
  *
  * ----------------------------------------------------------------
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
**/

/**
  * This plugin can be used to insert RSS Newsfeeds to your blog
  * Based on http://readinged.com/articles/rssparser/
             by ed@readinged.com
  * History:
  *      v0.9 : initial plugin
  *      v0.91: minor bugfixes
  *      v0.92: added posibillity to show site meta information
  *      v0.93: added options to toggle meta info on or off
  *             added the option to open links from a feed in a named target (like __blank or _top)
  *      v0.93b: problems with 2 blogs on the same url, now the query string is in included in the cache file (again) sorry Trent
  *      v0.94: somewhere there was a " too much in the output. 
  */

class NP_Newsfeed extends NucleusPlugin {

    function getName()    {return 'Newsfeed: Import RSS / XML News feeds in your weblog.'; }
    function getAuthor()  {return '-=Xiffy=-'; }
    function getURL()     {return 'http://xiffy.nl/weblog/'; }
    function getVersion() {return '0.94'; }
    function getDescription() {
        return 'Call this to import a newsfeed. Currently all feeds work with the same defaults.';
    }

	function supportsFeature($feature) {
		switch($feature) {
			case 'SqlTablePrefix':
				return 1;
			default:
				return 0;
		}
	}

    function install() {
        // create some options
        $this->createOption('Cachedir','Directory where to put the cached data (relative from MEDIADIR)','text','rsscache/');
        $this->createOption('Titlediv','Classname for the titleDiv item-title','text','feedTitle');
        $this->createOption('Linkdiv', 'Classname for the links when shown seperatly','text','feedLink');
        $this->createOption('Descriptiondiv','Classname for the description in de feed','text','feedDesc');
        $this->createOption('cacheTime','Time before cache gets refreshed','text','60');
        $this->createOption('showLogoAndTitle','Should we include the sites meta data as logo and title?','yesno','no');
        $this->createOption('target','If filled with anyname all links will include target="anyname" (can be _blank)','text','');
        $this->createOption('linktext','text visible for "read whole item" only for type 2 and 4 calls','text','[read on]');
        $this->createOption('localhost','Retrieve blogroll on localhost (yes/no)?','yesno','no');
    }

   function doSkinVar($skintype, $newsfeedURL, $what = 1, $amount = 10) {

    global $manager, $blog, $CONF, $i;

    $feed = $this->readFeed($newsfeedURL);
    if ($feed==-1) return;

		$titlediv       = $this->getOption(Titlediv);
		$linkdiv        = $this->getOption(Linkdiv);
		$descriptiondiv = $this->getOption(Descriptiondiv);
		$target         = $this->getOption(target);
		$linktext       = $this->getOption(linktext);

    if ($this->getOption(showLogoAndTitle) == "yes") $i = 0; else $i = 1;
    $poradi=1;
    echo "<ul>\n";
		foreach ( $feed as $feeditem ) {
		    if ($i <= $amount) {
		        $linkUrl = "<a href=\"".$feeditem[ "link" ]."\"";
		        if (($what % 2) == 1) {
		            if ($target <> "" ) {
		                $linkUrl .= " target=\"".$target."\"";
                }
                if ($feeditem['description'] <> "") {
                  $linkUrl .= " title=\"".htmlspecialchars(sql_unescape(strip_tags($feeditem["description"])))."\" ";
                }
                $linkUrl .= ">";
                $linkUrl = str_replace("&amp;","NONENONE",$linkUrl);
                $linkUrl = str_replace("&","&amp;",$linkUrl);
                $linkUrl = str_replace("NONENONE","&amp;",$linkUrl);
		        }
		        if (($what % 2) == 0) {
		            if ($target <> "" ) {
		                $linkUrl .= " target=\"" . $target . "\"";
                }
                $linkUrl .= "\">" .$linktext."</a>";
            }  
		        if ( ($i==0) && $feeditem[ "sitetitle"] <> "" )  {
		            // echo "<h3 class='item'>". sql_unescape($feeditem[ "sitetitle" ]) ."</h3>";
                if ($feeditem[ "url" ] <> "") {
                  // echo "";
		              // echo "<img class=\"centered\" src=\"" . $feeditem[ "url" ] ."\" alt=\"". sql_unescape($feeditem[ "sitetitle" ]) . "\" title=\"". sql_unescape($feeditem[ "sitetitle" ]) . "\" >";
                }
            } else 
              if ($what == 1 || $what == 3) {
                if ($poradi>1)
                echo "\t<li>".$linkUrl.sql_unescape(strip_tags($feeditem["title"]))."</a></li>\n";
                $poradi++;
              } else {
                if ($poradi>1){
                echo "<div class='$titlediv'>". sql_unescape($feeditem["title"]) ."</div>";
                echo "<div class='$linkdiv'>" . $linkUrl ."</div>\n";
                }
              }
              if ($what == 3 || $what == 4) {
                echo "<div class='$descriptiondiv'>"  . sql_unescape($feeditem[ "description" ]) . "</div>\n";
              }
		          $i++;
        }
    }
    echo "</ul>\n";
   }

    function isCurrent($filename, $minutes) {
         return ceil((time() - filemtime($filename)) / 60) < $minutes;
    }

    function readFeed($feedURL) {
        // which URL to get
        global $manager, $blog, $saxparser, $CONF, $contents, $cache_age, $cache_time, $cache_path, $last_modified_time, $DIR_MEDIA;
	if (!is_dir($DIR_MEDIA)) die('System is not configured properly');
        // get the cache path
        $cache_path    = $this->getOption(Cachedir);
        $cache_time    = $this->getOption(cacheTime);
	    $feedURL_parts = parse_url($feedURL);
	    $path          = isset($feedURL_parts["path"]) ? $feedURL_parts["path"] : "/";
	    $filename      = isset($feedURL_parts["host"]) ? $feedURL_parts["host"] : "feedfile";
	    $unique        = isset($feedURL_parts["query"]) ? $feedURL_parts["query"] : "";
	    $filename      = $filename . $path . $unique;	
	    $filename      = str_replace("/","_",$filename);
	    $filename      = $DIR_MEDIA.$cache_path.$filename;
	    $writedir      = $DIR_MEDIA.$cache_path;
	    $contents      = "";
	    $data          = "";

	    // create cache dir if non-excistent
        if (!@is_dir($writedir)){
			if (!@mkdir($writedir, 0777))
				return _ERROR_BADPERMISSIONS;
	    }
	
	    if ( !file_exists($filename)   ||
          ( 
            file_exists($filename) 
            && 
            !$this->isCurrent($filename, $cache_time)
            &&
            (
             ( (serverVar("REMOTE_ADDR")!='127.0.0.1')  &&
               strtolower($this->getOption('localhost'))!='yes' ) 
             ||
             ( strtolower($this->getOption('localhost'))=='yes' )
            ) // do not query on localhost
          )
         ) {
	
		    $tag    = "";
		    $isItem = false;
		    $i      = 0;
		    unset($saxparser);
            $saxparser = xml_parser_create();

		    xml_parser_set_option($saxparser, XML_OPTION_CASE_FOLDING, false);
		    xml_set_element_handler($saxparser, 'sax_start', 'sax_end');
		    xml_set_character_data_handler($saxparser, 'sax_data');


		    if (!function_exists('sax_start')) {
                function sax_start($parser, $name, $attribs) {
                    global $tag, $isItem, $i, $isChannel;
                    switch ($name){
                        case "channel":
                            $i++;
                            $isChannel = true;
                          break;
                        case "item":
                            $i++;
					        $isItem = true;
				          break;
                        case "image":
                        case "url":
                        case "docs":
                        case "language":
                        case "generator":
                        case "copyright":
                        case "title":
	    				case "link":
		    			case "pubDate":
			    		case "description":
				        case "author":
					    case "category":
					    case "guid":
				  	        if ($isItem || $isChannel) $tag = $name;
					      break;
                        default:
					        $isItem = false;
					        $isChannel = false;
				        break;
	                }
			    }
		    }

		    if (!function_exists('sax_end')) {
                function sax_end($parser, $name) {
                }
		    }

		    if (!function_exists('sax_data')) {
                function sax_data($parser, $data) {
			        global $tag, $isItem, $contents,                                                                                                         $isChannel, $i;
			        if ($data != "\n" && $isItem) {
		                switch ($tag) {
					        case "title":
					        case "link":
					        case "description":
						        (!isset($contents[$i-1][$tag]) || !strlen($contents[$i-1][$tag])) ?
							            $contents[$i-1][$tag] = sql_escape($data) :
							            $contents[$i-1][$tag].= sql_escape($data);
						        break;
					    }
				    } else if ($data != "\n" && $isChannel) {
				         switch ($tag) {
				             case "title":
                                 if ($tag == "title") {$tag = "sitetitle";}
						        (!isset($contents[$i-1][$tag]) || !strlen($contents[$i-1][$tag])) ?
							            $contents[$i-1][$tag] = sql_escape($data) :
							            $contents[$i-1][$tag] = sql_escape($data);
                               break;
				             case "url":
				             case "image":
                                 if ($tag == "title") {$tag = "sitetitle";}
						        (!isset($contents[$i-1][$tag]) || !strlen($contents[$i-1][$tag])) ?
							            $contents[$i-1][$tag] = sql_escape($data) :
							            $contents[$i-1][$tag] .= sql_escape($data);

				             break;
                         }
                    }
			    }
		    }

		    if ($fp = @fopen($feedURL, "r")){
		    while ($data = fread($fp, 4096)) {
			    $parsedOkay = xml_parse($saxparser, $data, feof($fp));

			    if (!$parsedOkay && xml_get_error_code($saxparser) != XML_ERROR_NONE) {
				    die("XML Error in File: ".xml_error_string(xml_get_error_code($saxparser)).
				        " at line ".xml_get_current_line_number($saxparser));
			    }
		    }

		    xml_parser_free($saxparser);
		    fclose($fp);
		    $cache = @fopen($filename, "w");
		    if ($cache) {
			    fwrite($cache, serialize($contents));
		        fclose($cache);
            }
		    $cache_age = 0;
		    } else { return -1;}

	    }
	    else  {
		    $cache_age = ceil((time() - filemtime($filename)) / 60);
		    if ($fp = @fopen($filename, "r")){
		    if ($fp) {
			    $data = fread($fp, filesize($filename));
		    }
		    fclose($fp);
		    $contents = unserialize($data);
		    } else {return -1;}
	    }
	    return $contents;
    }
}
?>