<?php

class NP_RSSAtom extends NucleusPlugin {

   /* ==========================================================================================
	* RSS/Atom Reader 0.14 for Nuclues CMS
	* Display RSS and Atom feeds on your blog
	*
	* Copyright 2004 by Niels Leenheer
	* ==========================================================================================
	* This program is free software and open source 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 program is distributed in the hope that it will be useful, but WITHOUT
	* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
	* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
	* more details.
	*
	* You should have received a copy of the GNU General Public License along
	* with this program; if not, write to the Free Software Foundation, Inc.,
	* 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
	* http://www.gnu.org/licenses/gpl.html
	* ==========================================================================================
	*
	* 0.14   - Again rewritten large parts of the charset conversion
	* 0.13   - Replaced code for charset conversion with faster optimized version
	* 0.12   - Added proper support for UTF-8 encoded RSS and Atom feeds
	*        - Added charset conversion for more exotic feeds
	* 0.11   - Changed version number to reflect updated XMLSupport
	* 0.10   - Large rewrite of the plugin code
	*        - Reorganized template settings
	*        - Now making use of the TEMPLATE class to fill values in templates
	* 0.9.5  - Data is now HTML entities encoded
	*        - Split of parser and cache class to make it reusable by 
	*          RSS/Atom Aggregator and XBEL Reader
	*        - Misc bugfixes
	* 0.9.4  - Added ability to cut the title after a preset number of chars
    *        - Added ability to specify an offset to start somewhere in the 
	*          middle, instead of at the top of the entries
	*        - Fixed a bug in cache reading, also added extra debug information
	*          which can be turned on by setting line 85 to true
	* 0.9.3  - Fixed parsing problem with entities in titles and urls
	* 0.9.2  - Misc bugfixes in feed parsing
	*        - Added more template configuration options
	*        - Added the option to hide retrieval and parsing errors
	* 0.9.1  - Added bugfix for Atoms reader
	* 0.9.0  - Initial release
	*/

	

	// PLUGIN INFORMATION
	function getName() {
		return 'RSS/Atom Reader';
	}

	function getAuthor()  {
		return 'Niels Leenheer';
	}

	function getURL() {
		return 'http://www.rakaz.nl/';
	}

	function getVersion() {
		return '0.14';
	}

	function getDescription() {
		return 'This plugin reads a RSS or Atom feed and shows the
		        entries as links on your blog. The feed can be 
				shown in any skin using the skinvar 
				&lt;%RSSAtom(feedurl,offset,numberofitems,defaulttitle)%&gt;.';
	}
	
	function supportsFeature($feature) {
    	switch($feature) {
	        case 'SqlTablePrefix':
	        	return 1;
	        default:
	    		return 0;
		}
	}
	


	// CONFIGURATION VARIABLES
	var $showDebug = false;
	var $showEmpty;
	var $showErrors;
	var $showTitleLink;
	
	var $defaultCount;
	var $defaultLength;
	
	var $XMLSupport;
		


	// PLUGIN INITIALISATION
	function init() {
		global $manager;

		$this->defaultCount = (int) $this->getOption('defaultCount');
		$this->defaultLength = (int) $this->getOption('defaultLength'); 
		$this->showEmpty = ($this->getOption('showEmpty') == 'yes') ? true : false; 
		$this->showErrors = ($this->getOption('showErrors') == 'yes') ? true : false; 
		$this->showTitleLink = ($this->getOption('showTitleLink') == 'yes') ? true : false; 
		
		if ($manager) if ($manager->pluginInstalled('NP_XMLSupport')) 
			$this->XMLSupport =& $manager->getPlugin('NP_XMLSupport');
	}	
	
	function install() {
    		$this->createOption('defaultCount','Maximum number of entries','text','10');
		$this->createOption('defaultLength','Maximum length of entries (0 = no limit)','text','0');
		$this->createOption('showEmpty',"Show box when there are no items available",'yesno','yes');
		$this->createOption('showTitleLink',"Always try to show a link in the title",'yesno','no');

		$this->createOption('tplBoxHeader','Box Header','textarea',"<div class='RSSAtom'>");
		$this->createOption('tplTitle','Title (with Link)','textarea',"<h4><a href='<%url%>'><%title%></a></h4>");
		$this->createOption('tplTitleNoLink','Title (without Link)','textarea',"<h4><%title%></h4>");
		$this->createOption('tplHeader','Header','textarea',"<ul class='feeds'>");
    		$this->createOption('tplItem','Item','textarea',"<li><a href='<%url%>' title='<%description%>'><%title%></a></li>");
		$this->createOption('tplFooter','Footer','textarea','</ul>');
		$this->createOption('tplEmpty',"'No items available' message",'textarea',"<p>No items available</p>");
    		$this->createOption('tplBoxFooter','Box Footer','textarea',"</div>");

		$this->createOption('showErrors','Show errors','yesno','no');
	} 
	
	function doSkinVar($skinType, $feedurl, $offset = 0, $count = 0, $defaultTitle = '', $alwaysUseDefault = 'no') {
	
		/* Get the data from the cache */
		$feed = $this->XMLSupport->createRSSAtomParser();
		$feed->setError($this->showErrors);
		$feed->setDebug($this->showDebug);
		$output = $feed->readURL ($feedurl);
		
		// Output
		$noItems = is_array($output['items']) ? count($output['items']) : 0;

		if ($noItems > 0) 
		{
			$output['items'] = array_slice($output['items'], $offset, $count == 0 ? $this->defaultCount : $count);
			$noItems = count($output['items']);
		}

		if ($noItems > 0 || $this->showEmpty) 
		{
			$title = (!isset($output['title']) || $alwaysUseDefault == 'yes') ? 
				$defaultTitle : $output['title'];
					
			$aGeneralVars = array (
				'title' => $title,
				'url' 	=> $output['href']
			);
			
			echo TEMPLATE::fill($this->getOption('tplBoxHeader'), $aGeneralVars);
			echo TEMPLATE::fill(($output['href'] != '' && $this->showTitleLink) ? 
				$this->getOption('tplTitle') : $this->getOption('tplTitleNoLink'), $aGeneralVars);

			if ($noItems > 0)
			{
				echo TEMPLATE::fill($this->getOption('tplHeader'), $aGeneralVars);
				
				while (list($k,$v) = each ($output['items']))
				{
					if (isset($v['href']))
					{
						$aVars = array (
							'url' 			=> htmlspecialchars($v['href']),
							'title' 		=> $this->_cut_string($v['title']),
							'description' 	=> str_replace("'","&#39;",$this->_strip_newline($v['title'])),
							'date' 			=> $v['date'],
							'bidi' 			=> $v['bidi']
						);
						
						echo TEMPLATE::fill($this->getOption('tplItem'), $aVars);
					}
				}
				
				echo TEMPLATE::fill($this->getOption('tplFooter'), $aGeneralVars);
			}
			else
			{
				echo TEMPLATE::fill($this->getOption('tplEmpty'), $aGeneralVars);
			}
			
			echo TEMPLATE::fill($this->getOption('tplBoxFooter'), $aGeneralVars);
		}
	}
	
	function _cut_string($string) {
	
		if ($this->defaultLength < 1)
			return $string;

		$i        = 0;
		$count    = 0;
		$ent_mode = false;
		$output   = '';

		while ($i < strlen($string) && $count <= $this->defaultLength)
		{
			$char = substr($string, $i, 1);
			if ($ent_mode == false && $char == '&') $ent_mode = true;
			if ($ent_mode == true && $char == ';') $ent_mode = false;
			if ($ent_mode == false) $count++;
			if ($char == ' ' && $count >= $this->defaultLength - 10) break;
			$output .= $char;
			$i++;
		}
		
		if (strlen($string) != strlen($output)) $output .= '...';
	
		return ($output);
	}
	
	function _strip_newline($string) {
		return preg_replace( "/(\r\n|\n|\r)/", " ", $string );    
	}
}


?>