<?php


#*****************************************************************************
#
# news.php
#
# Author: 		Wayne Beaton
# Date:			2005-11-07
#
# Description: Use the get_news($newsfile) function in this file to generate the html 
# equivalent of the provided RSS file. 
#
#****************************************************************************
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/xml_sax_parsing.php");

/*
 * This global variable defines the location of the 'articles' root directory.
 * The metadata for the articles is located in this directory. All articles
 * also hang off this directory.
 */
$events_root = $_SERVER['DOCUMENT_ROOT'] . "/community/events/";

function & get_events() {
	$events_file = $GLOBALS['events_root'] . "events.xml";
	$handler = new EventFileHandler($listing);
	parse_xml_file($events_file, $handler);
	return $handler->events;
}

/*
 * This class is used by the SAX parser to start parsing
 * a events file.
 */
class EventFileHandler extends XmlFileHandler {
	var $events;

	function EventFileHandler(& $listing) {
		parent :: XmlFileHandler();
	}

	/*
	 * This method returns the root handler for a event file
	 * The root handler essentially represents the file itself
	 * rather than any actual element in the file. The returned
	 * element handler will deal with any elements that may occur
	 * in the root of the XML file.
	 */
	function get_root_element_handler() {
		$retVal = new EventRootHandler($this->listing);
		return $retVal;
	}	
	
	function end_root_element_handler($handler) {
		$this->events = & $handler->events;
	}
}

/*
 * The EventRootHandler class takes care of the root element 
 * in the file. This handler doesn't correspond to any particular
 * element that may occur in the XML file. It represents the file
 * itself and must deal with any elements that occur at the root
 * level in that file.
 */
class EventRootHandler extends XmlElementHandler {
	var $events;

	/*
	 * This method handles the <events>...</events> element.
	 */
	function & get_events_handler($attributes) {
		$retVal = new EventsHandler($this->listing);
		return $retVal;
	}
	
	 function end_events_handler($handler) {
	 	$this->event = & $handler->events;
	 }
}

/*
 * The EventsHandler takes care of the <events> element. This
 * element is the root element in the file and is used to contain
 * all the events.
 * 
 * <events>
 * 		<event>...</event>
 * 		<event>...</event>
 * 		<event>...</event>
 * </events>
 */
class EventsHandler extends XmlElementHandler {
	var $events = array();

	/*
	 * This method handles the <event>...</event> element.
	 */
	function & get_event_handler(& $attributes) {
		$retVal = new EventHandler($this->listing, $attributes);
		return $retVal;
	}
	
	/*
	 * When the event handler is done gathering information about
	 * the event, add the event to the listing.
	 */
	function end_event_handler(& $handler) {
		array_push($this->events, $handler->event);
	}
}
/*
 * The EventHandler takes care of the <event> element. This
 * element may occur multiple times inside the <events> tag.
 * 
 * <events>
 * 		<event id="...">
 * 			<name>...</name>
 * 			<description>...</description>
 * 		</event>
 * 		<event>...</events>
 * 		<event>...</events>
 * </events>
 */
class EventHandler extends XmlElementHandler {
	var $event;

	function EventHandler(& $listing, & $attributes) {
		$this->event = new Event();
	}
	
	/*
	 * This method handles the <name>...</name> element.
	 */
	function & get_name_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "name");
		return $retVal;
	}
	
	/*
	 * This method handles the <description>...</description> element.
	 */
	function & get_description_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "description");
		return $retVal;
	}
	
	/*
	 * This method handles the <location>...</location> element.
	 */
	function & get_location_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "location");
		return $retVal;
	}
	
	/*
	 * This method handles the <link>...</link> element.
	 */
	function & get_link_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "link");
		return $retVal;
	}
	
	/*
	 * This method handles the <priority>...</priority> element.
	 */
	function & get_priority_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "priority");
		return $retVal;
	}	
	
	/*
	 * This method handles the <start-date>...</start-date> element.
	 */
	function & get_start_date_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "start_date");
		return $retVal; 
	}
	
	function end_start_date_handler($handler) {
		$this->event->start_date = strtotime($this->event->start_date);
	}
		
	/*
	 * This method handles the <end-date>...</end-date> element.
	 */
	function & get_end_date_handler($attributes) {
		$retVal = new SimplePropertyHandler($this->event, "end_date");
		return $retVal;
	}
	
	function end_end_date_handler($handler) {
		$this->event->end_date = strtotime($this->event->end_date);
	}
}
?>


