| <?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; |
| //} |
| // |
| ?> |
| |
| |
| |