WSCOMUN  2.1.2
Web Services Comunes para PHP/GVHidra
RTSOAClient.php
1 <?php
2 namespace WSCOMUN\RTSOA;
3 
5 use Exception;
6 use SoapClient;
7 use DOMDocument;
8 //use Exception;
9 
10 
14 require_once('ComposerRTSOA.php');
21 {
22 
23  const NS = 'http://services.v1.ws.web.mastin.tra.dgm.gva.es/';
24 
28  private $serviceParams = array(
29  'soap_version' => SOAP_1_1, //SOAP 1.2
30  'user_agent' => 'WSSSoapClient',
31  'exceptions' => true,
32  'exception' => 0,
33  // 'cache_wsdl' => self::$MYSOAPOP_WSDL_CACHE,
34  'trace' => 1 // self::$MYSOAPOP_TRACE
35  );
36 
38  private $wsURLWSDL;
39 
40 
46  public function __construct($wsURLWSDL)
47  {
48  $this->wsURLWSDL = $wsURLWSDL;
49  }
50 
51 
52  private function getTipoRegistro($esRegistroEntrada) {
53  if ($esRegistroEntrada) {
54  return "E";
55  }
56  return "S";
57  }
58  private function codificarBooleano($valor) {
59  if ($valor) {
60  return "S";
61  }
62  return "N";
63  }
64 
65 
72  private function lanzaDispatcher($xmlEntrada, $vDocs)
73  {
74  try
75  {
76  // Instancia y configura el cliente SOAP
77  $clienteWS = new \SoapClient($this->wsURLWSDL, $this->serviceParams);
78  $lanzaDispatcher = new \ArrayObject();
79  $lanzaDispatcher->append(new \SoapVar(base64_encode($xmlEntrada), XSD_STRING, null, null,'xmlEntrada', null));
80  if (!empty($vDocs)) {
81  for($iDoc=0; $iDoc < sizeof($vDocs); $iDoc++) {
82  $sDocB64 = base64_encode($vDocs[$iDoc]);
83  $lanzaDispatcher->append(new \SoapVar($sDocB64, XSD_STRING,null,null,'documentos', null));
84  }
85  }
86 
87  $miSoapRQ = new \SoapVar($lanzaDispatcher, SOAP_ENC_OBJECT,null,null,'lanzaDispatcher', self::NS);
88  $respuesta = $clienteWS->lanzaDispatcher($miSoapRQ);
89 
90  return $respuesta; // Nunca se ejecuta
91  }
92  catch (\Exception $e)
93  {
94  // Si se ha producido el error antes de tener disponible el cliente, vuelve a lanzar la exception para su tratamiento externo
95  if (!isset($clienteWS)) {
96  throw $e;
97  }
98 
99  // Obtiene el array con la respuesta o lanza excepcion
100  $vRetorno = $this->tratarInnerException($clienteWS, $e);
101 
102  // Convierte en el objeto apropiado, y lo devuelve
103  //$oRetorno = creacionRegistroDepartamentalResponse::fromSoap($vRetorno);
104  return $vRetorno;
105  }
106  }
107 
108 
116  public function crearRegistro($esRegistroEntrada, $oCrearReg, $vDocs)
117  {
118  // Prepara la información
119  $tipoRegistro = $this->getTipoRegistro($esRegistroEntrada);
120 
121  // Convierte el objeto a texto
122  $strCrearRegContent = $oCrearReg->generateString();
123 
124  // Codifica la petición
125  $xmlEntrada = <<<XML
126 <?xml version="1.0" encoding="UTF-8"?>
127 <API_CREAREGISTRO type="$tipoRegistro" formato="MASTIN" identificador="" version="3.0" idioma_error="" validarFirma="">
128 $strCrearRegContent
130 XML;
131 
132  return $this->lanzaDispatcher(utf8_encode($xmlEntrada), $vDocs);
133  }
134 
135 
146  public function consultarRegistro($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $devolverDocumentos, $docFirmados)
147  {
148  // Codifica los parametros de entrada
149  $tipoRegistro = $this->getTipoRegistro($esRegistroEntrada);
150  $devolverDocumentos = $this->codificarBooleano($devolverDocumentos);
151  $docFirmados = $this->codificarBooleano($docFirmados);
152 
153  // Codifica la petición
154  $xmlEntrada = <<<XML
155 <?xml version="1.0" encoding="UTF-8"?>
156 <API_CONSULTAREGISTRO type="$tipoRegistro" formato="MASTIN" identificador="" version="3.0" idioma_error="" validarFirma="">
157  <DATOS_CONSULTA>
158  <NUMERO_REGISTRO>$numeroRegistro</NUMERO_REGISTRO>
159  <FECHA_REGISTRO>$fechaRegistro</FECHA_REGISTRO>
160  <CLAVE_CONSULTA>$claveConsulta</CLAVE_CONSULTA>
161  <DEVOLVER_DOCUMENTOS>$devolverDocumentos</DEVOLVER_DOCUMENTOS>
162  <DOCUMENTOS_FIRMADOS>$docFirmados</DOCUMENTOS_FIRMADOS>
163  </DATOS_CONSULTA>
164 </API_CONSULTAREGISTRO>
165 XML;
166 
167  return $this->lanzaDispatcher(utf8_encode($xmlEntrada), null);
168  }
169 
179  public function consultarDocumento($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $tipoDocumento = 'T')
180  {
181  // Codifica los parametros de entrada
182  $tipoRegistro = $this->getTipoRegistro($esRegistroEntrada);
183 
184  // Codifica la petición
185  $xmlEntrada = <<<XML
186 <?xml version="1.0" encoding="UTF-8"?>
187 <API_CONSULTADOCUMENTO type="$tipoRegistro" formato="MASTIN" identificador="" version="1.0" idioma_error="" validarFirma="">
188  <DATOS_CONSULTA>
189  <NUMERO_REGISTRO>$numeroRegistro</NUMERO_REGISTRO>
190  <FECHA_REGISTRO>$fechaRegistro</FECHA_REGISTRO>
191  <CLAVE_CONSULTA>$claveConsulta</CLAVE_CONSULTA>
192  <TIPO_DOCUMENTO>$tipoDocumento</TIPO_DOCUMENTO>
193  </DATOS_CONSULTA>
194 </API_CONSULTADOCUMENTO>
195 XML;
196 
197  return $this->lanzaDispatcher(utf8_encode($xmlEntrada), null);
198  }
199 
200 
216  public function registrarAcuse($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $expediente,
217  $nombreFichero, $codDocumento, $descDocumento, $asocioExpediente,
218  $entidadCertificadora, $formatoFirma, $valorFirma, $contenidoDoc)
219  {
220  // Codifica los parametros de entrada
221  $tipoRegistro = $this->getTipoRegistro($esRegistroEntrada);
222  $asocioExpediente = $this->codificarBooleano($asocioExpediente);
223 
224  // Codifica la petición
225  $xmlEntrada = <<<XML
226 <?xml version="1.0" encoding="UTF-8"?>
227 <API_REGISTRAACUSE type="$tipoRegistro" formato="MASTIN" identificador="" version="" idioma_error="" validarFirma="">
228  <DATOS_A_CONSULTAR>
229  <DATOS_CONSULTA>
230  <NUMERO_REGISTRO>$numeroRegistro</NUMERO_REGISTRO>
231  <FECHA_REGISTRO>$fechaRegistro</FECHA_REGISTRO>
232  <CLAVE_CONSULTA>$claveConsulta</CLAVE_CONSULTA>
233  </DATOS_CONSULTA>
235  <NOMBRE_FICHERO>$nombreFichero</NOMBRE_FICHERO>
236  <CODIGO_DOCUMENTO>$codDocumento</CODIGO_DOCUMENTO>
237  <DESCRIPCION_DOCUMENTO>$descDocumento</DESCRIPCION_DOCUMENTO>
238  <ASOCIO_EXPEDIENTE>$asocioExpediente</ASOCIO_EXPEDIENTE>
239  <TIPO_DOCUMENTO>R</TIPO_DOCUMENTO>
241  <ENTIDAD_CERTIFICADORA>$entidadCertificadora</ENTIDAD_CERTIFICADORA>
242  <FORMATO_FIRMA>$formatoFirma</FORMATO_FIRMA>
243  <VALOR_FIRMA>$valorFirma</VALOR_FIRMA>
244  </FIRMA_DOCUMENTO>
246  <EXPEDIENTE></EXPEDIENTE>
247  </DATOS_A_CONSULTAR>
248 </API_REGISTRAACUSE>
249 XML;
250 
251  // Crea un array con el documento
252  $vDocs = array($contenidoDoc);
253 
254  return $this->lanzaDispatcher(utf8_encode($xmlEntrada), $vDocs);
255  }
256 
257 
258 
259 
267  private function tratarInnerException($clienteWS, $e)
268  {
269  // Comprobamos si estamos ante excepcion MTOM
270  $mensaje = $e->getMessage();
271  $mensaje = trim(strtolower($mensaje));
272  switch ($mensaje)
273  {
274  case 'looks like we got no xml document' :
275  // Obtiene la respuesta
276  $response = $clienteWS->__getLastResponse();
277 
278  $vRetorno = $this->tratarMTOMEstandar($response);
279  return $vRetorno;
280  break;
281 
282  default:
283  // Por defecto, vuelve a lanzar la excepcion
284  throw $e;
285  break;
286  }
287  }//tratarInnerException
288 
289 
299  protected function tratarMTOMEstandar($response, $itemToReturn = null)
300  {
301  //Comprobamos si existen anexos
302  $mimeBoundary = '--MIME_Boundary';//Probamos con --MIME Boundary hasta mejora de detección
303  $vBodyResponse = explode($mimeBoundary, $response); //Fraccionamos la respuesta.
304  $numElementos = count($vBodyResponse);
305 
306  $srcData='';
307  if ($numElementos<=1)
308  {
309  $mimeBoundary = '--uuid:';//Probamos de nuevo con --uuid hasta mejora de detección
310  $vBodyResponse = explode($mimeBoundary, $response); //Fraccionamos la respuesta.
311  $numElementos = count($vBodyResponse);
312  $srcData = $response;
313  }
314  elseif ($numElementos>1)
315  {
316  $srcData = $vBodyResponse[1];
317  }
318 
319  $vRespuesta = array();
320  ini_set('pcre.backtrack_limit','100000000'); //Valor por defecto = 1000000 (aprox. 100KBytes)
321  preg_match("/<[a-z]*:Envelope.*?>(.*)<\/[a-z]*:Envelope>/is", $srcData, $vRespuesta);
322  if (preg_last_error()!=PREG_NO_ERROR)
323  {
324  //Si falta intentamos obtener el anexo con otro sistema
325  $start = stripos($srcData, ':Envelope');
326  $start = strripos($srcData, '<', $start - strlen($srcData));
327  $end = strripos($srcData, ':Envelope>');
328  $cadenaRespuesta = substr($srcData, $start, $end);
329  }
330  elseif (count($vRespuesta)<1)
331  {
332  throw new Exception('No puede ubicarse RESPONSE dentro de MTOM');
333  }
334  else
335  {
336  $cadenaRespuesta = $vRespuesta[0];
337  unset($vRespuesta);
338  }
339 
340  $dom = new DOMDocument('1.0');
341  $dom->loadXML($cadenaRespuesta);//Cargamo el XML
342  $xpath = new \DOMXpath($dom);
343  $vNodoRespuesta = $xpath->query("/*[local-name()='Envelope']/*[local-name()='Body']/*/*[local-name()='respuesta']");
344  $subStrXpath='';
345  if (!empty($itemToReturn))
346  {
347  $subStrXpath = "/*[local-name()='{$itemToReturn}']";
348  }
349  $vNodoRespuesta = $xpath->query("/*[local-name()='Envelope']/*[local-name()='Body']/*".$subStrXpath);
350  $nodoRespuesta = $vNodoRespuesta->item(0);
351 
352  if ($numElementos>0)
353  {
354  $oMimeParser = new WSCMimeParser();
355  $oMime = $oMimeParser->decodeMTOM($vBodyResponse);
356  unset($oMime->body);$oMime->body=null;gc_collect_cycles();
357 
358  $vNodoInclude = $xpath->query("//*[local-name()='Include']");
359  foreach ($vNodoInclude as $nodoItem)//Recorremos los nodosXML include y sustituidmos por el contenido
360  {
361  $subIdBuscado = (string) $nodoItem->getAttribute('href');
362  $subIdBuscado = urldecode($subIdBuscado);
363  $idBuscado = '<'.substr($subIdBuscado, 4).'>';
364  foreach ($oMime->parts as &$parte)
365  {
366  if ($idBuscado == ($parte->headers['content-id']))
367  {
368  if ( strtolower(substr($parte->mimetype, 0, 4)) !== 'text')//Si el tipo mime no es texto, convertimos a B64 por ser contenido binario
369  {
370  $parte->body = base64_encode($parte->body);
371  }
372  $textNode = $dom->createTextNode(($parte->body));
373  $nodoItem->parentNode->replaceChild($textNode, $nodoItem);
374  }
375  }//Fin for partes
376  }//Fin for nodos
377  }
378 
379  return $this->xml_to_object($nodoRespuesta);
380  }//tratarMTOMEstandar
381 
382 
388  protected function xml_to_object(&$root)
389  {
390  // Si no hay respuesta, devuelve una respuesta vacia
391  $vNodeRespuesta = $root->getElementsByTagName('respuesta');
392  if ($vNodeRespuesta->length == 0)
393  {
394  return new RTSOAResponse();
395  }
396 
397  // Accede al nodo 'respuesta', y crea el objeto respuesta
398  $nodeRespuesta = $vNodeRespuesta->item(0);
399  $oResp = RTSOAResponse::fromDOM($nodeRespuesta);
400 
401  return $oResp;
402  }//xml_to_object
403 
404 
405 
406 
412  static public function CrearFicheroAviso($texto) {
413  // Codifica la petición
414  $xmlEntrada = <<<XML
415 <?xml version="1.0" encoding="UTF-8"?>
416 <AVISO_NOTIFICACION_GRED>
417  <TITULO_AVISO>SIN USO</TITULO_AVISO>
418  <TEXTO_AVISO>$texto</TEXTO_AVISO>
419 </AVISO_NOTIFICACION_GRED>
420 XML;
421 
422  return utf8_encode($xmlEntrada);
423  }
424 
425 
431  static public function CrearFicheroOficioRemision($texto) {
432  // Codifica la petición
433  $xmlEntrada = <<<XML
434 <?xml version="1.0" encoding="UTF-8"?>
435 <OFICIO_REMISION_GRED>
436  <TITULO_OFICIO_REMISION>SIN USO</TITULO_OFICIO_REMISION>
437  <TEXTO_OFICIO_REMISION>$texto</TEXTO_OFICIO_REMISION>
438 </OFICIO_REMISION_GRED>
439 XML;
440 
441  return utf8_encode($xmlEntrada);
442  }
443 
444 }//End RTSOAClient
445 
446 
447 
448 
449 
450 
451 
452 
453 
454 class RTSOAResponse {
455 
456  // Resultado
457  private $_resultado = null;
458  private $_hasResultado = false;
459  public function setResultado($value) {
460  $this->_resultado = $value;
461  $this->_hasResultado = ($value !== null);
462  }
463  public function hasResultado() {
464  return $this->_hasResultado;
465  }
466  public function getResultado() {
467  return $this->_resultado;
468  }
469 
470  // Document
471  private $_document = array();
472  private $_hasDocument = false;
473  public function replaceArrayDocument($value) {
474  $this->_document = $value;
475  $this->_hasDocument = (isset($this->_document) && !empty($this->_document));
476  }
477  public function retrieveArrayDocument() {
478  return $this->_document;
479  }
480  public function addDocument($value) {
481  array_push($this->_document, $value);
482  $this->_hasDocument = (isset($this->_document) && !empty($this->_document));
483  }
484  public function hasDocument() {
485  return $this->_hasDocument;
486  }
487  public function getDocument($index) {
488  return $this->_document[$index];
489  }
490  public function countDocument() {
491  return count($this->_document);
492  }
493 
494 
495  static public function fromDOM($nodoRespuesta) {
496  $newItem = new RTSOAResponse();
497 
498  // Si hay un resultado en la respuesta, lo incluye
499  $vNodeResultado = $nodoRespuesta->getElementsByTagName('resultado');
500  if ($vNodeResultado->length > 0)
501  {
502  $newItem->setResultado( $vNodeResultado->item(0)->nodeValue );
503  }
504 
505  // Recorre los documentos añadiendolos
506  $vNodeDocumentos = $nodoRespuesta->getElementsByTagName('documentos');
507  if ($vNodeDocumentos->length > 0)
508  {
509  foreach($vNodeDocumentos as $nDoc) {
510  $newItem->addDocument( RTSOADocumentResponse::fromDOM($nDoc) );
511  }
512  }
513 
514  return $newItem;
515  }
516 
517  public function ReadAPICrearRegistroFromString($strIn) {
518  $doc = new \DOMDocument();
519  $doc->loadXML($strIn);
520 
521  $vAPI = $doc->getElementsByTagName('API_CREAREGISTRO');
522  if ($vAPI->length <= 0) {
523  return null;
524  }
525 
526  $xmlAPI = $vAPI->item(0);
527  $oAPI = API_CREAREGISTRO::fromDOM( $xmlAPI );
528 
529  return $oAPI;
530  }
531 
532  public function ReadDatosRegistroFromString($strIn) {
533  $doc = new \DOMDocument();
534  $doc->loadXML($strIn);
535 
536  $vAPI = $doc->getElementsByTagName('DATOS_DEL_REGISTRO');
537  if ($vAPI->length <= 0) {
538  return null;
539  }
540 
541  $xmlAPI = $vAPI->item(0);
542  $oAPI = DATOS_DEL_REGISTRO::fromDOM( $xmlAPI );
543 
544  return $oAPI;
545  }
546 } // RTSOAResponse
547 
548 
549 
550 class RTSOADocumentResponse
551 {
552  private $_nombre = null;
553  private $_hasNombre = false;
554  private $_tipo = null;
555  private $_hasTipo = false;
556  private $_contenido = null;
557  private $_hasContenido = false;
558 
559  // Nombre
560  public function setNombre($value) {
561  $this->_nombre = $value;
562  $this->_hasNombre = ($value !== null);
563  }
564  public function hasNombre() {
565  return $this->_hasNombre;
566  }
567  public function getNombre() {
568  return $this->_nombre;
569  }
570 
571 
572  // Tipo
573  public function setTipo($value) {
574  $this->_tipo = $value;
575  $this->_hasTipo = ($value !== null);
576  }
577  public function hasTipo() {
578  return $this->_hasTipo;
579  }
580  public function getTipo() {
581  return $this->_tipo;
582  }
583 
584 
585  // Contenido
586  public function setContenido($value) {
587  $this->_contenido = $value;
588  $this->_hasContenido = ($value !== null);
589  }
590  public function hasContenido() {
591  return $this->_hasContenido;
592  }
593  public function getContenido() {
594  return $this->_contenido;
595  }
596 
597 
598  static public function fromDOM($nodeDocumento) {
599  $newItem = new RTSOADocumentResponse();
600 
601  $vNode = $nodeDocumento->getElementsByTagName('nombre');
602  if ($vNode->length > 0)
603  {
604  $newItem->setNombre( $vNode->item(0)->nodeValue );
605  }
606 
607  $vNode = $nodeDocumento->getElementsByTagName('tipo');
608  if ($vNode->length > 0)
609  {
610  $newItem->setTipo( $vNode->item(0)->nodeValue );
611  }
612 
613  $vNode = $nodeDocumento->getElementsByTagName('contenido');
614  if ($vNode->length > 0)
615  {
616  $newItem->setContenido( $vNode->item(0)->nodeValue );
617  }
618 
619  return $newItem;
620  }
621 
622 } // RTSOADocumentResponse
623 
624 
625 ?>
registrarAcuse($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $expediente, $nombreFichero, $codDocumento, $descDocumento, $asocioExpediente, $entidadCertificadora, $formatoFirma, $valorFirma, $contenidoDoc)
crearRegistro($esRegistroEntrada, $oCrearReg, $vDocs)
consultarRegistro($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $devolverDocumentos, $docFirmados)
static CrearFicheroOficioRemision($texto)
consultarDocumento($esRegistroEntrada, $numeroRegistro, $fechaRegistro, $claveConsulta, $tipoDocumento='T')
static CrearFicheroAviso($texto)
tratarMTOMEstandar($response, $itemToReturn=null)