<?php
/**
 * Description of Clase_SlcXml
 *
 * @author Abner
 */
//require_once('xmlseclibs/xmlseclibs.php');
//require_once('../Clases/xmlseclibs/XmlseclibsAdapter.php');

class Clase_SlcXml {
    
      /**
       * firmar string como xml
       * @param string $sXml
       * @param array $aKey array
       * @param array $options
       * @return type
       */
      public function singXmlString($sXml, $aKey, $options=array()){
            $oDoc = new DOMDocument('1.0', 'ISO-8859-1'); 
            $oDoc->formatOutput = FALSE; 
            $oDoc->preserveWhiteSpace = TRUE;
            
            if (isset($options['ruta'])){
                if (isset($options['archivo'])){
                    $aResp['archivo']=$options['ruta'].$options['archivo'];
                }else{
                    $aResp['archivo']=$options['ruta'].date('Ymd-His').'_xml_sign.xml';
                }
                $bEsTemp=false;
            }else{
                $aResp['archivo']=RUTA_ARCHIVOS_TMP.date('Ymd-His').'_xml_sign.xml';
                $bEsTemp=true;
            }
            
            if (file_exists($aResp['archivo'])) {
                    unlink($aResp['archivo']);
            }
            
            $oDoc->loadXML($sXml);
            /*
            $archivoDatos = fopen($aResp['archivo'], 'w');
            fwrite($archivoDatos, $sXml);
            fclose($archivoDatos);
            $aResp['archivo']=str_replace('.xml','.txt',$aResp['archivo']);
            
            $oDoc->save($aResp['archivo']);
            exit();
             */
            $objDSig = new XMLSecurityDSig(FALSE);
            $objDSig->setCanonicalMethod(XMLSecurityDSig::C14N);
            
            $options['prefix'] = (!isset($options['prefix']))?'':$options['prefix'];
            $options['prefix_ns'] =  (!isset($options['prefix_ns']))?'':$options['prefix_ns'];
            $options['force_uri'] = (!isset($options['force_uri']))?TRUE:$options['force_uri'];
            $options['id_name'] = (!isset($options['id_name']))?'ID':$options['id_name'];
            $options['uri'] = (!isset($options['uri']))?NULL:$options['uri'];
            $options['overwrite'] =(!isset($options['overwrite']))?false:$options['overwrite'];;
            
            $options['node']=(!isset($options['node']))?NULL:$options['node'];
            if ($options['node'] != NULL){
                $oNodeDocto=$oDoc->getElementsByTagName($options['node'])->item(0);
                $objDSig->addReference($oNodeDocto, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), $options);
            }else{
                $objDSig->addReference($oDoc, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), $options);
            }

            $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
            
            $objKey->loadKey($aKey["pkey"]);
            $objDSig->add509Cert($aKey["cert"]);
            $objDSig->sign($objKey, $oDoc->documentElement);
           
            $oDoc->save($aResp['archivo']);
            $aResp['contenido']=str_replace('<?xml version="1.0"?>'.chr(10), '',file_get_contents( $aResp['archivo']));
            if ($bEsTemp){
                unlink($aResp['archivo']);
            }
            return $aResp;
      }
      
      public function verifySignXmlString($sXml){
            $doc = new DOMDocument();
            $doc->loadXML($sXml);
            $objXMLSecDSig = new XMLSecurityDSig();
            $aRet['success']=true;
            $objXMLSecDSig->idKeys = array('ID');

            $objDSig = $objXMLSecDSig->locateSignature($doc);
            if (! $objDSig) {
                $aRet['success']=false;
                $aRet['error']="No se pudo localizar el nodo";
            }

            $retVal = $objXMLSecDSig->validateReference();
            if (! $retVal) {
                $aRet['success']=false;
                $aRet['error']="La referencia no es válida";
            }
            return $aRet;
      }
      
      public function getArrayFromXml($xmlstr) {
            $doc = new DOMDocument();
            $doc->loadXML($xmlstr);
            return $this->domnode_to_array($doc->documentElement);
      }
      
      public function domnode_to_array($node) {
            $output = array();
            
            switch ($node->nodeType) {
                case XML_CDATA_SECTION_NODE:
                case XML_TEXT_NODE:
                    $output = trim($node->textContent);
                break;
                case XML_ELEMENT_NODE:
                    for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) { 
                        $child = $node->childNodes->item($i);
                        $v = $this->domnode_to_array($child);
                        
                        if(isset($child->tagName)) {
                            $t = $child->tagName;
                            if(!isset($output[$t])) {
                                $output[$t] = array();
                            }
                            $output[$t][] = $v;
                        }else if ($v != '') {
                             $output = (string) $v;
                        }
                     }
                     
                     if(is_array($output)) {
                        if($node->attributes->length) {
                             $a = array();
                             foreach($node->attributes as $attrName => $attrNode) {
                                $a[$attrName] = (string) $attrNode->value;
                             }
                             $output['@attributes'] = $a;
                        }
                        
                        foreach ($output as $t => $v) {
                            if(is_array($v) && count($v)==1 && $t!='@attributes') {
                                $output[$t] = $v[0];
                            }
                        }
                    }
                break;
            }
            return $output;
      }   
/*********** ESTE SACA EL PFX *************************************************/      
      public function staticGetArrayPrivateKey($sPathFilePrivateSing, $sPassword){
            $sPkcs12 = file_get_contents($sPathFilePrivateSing);
            $aKey = array();
            openssl_pkcs12_read($sPkcs12, $aKey, $sPassword);
            return $aKey;
      }
}
?>