[geeklog-cvs] geeklog-1.3/system/classes/syndication atom.feed.class.php,NONE,1.1 feedparserbase.class.php,NONE,1.1 parserfactory.class.php,NONE,1.1 rdf.feed.class.php,NONE,1.1 rss.feed.class.php,NONE,1.1
dhaun at iowaoutdoors.org
dhaun at iowaoutdoors.org
Sun Jan 23 06:07:22 EST 2005
Update of /var/cvs/geeklog-1.3/system/classes/syndication
In directory www:/tmp/cvs-serv31343/system/classes/syndication
Added Files:
atom.feed.class.php feedparserbase.class.php
parserfactory.class.php rdf.feed.class.php rss.feed.class.php
Log Message:
Incorporated new framework for reading and writing feeds (RSS, RDF, Atom), provided by Michael Jervis.
--- NEW FILE: rss.feed.class.php ---
<?php
/****************************************************************************/
/* rss.feed.class.php */
/* */
/****************************************************************************/
/* Copyright (c) 2004 Michael Jervis (mike at fuckingbrit.com) */
/* */
/* This software is provided 'as-is', without any express or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be*/
/* appreciated but is not required. */
/* */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/****************************************************************************/
/**
* Provides feed handlers for RSS 0.9x and RSS 2.0
*
* This library file provides multiple class definitions for dealing with
* variants of the RSS syndication format. We will <b>not</b> handle RSS 1.0
* however, that is RDF and handled in a seperate case. This is purely for
* the original RSS and the 2.0 that was created to deal with the fact
* that RDF was overkill for the original purpose of RSS.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @version 1.0
*/
/**
* rss0x provides reading and writing of RSS 0.91 format syndication feeds.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
* @abstract
*/
class RSS0x extends FeedParserBase
{
/**
* @access private
* @var boolean
*/
var $_inItem;
/**
* @access private
* @var array
*/
var $_currentItem;
function RSS0x()
{
$this->FeedParserBase();
$this->_inItem = false;
}
/**
* Format an article into an RSS 0.91 <item> tag.
*
* Takes an associative article array and turns it into an XML definition
* of an article. Uses merely title, link and summary.
*
* @param array $article Associative array describing an article.
*/
function _formatArticle( $article )
{
$xml = "<item>\n";
$xml .= '<title>'.$this->_safeXML( $article['title'] )."</title>\n";
$xml .= '<link>'.$this->_safeXML( $article['link'] )."</link>\n";
if( array_key_exists( 'summary', $article ) )
{
if( strlen( $article['summary'] ) > 0 )
{
$xml .= '<description>'.$this->_safeXML( $article['summary'] )."</description>\n";
}
}
$xml .= "</item>\n";
return $xml;
}
/**
* Return the formatted start of a feed.
*
* This will start the xml and create header information about the feed
* itself.
*/
function _feedHeader()
{
$xml = "<?xml version=\"1.0\" encoding=\"{$this->encoding}\"?>\n\n";
$xml .= "<rss version=\"0.91\">\n<channel>\n";
$xml .= "<title>".$this->_safeXML( $this->title )."</title>\n";
$xml .= "<link>".$this->_safeXML( $this->sitelink )."</link>\n";
if( strlen( $this->description ) > 0 )
{
$xml .= "<description>".$this->_safeXML( $this->description )."</description>\n";
}
$xml .= "<lang>{$this->lang}</lang>\n";
return $xml;
}
/**
* Return the formatted end of a feed.
*
* just closes things off nicely.
*/
function _feedFooter()
{
$xml = "</channel>\n</rss>\n";
return $xml;
}
/**
* Handle the begining of an XML element
*
* This is called from the parserfactory once the type of data has been
* determined. Standard XML_PARSER element handler.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
*/
function startElement($parser, $name, $attributes)
{
if( $name == 'ITEM' )
{
$this->_inItem = true;
$this->_currentItem = array();
}
$this->_currentTag = $name;
}
/**
* Handle the close of an XML element
*
* Called by the parserfactory during parsing.
*/
function endElement($parser, $name)
{
if( $name == 'ITEM' )
{
$this->_inItem = false;
$this->articles[] = $this->_currentItem;
}
$this->_currentTag = '';
}
/**
* Handles character data.
*
* Called by the parserfactory during parsing.
*/
function charData($parser, $data)
{
if( $this->_inItem )
{
if( $this->_currentTag == 'TITLE' )
{
if( empty( $this->_currentItem['title'] ) )
{
$this->_currentItem['title'] = $data;
} else {
$this->_currentItem['title'] .= $data;
}
} else if( $this->_currentTag == 'LINK' ) {
if( empty( $this->_currentItem['link'] ) )
{
$this->_currentItem['link'] = $data;
} else {
$this->_currentItem['link'] .= $data;
}
} else if( $this->_currentTag == 'DESCRIPTION' ) {
if( empty( $this->_currentItem['summary'] ) )
{
$this->_currentItem['summary'] = $data;
} else {
$this->_currentItem['summary'] .= $data;
}
}
} else {
if( $this->_currentTag == 'TITLE' )
{
$this->title .= $data;
} else if( $this->_currentTag == 'LINK' ) {
$this->sitelink .= $data;
} else if( $this->_currentTag == 'DESCRIPTION' ) {
$this->description .= $data;
}
}
}
}
/**
* rss20 provides reading and writing of RSS 2.0 format syndication feeds.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
* @abstract
*/
class RSS20 extends FeedParserBase
{
/**
* @access private
* @var boolean
*/
var $_inItem;
/**
* @access private
* @var array
*/
var $_currentItem;
/**
* Date of feed, for reading only
*/
var $date;
/**
* is the guid element a permalink?
*/
var $_permaLink;
function RSS20()
{
$this->FeedParserBase();
$this->_inItem = false;
}
/**
* Format an article into an RSS 2.0 <item> tag.
*
* Takes an associative article array and turns it into an XML definition
* of an article. Uses merely title, link and summary.
*
* @param array $article Associative array describing an article.
*/
function _formatArticle( $article )
{
$xml = "<item>\n";
$xml .= '<title>'.$this->_safeXML( $article['title'] )."</title>\n";
$xml .= '<link>'.$this->_safeXML( $article['link'] )."</link>\n";
$xml .= '<guid isPermaLink="true">'.$this->_safeXML( $article['link'] )."</guid>\n";
$xml .= '<pubDate>'.strftime( "%a, %d %b %Y %T %Z", $article['date'] )."</pubDate>\n";
if( array_key_exists( 'commenturl', $article ) )
{
$xml .= '<comments>'.$this->_safeXML( $article['commenturl'] )."</comments>\n";
}
if( array_key_exists( 'summary', $article ) )
{
if( strlen( $article['summary'] ) > 0 )
{
$xml .= '<description>'.$this->_safeXML( $article['summary'] )."</description>\n";
}
}
$xml .= "</item>\n";
return $xml;
}
/**
* Return the formatted start of a feed.
*
* This will start the xml and create header information about the feed
* itself.
*/
function _feedHeader()
{
$xml = "<?xml version=\"1.0\" encoding=\"{$this->encoding}\"?>\n\n";
$xml .= "<rss version=\"2.0\">\n<channel>\n";
$xml .= "<title>".$this->_safeXML( $this->title )."</title>\n";
$xml .= "<link>".$this->_safeXML( $this->sitelink )."</link>\n";
if( strlen( $this->description ) > 0 )
{
$xml .= "<description>".$this->_safeXML( $this->description )."</description>\n";
}
if( strlen($this->sitecontact) > 0 )
{
$xml .= '<managingEditor>'.$this->_safeXML( $this->sitecontact )."</managingEditor>\n";
$xml .= '<webMaster>'.$this->_safeXML( $this->sitecontact )."</webMaster>\n";
}
if( strlen($this->copyright) > 0 )
{
$xml .= '<copyright>'.$this->_safeXML( $this->copyright )."</copyright>\n";
}
if( strlen($this->system) > 0 )
{
$xml .= '<generator>'.$this->_safeXML( $this->system )."</generator>\n";
}
$xml .= '<pubDate>'.strftime( "%a, %d %b %Y %T %Z" )."</pubDate>\n";
$xml .= "<language>{$this->lang}</language>\n";
return $xml;
}
/**
* Return the formatted end of a feed.
*
* just closes things off nicely.
*/
function _feedFooter()
{
$xml = "</channel>\n</rss>\n";
return $xml;
}
/**
* Handle the begining of an XML element
*
* This is called from the parserfactory once the type of data has been
* determined. Standard XML_PARSER element handler.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
*/
function startElement($parser, $name, $attributes)
{
if( $name == 'ITEM' )
{
$this->_inItem = true;
$this->_currentItem = array();
$this->_permaLink = false;
} else if( ($name == 'GUID') && array_key_exists('ISPERMALINK', $attributes) ) {
if( $attributes['ISPERMALINK'] == 'true' )
{
$this->_permaLink = true;
} else {
$this->_permaLink = false;
}
} else {
$this->_permaLink = false;
}
$this->_currentTag = $name;
}
/**
* Handle the close of an XML element
*
* Called by the parserfactory during parsing.
*/
function endElement($parser, $name)
{
if( $name == 'ITEM' )
{
$this->_inItem = false;
$this->articles[] = $this->_currentItem;
}
$this->_currentTag = '';
}
/**
* Handles character data.
*
* Called by the parserfactory during parsing.
*/
function charData($parser, $data)
{
if( $this->_inItem )
{
if( $this->_currentTag == 'TITLE' )
{
$this->_currentItem['title'] = $data;
} else if( $this->_currentTag == 'LINK' ) {
if( $this->_currentItem['link'] == '' )
{
$this->_currentItem['link'] = $data;
}
} else if( $this->_currentTag == 'DESCRIPTION' ) {
$this->_currentItem['summary'] = $data;
} else if( $this->_currentTag == 'PUBDATE' ) {
$this->_currentItem['date'] = $data;
} else if( ($this->_currentTag == 'GUID') && $this->_permaLink) {
/* if we have a guid that is ALSO a permalink, override link with it */
$this->_currentItem['link'] = $data;
}
} else {
if( $this->_currentTag == 'TITLE' )
{
$this->title .= $data;
} else if( $this->_currentTag == 'LINK' ) {
$this->sitelink .= $data;
} else if( $this->_currentTag == 'DESCRIPTION' ) {
$this->description .= $data;
} else if( $this->_currentTag == 'MANAGINGEDITOR' ) {
$this->sitecontact .= $data;
} else if( $this->_currentTag == 'COPYRIGHT' ) {
$this->copyright .= $data;
} else if( $this->_currentTag == 'PUBDATE' ) {
$this->date .= $data;
}
}
}
}
?>
--- NEW FILE: atom.feed.class.php ---
<?php
/****************************************************************************/
/* atom.feed.class.php */
/* */
/****************************************************************************/
/* Copyright (c) 2004 Michael Jervis (mike at fuckingbrit.com) */
/* */
/* This software is provided 'as-is', without any express or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be*/
/* appreciated but is not required. */
/* */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/****************************************************************************/
/**
* Provides feed handlers for Atom 0.3
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @version 1.0
*/
/**
* atom03 provides reading and writing of Atom 0.3 format syndication feeds.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
* @abstract
*/
class Atom03 extends FeedParserBase
{
/**
* @access private
* @var boolean
*/
var $_inItem;
/**
* @access private
* @var array
*/
var $_currentItem;
function Atom03()
{
$this->FeedParserBase();
$this->_inItem = false;
}
/**
* Format an article into an Atom 0.3 <entry> tag.
*
* Takes an associative article array and turns it into an XML definition
* of an article. Uses merely title, link and summary.
*
* @param array $article Associative array describing an article.
*/
function _formatArticle( $article )
{
$xml = "<entry>\n";
$xml .= '<title mode="escaped">'.$this->_safeXML( $article['title'] )."</title>\n";
$xml .= '<link rel="alternative" type="text/html" href="'.$this->_safeXML( $article['link'] )."\">\n";
$xml .= '<id>'.htmlspecialchars( $entry['link'] )."</id>\n";
$xml .= '<issued>'.strftime( "%a, %d %b %Y %T %Z", $article['date'] )."</issued>\n";
$xml .= '<modified>'.strftime( "%a, %d %b %Y %T %Z", $article['date'] )."</modified>\n";
if( array_key_exists( 'author', $article ) )
{
$xml .= "<author>\n<name>{$article['author']}</name>\n</author>\n";
}
if( array_key_exists( 'summary', $article ) )
{
if( strlen( $article['summary'] ) > 0 )
{
$xml .= '<content type="text/html" mode="escaped">'
. $this->_safeXML ($article['text'])
. "</content>\n";
}
}
$xml .= "</entry>\n";
return $xml;
}
/**
* Return the formatted start of a feed.
*
* This will start the xml and create header information about the feed
* itself.
*/
function _feedHeader()
{
$xml = "<?xml version=\"1.0\" encoding=\"{$this->encoding}\"?>\n\n";
$xml .= "<feed version=\"0.3\">\n";
$xml .= "<title mode=\"escaped\">".$this->_safeXML( $this->title )."</title>\n";
$xml .= '<tagline mode=\"escaped\">'.$this->_safeXML( $this->description )."</tagline>\n";
$xml .= '<link rel="alternative" type="text/html" href="'.$this->_safeXML( $this->sitelink )."\"/>\n";
return $xml;
}
/**
* Return the formatted end of a feed.
*
* just closes things off nicely.
*/
function _feedFooter()
{
$xml = "</feed>\n";
return $xml;
}
/**
* Handle the begining of an XML element
*
* This is called from the parserfactory once the type of data has been
* determined. Standard XML_PARSER element handler.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
*/
function startElement($parser, $name, $attributes)
{
if( $name == 'ENTRY' )
{
$this->_inItem = true;
$this->_currentItem = array();
} else if( $this->_inItem ) {
if( $name == 'LINK' )
{
$this->_currentItem['link'] = $attributes['HREF'];
}
} else {
if( $name == 'LINK' )
{
$this->sitelink = $attributes['HREF'];
}
}
$this->_currentTag = $name;
}
/**
* Handle the close of an XML element
*
* Called by the parserfactory during parsing.
*/
function endElement($parser, $name)
{
if( $name == 'ENTRY' )
{
$this->_inItem = false;
$this->articles[] = $this->_currentItem;
}
$this->_currentTag = '';
}
/**
* Handles character data.
*
* Called by the parserfactory during parsing.
*/
function charData($parser, $data)
{
if( $this->_inItem )
{
if( $this->_currentTag == 'TITLE' )
{
if( empty( $this->_currentItem['title'] ) )
{
$this->_currentItem['title'] = $data;
} else {
$this->_currentItem['title'] .= $data;
}
} else if( $this->_currentTag == 'CONTENT' ) {
if( empty( $this->_currentItem['summary'] ) )
{
$this->_currentItem['summary'] = $data;
} else {
$this->_currentItem['summary'] .= $data;
}
} else if( $this->_currentTag == 'MODIFIED' ) {
$this->_currentItem['date'] = $data;
} else if( $this->_currentTag == 'ISSUED' ) {
if( empty( $this->currentItem['date'] ) )
{
$this->currentITem['date'] = $data;
}
}
} else {
if( $this->_currentTag == 'TITLE' )
{
$this->title .= $data;
} else if( $this->_currentTag == 'TAGLINE' ) {
$this->description .= $data;
}
}
}
}
--- NEW FILE: parserfactory.class.php ---
<?php
/****************************************************************************/
/* feedparserfactory.class.php */
/* */
/****************************************************************************/
/* Copyright (c) 2004 Michael Jervis (mike at fuckingbrit.com) */
/* */
/* This software is provided 'as-is', without any express or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be*/
/* appreciated but is not required. */
/* */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/****************************************************************************/
/**
* FeedParserFactory provides generic access to syndication feed formats.
*
* <p>This library provides abstraction of feed formats. It provides a factory
* pattern interface to constructing feed handlers to parse incoming
* syndication files, and write outgoing syndication files. The interface is
* not tied to any system implementation, however, I plan to provide interface
* to geeklog.</p>
*
* @author Michael Jervis (mike at Fuckingbrit.com)
* @copyright Michael Jervis 2004
* @see FeedParserBase
*/
class FeedParserFactory
{
var $readerName;
var $reader;
/**
* Constructor, loads feedparser classes into memory.
*
* This takes a path on which the supporting feed classes exist, and then
* tries to find all *.feed.class.php and brings them into scope.
*
* @param string $path path to include files from.
*/
function FeedParserFactory( $path='' )
{
if( $path != '' )
{
if( is_dir( $path ) )
{
$folder = opendir( $path );
while( ( $filename = @readdir( $folder ) ) !== false )
{
if( preg_match( '/(.*)\.feed\.class\.php$/i', $filename ) )
{
require_once( $path.'/'.$filename );
}
}
}
}
}
/**
* Method to get a feed handler class.
*
* This function takes a url, fetches it, parses it, and thus figures out
* what type of feed parser to return, with the contents all parsed for your
* viewing pleasure.
*
* @access public
* @param string $url The url to a feed type to syndicate.
*/
function reader( $url, $targetformat='' )
{
if( $fp = $this->_getFeed( $url ) )
{
return $this->_findFeed( $fp );
} else {
return false;
}
}
/**
* Method to get a feed handler class.
*
* this function assumes you know what you want, and gets you a blank feed
* handler to write that data.
*
* @access public
* @param string $feedtype the type of feed to get
* @param float $version the version
*/
function writer( $feedtype, $version=2.0 )
{
$feedtype = strtolower($feedtype);
switch ($feedtype)
{
case 'rss':
if( $version == '' )
{
return new RSS0x();
} else {
if( $version < 1.0 )
{
return new RSS0x();
} else if( $version >= 2.0 ) {
return new RSS20();
} else {
return new RSS0x();
}
}
break;
case 'rdf':
return new RDF();
break;
case 'atom':
return new Atom03();
break;
default:
return false;
break;
}
}
/**
* Provides an array of feed types understood.
*
* Provides an array of feed types understood. Yeah it's manual, but, the
* feed reader has to be edited to support new inbounds anyway.
*
* @access public
*/
function getFeedTypes()
{
$types = array();
$types[] = array('name'=>'RSS','version'=>'0.9x');
$types[] = array('name'=>'RSS','version'=>'2.0');
$types[] = array('name'=>'RDF','version'=>'1.0');
$types[] = array('name'=>'Atom','version'=>'0.3');
return $types;
}
/**
* Opens a url in a file pointer
*
* @access private
* @param string $url The URL to open.
*/
function _getFeed( $url )
{
if( $fp = @fopen( $url, 'r' ) )
{
return $fp;
} else {
return false;
}
}
/**
* Find out what format a feed is in.
*
* @access private
*/
function _findFeed( $fp, $format='' )
{
$xml_parser = xml_parser_create();
xml_parser_set_option( $xml_parser, XML_OPTION_CASE_FOLDING, true );
if( $format != '' )
{
@xml_parser_set_option( $xml_parser, XML_OPTION_TARGET_ENCODING,
$format );
}
xml_set_element_handler( $xml_parser, array(&$this,'_startElement'), array(&$this, '_endElement') );
xml_set_character_data_handler( $xml_parser, array(&$this,'_charData') );
while( $data = fread( $fp, 4096 ) )
{
if( !xml_parse( $xml_parser, $data, feof($fp) ) )
{
fclose($fp);
xml_parser_free( $xml_parser );
return false;
}
}
fclose( $fp );
xml_parser_free( $xml_parser );
if( $this->reader != false )
{
return $this->reader;
} else {
return false;
}
}
function _startElement( $parser, $name, $attributes )
{
if( !$this->readerName )
{
/* Check for atom */
if( $name == 'FEED' )
{
$this->readerName = 'Atom03';
} elseif ( $name == 'RSS' ) {
if( array_key_exists('VERSION', $attributes) )
{
$version = $attributes['VERSION'];
} else {
$version = 0.91;
}
if( $version < 1 )
{
$this->readerName = 'RSS0x';
} else {
$this->readerName = 'RSS20';
}
} elseif ( $name = 'RDF:RDF' ) {
$this->readerName = 'RDF';
}
if( $this->readerName )
{
$this->reader = new $this->readerName;
//echo( "Made a new {$this->readerName} called {$this->reader} it's a ".get_class($this->reader)." I'm a ".get_class($this) );
}
}
if( $this->reader )
{
$this->reader->startElement( $parser, $name, $attributes );
}
}
function _endElement( $parser, $name )
{
if( $this->reader )
{
$this->reader->endElement( $parser, $name );
}
}
function _charData( $parser, $data )
{
if( $this->reader )
{
$this->reader->charData( $parser, $data );
}
}
}
?>
--- NEW FILE: rdf.feed.class.php ---
<?php
/****************************************************************************/
/* rdf.feed.class.php */
/* */
/****************************************************************************/
/* Copyright (c) 2004 Michael Jervis (mike at fuckingbrit.com) */
/* */
/* This software is provided 'as-is', without any express or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be*/
/* appreciated but is not required. */
/* */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/****************************************************************************/
/**
* Provides feed handlers for RDF 1.0
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @version 1.0
*/
/**
* RDF provides reading and writing of RDF 1.0 format syndication feeds.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
* @abstract
*/
class RDF extends FeedParserBase
{
/**
* @access private
* @var boolean
*/
var $_inItem;
/**
* @access private
* @var array
*/
var $_currentItem;
function RDF()
{
$this->FeedParserBase();
$this->_inItem = false;
}
/**
* Format an article into an Atom 0.3 <entry> tag.
*
* Takes an associative article array and turns it into an XML definition
* of an article. Uses merely title, link and summary.
*
* @param array $article Associative array describing an article.
*/
function _formatArticle( $article )
{
$xml = "<item rdf:about=\"{$article['link']}\">\n";
$xml .= '<title>'.$this->_safeXML( $article['title'] )."</title>\n";
$xml .= '<link>'.$this->_safeXML( $article['link'] )."</link>\n";
if( array_key_exists( 'author', $article ) )
{
$xml .= '<dc:creator>'.$article['author']."</dc:creator>\n";
}
if( array_key_exists( 'summary', $article ) )
{
if( strlen( $article['summary'] ) > 0 )
{
$xml .= '<content:encoded>'
. $this->_safeXML ($article['text'])
. "</content:encoded>\n";
}
}
$xml .= "</item>\n";
return $xml;
}
/**
* Return the formatted start of a feed.
*
* This will start the xml and create header information about the feed
* itself.
*/
function _feedHeader()
{
$xml = "<?xml version=\"1.0\" encoding=\"{$this->encoding}\"?>\n\n";
$xml .= "<rdf:RDF>\n<channel>\n";
$xml .= "<title>".$this->_safeXML( $this->title )."</title>\n";
$xml .= '<link>'.$this->_safeXML( $this->sitelink )."</link>\n";
$xml .= '<description>'.$this->_safeXML( $this->description )."</description>\n";
$xml .= '<dc:language>'.$this->lang."</dc:language>\n";
if( strlen($this->sitecontact) > 0 )
{
$xml .= '<dc:creator>'.$this->sitecontact."</dc:creator>\n";
}
$xml .= "<items>\n<rdf:Seq/>\n</items></channel>\n";
return $xml;
}
/**
* Return the formatted end of a feed.
*
* just closes things off nicely.
*/
function _feedFooter()
{
$xml = "</rdf:RDF>\n";
return $xml;
}
/**
* Handle the begining of an XML element
*
* This is called from the parserfactory once the type of data has been
* determined. Standard XML_PARSER element handler.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
*/
function startElement($parser, $name, $attributes)
{
if( $name == 'ITEM' )
{
$this->_inItem = true;
$this->_currentItem = array();
}
$this->_currentTag = $name;
}
/**
* Handle the close of an XML element
*
* Called by the parserfactory during parsing.
*/
function endElement($parser, $name)
{
if( $name == 'ITEM' )
{
$this->_inItem = false;
$this->articles[] = $this->_currentItem;
}
$this->_currentTag = '';
}
/**
* Handles character data.
*
* Called by the parserfactory during parsing.
*/
function charData($parser, $data)
{
if( $this->_inItem )
{
if( $this->_currentTag == 'TITLE' )
{
if( empty( $this->_currentItem['title'] ) )
{
$this->_currentItem['title'] = $data;
} else {
$this->_currentItem['title'] .= $data;
}
} else if( $this->_currentTag == 'LINK' ) {
if( empty( $this->_currentItem['link'] ) )
{
$this->_currentItem['link'] = $data;
} else {
$this->_currentItem['link'] .= $data;
}
} else if( $this->_currentTag == 'CONTENT:ENCODED' ) {
if( empty( $this->_currentItem['summary'] ) )
{
$this->_currentItem['summary'] = $data;
} else {
$this->_currentItem['summary'] .= $data;
}
}
} else {
if( $this->_currentTag == 'TITLE' )
{
$this->title .= $data;
} else if( $this->_currentTag == 'LINK' ) {
$this->sitelink .= $data;
} else if( $this->_currentTag == 'DESCRIPTION' ) {
$this->description .= $data;
}
}
}
}
--- NEW FILE: feedparserbase.class.php ---
<?php
/****************************************************************************/
/* FeedParserBase.class.php */
/* */
/****************************************************************************/
/* Copyright (c) 2004 Michael Jervis (mike at fuckingbrit.com) */
/* */
/* This software is provided 'as-is', without any express or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be*/
/* appreciated but is not required. */
/* */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/****************************************************************************/
/**
* FeedParserBase provides an abstract ancestor class for feed parsers.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
* @abstract
*/
class FeedParserBase
{
/**
* An array of items.
*
* This holds all the news from the source. This should be an array of
* associative arrays. Each item will have:
* title - The title
* URI - Link to the full story
* date - The date of the article
* Optional (pre-defined) items are:
* summary - Short version of article
* text - full version
* author - Who wrote the article
*/
var $articles;
/**
* Encoding tag for the XML declaration
*/
var $encoding;
/**
* Language for the feed
*/
var $lang;
/**
* Title for the feed
*/
var $title;
/**
* The description of the feed
*/
var $description;
/**
* The URL of the feed
*/
var $url;
/**
* URL of the site
*/
var $sitelink;
/**
* Site contact
*/
var $sitecontact;
/**
* copyright tag:
*/
var $copyright;
/**
* system powering the feed
*/
var $system;
/**
* Stuff for parsing XML
*/
var $_currentTag;
function FeedParserBase()
{
$this->encoding = 'iso-8859-1';
$title = 'Killer Feed System Feed';
$this->lang = 'en-gb';
$currentTag = '';
$articles = array();
}
/**
* Create a file for the stream
*
* Writes the $items content to the file supplied in the format we have
* specified. Uses the (abstract) function formatArticle to return XML
* for an article.
*
* @param string $fileName The fully qualified path to the file to create.
* @param integer $limit (optional) max number of items to write.
*/
function createFeed( $fileName, $limit='' )
{
/* If we have no items, return false */
if( count( $this->articles ) == 0 )
{
return false;
} else {
/* Start the XML Feed formating */
$xml = $this->_feedHeader();
/* Start with a limit of the size of the array, then, if we have a
* specific max length use that unless it's bigger than our count */
$count = count( $this->articles );
if( $limit )
{
if( $limit < $count )
{
$count = $limit;
}
}
/* Put the first $count items into the xml, using formatArticle */
for( $i = 0; $i < $count; $i++ )
{
$xml .= $this->_formatArticle( $this->articles[$i] );
}
/* Close off the feed */
$xml .= $this->_feedFooter();
/* And write it to file */
return $this->_writeFile( $fileName, $xml );
}
}
function _writeFile( $fileName, $data )
{
if( $fp = @fopen( $fileName, 'w' ) )
{
fputs( $fp, $data );
fclose( $fp );
return true;
} else {
return false;
}
}
/**
* Format an article into feed specific XML.
*
* Takes an associative article array and turns it into an XML definition
* of an article.
* @param array $article ASsociative array describing an article.
*/
function _formatArticle( $article )
{
$xml = "<article>\n";
while( list($key, $value) = each( $article ) )
{
$value = $this->safeXML( $value );
$xml .= "<$key>$value</$key>\n>";
}
$xml .= "</article>\n";
return $xl;
}
/**
* Make sure a string is safe to be chardata in an xml element
*
* @param string $string the string to escape.
*/
function _safeXML( $string )
{
return htmlspecialchars($string);
}
/**
* Return the formatted start of a feed.
*
* This will start the xml and create header information about the feed
* itself.
*/
function _feedHeader()
{
$xml = "<?xml version=\"1.0\" encoding=\"{$this->encoding}\"?>\n\n";
$xml .= "<feed>\n<title>{$this->title}</title>\n";
return $xml;
}
/**
* Return the formatted end of a feed.
*
* just closes things off nicely.
*/
function _feedFooter()
{
$xml = '</feed>';
return $xml;
}
/**
* Handle the begining of an XML element
*
* This is called from the parserfactory once the type of data has been
* determined. Standard XML_PARSER element handler.
*
* @author Michael Jervis (mike at fuckingbrit.com)
* @copyright Michael Jervis 2004
*/
function startElement($parser, $name, $attributes)
{
}
/**
* Handle the close of an XML element
*
* Called by the parserfactory during parsing.
*/
function endElement($parser, $name)
{
}
/**
* Handles character data.
*
* Called by the parserfactory during parsing.
*/
function charData($parser, $data)
{
}
}
?>
More information about the geeklog-cvs
mailing list