<?php
/**
 * Help to load, parse and cache XML files.
 *
 * @author Camilo Carromeu <camilo@carromeu.com>
 * @category class
 * @package core
 * @subpackage util
 * @copyright 2005-2017 Titan Framework
 * @license http://www.titanframework.com/license/ BSD License (3 Clause)
 * @see Instance
 */
class Xml
{
	private $array = array ();

	public function __construct ($file)
	{
		if (!file_exists ($file))
			throw new Exception ('Arquivo XML ['. $file .'] não encontrado!');

		$this->array = self::xmlParser (file_get_contents ($file));
	}

	private static function xmlParser ($text)
	{
		$regTag = '/<([a-zA-Z0-9-_]*)(\s.*?)?((>(.*?)<\/\\1>)|(\/>))/s';
		$regDirective = '/([a-zA-Z0-9-_]*)="(.*?)"/s';
		$regComentary = '/<!--(.*)-->/Uis';

		$text = preg_replace ($regComentary, '', $text);

		preg_match_all ($regTag, $text, $matchTag);

		foreach ($matchTag [1] as $key => $value)
		{
			if (preg_match ($regTag, $matchTag [5][$key]))
			{
				if(preg_match_all ($regDirective, $matchTag [2][$key], $matchDirective) != 0)
				{
					array_shift ($matchDirective);

					$aux = array();

					foreach($matchDirective [0] as $keyAux => $valueAux)
						$aux [$valueAux] = $matchDirective [1][$keyAux];

					$array [$value][] = array_merge ($aux, self::xmlParser ($matchTag [5][$key]));
				}
				else
					$array [$value][] = self::xmlParser ($matchTag [5][$key]);
			}
			else
			{
				if(preg_match_all ($regDirective, $matchTag [2][$key], $matchDirective) != 0)
				{
					array_shift ($matchDirective);

					$aux = array();

					foreach ($matchDirective [0] as $keyAux => $valueAux)
						$aux [$valueAux] = $matchDirective [1][$keyAux];

					$matchTag [5][$key] = array_merge ($aux, array ($matchTag [5][$key]));
				}

				if (isset ($array [$value]))
					if (is_array($array [$value]))
						$array [$value][] = $matchTag [5][$key];
					else
						$array [$value] = array ($array [$value], $matchTag [5][$key]);
				else
					if(is_array($matchTag [5][$key]))
						$array [$value][] = $matchTag [5][$key];
					else
						$array [$value] = $matchTag [5][$key];
			}
		}

		if (strnatcmp (phpversion (), '5.3.4') >= 0)
			$table = get_html_translation_table (HTML_ENTITIES, ENT_COMPAT, 'UTF-8');
		else
		{
			$aux = get_html_translation_table (HTML_ENTITIES);

			$table = array ();

			foreach ($aux as $key => $value)
				$table [utf8_encode ($key)] = utf8_encode ($value);
		}

		$table = array_flip ($table);

		return self::decode ($array, $table);
	}

	public function getArray ()
	{
		return $this->array;
	}

	public function getTag ($tag, $subtag = NULL, $key = 0, $array = NULL)
	{
		if($array == NULL)
			$array = $this->getArray();

		if( $subtag !== NULL && is_array ($array[$tag][$key]) && array_key_exists ($subtag, $array[$tag][$key]) )
			return $array[$tag][$key][$subtag];

		if( $subtag === NULL && is_array ($array) && array_key_exists ($tag, $array) )
			return $array[$tag];

		if ( is_array (reset($array)) )
			return $this->getTag ($tag, $subtag, $key, reset($array));

		return FALSE;
	}

	public static function decode ($array, $table)
	{
		foreach ($array as $key => $cell)
			if (is_array ($cell))
				$array [$key] = self::decode ($cell, $table);
			else
				$array [$key] = strtr ($cell, $table);

		return $array;
	}
}
?>