<?php

/*
   +----------------------------------------------------------------------+
   | XML Parsing Class                                                    |
   | Author: Adam Goldberg                                                |
   +----------------------------------------------------------------------+
   | Copyright (c) 2008-2009 Adam J Goldberg                              |
   | This file is part of Lifebox.                                        |
   |                                                                      |
   | Lifebox is free 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 3 of the License, or    |
   | (at your option) any later version.                                  |
   |                                                                      |
   | Lifebox 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 Lifebox.  If not, see <http://www.gnu.org/licenses/>.     |
   +----------------------------------------------------------------------+
   | Parse XML Structure						  |
   +----------------------------------------------------------------------+
	function XML ($file) {
	function XMLToArray($get_attributes = 1, $priority = 'tag') {
   +----------------------------------------------------------------------+
*/

class XML {

	var $file;

	/*****************************************************************
	 * Constructor
         *****************************************************************/
	function XML ($file) {
		$this->file = $file;
	}

	/*****************************************************************
	 * Convert XML file to an array and return it
         *****************************************************************/
	function XMLToArray($get_attributes = 1, $priority = 'tag') {
	    $url = $this->file;
	    $contents = "";
	    if (!function_exists('xml_parser_create'))
	    {
		return array ();
	    }
	    $parser = xml_parser_create('');
	    if (!($fp = @ fopen($url, 'rb')))
	    {
		return array ();
	    }
	    while (!feof($fp))
	    {
		$contents .= fread($fp, 8192);
	    }
	    fclose($fp);
	    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
	    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
	    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
	    xml_parse_into_struct($parser, trim($contents), $xml_values);
	    xml_parser_free($parser);
	    if (!$xml_values)
		return; //Hmm...
	    $xml_array = array ();
	    $parents = array ();
	    $opened_tags = array ();
	    $arr = array ();
	    $current = & $xml_array;
	    $repeated_tag_index = array (); 
	    foreach ($xml_values as $data)
	    {
		unset ($attributes, $value);
		extract($data);
		$result = array ();
		$attributes_data = array ();
		if (isset ($value))
		{
		    if ($priority == 'tag')
			$result = $value;
		    else
			$result['value'] = $value;
		}
		if (isset ($attributes) and $get_attributes)
		{
		    foreach ($attributes as $attr => $val)
		    {
			if ($priority == 'tag')
			    $attributes_data[$attr] = $val;
			else
			    $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
		    }
		}
		if ($type == "open")
		{ 
		    $parent[$level -1] = & $current;
		    if (!is_array($current) or (!in_array($tag, array_keys($current))))
		    {
			$current[$tag] = $result;
			if ($attributes_data)
			    $current[$tag . '_attr'] = $attributes_data;
			$repeated_tag_index[$tag . '_' . $level] = 1;
			$current = & $current[$tag];
		    }
		    else
		    {
			if (isset ($current[$tag][0]))
			{
			    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
			    $repeated_tag_index[$tag . '_' . $level]++;
			}
			else
			{ 
			    $current[$tag] = array (
				$current[$tag],
				$result
			    ); 
			    $repeated_tag_index[$tag . '_' . $level] = 2;
			    if (isset ($current[$tag . '_attr']))
			    {
				$current[$tag]['0_attr'] = $current[$tag . '_attr'];
				unset ($current[$tag . '_attr']);
			    }
			}
			$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
			$current = & $current[$tag][$last_item_index];
		    }
		}
		elseif ($type == "complete")
		{
		    if (!isset ($current[$tag]))
		    {
			$current[$tag] = $result;
			$repeated_tag_index[$tag . '_' . $level] = 1;
			if ($priority == 'tag' and $attributes_data)
			    $current[$tag . '_attr'] = $attributes_data;
		    }
		    else
		    {
			if (isset ($current[$tag][0]) and is_array($current[$tag]))
			{
			    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
			    if ($priority == 'tag' and $get_attributes and $attributes_data)
			    {
				$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
			    }
			    $repeated_tag_index[$tag . '_' . $level]++;
			}
			else
			{
			    $current[$tag] = array (
				$current[$tag],
				$result
			    ); 
			    $repeated_tag_index[$tag . '_' . $level] = 1;
			    if ($priority == 'tag' and $get_attributes)
			    {
				if (isset ($current[$tag . '_attr']))
				{ 
				    $current[$tag]['0_attr'] = $current[$tag . '_attr'];
				    unset ($current[$tag . '_attr']);
				}
				if ($attributes_data)
				{
				    $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
				}
			    }
			    $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
			}
		    }
		}
		elseif ($type == 'close')
		{
		    $current = & $parent[$level -1];
		}
	    }
	    return ($xml_array);
	}
}
