<?php

/**
 * Copyright 2005-2017 de Solis Soluções Livres Ltda.
 *
 * Este arquivo é parte do programa Gnuteca.
 *
 * O Gnuteca é um software de propriedade da SOLIS, sendo desenvolvido
 * e mantido exclusivamente por esta empresa.
 *
 * A licença de uso está disponível mediante aquisição exclusiva junto à
 * SOLIS. A licença é concedida sem caráter de exclusividade ao licenciado.
 * Os direitos de uso são perpétuos.
 *
 * Embora os códigos fontes sejam fornecidos, o software é de propriedade
 * da SOLIS, não sendo permitido ao adquirente da licença a sua revenda,
 * empréstimo ou cessão (onerosa ou não) à terceiros. Também não é permitido,
 * a qualquer título e tempo, promover no software qualquer tipo de alienação,
 * reprodução, distribuição, divulgação, registro, licenciamento, transferência
 * ou qualquer outro ato que prejudique ou comprometa os direitos de propriedade
 * de software, o nome e a imagem da sua proprietária e do próprio software,
 * além de configurar concorrência à SOLIS.
 *
 * O licenciado, com o acesso ao código fonte do software, terá o direito de
 * promover mudanças no respectivo código. No entanto, nas situações em que ele
 * contar com o suporte oficial prestado pela SOLIS, não poderá promover mudanças
 * no código fonte, sob pena de perda do referido suporte.
 *
 * Para conhecer em detalhes o Termo de Licenciamento do Software Gnuteca
 * leia o arquivo “LICENCA.txt” disponível junto ao código deste software.
 * 
 * 
 * Class
 *
 *
 *
 *
 *
 **/

class GXML
{

    private $return     = false,
            $array      = false,
            $firstTag   = 'gnuteca3',
            $xml        = '';


    function __construct($var, $type = 'xmlToPhp', $encoding = "ISO-8859-1")
    {
        if(strtoupper($type) == 'XMLTOPHP')
        {
            $this->xmlToPhp($var, $this->return);
        }
        elseif(strtoupper($type) == 'PHPTOXML')
        {
            $xmlStart = '<?xml version="1.0" encoding="'. $encoding .'" standalone="yes"?><'. $this->firstTag .'></'. $this->firstTag .'>';

            $this->xml = new SimpleXMLElement($xmlStart);
            $this->arrayToXml($var, $this->xml);
        }
    }


    /**
     * Retona o conteudo
     *
     * @return unknown
     */
    public function getResult()
    {
        return $this->return;
    }


    /**
     * Este metodo foi implementado para transformar o XML do Z3950 para PHP
     *
     */
    function makeAttributes($attributes, $tag)
    {
        $attributes = str_replace("  ", " ", $attributes);
        $attributes = preg_replace('/([\'"]{1}) ([\'"]{1})/', '""', $attributes);
        $attributes = explode(" ", $attributes);

        $returnAttr = array();

        foreach ($attributes as $attr)
        {
            preg_match('/^([a-zA-Z0-9]{1,})=?([\'"]{0,1})?([\w:\/\. ]{0,})?([\'"]{0,1})$/', $attr, $match);
            if(strlen($match[1]) && $match[1] != substr($tag,strlen($tag)-1, strlen($tag)))
            {
                $returnAttr[$match[1]] = $match[3];
            }
        }

        return $returnAttr;
    }


    /**
     * Este metodo foi implementado para transformar o XML do Z3950 para PHP
     *
     * @param unknown_type $xml
     * @param unknown_type $result
     * @return unknown
     */
    function xmlToPhp($xml, &$result)
    {
        $x = 0;
        while(strlen($xml))
        {
            // CAPTURA A TAG
            preg_match('/^<([a-zA-Z0-9]{1,})/', $xml, $tag);
            $tag = trim($tag[1]);

            if(!strlen($tag))
            {
                return $xml;
            }

            // REMOVE ESPEÇOS, QUEBRA DE LINHA, TABS
            $xml = str_replace(array("\n", "\t", "\r"), "", $xml);
            $xml = preg_replace('/>[ ]{1,}</', '><', $xml);

            if(!strlen($xml))
            {
                return $xml;
            }

            $xmlExplode = explode("</$tag>", $xml);

            $x = 0;
            foreach ($xmlExplode as $index => $xml)
            {
                $xml = trim($xml);
                if(!strlen($xml))
                {
                    continue;
                }

                $xml.= "</$tag>";

                $result[$tag][$x] = null;

                // CAPTURA OS ATRIBUTOS E O CONTEUDO
                preg_match('/<'.$tag.'?([a-zA-Z0-9="\':\/\. ]{1,})>(.*)<\/'. $tag .'>/', $xml, $match);
                $xml = preg_replace('/<'.$tag.'?([a-zA-Z0-9="\':\/\. ]{1,})>(.*)<\/'. $tag .'>/', '', $xml);

                $attributes = $match[1];
                $content    = $match[2];

                // TRABALHA OS ATRIBUTOS
                $attributes = $this->makeAttributes($attributes, $tag);

                if(strlen($content))
                {
                    $content = $this->xmlToPhp($content, $result[$tag][$index]);
                }

                if(!is_array($result[$tag][$x]))
                {
                    $result[$tag][$x]['_content_'] = is_string($content) ? $content : $result[$tag]->content ;
                }

                $result[$tag][$x]['_attributes_']   = $attributes;

                $x++;
            }
        }
    }


    public function arrayToXml($array, $sun = false)
    {

        if(is_array($array) || is_object($array))
        {
            foreach ($array as $tagName => $content)
            {
                if(is_array($content) || is_object($content))
                {
                    $sunX = $sun->addChild($tagName);
                    $this->arrayToXml($content, $sunX);
                    continue;
                }

                $sun->addChild($tagName, $content);
            }
        }
        else
        {
            $array = is_bool($array) ? ($array ? "true" : "false") : "$array";
            $sun->addChild($array, $array);
        }

        $this->return = str_replace(array("\n", "\t", "\r"), "", $this->xml->asXML());
    }

}// final da classe