<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: 			*/
// +----------------------------------------------------------------------+
// | PHP version 4/5                                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 2004-2010 ARMIA INC                                    |
// +----------------------------------------------------------------------+
// | This source file is a part of iScripts VistaCart                     |
// +----------------------------------------------------------------------+
// | Authors: Jipson<jipson.thomas@armiasystems.com>             		  |
// +----------------------------------------------------------------------+
class XmlparserComponent extends Object
{
	var $params = array(); //Stores the object representation of XML data
    var $root;
    var $global_index = -1;
    function GetChildren($vals, &$i) 
    {
        $children = array(); 
    
    
        if (isset($vals[$i]['value'])) 
            $children['VALUE'] = $vals[$i]['value']; 
    
    
        while (++$i < count($vals))
        { 
            switch ($vals[$i]['type']) 
            { 
                case 'cdata': 
                    if (isset($children['VALUE']))
                        $children['VALUE'] .= $vals[$i]['value']; 
                    else
                        $children['VALUE'] = $vals[$i]['value']; 
                    break;
    
                case 'complete': 
                    if (isset($vals[$i]['attributes'])) {
                        $children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
                        $index = count($children[$vals[$i]['tag']])-1;
    
                        if (isset($vals[$i]['value'])) 
                            $children[$vals[$i]['tag']][$index]['VALUE'] = $vals[$i]['value']; 
                        else
                            $children[$vals[$i]['tag']][$index]['VALUE'] = ''; 
                    } else {
                        if (isset($vals[$i]['value'])) 
                            $children[$vals[$i]['tag']][]['VALUE'] = $vals[$i]['value']; 
                        else
                            $children[$vals[$i]['tag']][]['VALUE'] = ''; 
    		}
                    break; 
    
                case 'open': 
                    if (isset($vals[$i]['attributes'])) {
                        $children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
                        $index = count($children[$vals[$i]['tag']])-1;
                        $children[$vals[$i]['tag']][$index] = array_merge($children[$vals[$i]['tag']][$index],$this->GetChildren($vals, $i));
                    } else {
                        $children[$vals[$i]['tag']][] = $this->GetChildren($vals, $i);
                    }
                    break; 
    
                case 'close': 
                    return $children; 
            } 
        } 
    } 

    function GetXMLTree($xml) 
    { 
        $data = $xml;
       
        $parser = xml_parser_create();
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 
        xml_parse_into_struct($parser, $data, $vals, $index); 
        xml_parser_free($parser);
        
        //print_r($index);
    
        $tree = array(); 
        $i = 0; 
        
        if (isset($vals[$i]['attributes'])) {
    	$tree[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes']; 
    	$index = count($tree[$vals[$i]['tag']])-1;
    	$tree[$vals[$i]['tag']][$index] =    array_merge($tree[$vals[$i]['tag']][$index], $this->GetChildren($vals, $i));
        }
        else
            $tree[$vals[$i]['tag']][] = $this->GetChildren($vals, $i); 
        
        return $tree; 
    } 
    
    function printa($obj) {
        global $__level_deep;
        if (!isset($__level_deep)) $__level_deep = array();
    
        if (is_object($obj))
            print '[obj]';
        elseif (is_array($obj)) {
            foreach(array_keys($obj) as $keys) {
                array_push($__level_deep, "[".$keys."]");
                $this->printa($obj[$keys]);
                array_pop($__level_deep);
            }
        }
        else print implode(" ",$__level_deep)." = $obj\n";
    }
	 /* Constructor for the class
    * Takes in XML data as input( do not include the <xml> tag
    */
    function XmlParserch($input) {
      $xmlp = xml_parser_create();
      xml_parse_into_struct($xmlp, $input, $vals, $index);
      xml_parser_free($xmlp);
      $this->root = strtolower($vals[0]['tag']);
      $this->params = $this->UpdateRecursive($vals);
    }

   /* Returns true if a given variable represents an associative array */
    function is_associative_array( $var ) {
      return is_array( $var ) && !is_numeric( implode( '', array_keys( $var ) ) );
    }

   /* Converts the output of SAX parser into a PHP associative array similar to the 
    * DOM parser output
    */
    function UpdateRecursive($vals) {
      $params = array();
      $this->global_index++;
      //Reached end of array
      if($this->global_index >= count($vals))
        return;

      $tag = strtolower($vals[$this->global_index]['tag']);
	if(isset($vals[$this->global_index]['value'])){
        $value = trim($vals[$this->global_index]['value']);
     }
      $type = $vals[$this->global_index]['type'];

      //Add attributes
      if(isset($vals[$this->global_index]['attributes'])) {
        foreach($vals[$this->global_index]['attributes'] as $key=>$val) {
          $key = strtolower($key);
          $params[$tag][$key] = $val;
        }
      }

      if($type == 'open') {
        $new_arr = array();

        //Read all elements at the next levels and add to an array
        while($vals[$this->global_index]['type'] != 'close' && 
              $this->global_index < count($vals)) {
          $arr = $this->UpdateRecursive($vals);
          if(count($arr) > 0) {
            $new_arr[] = $arr;
          }
        }
        $this->global_index++;
        foreach($new_arr as $arr) {
          foreach($arr as $key=>$val) {
            if(isset($params[$tag][$key])) {
              //If this key already exists
              if($this->is_associative_array($params[$tag][$key])) {
                //If this is an associative array and not an indexed array
                // remove exisiting value and convert to an indexed array
                $val_key = $params[$tag][$key];
                array_splice($params[$tag][$key], 0);
                $params[$tag][$key][0] =  $val_key;
                $params[$tag][$key][] =  $val;
              } else {
                $params[$tag][$key][] =  $val; 
              }
            } else {
              $params[$tag][$key] =  $val;
            }
          }
        }
      }
      else if ($type ==  'complete') {
        if($value != '') 
          $params[$tag]['VALUE'] = $value;
      }
      else {
        $params = array();
      }
      return $params;
    }

    /* Returns the root of the XML data */
    function GetRoot() {
      return $this->root;	
    }

    /* Returns the array representing the XML data */
    function GetData() {
      return $this->params;	
    }
}
?>
