Completed
Pull Request — master (#38)
by
unknown
16:06
created

BaseTools::zLoadServico()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 45
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 45
ccs 0
cts 33
cp 0
rs 6.7272
cc 7
eloc 31
nc 7
nop 4
crap 56
1
<?php
2
3
namespace NFePHP\Common\Base;
4
5
/**
6
 * Classe base das classes principais para a comunicação com a SEFAZ
7
 *
8
 * @category   NFePHP
9
 * @package    NFePHP\Common\Base
10
 * @copyright  Copyright (c) 2008-2015
11
 * @license    http://www.gnu.org/licenses/lesser.html LGPL v3
12
 * @author     Roberto L. Machado <linux.rlm at gmail dot com>
13
 * @link       http://github.com/nfephp-org/nfephp for the canonical source repository
14
 */
15
16
use NFePHP\Common\Certificate\Pkcs12;
17
use NFePHP\Common\DateTime\DateTime;
18
use NFePHP\Common\Dom\Dom;
19
use NFePHP\Common\Soap\CurlSoap;
20
use NFePHP\Common\Files;
21
use NFePHP\Common\Exception;
22
23
if (!defined('NFEPHP_ROOT')) {
24
    define('NFEPHP_ROOT', dirname(dirname(dirname(__FILE__))));
25
}
26
27
class BaseTools
28
{
29
    /**
30
     * enableSVCRS
31
     * Habilita contingência ao serviço SVC-RS: Sefaz Virtual de Contingência Rio Grande do Sul
32
     * @var boolean
33
     */
34
    public $enableSVCRS = false;
35
    /**
36
     * enableSVCAN
37
     * Habilita contingência ao serviço SVC-AN: Sefaz Virtual de Contingência Ambiente Nacional
38
     * @var boolean
39
     */
40
    public $enableSVCAN = false;
41
    /**
42
     * enableSVCAN
43
     * Habilita contingência ao serviço SVC-AN: Sefaz Virtual de Contingência Ambiente Nacional
44
     * @var boolean
45
     */
46
    public $enableEPEC = false;
47
    /**
48
     * motivoContingencia
49
     * Motivo por ter entrado em Contingencia
50
     * @var string
51
     */
52
    public $motivoContingencia = '';
53
    /**
54
     * tsContingencia
55
     * Timestamp UNIX da data e hora de entrada em contingência
56
     * @var int
57
     */
58
    public $tsContingencia = '';
59
    /**
60
     * verAplic
61
     * Versão da aplicação
62
     * @var string
63
     */
64
    public $verAplic = '';
65
    /**
66
     * certExpireTimestamp
67
     * TimeStamp com a data de vencimento do certificado
68
     * @var double
69
     */
70
    public $certExpireTimestamp = 0;
71
    /**
72
     * ambiente
73
     * @var string
74
     */
75
    public $ambiente = 'homologacao';
76
    /**
77
     * aConfig
78
     * @var array
79
     */
80
    public $aConfig = array();
81
    /**
82
     * sslProtocol
83
     * @var int
84
     */
85
    public $sslProtocol = 0;
86
    /**
87
     * soapTimeout
88
     * @var int
89
     */
90
    public $soapTimeout = 10;
91
    
92
    /**
93
     * oCertificate
94
     * @var Object Class
95
     */
96
    protected $oCertificate;
97
    /**
98
     * oSoap
99
     * @var Object Class
100
     */
101
    protected $oSoap;
102
    /**
103
     * aDocFormat
104
     * @var array
105
     */
106
    protected $aDocFormat = array();
107
    /**
108
     * aProxyConf
109
     * @var array
110
     */
111
    protected $aProxyConf = array();
112
    /**
113
     * aMailConf
114
     * @var array
115
     */
116
    protected $aMailConf = array();
117
    /**
118
     * urlPortal
119
     * Instância do WebService
120
     * @var string
121
     */
122
    protected $urlPortal = '';
123
    /**
124
     * urlcUF
125
     * @var string
126
     */
127
    protected $urlcUF = '';
128
    /**
129
     * urlVersion
130
     * @var string
131
     */
132
    protected $urlVersion = '';
133
    /**
134
     * urlService
135
     * @var string
136
     */
137
    protected $urlService = '';
138
    /**
139
     * urlMethod
140
     * @var string
141
     */
142
    protected $urlMethod = '';
143
    /**
144
     * urlOperation
145
     * @var string
146
     */
147
    protected $urlOperation = '';
148
    /**
149
     * urlNamespace
150
     * @var string
151
     */
152
    protected $urlNamespace = '';
153
    /**
154
     * urlHeader
155
     * @var string
156
     */
157
    protected $urlHeader = '';
158
    /**
159
     * modelo da NFe 55 ou 65
160
     * @var string
161
     */
162
    protected $modelo = '55';
163
    
164
    /**
165
     * cUFlist
166
     * @var array
167
     */
168
    protected $cUFlist = array(
169
        'AC'=>'12',
170
        'AL'=>'27',
171
        'AM'=>'13',
172
        'AN'=>'91',
173
        'AP'=>'16',
174
        'BA'=>'29',
175
        'CE'=>'23',
176
        'DF'=>'53',
177
        'ES'=>'32',
178
        'GO'=>'52',
179
        'MA'=>'21',
180
        'MG'=>'31',
181
        'MS'=>'50',
182
        'MT'=>'51',
183
        'PA'=>'15',
184
        'PB'=>'25',
185
        'PE'=>'26',
186
        'PI'=>'22',
187
        'PR'=>'41',
188
        'RJ'=>'33',
189
        'RN'=>'24',
190
        'RO'=>'11',
191
        'RR'=>'14',
192
        'RS'=>'43',
193
        'SC'=>'42',
194
        'SE'=>'28',
195
        'SP'=>'35',
196
        'TO'=>'17',
197
        'SVAN' => '91'
198
    );
199
    
200
    /**
201
     * __construct
202
     * @param string $configJson
203
     * @throws Exception\InvalidArgumentException
204
     * @throws Exception\RuntimeException
205
     */
206
    public function __construct($configJson = '')
207
    {
208
        if ($configJson == '') {
209
            $msg = 'O arquivo de configuração no formato JSON deve ser passado para a classe.';
210
            throw new Exception\InvalidArgumentException($msg);
211
        }
212
        if (is_file($configJson)) {
213
            $configJson = Files\FilesFolders::readFile($configJson);
214
        }
215
        //carrega os dados de configuração
216
        $this->aConfig    = (array) json_decode($configJson);
217
        if (key_exists('aDocFormat', $this->aConfig)) {
218
            $this->aDocFormat = (array) $this->aConfig['aDocFormat'];
219
        }
220
        if (key_exists('aProxyConf', $this->aConfig)) {
221
            $this->aProxyConf = (array) $this->aConfig['aProxyConf'];
222
        }
223
        if (key_exists('aMailConf', $this->aConfig)) {
224
            $this->aMailConf  = (array) $this->aConfig['aMailConf'];
225
        }
226
        
227
        //seta o timezone
228
        DateTime::tzdBR($this->aConfig['siglaUF']);
229
        //carrega os certificados
230
        $this->oCertificate = new Pkcs12(
231
            $this->aConfig['pathCertsFiles'],
232
            $this->aConfig['cnpj']
233
        );
234
        if ($this->oCertificate->priKey == '') {
235
            //tentar carregar novo certificado
236
            $this->atualizaCertificado(
237
                $this->aConfig['pathCertsFiles'].$this->aConfig['certPfxName'],
238
                $this->aConfig['certPassword']
239
            );
240
            if ($this->oCertificate->expireTimestamp == 0) {
241
                $msg = 'Não existe certificado válido disponível. Atualize o Certificado.';
242
                throw new Exception\RuntimeException($msg);
243
            }
244
        }
245
        $this->setAmbiente($this->aConfig['tpAmb']);
246
        $this->certExpireTimestamp = $this->oCertificate->expireTimestamp;
247
        $this->zLoadSoapClass();
248
        //verifica se a contingência está ativada
249
        $pathContingencia = NFEPHP_ROOT.DIRECTORY_SEPARATOR.'config'.
250
            DIRECTORY_SEPARATOR.$this->aConfig['cnpj'].'_contingencia.json';
251
        if (is_file($pathContingencia)) {
252
            $contJson = Files\FilesFolders::readFile($pathContingencia);
253
            if (! empty($contJson)) {
254
                 $aCont = (array) json_decode($contJson);
255
                 $this->motivoContingencia = $aCont['motivo'];
256
                 $this->tsContingencia = $aCont['ts'];
257
                 $this->enableSVCAN = $aCont['SVCAN'];
258
                 $this->enableSVCRS = $aCont['SVCRS'];
259
            }
260
        }
261
    }
262
    
263
    /**
264
     * setSSLProtocol
265
     * Força o uso de um determinado protocolo de encriptação
266
     * na comunicação https com a SEFAZ usando cURL
267
     * Apenas é necessário quando a versão do PHP e do libssl não
268
     * consegue estabelecer o protocolo correto durante o handshake
269
     * @param string $protocol
270
     */
271
    public function setSSLProtocol($protocol = '')
272
    {
273
        if (! empty($protocol)) {
274
            switch ($protocol) {
275
                case 'TLSv1':
276
                    $this->sslProtocol = 1;
277
                    break;
278
                case 'SSLv2':
279
                    $this->sslProtocol = 2;
280
                    break;
281
                case 'SSLv3':
282
                    $this->sslProtocol = 3;
283
                    break;
284
                case 'TLSv1.0':
285
                    $this->sslProtocol = 4;
286
                    break;
287
                case 'TLSv1.1':
288
                    $this->sslProtocol = 5;
289
                    break;
290
                case 'TLSv1.2':
291
                    $this->sslProtocol = 6;
292
                    break;
293
                default:
294
                    $this->sslProtocol = 0;
295
            }
296
            $this->zLoadSoapClass();
297
        }
298
    }
299
    
300
    /**
301
     * getSSLProtocol
302
     * Retrona o protocolo que está setado
303
     * @return string
304
     */
305
    public function getSSLProtocol()
306
    {
307
        $aPr = array('default','TLSv1','SSLv2','SSLv3','TLSv1.0','TLSv1.1','TLSv1.2');
308
        return $aPr[$this->sslProtocol];
309
    }
310
    
311
    /**
312
     * setSoapTimeOut
313
     * @param integer $segundos
314
     */
315
    public function setSoapTimeOut($segundos = 10)
316
    {
317
        if (! empty($segundos)) {
318
            $this->soapTimeout = $segundos;
319
            $this->zLoadSoapClass();
320
        }
321
    }
322
    
323
    /**
324
     * getSoapTimeOut
325
     * @return integer
326
     */
327
    public function getSoapTimeOut()
328
    {
329
        return $this->soapTimeout;
330
    }
331
    
332
    /**
333
     * setAmbiente
334
     * Seta a varável de ambiente
335
     * @param string $tpAmb
336
     */
337
    protected function setAmbiente($tpAmb = '2')
338
    {
339
        $this->ambiente = 'homologacao';
340
        if ($tpAmb == '1') {
341
            $this->ambiente = 'producao';
342
        }
343
    }
344
    
345
    /**
346
     * atualizaCertificado
347
     * @param string $certpfx certificado pfx em string ou o path para o certificado
348
     * @param string $senha senha para abrir o certificado
349
     * @return boolean
350
     */
351
    public function atualizaCertificado($certpfx = '', $senha = '')
352
    {
353
        if ($certpfx == '' && $senha != '') {
354
            return false;
355
        }
356
        if (is_file($certpfx)) {
357
            $this->oCertificate->loadPfxFile($certpfx, $senha);
358
            return true;
359
        }
360
        $this->oCertificate->loadPfx($certpfx, $senha);
361
        $this->zLoadSoapClass();
362
        return true;
363
    }
364
    
365
    /**
366
     * assinaDoc
367
     * @param string $xml
368
     * @param string $tipo nfe, cte, ou mdfe
369
     * @param string $tag Nome da tag a ser assinada
370
     * @param boolean $saveFile APENAS para salvar NFe, CTe ou MDFe
371
     * @return string
372
     * @throws Exception\InvalidArgumentException
373
     * @throws Exception\RuntimeException
374
     */
375
    public function assinaDoc($xml = '', $tipo = '', $tag = '', $saveFile = false)
376
    {
377
        if ($tag == '') {
378
            $msg = 'Deve ser indicada uma tag a ser assinada';
379
            throw new Exception\InvalidArgumentException($msg);
380
        }
381
        if (is_file($xml)) {
382
            $xml = Files\FilesFolders::readFile($xml);
383
        }
384
        $sxml = $this->oCertificate->signXML($xml, $tag);
385
        $dom = new Dom();
386
        $dom->loadXMLString($sxml);
387
        //$versao = $dom->getElementsByTagName($tag)->item(0)->getAttribute('versao');
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
388
        //if (! $this->zValidMessage($sxml, $tipo, $versao)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
389
        //$msg = "Falha na validação do $tipo. ".$this->error;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
390
        //  throw new Exception\RuntimeException($msg);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
391
        //}
392
        if ($saveFile && $tipo != '') {
393
            $dom = new Dom();
394
            $dom->loadXMLString($sxml);
395
            $tpAmb = $dom->getElementsByTagName('tpAmb')->item(0)->nodeValue;
396
            $anomes = date(
397
                'Ym',
398
                DateTime::convertSefazTimeToTimestamp($dom->getElementsByTagName('dhEmi')->item(0)->nodeValue)
399
            );
400
            $chave = $dom->getChave($tag);
401
            $filename = "$chave-$tipo.xml";
402
            $this->zGravaFile($tipo, $tpAmb, $filename, $sxml, 'assinadas', $anomes);
403
        }
404
        return $sxml;
405
    }
406
    
407
    /**
408
     * setVerAplic
409
     * @param string $versao
410
     */
411
    public function setVerAplic($versao = '')
412
    {
413
        $this->verAplic = $versao;
414
    }
415
416
    /**
417
     * Carrega a classe SOAP e os certificados
418
     */
419
    protected function zLoadSoapClass()
420
    {
421
        $this->oSoap = null;
422
        $this->oSoap = new CurlSoap(
423
            $this->oCertificate->priKeyFile,
424
            $this->oCertificate->pubKeyFile,
425
            $this->oCertificate->certKeyFile,
426
            $this->soapTimeout,
427
            $this->sslProtocol
428
        );
429
    }
430
    
431
    /**
432
     * zLoadServico
433
     * Monta o namespace e o cabecalho da comunicação SOAP
434
     * @param string $service
435
     * @param string $siglaUF
436
     * @param string $tpAmb
437
     * @param string $tipo
438
     * @return bool
439
     * @internal param string $servico Identificação do Servico
440
     * @internal param array $aURL Dados das Urls do SEFAZ
441
     */
442
    protected function zLoadServico(
443
        $tipo,
444
        $service,
445
        $siglaUF,
446
        $tpAmb
447
    ) {
448
        if (empty($tipo) || empty($service) || empty($siglaUF)) {
449
            $this->urlVersion = '';
450
            $this->urlService = '';
451
            $this->urlMethod = '';
452
            $this->urlOperation = '';
453
            $this->urlNamespace = '';
454
            $this->urlHeader = '';
455
            return false;
456
        }
457
        $this->urlcUF = $this->getcUF($siglaUF);
458
        $pathXmlUrlFile = $this->zGetXmlUrlPath($tipo);
459
        
460
        if ($this->enableSVCAN) {
461
            $aURL = self::zLoadSEFAZ($pathXmlUrlFile, $tpAmb, 'SVCAN');
462
        } elseif ($this->enableSVCRS) {
463
            $aURL = self::zLoadSEFAZ($pathXmlUrlFile, $tpAmb, 'SVCRS');
464
        } else {
465
            $aURL = self::zLoadSEFAZ($pathXmlUrlFile, $tpAmb, $siglaUF, $tipo);
466
        }
467
        //recuperação da versão
468
        $this->urlVersion = $aURL[$service]['version'];
469
        //recuperação da url do serviço
470
        $this->urlService = $aURL[$service]['URL'];
471
        //recuperação do método
472
        $this->urlMethod = $aURL[$service]['method'];
473
474
        //montagem do namespace do serviço
475
        if ($tipo == "cte") {
476
            $this->urlNamespace = sprintf("%s/wsdl/%s", $this->urlPortal, $service);
477
478
        } else {
479
            $this->urlOperation = $aURL[$service]['operation'];
480
            $this->urlNamespace = sprintf("%s/wsdl/%s", $this->urlPortal, $this->urlOperation);
481
        }
482
483
        //montagem do cabeçalho da comunicação SOAP
484
        $this->urlHeader = $this->zMountHeader($tipo, $this->urlNamespace, $this->urlcUF, $this->urlVersion);
485
        return true;
486
    }
487
    
488
    /**
489
     * zGetXmlUrlPath
490
     * @param string $tipo
491
     * @return string
492
     */
493
    private function zGetXmlUrlPath($tipo)
494
    {
495
        $path = '';
496
        if ($tipo == 'nfe') {
497
            $path = $this->aConfig['pathXmlUrlFileNFe'];
498
            if ($this->modelo == '65') {
499
                $path = str_replace('55', '65', $path);
500
            } else {
501
                $path = str_replace('65', '55', $path);
502
            }
503
        } elseif ($tipo == 'cte') {
504
            $path = $this->aConfig['pathXmlUrlFileCTe'];
505
        } elseif ($tipo == 'mdfe') {
506
            $path = $this->aConfig['pathXmlUrlFileMDFe'];
507
        } elseif ($tipo == 'cle') {
508
            $path = $this->aConfig['pathXmlUrlFileCLe'];
509
        }
510
        
511
        $pathXmlUrlFile = NFEPHP_ROOT
512
            . DIRECTORY_SEPARATOR
513
            . 'config'
514
            . DIRECTORY_SEPARATOR
515
            . $path;
516
        
517
        return $pathXmlUrlFile;
518
    }
519
    
520
    /**
521
     * zMountHeader
522
     * @param string $tipo
523
     * @param string $namespace
524
     * @param string $cUF
525
     * @param string $version
526
     * @return string
527
     */
528
    private function zMountHeader($tipo, $namespace, $cUF, $version)
529
    {
530
        $header = '';
531
        if ($tipo == 'nfe') {
532
            $header = "<nfeCabecMsg "
533
                . "xmlns=\"$namespace\">"
534
                . "<cUF>$cUF</cUF>"
535
                . "<versaoDados>$version</versaoDados>"
536
                . "</nfeCabecMsg>";
537
        } elseif ($tipo == 'cte') {
538
            $header = "<cteCabecMsg "
539
                . "xmlns=\"$namespace\">"
540
                . "<cUF>$cUF</cUF>"
541
                . "<versaoDados>$version</versaoDados>"
542
                . "</cteCabecMsg>";
543
        } elseif ($tipo == 'mdfe') {
544
            $header = "<mdfeCabecMsg "
545
                . "xmlns=\"$namespace\">"
546
                . "<cUF>$cUF</cUF>"
547
                . "<versaoDados>$version</versaoDados>"
548
                . "</mdfeCabecMsg>";
549
        }
550
        return $header;
551
    }
552
    
553
    /**
554
     * zLoadSEFAZ
555
     * Extrai o URL, nome do serviço e versão dos webservices das SEFAZ de
556
     * todos os Estados da Federação, a partir do arquivo XML de configurações,
557
     * onde este é estruturado para os modelos 55 (NF-e) e 65 (NFC-e) já que
558
     * os endereços dos webservices podem ser diferentes.
559
     * @param string $pathXmlUrlFile
560
     * @param  string $tpAmb Pode ser "2-homologacao" ou "1-producao"
561
     * @param string $siglaUF
562
     * @param strign $tipo nfe, mdfe ou cte
563
     * @return mixed false se houve erro ou array com os dados dos URLs da SEFAZ
564
     * @internal param string $sUF Sigla da Unidade da Federação (ex. SP, RS, SVRS, etc..)
565
     * @see /config/nfe_ws3_modXX.xml
566
     */
567
    protected function zLoadSEFAZ($pathXmlUrlFile = '', $tpAmb = '2', $siglaUF = 'SP', $tipo = 'nfe')
568
    {
569
        //verifica se o arquivo xml pode ser encontrado no caminho indicado
570
        if (! file_exists($pathXmlUrlFile)) {
571
            throw new Exception\RuntimeException(
572
                "Arquivo $pathXmlUrlFile não encontrado."
573
            );
574
        }
575
        //carrega o xml
576
        if (!$xmlWS = simplexml_load_file($pathXmlUrlFile)) {
577
            throw new Exception\RuntimeException(
578
                "Arquivo $pathXmlUrlFile parece ser invalido ou está corrompido."
579
            );
580
        }
581
        $autorizadores = array();
582
        $autorizadores['65'] = array(
583
            'AC'=>'SVRS',
584
            'AL'=>'SVRS',
585
            'AM'=>'AM',
586
            'AN'=>'AN',
587
            'AP'=>'SVRS',
588
            'BA'=>'SVRS',
589
            'CE'=>'CE',
590
            'DF'=>'SVRS',
591
            'ES'=>'SVRS',
592
            'GO'=>'SVRS',
593
            'MA'=>'SVRS',
594
            'MG'=>'MG',
595
            'MS'=>'MS',
596
            'MT'=>'MT',
597
            'PA'=>'SVRS',
598
            'PB'=>'SVRS',
599
            'PE'=>'PE',
600
            'PI'=>'SVRS',
601
            'PR'=>'PR',
602
            'RJ'=>'SVRS',
603
            'RN'=>'SVRS',
604
            'RO'=>'SVRS',
605
            'RR'=>'SVRS',
606
            'RS'=>'RS',
607
            'SC'=>'SVRS',
608
            'SE'=>'SVRS',
609
            'SP'=>'SP',
610
            'TO'=>'SVRS',
611
            'SVAN'=>'SVAN',
612
            'SVRS'=>'SVRS',
613
            'SVCAN'=>'SVCAN',
614
        );
615
        
616
        $autorizadores['55'] = array(
617
            'AC'=>'SVRS',
618
            'AL'=>'SVRS',
619
            'AM'=>'AM',
620
            'AN'=>'AN',
621
            'AP'=>'SVRS',
622
            'BA'=>'BA',
623
            'CE'=>'CE',
624
            'DF'=>'SVRS',
625
            'ES'=>'SVRS',
626
            'GO'=>'GO',
627
            'MA'=>'SVAN',
628
            'MG'=>'MG',
629
            'MS'=>'MS',
630
            'MT'=>'MT',
631
            'PA'=>'SVAN',
632
            'PB'=>'SVRS',
633
            'PE'=>'PE',
634
            'PI'=>'SVAN',
635
            'PR'=>'PR',
636
            'RJ'=>'SVRS',
637
            'RN'=>'SVRS',
638
            'RO'=>'SVRS',
639
            'RR'=>'SVRS',
640
            'RS'=>'RS',
641
            'SC'=>'SVRS',
642
            'SE'=>'SVRS',
643
            'SP'=>'SP',
644
            'TO'=>'SVRS',
645
            'SVAN'=>'SVAN',
646
            'SVRS'=>'SVRS',
647
            'SVCAN'=>'SVCAN',
648
            'SVCRS'=>'SVCRS'
649
        );
650
        //variável de retorno do método
651
        $aUrl = array();
652
        //testa parametro tpAmb
653
        $sAmbiente = 'homologacao';
654
        if ($tpAmb == '1') {
655
            $sAmbiente = 'producao';
656
        }
657
        $alias = $autorizadores[$this->modelo][$siglaUF];
658
        if ($tipo == 'mdfe') {
659
            $alias = 'RS';
660
        }
661
        //estabelece a expressão xpath de busca
662
        $xpathExpression = "/WS/UF[sigla='$alias']/$sAmbiente";
663
        $aUrl = $this->zExtractUrl($xmlWS, $aUrl, $xpathExpression);
664
        //verifica se existem outros serviços exclusivos para esse estado
665
        if ($alias == 'SVAN' || $alias == 'SVRS') {
666
            $xpathExpression = "/WS/UF[sigla='$siglaUF']/$sAmbiente";
667
            $aUrl = $this->zExtractUrl($xmlWS, $aUrl, $xpathExpression);
668
        }
669
        return $aUrl;
670
    }
671
    
672
    /**
673
     * zExtractUrl
674
     * @param \SimpleXMLElement $xmlWS
675
     * @param array $aUrl
676
     * @param string $expression
677
     * @return array
678
     */
679
    protected function zExtractUrl($xmlWS, $aUrl = array(), $expression = '')
680
    {
681
        //para cada "nó" no xml que atenda aos critérios estabelecidos
682
        foreach ($xmlWS->xpath($expression) as $gUF) {
683
            //para cada "nó filho" retonado
684
            foreach ($gUF->children() as $child) {
685
                $u = (string) $child[0];
686
                $aUrl[$child->getName()]['URL'] = $u;
687
                // em cada um desses nós pode haver atributos como a identificação
688
                // do nome do webservice e a sua versão
689
                foreach ($child->attributes() as $a => $b) {
690
                    $aUrl[$child->getName()][$a] = (string) $b;
691
                }
692
            }
693
        }
694
        return $aUrl;
695
    }
696
    
697
    /**
698
     * zGravaFile
699
     * Grava os dados no diretorio das NFe
700
     * @param string $tpAmb ambiente
701
     * @param string $filename nome do arquivo
702
     * @param string $data dados a serem salvos
703
     * @param string $subFolder
704
     * @param string $anomes
705
     * @throws Exception\RuntimeException
706
     */
707
    protected function zGravaFile(
708
        $tipo = '',
709
        $tpAmb = '2',
710
        $filename = '',
711
        $data = '',
712
        $subFolder = 'temporarias',
713
        $anomes = ''
714
    ) {
715
        if ($anomes == '') {
716
            $anomes = date('Ym');
717
        }
718
        $path = '';
719
        if ($tipo == 'nfe') {
720
            $path = $this->aConfig['pathNFeFiles'];
721
        } elseif ($tipo == 'cte') {
722
            $path = $this->aConfig['pathCTeFiles'];
723
        } elseif ($tipo == 'mdfe') {
724
            $path = $this->aConfig['pathMDFeFiles'];
725
        }
726
        $pathTemp = Files\FilesFolders::getFilePath($tpAmb, $path, $subFolder)
727
            . DIRECTORY_SEPARATOR.$anomes;
728
        if (! Files\FilesFolders::saveFile($pathTemp, $filename, $data)) {
729
            $msg = 'Falha na gravação no diretório. '.$pathTemp;
730
            throw new Exception\RuntimeException($msg);
731
        }
732
    }
733
734
    /**
735
     * getcUF
736
     * @param string $siglaUF
737
     * @return string numero cUF
738
     */
739
    public function getcUF($siglaUF = '')
740
    {
741
        return $this->cUFlist[$siglaUF];
742
    }
743
    
744
    /**
745
     * zGetSigla
746
     * @param string $cUF
747
     * @return string
748
     */
749
    protected function zGetSigla($cUF = '')
750
    {
751
        return array_search($cUF, $this->cUFlist);
752
    }
753
}
754