These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace NFePHP\MDFe; |
||
4 | |||
5 | /** |
||
6 | * Classe principal para a comunicação com a SEFAZ |
||
7 | * |
||
8 | * @category Library |
||
9 | * @package nfephp-org/sped-mdfe |
||
10 | * @copyright 2008-2016 NFePHP |
||
11 | * @license http://www.gnu.org/licenses/lesser.html LGPL v3 |
||
12 | * @link http://github.com/nfephp-org/sped-mdfe for the canonical source repository |
||
13 | * @author Roberto L. Machado <linux.rlm at gmail dot com> |
||
14 | */ |
||
15 | |||
16 | use NFePHP\Common\Base\BaseTools; |
||
17 | use NFePHP\Common\DateTime\DateTime; |
||
18 | use NFePHP\Common\LotNumber\LotNumber; |
||
19 | use NFePHP\Common\Strings\Strings; |
||
20 | use NFePHP\Common\Files; |
||
21 | use NFePHP\Common\Exception; |
||
22 | use NFePHP\Common\Dom\Dom; |
||
23 | use NFePHP\Common\Dom\ValidXsd; |
||
24 | use NFePHP\MDFe\Auxiliar\Response; |
||
25 | use NFePHP\MDFe\Mail; |
||
26 | use NFePHP\MDFe\Auxiliar\Identify; |
||
27 | |||
28 | 3 | if (!defined('NFEPHP_ROOT')) { |
|
29 | 3 | define('NFEPHP_ROOT', dirname(dirname(__FILE__))); |
|
30 | 2 | } |
|
31 | |||
32 | class Tools extends BaseTools |
||
33 | { |
||
34 | /** |
||
35 | * errrors |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | public $errors = array(); |
||
40 | /** |
||
41 | * soapDebug |
||
42 | * |
||
43 | * @var string |
||
44 | */ |
||
45 | public $soapDebug = ''; |
||
46 | /** |
||
47 | * urlPortal |
||
48 | * Instância do WebService |
||
49 | * |
||
50 | * @var string |
||
51 | */ |
||
52 | protected $urlPortal = 'http://www.portalfiscal.inf.br/mdfe'; |
||
53 | /** |
||
54 | * aLastRetEvent |
||
55 | * |
||
56 | * @var array |
||
57 | */ |
||
58 | private $aLastRetEvent = array(); |
||
59 | /** |
||
60 | * imprime |
||
61 | * Imprime o documento eletrônico (MDFe, CCe, Inut.) |
||
62 | * |
||
63 | * @param string $pathXml |
||
64 | * @param string $pathDestino |
||
65 | * @param string $printer |
||
66 | * @return string |
||
67 | */ |
||
68 | public function imprime($pathXml = '', $pathDestino = '', $printer = '') |
||
69 | { |
||
70 | //TODO : falta implementar esse método para isso é necessária a classe |
||
71 | //PrintMDFe |
||
72 | return "$pathXml $pathDestino $printer"; |
||
73 | } |
||
74 | /** |
||
75 | * enviaMail |
||
76 | * Envia a MDFe por email aos destinatários |
||
77 | * Caso $aMails esteja vazio serão obtidos os email do destinatário e |
||
78 | * os emails que estiverem registrados nos campos obsCont do xml |
||
79 | * |
||
80 | * @param string $pathXml |
||
81 | * @param array $aMails |
||
82 | * @param string $templateFile path completo ao arquivo template html do corpo do email |
||
83 | * @param boolean $comPdf se true o sistema irá renderizar o DANFE e anexa-lo a mensagem |
||
84 | * @return boolean |
||
85 | */ |
||
86 | public function enviaMail($pathXml = '', $aMails = array(), $templateFile = '', $comPdf = false) |
||
87 | { |
||
88 | $mail = new Mail($this->aMailConf); |
||
89 | if ($templateFile != '') { |
||
90 | $mail->setTemplate($templateFile); |
||
91 | } |
||
92 | return $mail->envia($pathXml, $aMails, $comPdf); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * addProtocolo |
||
97 | * Adiciona o protocolo de autorização de uso da MDFe |
||
98 | * NOTA: exigência da SEFAZ, a MDFe somente é válida com o seu respectivo protocolo |
||
99 | * |
||
100 | * @param string $pathMDFefile |
||
101 | * @param string $pathProtfile |
||
102 | * @param boolean $saveFile |
||
103 | * @return string |
||
104 | * @throws Exception\RuntimeException |
||
105 | */ |
||
106 | public function addProtocolo($pathMDFefile = '', $pathProtfile = '', $saveFile = false) |
||
107 | { |
||
108 | //carrega a MDFe |
||
109 | $docmdfe = new Dom(); |
||
110 | $docmdfe->loadXMLFile($pathMDFefile); |
||
111 | $nodemdfe = $docmdfe->getNode('MDFe', 0); |
||
112 | if ($nodemdfe == '') { |
||
113 | $msg = "O arquivo indicado como MDFe não é um xml de MDFe!"; |
||
114 | throw new Exception\RuntimeException($msg); |
||
115 | } |
||
116 | if ($docmdfe->getNode('Signature') == '') { |
||
117 | $msg = "O MDFe não está assinado!"; |
||
118 | throw new Exception\RuntimeException($msg); |
||
119 | } |
||
120 | //carrega o protocolo |
||
121 | $docprot = new Dom(); |
||
122 | $docprot->loadXMLFile($pathProtfile); |
||
123 | $nodeprots = $docprot->getElementsByTagName('protMDFe'); |
||
124 | if ($nodeprots->length == 0) { |
||
125 | $msg = "O arquivo indicado não contêm um protocolo de autorização!"; |
||
126 | throw new Exception\RuntimeException($msg); |
||
127 | } |
||
128 | //carrega dados da MDFe |
||
129 | $tpAmb = $docmdfe->getNodeValue('tpAmb'); |
||
130 | $anomes = date( |
||
131 | 'Ym', |
||
132 | DateTime::convertSefazTimeToTimestamp($docmdfe->getNodeValue('dhEmi')) |
||
133 | ); |
||
134 | $infMDFe = $docmdfe->getNode("infMDFe", 0); |
||
135 | $versao = $infMDFe->getAttribute("versao"); |
||
136 | $chaveId = $infMDFe->getAttribute("Id"); |
||
137 | $chaveMDFe = preg_replace('/[^0-9]/', '', $chaveId); |
||
138 | $digValueMDFe = $docmdfe->getNodeValue('DigestValue'); |
||
139 | //carrega os dados do protocolo |
||
140 | for ($i = 0; $i < $nodeprots->length; $i++) { |
||
141 | $nodeprot = $nodeprots->item($i); |
||
142 | $protver = $nodeprot->getAttribute("versao"); |
||
143 | $chaveProt = $nodeprot->getElementsByTagName("chMDFe")->item(0)->nodeValue; |
||
144 | $digValueProt = $nodeprot->getElementsByTagName("digVal")->item(0)->nodeValue; |
||
145 | $infProt = $nodeprot->getElementsByTagName("infProt")->item(0); |
||
146 | if ($digValueMDFe == $digValueProt && $chaveMDFe == $chaveProt) { |
||
147 | break; |
||
148 | } |
||
149 | } |
||
150 | if ($digValueMDFe != $digValueProt) { |
||
151 | $msg = "Inconsistência! O DigestValue do MDFe não combina com o" |
||
152 | . " do digVal do protocolo indicado!"; |
||
153 | throw new Exception\RuntimeException($msg); |
||
154 | } |
||
155 | if ($chaveMDFe != $chaveProt) { |
||
156 | $msg = "O protocolo indicado pertence a outro MDFe. Os números das chaves não combinam !"; |
||
157 | throw new Exception\RuntimeException($msg); |
||
158 | } |
||
159 | //cria a MDFe processada com a tag do protocolo |
||
160 | $procmdfe = new \DOMDocument('1.0', 'utf-8'); |
||
161 | $procmdfe->formatOutput = false; |
||
162 | $procmdfe->preserveWhiteSpace = false; |
||
163 | //cria a tag mdfeProc |
||
164 | $mdfeProc = $procmdfe->createElement('mdfeProc'); |
||
165 | $procmdfe->appendChild($mdfeProc); |
||
166 | //estabele o atributo de versão |
||
167 | $mdfeProcAtt1 = $mdfeProc->appendChild($procmdfe->createAttribute('versao')); |
||
168 | $mdfeProcAtt1->appendChild($procmdfe->createTextNode($protver)); |
||
169 | //estabelece o atributo xmlns |
||
170 | $mdfeProcAtt2 = $mdfeProc->appendChild($procmdfe->createAttribute('xmlns')); |
||
171 | $mdfeProcAtt2->appendChild($procmdfe->createTextNode($this->urlPortal)); |
||
172 | //inclui a tag MDFe |
||
173 | $node = $procmdfe->importNode($nodemdfe, true); |
||
174 | $mdfeProc->appendChild($node); |
||
175 | //cria tag protMDFe |
||
176 | $protMDFe = $procmdfe->createElement('protMDFe'); |
||
177 | $mdfeProc->appendChild($protMDFe); |
||
178 | //estabele o atributo de versão |
||
179 | $protMDFeAtt1 = $protMDFe->appendChild($procmdfe->createAttribute('versao')); |
||
180 | $protMDFeAtt1->appendChild($procmdfe->createTextNode($versao)); |
||
181 | //cria tag infProt |
||
182 | $nodep = $procmdfe->importNode($infProt, true); |
||
183 | $protMDFe->appendChild($nodep); |
||
184 | //salva o xml como string em uma variável |
||
185 | $procXML = $procmdfe->saveXML(); |
||
186 | //remove as informações indesejadas |
||
187 | $procXML = Strings::clearProt($procXML); |
||
188 | View Code Duplication | if ($saveFile) { |
|
189 | $filename = "$chaveMDFe-protMDFe.xml"; |
||
190 | $this->zGravaFile( |
||
191 | 'mdfe', |
||
192 | $tpAmb, |
||
193 | $filename, |
||
194 | $procXML, |
||
195 | 'enviadas'.DIRECTORY_SEPARATOR.'aprovadas', |
||
196 | $anomes |
||
197 | ); |
||
198 | } |
||
199 | return $procXML; |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * addCancelamento |
||
204 | * Adiciona a tga de cancelamento a uma MDFe já autorizada |
||
205 | * NOTA: não é requisito da SEFAZ, mas auxilia na identificação das MDFe que foram canceladas |
||
206 | * |
||
207 | * @param string $pathMDFefile |
||
208 | * @param string $pathCancfile |
||
209 | * @param bool $saveFile |
||
210 | * @return string |
||
211 | * @throws Exception\RuntimeException |
||
212 | */ |
||
213 | public function addCancelamento($pathMDFefile = '', $pathCancfile = '', $saveFile = false) |
||
214 | { |
||
215 | $procXML = ''; |
||
216 | //carrega a MDFe |
||
217 | $docmdfe = new Dom(); |
||
218 | $docmdfe->loadXMLFile($pathMDFefile); |
||
219 | $nodemdfe = $docmdfe->getNode('MDFe', 0); |
||
220 | if ($nodemdfe == '') { |
||
221 | $msg = "O arquivo indicado como MDFe não é um xml de MDFe!"; |
||
222 | throw new Exception\RuntimeException($msg); |
||
223 | } |
||
224 | $proMDFe = $docmdfe->getNode('protMDFe'); |
||
225 | if ($proMDFe == '') { |
||
226 | $msg = "O MDFe não está protocolado ainda!!"; |
||
227 | throw new Exception\RuntimeException($msg); |
||
228 | } |
||
229 | $chaveMDFe = $proMDFe->getElementsByTagName('chMDFe')->item(0)->nodeValue; |
||
230 | //$nProtMDFe = $proMDFe->getElementsByTagName('nProt')->item(0)->nodeValue; |
||
231 | $tpAmb = $docmdfe->getNodeValue('tpAmb'); |
||
232 | $anomes = date( |
||
233 | 'Ym', |
||
234 | DateTime::convertSefazTimeToTimestamp($docmdfe->getNodeValue('dhEmi')) |
||
235 | ); |
||
236 | //carrega o cancelamento |
||
237 | //pode ser um evento ou resultado de uma consulta com multiplos eventos |
||
238 | $doccanc = new Dom(); |
||
239 | $doccanc->loadXMLFile($pathCancfile); |
||
240 | $eventos = $doccanc->getElementsByTagName('infEvento'); |
||
241 | foreach ($eventos as $evento) { |
||
242 | //evento |
||
243 | $cStat = $evento->getElementsByTagName('cStat')->item(0)->nodeValue; |
||
244 | $tpAmb = $evento->getElementsByTagName('tpAmb')->item(0)->nodeValue; |
||
245 | $chaveEvento = $evento->getElementsByTagName('chMDFe')->item(0)->nodeValue; |
||
246 | $tpEvento = $evento->getElementsByTagName('tpEvento')->item(0)->nodeValue; |
||
247 | //$nProtEvento = $evento->getElementsByTagName('nProt')->item(0)->nodeValue; |
||
248 | //verifica se conferem os dados |
||
249 | //cStat = 135 ==> evento homologado |
||
250 | //tpEvento = 110111 ==> Cancelamento |
||
251 | //chave do evento == chave da NFe |
||
252 | //protocolo do evento == protocolo da NFe |
||
253 | if ($cStat == '135' |
||
254 | && $tpEvento == '110111' |
||
255 | && $chaveEvento == $chaveMDFe |
||
256 | ) { |
||
257 | $proMDFe->getElementsByTagName('cStat')->item(0)->nodeValue = '101'; |
||
258 | $proMDFe->getElementsByTagName('xMotivo')->item(0)->nodeValue = 'Cancelamento de MDF-e homologado'; |
||
259 | $procXML = $docmdfe->saveXML(); |
||
260 | //remove as informações indesejadas |
||
261 | $procXML = Strings::clearProt($procXML); |
||
262 | View Code Duplication | if ($saveFile) { |
|
263 | $filename = "$chaveMDFe-protMDFe.xml"; |
||
264 | $this->zGravaFile( |
||
265 | 'mdfe', |
||
266 | $tpAmb, |
||
267 | $filename, |
||
268 | $procXML, |
||
269 | 'enviadas'.DIRECTORY_SEPARATOR.'aprovadas', |
||
270 | $anomes |
||
271 | ); |
||
272 | } |
||
273 | break; |
||
274 | } |
||
275 | } |
||
276 | return (string) $procXML; |
||
277 | } |
||
278 | |||
279 | |||
280 | /** |
||
281 | * verificaValidade |
||
282 | * |
||
283 | * @param string $pathXmlFile |
||
284 | * @param array $aRetorno |
||
285 | * @return boolean |
||
286 | * @throws Exception\InvalidArgumentException |
||
287 | */ |
||
288 | public function verificaValidade($pathXmlFile = '', &$aRetorno = array()) |
||
289 | { |
||
290 | $aRetorno = array(); |
||
291 | if (!file_exists($pathXmlFile)) { |
||
292 | $msg = "Arquivo não localizado!!"; |
||
293 | throw new Exception\InvalidArgumentException($msg); |
||
294 | } |
||
295 | //carrega a MDFe |
||
296 | $xml = Files\FilesFolders::readFile($pathXmlFile); |
||
297 | $this->oCertificate->verifySignature($xml, 'infMDFe'); |
||
298 | //obtem o chave da MDFe |
||
299 | $docmdfe = new Dom(); |
||
300 | $docmdfe->loadXMLFile($pathXmlFile); |
||
301 | $tpAmb = $docmdfe->getNodeValue('tpAmb'); |
||
302 | $chMDFe = $docmdfe->getChave('infMDFe'); |
||
303 | $this->sefazConsultaChave($chMDFe, $tpAmb, $aRetorno); |
||
304 | if ($aRetorno['cStat'] != '100') { |
||
305 | return false; |
||
306 | } |
||
307 | return true; |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * assina |
||
312 | * |
||
313 | * @param string $xml |
||
314 | * @param boolean $saveFile |
||
315 | * @return string |
||
316 | * @throws Exception\RuntimeException |
||
317 | */ |
||
318 | public function assina($xml = '', $saveFile = false) |
||
319 | { |
||
320 | return $this->assinaDoc($xml, 'mdfe', 'infMDFe', $saveFile); |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * sefazEnviaLote |
||
325 | * |
||
326 | * @param string $xml |
||
327 | * @param string $tpAmb |
||
328 | * @param string $idLote |
||
329 | * @param array $aRetorno |
||
330 | * @return string |
||
331 | * @throws Exception\InvalidArgumentException |
||
332 | * @throws Exception\RuntimeException |
||
333 | * @internal function zLoadServico (Common\Base\BaseTools) |
||
334 | */ |
||
335 | public function sefazEnviaLote( |
||
336 | $xml, |
||
337 | $tpAmb = '2', |
||
338 | $idLote = '', |
||
339 | &$aRetorno = array() |
||
340 | ) { |
||
341 | if (empty($xml)) { |
||
342 | $msg = "Pelo menos uma MDFe deve ser informada."; |
||
343 | throw new Exception\InvalidArgumentException($msg); |
||
344 | } |
||
345 | $sxml = preg_replace("/<\?xml.*\?>/", "", $xml); |
||
346 | $siglaUF = $this->aConfig['siglaUF']; |
||
347 | if ($tpAmb == '') { |
||
348 | $tpAmb = $this->aConfig['tpAmb']; |
||
349 | } |
||
350 | if ($idLote == '') { |
||
351 | $idLote = LotNumber::geraNumLote(15); |
||
352 | } |
||
353 | //carrega serviço |
||
354 | $servico = 'MDFeRecepcao'; |
||
355 | $this->zLoadServico( |
||
356 | 'mdfe', |
||
357 | $servico, |
||
358 | $siglaUF, |
||
359 | $tpAmb |
||
360 | ); |
||
361 | if ($this->urlService == '') { |
||
362 | $msg = "O envio de lote não está disponível na SEFAZ $siglaUF!!!"; |
||
363 | throw new Exception\RuntimeException($msg); |
||
364 | } |
||
365 | //montagem dos dados da mensagem SOAP |
||
366 | $cons = "<enviMDFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
367 | . "<idLote>$idLote</idLote>$sxml</enviMDFe>"; |
||
368 | //valida a mensagem com o xsd |
||
369 | //if (! $this->zValidMessage($cons, 'mdfe', 'enviMDFe', $version)) { |
||
370 | // $msg = 'Falha na validação. '.$this->error; |
||
371 | // throw new Exception\RuntimeException($msg); |
||
372 | //} |
||
373 | //montagem dos dados da mensagem SOAP |
||
374 | $body = "<mdfeDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
375 | $method = $this->urlMethod; |
||
376 | //envia a solicitação via SOAP |
||
377 | $retorno = $this->oSoap->send($this->urlService, $this->urlNamespace, $this->urlHeader, $body, $method); |
||
378 | $lastMsg = $this->oSoap->lastMsg; |
||
379 | $this->soapDebug = $this->oSoap->soapDebug; |
||
380 | //salva mensagens |
||
381 | $filename = "$idLote-enviMDFe.xml"; |
||
382 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
383 | $filename = "$idLote-retEnviMDFe.xml"; |
||
384 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
385 | //tratar dados de retorno |
||
386 | $aRetorno = Response::readReturnSefaz($servico, $retorno); |
||
387 | return (string) $retorno; |
||
388 | } |
||
389 | |||
390 | /** |
||
391 | * sefazConsultaRecibo |
||
392 | * |
||
393 | * @param string $recibo |
||
394 | * @param string $tpAmb |
||
395 | * @param array $aRetorno |
||
396 | * @return string |
||
397 | * @throws Exception\InvalidArgumentException |
||
398 | * @throws Exception\RuntimeException |
||
399 | * @internal function zLoadServico (Common\Base\BaseTools) |
||
400 | */ |
||
401 | public function sefazConsultaRecibo($recibo = '', $tpAmb = '2', &$aRetorno = array()) |
||
402 | { |
||
403 | if ($recibo == '') { |
||
404 | $msg = "Deve ser informado um recibo."; |
||
405 | throw new Exception\InvalidArgumentException($msg); |
||
406 | } |
||
407 | if ($tpAmb == '') { |
||
408 | $tpAmb = $this->aConfig['tpAmb']; |
||
409 | } |
||
410 | $siglaUF = $this->aConfig['siglaUF']; |
||
411 | //carrega serviço |
||
412 | $servico = 'MDFeRetRecepcao'; |
||
413 | $this->zLoadServico( |
||
414 | 'mdfe', |
||
415 | $servico, |
||
416 | $siglaUF, |
||
417 | $tpAmb |
||
418 | ); |
||
419 | if ($this->urlService == '') { |
||
420 | $msg = "A consulta de MDFe não está disponível na SEFAZ $siglaUF!!!"; |
||
421 | throw new Exception\RuntimeException($msg); |
||
422 | } |
||
423 | $cons = "<consReciMDFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
424 | . "<tpAmb>$tpAmb</tpAmb>" |
||
425 | . "<nRec>$recibo</nRec>" |
||
426 | . "</consReciMDFe>"; |
||
427 | //valida a mensagem com o xsd |
||
428 | //if (! $this->zValidMessage($cons, 'mdfe', 'consReciMDFe', $version)) { |
||
429 | // $msg = 'Falha na validação. '.$this->error; |
||
430 | // throw new Exception\RuntimeException($msg); |
||
431 | //} |
||
432 | //montagem dos dados da mensagem SOAP |
||
433 | $body = "<mdfeDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
434 | //envia a solicitação via SOAP |
||
435 | $retorno = $this->oSoap->send( |
||
436 | $this->urlService, |
||
437 | $this->urlNamespace, |
||
438 | $this->urlHeader, |
||
439 | $body, |
||
440 | $this->urlMethod |
||
441 | ); |
||
442 | $lastMsg = $this->oSoap->lastMsg; |
||
443 | $this->soapDebug = $this->oSoap->soapDebug; |
||
444 | //salva mensagens |
||
445 | $filename = "$recibo-consReciMDFe.xml"; |
||
446 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
447 | $filename = "$recibo-retConsReciMDFe.xml"; |
||
448 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
449 | //tratar dados de retorno |
||
450 | $aRetorno = Response::readReturnSefaz($servico, $retorno); |
||
451 | return (string) $retorno; |
||
452 | } |
||
453 | |||
454 | /** |
||
455 | * sefazConsultaChave |
||
456 | * Consulta o status da MDFe pela chave de 44 digitos |
||
457 | * |
||
458 | * @param string $chave |
||
459 | * @param string $tpAmb |
||
460 | * @param array $aRetorno |
||
461 | * @return string |
||
462 | * @throws Exception\InvalidArgumentException |
||
463 | * @throws Exception\RuntimeException |
||
464 | * @internal function zLoadServico (Common\Base\BaseTools) |
||
465 | */ |
||
466 | public function sefazConsultaChave($chave = '', $tpAmb = '2', &$aRetorno = array()) |
||
467 | { |
||
468 | $chMDFe = preg_replace('/[^0-9]/', '', $chave); |
||
469 | if (strlen($chMDFe) != 44) { |
||
470 | $msg = "Uma chave de 44 dígitos da MDFe deve ser passada."; |
||
471 | throw new Exception\InvalidArgumentException($msg); |
||
472 | } |
||
473 | if ($tpAmb == '') { |
||
474 | $tpAmb = $this->aConfig['tpAmb']; |
||
475 | } |
||
476 | $cUF = substr($chMDFe, 0, 2); |
||
477 | $siglaUF = self::zGetSigla($cUF); |
||
478 | //carrega serviço |
||
479 | $servico = 'MDFeConsulta'; |
||
480 | $this->zLoadServico( |
||
481 | 'mdfe', |
||
482 | $servico, |
||
483 | $siglaUF, |
||
484 | $tpAmb |
||
485 | ); |
||
486 | if ($this->urlService == '') { |
||
487 | $msg = "A consulta de MDFe não está disponível na SEFAZ $siglaUF!!!"; |
||
488 | throw new Exception\RuntimeException($msg); |
||
489 | } |
||
490 | $cons = "<consSitMDFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
491 | . "<tpAmb>$tpAmb</tpAmb>" |
||
492 | . "<xServ>CONSULTAR</xServ>" |
||
493 | . "<chMDFe>$chMDFe</chMDFe>" |
||
494 | . "</consSitMDFe>"; |
||
495 | //valida a mensagem com o xsd |
||
496 | //if (! $this->zValidMessage($cons, 'mdfe', 'consSitMDFe', $version)) { |
||
497 | // $msg = 'Falha na validação. '.$this->error; |
||
498 | // throw new Exception\RuntimeException($msg); |
||
499 | //} |
||
500 | //montagem dos dados da mensagem SOAP |
||
501 | $body = "<mdfeDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
502 | //envia a solicitação via SOAP |
||
503 | $retorno = $this->oSoap->send( |
||
504 | $this->urlService, |
||
505 | $this->urlNamespace, |
||
506 | $this->urlHeader, |
||
507 | $body, |
||
508 | $this->urlMethod |
||
509 | ); |
||
510 | $lastMsg = $this->oSoap->lastMsg; |
||
511 | $this->soapDebug = $this->oSoap->soapDebug; |
||
512 | //salva mensagens |
||
513 | $filename = "$chMDFe-consSitMDFe.xml"; |
||
514 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
515 | $filename = "$chMDFe-retConsSitMDFe.xml"; |
||
516 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
517 | //tratar dados de retorno |
||
518 | $aRetorno = Response::readReturnSefaz($servico, $retorno); |
||
519 | return (string) $retorno; |
||
520 | } |
||
521 | |||
522 | /** |
||
523 | * sefazStatus |
||
524 | * Verifica o status do serviço da SEFAZ |
||
525 | * NOTA : Este serviço será removido no futuro, segundo da Receita/SEFAZ devido |
||
526 | * ao excesso de mau uso !!! |
||
527 | * |
||
528 | * @param string $siglaUF sigla da unidade da Federação |
||
529 | * @param string $tpAmb tipo de ambiente 1-produção e 2-homologação |
||
530 | * @param array $aRetorno parametro passado por referencia contendo a resposta da consulta em um array |
||
531 | * @return mixed string XML do retorno do webservice, ou false se ocorreu algum erro |
||
532 | * @throws Exception\RuntimeException |
||
533 | * @internal function zLoadServico (Common\Base\BaseTools) |
||
534 | */ |
||
535 | View Code Duplication | public function sefazStatus($siglaUF = '', $tpAmb = '2', &$aRetorno = array()) |
|
536 | { |
||
537 | if ($tpAmb == '') { |
||
538 | $tpAmb = $this->aConfig['tpAmb']; |
||
539 | } |
||
540 | if ($siglaUF == '') { |
||
541 | $siglaUF = $this->aConfig['siglaUF']; |
||
542 | } |
||
543 | //carrega serviço |
||
544 | $servico = 'MDFeStatusServico'; |
||
545 | $this->zLoadServico( |
||
546 | 'mdfe', |
||
547 | $servico, |
||
548 | $siglaUF, |
||
549 | $tpAmb |
||
550 | ); |
||
551 | if ($this->urlService == '') { |
||
552 | $msg = "O status não está disponível na SEFAZ $siglaUF!!!"; |
||
553 | throw new Exception\RuntimeException($msg); |
||
554 | } |
||
555 | $cons = "<consStatServMDFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
556 | . "<tpAmb>$tpAmb</tpAmb>" |
||
557 | . "<xServ>STATUS</xServ></consStatServMDFe>"; |
||
558 | //valida mensagem com xsd |
||
559 | //if (! $this->zValidMessage($cons, 'mdfe', 'consStatServMDFe', $version)) { |
||
560 | // $msg = 'Falha na validação. '.$this->error; |
||
561 | // throw new Exception\RuntimeException($msg); |
||
562 | //} |
||
563 | //montagem dos dados da mensagem SOAP |
||
564 | $body = "<mdfeDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
565 | //consome o webservice e verifica o retorno do SOAP |
||
566 | $retorno = $this->oSoap->send( |
||
567 | $this->urlService, |
||
568 | $this->urlNamespace, |
||
569 | $this->urlHeader, |
||
570 | $body, |
||
571 | $this->urlMethod |
||
572 | ); |
||
573 | $lastMsg = $this->oSoap->lastMsg; |
||
574 | $this->soapDebug = $this->oSoap->soapDebug; |
||
575 | $datahora = date('Ymd_His'); |
||
576 | $filename = $siglaUF."_"."$datahora-consStatServ.xml"; |
||
577 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
578 | $filename = $siglaUF."_"."$datahora-retConsStatServ.xml"; |
||
579 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
580 | //tratar dados de retorno |
||
581 | $aRetorno = Response::readReturnSefaz($servico, $retorno); |
||
582 | return (string) $retorno; |
||
583 | } |
||
584 | |||
585 | /** |
||
586 | * sefazCancela |
||
587 | * |
||
588 | * @param string $chave |
||
589 | * @param string $tpAmb |
||
590 | * @param string $xJust |
||
591 | * @param string $nProt |
||
592 | * @param array $aRetorno |
||
593 | * @return string |
||
594 | * @throws Exception\InvalidArgumentException |
||
595 | */ |
||
596 | public function sefazCancela( |
||
597 | $chave = '', |
||
598 | $tpAmb = '2', |
||
599 | $nSeqEvento = '1', |
||
600 | $nProt = '', |
||
601 | $xJust = '', |
||
602 | &$aRetorno = array() |
||
603 | ) { |
||
604 | if ($tpAmb == '') { |
||
605 | $tpAmb = $this->aConfig['tpAmb']; |
||
606 | } |
||
607 | $chMDFe = preg_replace('/[^0-9]/', '', $chave); |
||
608 | $nProt = preg_replace('/[^0-9]/', '', $nProt); |
||
609 | $xJust = Strings::cleanString($xJust); |
||
610 | if (strlen($chMDFe) != 44) { |
||
611 | $msg = "Uma chave de MDFe válida não foi passada como parâmetro $chMDFe."; |
||
612 | throw new Exception\InvalidArgumentException($msg); |
||
613 | } |
||
614 | if ($nProt == '') { |
||
615 | $msg = "Não foi passado o numero do protocolo!!"; |
||
616 | throw new Exception\InvalidArgumentException($msg); |
||
617 | } |
||
618 | if (strlen($xJust) < 15 || strlen($xJust) > 255) { |
||
619 | $msg = "A justificativa deve ter pelo menos 15 digitos e no máximo 255!!"; |
||
620 | throw new Exception\InvalidArgumentException($msg); |
||
621 | } |
||
622 | $siglaUF = self::zGetSigla(substr($chMDFe, 0, 2)); |
||
623 | //estabelece o codigo do tipo de evento CANCELAMENTO |
||
624 | $tpEvento = '110111'; |
||
625 | if ($nSeqEvento == '') { |
||
626 | $nSeqEvento = '1'; |
||
627 | } |
||
628 | $tagAdic = "<evCancMDFe><descEvento>Cancelamento</descEvento>" |
||
629 | . "<nProt>$nProt</nProt><xJust>$xJust</xJust></evCancMDFe>"; |
||
630 | $retorno = $this->zSefazEvento($siglaUF, $chMDFe, $tpAmb, $tpEvento, $nSeqEvento, $tagAdic); |
||
631 | $aRetorno = $this->aLastRetEvent; |
||
632 | return $retorno; |
||
633 | } |
||
634 | |||
635 | /** |
||
636 | * sefazEncerra |
||
637 | * |
||
638 | * @param string $chave |
||
639 | * @param string $tpAmb |
||
640 | * @param string $nProt |
||
641 | * @param string $cUF |
||
642 | * @param string $cMun |
||
643 | * @param array $aRetorno |
||
644 | * @return string |
||
645 | * @throws Exception\InvalidArgumentException |
||
646 | */ |
||
647 | View Code Duplication | public function sefazEncerra( |
|
0 ignored issues
–
show
|
|||
648 | $chave = '', |
||
649 | $tpAmb = '2', |
||
650 | $nSeqEvento = '1', |
||
651 | $nProt = '', |
||
652 | $cUF = '', |
||
653 | $cMun = '', |
||
654 | &$aRetorno = array() |
||
655 | ) { |
||
656 | if ($tpAmb == '') { |
||
657 | $tpAmb = $this->aConfig['tpAmb']; |
||
658 | } |
||
659 | $chMDFe = preg_replace('/[^0-9]/', '', $chave); |
||
660 | $nProt = preg_replace('/[^0-9]/', '', $nProt); |
||
661 | if (strlen($chMDFe) != 44) { |
||
662 | $msg = "Uma chave de MDFe válida não foi passada como parâmetro $chMDFe."; |
||
663 | throw new Exception\InvalidArgumentException($msg); |
||
664 | } |
||
665 | if ($nProt == '') { |
||
666 | $msg = "Não foi passado o numero do protocolo!!"; |
||
667 | throw new Exception\InvalidArgumentException($msg); |
||
668 | } |
||
669 | $siglaUF = self::zGetSigla(substr($chMDFe, 0, 2)); |
||
670 | //estabelece o codigo do tipo de evento CANCELAMENTO |
||
671 | $tpEvento = '110112'; |
||
672 | if ($nSeqEvento == '') { |
||
673 | $nSeqEvento = '1'; |
||
674 | } |
||
675 | $dtEnc = date('Y-m-d'); |
||
676 | $tagAdic = "<evEncMDFe><descEvento>Encerramento</descEvento>" |
||
677 | . "<nProt>$nProt</nProt><dtEnc>$dtEnc</dtEnc><cUF>$cUF</cUF>" |
||
678 | . "<cMun>$cMun</cMun></evEncMDFe>"; |
||
679 | $retorno = $this->zSefazEvento($siglaUF, $chMDFe, $tpAmb, $tpEvento, $nSeqEvento, $tagAdic); |
||
680 | $aRetorno = $this->aLastRetEvent; |
||
681 | return $retorno; |
||
682 | } |
||
683 | |||
684 | /** |
||
685 | * sefazIncluiCondutor |
||
686 | * |
||
687 | * @param string $chave |
||
688 | * @param string $tpAmb |
||
689 | * @param string $nSeqEvento |
||
690 | * @param string $xNome |
||
691 | * @param string $cpf |
||
692 | * @param array $aRetorno |
||
693 | * @return string |
||
694 | * @throws Exception\InvalidArgumentException |
||
695 | */ |
||
696 | View Code Duplication | public function sefazIncluiCondutor( |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
697 | $chave = '', |
||
698 | $tpAmb = '2', |
||
699 | $nSeqEvento = '1', |
||
700 | $xNome = '', |
||
701 | $cpf = '', |
||
702 | &$aRetorno = array() |
||
703 | ) { |
||
704 | if ($tpAmb == '') { |
||
705 | $tpAmb = $this->aConfig['tpAmb']; |
||
706 | } |
||
707 | $chMDFe = preg_replace('/[^0-9]/', '', $chave); |
||
708 | $nProt = preg_replace('/[^0-9]/', '', $nProt); |
||
0 ignored issues
–
show
The variable
$nProt seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case,
Loading history...
|
|||
709 | if (strlen($chMDFe) != 44) { |
||
710 | $msg = "Uma chave de MDFe válida não foi passada como parâmetro $chMDFe."; |
||
711 | throw new Exception\InvalidArgumentException($msg); |
||
712 | } |
||
713 | if ($nProt == '') { |
||
714 | $msg = "Não foi passado o numero do protocolo!!"; |
||
715 | throw new Exception\InvalidArgumentException($msg); |
||
716 | } |
||
717 | $siglaUF = self::zGetSigla(substr($chMDFe, 0, 2)); |
||
718 | //estabelece o codigo do tipo de evento Inclusão de condutor |
||
719 | $tpEvento = '110114'; |
||
720 | if ($nSeqEvento == '') { |
||
721 | $nSeqEvento = '1'; |
||
722 | } |
||
723 | //monta mensagem |
||
724 | $tagAdic = "<evIncCondutorMDFe><descEvento>Inclusao Condutor</descEvento>" |
||
725 | . "<Condutor><xNome>$xNome</xNome><CPF>$cpf</CPF></Condutor></evIncCondutorMDFe>"; |
||
726 | |||
727 | $cOrgao = ''; |
||
728 | |||
729 | $retorno = $this->zSefazEvento($siglaUF, $chMDFe, $cOrgao, $tpAmb, $tpEvento, $nSeqEvento, $tagAdic); |
||
730 | $aRetorno = $this->aLastRetEvent; |
||
731 | return $retorno; |
||
732 | } |
||
733 | |||
734 | /** |
||
735 | * sefazConsultaNaoEncerrados |
||
736 | * |
||
737 | * @param string $tpAmb |
||
738 | * @param string $cnpj |
||
739 | * @param array $aRetorno |
||
740 | * @return string |
||
741 | * @throws Exception\RuntimeException |
||
742 | */ |
||
743 | View Code Duplication | public function sefazConsultaNaoEncerrados($tpAmb = '2', $cnpj = '', &$aRetorno = array()) |
|
744 | { |
||
745 | if ($tpAmb == '') { |
||
746 | $tpAmb = $this->aConfig['tpAmb']; |
||
747 | } |
||
748 | if ($cnpj == '') { |
||
749 | $cnpj = $this->aConfig['cnpj']; |
||
750 | } |
||
751 | $siglaUF = $this->aConfig['siglaUF']; |
||
752 | //carrega serviço |
||
753 | $servico = 'MDFeConsNaoEnc'; |
||
754 | $this->zLoadServico( |
||
755 | 'mdfe', |
||
756 | $servico, |
||
757 | $siglaUF, |
||
758 | $tpAmb |
||
759 | ); |
||
760 | if ($this->urlService == '') { |
||
761 | $msg = "O serviço não está disponível na SEFAZ $siglaUF!!!"; |
||
762 | throw new Exception\RuntimeException($msg); |
||
763 | } |
||
764 | $cons = "<consMDFeNaoEnc xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
765 | . "<tpAmb>$tpAmb</tpAmb>" |
||
766 | . "<xServ>CONSULTAR NÃO ENCERRADOS</xServ><CNPJ>$cnpj</CNPJ></consMDFeNaoEnc>"; |
||
767 | //valida mensagem com xsd |
||
768 | //if (! $this->zValidMessage($cons, 'mdfe', 'consMDFeNaoEnc', $version)) { |
||
769 | // $msg = 'Falha na validação. '.$this->error; |
||
770 | // throw new Exception\RuntimeException($msg); |
||
771 | //} |
||
772 | //montagem dos dados da mensagem SOAP |
||
773 | $body = "<mdefDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
774 | //consome o webservice e verifica o retorno do SOAP |
||
775 | $retorno = $this->oSoap->send( |
||
776 | $this->urlService, |
||
777 | $this->urlNamespace, |
||
778 | $this->urlHeader, |
||
779 | $body, |
||
780 | $this->urlMethod |
||
781 | ); |
||
782 | $lastMsg = $this->oSoap->lastMsg; |
||
783 | $this->soapDebug = $this->oSoap->soapDebug; |
||
784 | $datahora = date('Ymd_His'); |
||
785 | $filename = $siglaUF."_"."$datahora-consNaoEnc.xml"; |
||
786 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
787 | $filename = $siglaUF."_"."$datahora-retConsNaoEnc.xml"; |
||
788 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
789 | //tratar dados de retorno |
||
790 | $aRetorno = Response::readReturnSefaz($servico, $retorno); |
||
791 | return (string) $retorno; |
||
792 | } |
||
793 | |||
794 | /** |
||
795 | * zSefazEvento |
||
796 | * |
||
797 | * @param string $siglaUF |
||
798 | * @param string $chave |
||
799 | * @param string $cOrgao |
||
800 | * @param string $tpAmb |
||
801 | * @param string $tpEvento |
||
802 | * @param string $nSeqEvento |
||
803 | * @param string $tagAdic |
||
804 | * @return string |
||
805 | * @throws Exception\RuntimeException |
||
806 | * @internal function zLoadServico (Common\Base\BaseTools) |
||
807 | */ |
||
808 | protected function zSefazEvento( |
||
809 | $siglaUF = '', |
||
810 | $chave = '', |
||
811 | $cOrgao = '', |
||
812 | $tpAmb = '2', |
||
813 | $tpEvento = '', |
||
814 | $nSeqEvento = '1', |
||
815 | $tagAdic = '' |
||
816 | ) { |
||
817 | if ($tpAmb == '') { |
||
818 | $tpAmb = $this->aConfig['tpAmb']; |
||
819 | } |
||
820 | //carrega serviço |
||
821 | $servico = 'MDFeRecepcaoEvento'; |
||
822 | $this->zLoadServico( |
||
823 | 'mdfe', |
||
824 | $servico, |
||
825 | $siglaUF, |
||
826 | $tpAmb |
||
827 | ); |
||
828 | if ($this->urlService == '') { |
||
829 | $msg = "A recepção de eventos não está disponível na SEFAZ $siglaUF!!!"; |
||
830 | throw new Exception\RuntimeException($msg); |
||
831 | } |
||
832 | $aRet = $this->zTpEv($tpEvento); |
||
833 | $aliasEvento = $aRet['alias']; |
||
834 | $cnpj = $this->aConfig['cnpj']; |
||
835 | $dhEvento = (string) str_replace(' ', 'T', date('Y-m-d H:i:s')); |
||
836 | $sSeqEvento = str_pad($nSeqEvento, 2, "0", STR_PAD_LEFT); |
||
837 | $eventId = "ID".$tpEvento.$chave.$sSeqEvento; |
||
838 | if ($cOrgao == '') { |
||
839 | $cOrgao = $this->urlcUF; |
||
840 | } |
||
841 | $mensagem = "<eventoMDFe xmlns=\"$this->urlPortal\" versao=\"$this->urlVersion\">" |
||
842 | . "<infEvento Id=\"$eventId\">" |
||
843 | . "<cOrgao>$cOrgao</cOrgao>" |
||
844 | . "<tpAmb>$tpAmb</tpAmb>" |
||
845 | . "<CNPJ>$cnpj</CNPJ>" |
||
846 | . "<chMDFe>$chave</chMDFe>" |
||
847 | . "<dhEvento>$dhEvento</dhEvento>" |
||
848 | . "<tpEvento>$tpEvento</tpEvento>" |
||
849 | . "<nSeqEvento>$nSeqEvento</nSeqEvento>" |
||
850 | . "<detEvento versaoEvento=\"$this->urlVersion\">" |
||
851 | . "$tagAdic" |
||
852 | . "</detEvento>" |
||
853 | . "</infEvento>" |
||
854 | . "</eventoMDFe>"; |
||
855 | //assinatura dos dados |
||
856 | $signedMsg = $this->oCertificate->signXML($mensagem, 'infEvento'); |
||
857 | $cons = Strings::clearXml($signedMsg, true); |
||
858 | //valida mensagem com xsd |
||
859 | //no caso do evento nao tem xsd organizado, esta fragmentado |
||
860 | //e por vezes incorreto por isso essa validação está desabilitada |
||
861 | //if (! $this->zValidMessage($cons, 'mdfe', 'eventoMDFe', $version)) { |
||
862 | // $msg = 'Falha na validação. '.$this->error; |
||
863 | // throw new Exception\RuntimeException($msg); |
||
864 | //} |
||
865 | $body = "<mdfeDadosMsg xmlns=\"$this->urlNamespace\">$cons</mdfeDadosMsg>"; |
||
866 | //envia a solicitação via SOAP |
||
867 | $retorno = $this->oSoap->send( |
||
868 | $this->urlService, |
||
869 | $this->urlNamespace, |
||
870 | $this->urlHeader, |
||
871 | $body, |
||
872 | $this->urlMethod |
||
873 | ); |
||
874 | $lastMsg = $this->oSoap->lastMsg; |
||
875 | $this->soapDebug = $this->oSoap->soapDebug; |
||
876 | //salva mensagens |
||
877 | $filename = "$chave-$aliasEvento-eventoMDFe.xml"; |
||
878 | $this->zGravaFile('mdfe', $tpAmb, $filename, $lastMsg); |
||
879 | $filename = "$chave-$aliasEvento-retEventoMDFe.xml"; |
||
880 | $this->zGravaFile('mdfe', $tpAmb, $filename, $retorno); |
||
881 | //tratar dados de retorno |
||
882 | $this->aLastRetEvent = Response::readReturnSefaz($servico, $retorno); |
||
883 | return (string) $retorno; |
||
884 | } |
||
885 | |||
886 | /** |
||
887 | * zTpEv |
||
888 | * |
||
889 | * @param string $tpEvento |
||
890 | * @return array |
||
891 | * @throws Exception\RuntimeException |
||
892 | */ |
||
893 | private function zTpEv($tpEvento = '') |
||
894 | { |
||
895 | //montagem dos dados da mensagem SOAP |
||
896 | switch ($tpEvento) { |
||
897 | case '110111': |
||
898 | //cancelamento |
||
899 | $aliasEvento = 'CancMDFe'; |
||
900 | $descEvento = 'Cancelamento'; |
||
901 | break; |
||
902 | case '110112': |
||
903 | //encerramento |
||
904 | $aliasEvento = 'EncMDFe'; |
||
905 | $descEvento = 'Encerramento'; |
||
906 | break; |
||
907 | case '110114': |
||
908 | //inclusao do condutor |
||
909 | $aliasEvento = 'EvIncCondut'; |
||
910 | $descEvento = 'Inclusao Condutor'; |
||
911 | break; |
||
912 | default: |
||
913 | $msg = "O código do tipo de evento informado não corresponde a " |
||
914 | . "nenhum evento estabelecido."; |
||
915 | throw new Exception\RuntimeException($msg); |
||
916 | } |
||
917 | return array('alias' => $aliasEvento, 'desc' => $descEvento); |
||
918 | } |
||
919 | |||
920 | /** |
||
921 | * validarXml |
||
922 | * Valida qualquer xml do sistema MDFe com seu xsd |
||
923 | * NOTA: caso não exista um arquivo xsd apropriado retorna false |
||
924 | * |
||
925 | * @param string $xml path ou conteudo do xml |
||
926 | * @return boolean |
||
927 | */ |
||
928 | public function validarXml($xml = '') |
||
929 | { |
||
930 | $aResp = array(); |
||
931 | $schem = Identify::identificar($xml, $aResp); |
||
932 | if ($schem == '') { |
||
933 | return true; |
||
934 | } |
||
935 | $xsdFile = $aResp['Id'].'_v'.$aResp['versao'].'.xsd'; |
||
936 | $xsdPath = NFEPHP_ROOT.DIRECTORY_SEPARATOR . |
||
937 | 'schemes' . |
||
938 | DIRECTORY_SEPARATOR . |
||
939 | $this->aConfig['schemesMDFe'] . |
||
940 | DIRECTORY_SEPARATOR . |
||
941 | $xsdFile; |
||
942 | if (! is_file($xsdPath)) { |
||
943 | $this->errors[] = "O arquivo XSD $xsdFile não foi localizado."; |
||
944 | return false; |
||
945 | } |
||
946 | if (! ValidXsd::validar($aResp['xml'], $xsdPath)) { |
||
947 | $this->errors[] = ValidXsd::$errors; |
||
948 | return false; |
||
949 | } |
||
950 | return true; |
||
951 | } |
||
952 | } |
||
953 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.