blob: 41a7c5ba27d0fae7c64185c2ca9fa6a127444d9a [file] [log] [blame]
<?php
#*****************************************************************************
#
# news.php
#
# Author: Wayne Beaton
# Date: 2005-11-07
#
# Description: This file contains the code required to read the RSS file
# into an object representation.
#
#****************************************************************************
function get_library() {
return get_books_from_file($_SERVER['DOCUMENT_ROOT'] . "/community/books/books.xml");
// $xml = simplexml_load_file($_SERVER['DOCUMENT_ROOT'] . "/community/books/books.xml");
// return xml_to_library($xml);
}
/*
* This method extracts the RSS information from the file with the
* given name.
*/
function &get_books_from_file($file_name) {
// PHP 5: simplexml_load_file($newsfile);
return parse_books_xml_file($file_name);
}
/*
* The rest of the code in this file is concerned with reading XML
* into an object format. Once we update to PHP 5, we can get rid of
* all of this junk and just use the simpleXML apis.
*/
/*
* This function does the actual work of parsing the RSS
* file into an object representation. We use a SAX parser
* to do this.
*
* Note that this function is intended to be used with relatively
* short files (the entire file contents are loaded into memory).
* If the RSS files start to get too large, this method will need
* to be updated.
*/
function &parse_books_xml_file($file_name) {
global $handler;
$handler->reset();
// Read the entire file contents in to memory.
// If file sizes get too large, we'll have to be smarter here.
$file = fopen($file_name, "r");
$xml = fread($file, filesize($file_name));
fclose($file);
$parser = xml_parser_create();
xml_set_element_handler($parser, 'startHandler', 'endHandler');
xml_set_character_data_handler($parser, 'dataHandler');
xml_parse($parser, $xml);
return $handler->library;
}
/*
* The $handler variable is global. It manages all the call backs
* that come (indirectly) from the SAX parser.
*/
$handler = new XmlHandler();
/*
* SAX parser callback method to handle the start of an element.
* This method just defers to the global handler to do the actual
* work.
*/
function startHandler($parser, $name, $attributes) {
global $handler;
$handler->start($name, $attributes);
}
/*
* SAX parser callback method to handle the text for an element.
* This method just defers to the global handler to do the actual
* work.
*/
function dataHandler($parser, $data) {
global $handler;
$handler->data($data);
}
/*
* SAX parser callback method to handle the end of an element.
* This method just defers to the global handler to do the actual
* work.
*/
function endHandler($parser, $name) {
global $handler;
$handler->end($name);
}
/*
* The XmlHandler class is the focal point of the SAX parser callbacks.
* It keeps track of a stack of element handlers. The element handlers
* are used to handle whatever elements come in.
*/
class XmlHandler {
var $library;
var $stack;
/*
* This method resets the handler so that it is ready to parse
* something. Effectively, this cleans up a potentially dirty handler.
*/
function reset() {
$this->library = new Library();
$this->stack = array(new LibraryHandler($this->library));
}
/*
* Handle the start callback. Here, we get the current element handler
* from the top of the stack and ask it what to do. The element handler
* is asked to provide a new handler to handle the new element. That new
* handler is put on the top of the stack and will handle all future
* callbacks until it is removed (by the end method).
*/
function start($name, $attributes) {
$handler =& array_last($this->stack);
$next =& $handler->get_next($name, $attributes);
array_push($this->stack, $next);
}
/*
* Data has been encountered, send the data to the current element handler
* to sort out what needs to be done.
*/
function data($data) {
$handler =& array_last($this->stack);
$handler->data($data);
}
/*
* The end of an element has occurred. Pop the current element handler
* from the top of the stack and tell it that it's work is done.
*/
function end($name) {
$handler =& array_pop($this->stack);
$handler->end($name);
}
}
/*
* The FeedHandler class takes care of the root element in the file.
*/
class LibraryHandler {
var $library;
function LibraryHandler(&$library) {
$this->library =& $library;
}
/*
* Return an appropriate handler to deal with an element named $name.
* At this point, we only expect to see an <rss> element.
*/
function &get_next($name, $attributes) {
if (strcasecmp($name, "books") == 0) {
return new BooksHandler($this->library);
} else {
return new DoNothingHandler();
}
}
/*
* Ignore data for this element.
*/
function data($data) {}
}
class BooksHandler {
var $library;
function BooksHandler(&$library) {
$this->library =& $library;
}
function data($data) {}
/*
* Return an appropriate handler to deal with an element named $name.
* At this point, we only expect to see an <channel> element.
*/
function &get_next($name, $attributes) {
if (strcasecmp($name, "book") == 0) {
return new BookHandler($this->library);
}
}
/*
* Ignore data for this element.
*/
function end($name) {}
}
class BookHandler {
var $library;
var $book;
function BookHandler(&$library) {
$this->library =& $library;
$this->book = new Book();
}
function data($data) {}
function &get_next($name, $attributes) {
if (strcasecmp($name, "title") == 0) {
return new SimplePropertyHandler($this->book, "title");
} else if (strcasecmp($name, "author") == 0) {
return new AuthorHandler($this->book);
} else if (strcasecmp($name, "url") == 0) {
return new SimplePropertyHandler($this->book, "url");
} else if (strcasecmp($name, "date") == 0) {
return new DateHandler($this->book, "date");
} else if (strcasecmp($name, "description") == 0) {
return new SimplePropertyHandler($this->book, "description");
} else {
return new DoNothingHandler();
}
}
function end($name) {
$this->library->add_book($this->book);
}
}
class SimpleTextHandler {
var $text;
function &get_next($name, $attributes) {
return new DoNothingHandler();
}
function data($data) {
$this->text .= $data;
}
function end($name) {
}
}
class SimplePropertyHandler extends SimpleTextHandler {
var $owner;
var $property;
function SimplePropertyHandler(&$owner, $property) {
$this->owner =& $owner;
$this->property = $property;
}
function end($name) {
$this->set_property_value($this->text);
}
function set_property_value(&$value) {
$property = $this->property;
$this->owner->$property = $value;
}
}
class DateHandler extends SimplePropertyHandler {
function end($name) {
$this->set_property_value(strtotime($this->text));
}
}
class AuthorHandler extends SimpleTextHandler {
var $book;
function AuthorHandler(&$book) {
$this->book =& $book;
}
function end($name) {
$this->book->add_author($this->text);
}
}
class DoNothingHandler {
function DoNothingHandler() {
}
function data($data) {
}
function end($name) {
}
function &get_next($name, $attributes) {
return $this;
}
}
function &array_last(&$array) {
return $array[count($array)-1];
}
//
//function xml_to_library(&$xml) {
// $library = new Library();
// foreach ($xml->book as $book) {
// $library->add_book(xml_to_book($book));
// }
// return $library;
//}
//
//function xml_to_book(&$xml) {
// $book = new Book();
// $book->title = $xml->title;
// foreach ($xml->author as $author) {
// $book->add_author($author);
// }
// $date = $xml->date;
// if (strlen($date) > 0) {
// $book->date = strtotime($date);
// }
// $book->url = $xml->url;
// $book->description = $xml->description;
//
// return $book;
//}
//
?>