Passed
Push — master ( e9549c...b94f21 )
by
unknown
02:47
created

Tools::getModalXML()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 9
cp 0
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 6
1
<?php
2
3
namespace NFePHP\CTe\Common;
4
5
/**
6
 * Class base responsible for communication with SEFAZ
7
 *
8
 * @category  NFePHP
9
 * @package   NFePHP\CTe\Common\Tools
10
 * @copyright NFePHP Copyright (c) 2008-2017
11
 * @license   http://www.gnu.org/licenses/lgpl.txt LGPLv3+
12
 * @license   https://opensource.org/licenses/MIT MIT
13
 * @license   http://www.gnu.org/licenses/gpl.txt GPLv3+
14
 * @author    Roberto L. Machado <linux.rlm at gmail dot com>
15
 * @link      http://github.com/nfephp-org/sped-nfe for the canonical source repository
16
 */
17
18
use DOMDocument;
19
use InvalidArgumentException;
20
use NFePHP\Common\Certificate;
21
use NFePHP\Common\Signer;
22
use NFePHP\Common\Soap\SoapCurl;
23
use NFePHP\Common\Soap\SoapInterface;
24
use NFePHP\Common\Strings;
25
use NFePHP\Common\TimeZoneByUF;
26
use NFePHP\Common\UFList;
27
use NFePHP\Common\Validator;
28
use NFePHP\CTe\Factories\Contingency;
29
use NFePHP\CTe\Factories\ContingencyCTe;
30
use NFePHP\CTe\Factories\Header;
31
use NFePHP\CTe\Factories\QRCode;
32
use RuntimeException;
33
34
class Tools
35
{
36
    /**
37
     * config class
38
     * @var \stdClass
39
     */
40
    public $config;
41
    /**
42
     * Path to storage folder
43
     * @var string
44
     */
45
    public $pathwsfiles = '';
46
    /**
47
     * Path to schemes folder
48
     * @var string
49
     */
50
    public $pathschemes = '';
51
    /**
52
     * ambiente
53
     * @var string
54
     */
55
    public $ambiente = 'homologacao';
56
    /**
57
     * Environment
58
     * @var int
59
     */
60
    public $tpAmb = 2;
61
    /**
62
     * contingency class
63
     * @var Contingency
64
     */
65
    public $contingency;
66
    /**
67
     * soap class
68
     * @var SoapInterface
69
     */
70
    public $soap;
71
    /**
72
     * Application version
73
     * @var string
74
     */
75
    public $verAplic = '';
76
    /**
77
     * last soap request
78
     * @var string
79
     */
80
    public $lastRequest = '';
81
    /**
82
     * last soap response
83
     * @var string
84
     */
85
    public $lastResponse = '';
86
    /**
87
     * certificate class
88
     * @var Certificate
89
     */
90
    protected $certificate;
91
    /**
92
     * Sign algorithm from OPENSSL
93
     * @var int
94
     */
95
    protected $algorithm = OPENSSL_ALGO_SHA1;
96
    /**
97
     * Canonical conversion options
98
     * @var array
99
     */
100
    protected $canonical = [true, false, null, null];
101
    /**
102
     * Model of CTe 57 or 67
103
     * @var int
104
     */
105
    protected $modelo = 57;
106
    /**
107
     * Version of layout
108
     * @var string
109
     */
110
    protected $versao = '3.00';
111
    /**
112
     * urlPortal
113
     * Instância do WebService
114
     *
115
     * @var string
116
     */
117
    protected $urlPortal = 'http://www.portalfiscal.inf.br/cte';
118
    /**
119
     * urlcUF
120
     * @var string
121
     */
122
    protected $urlcUF = '';
123
    /**
124
     * urlVersion
125
     * @var string
126
     */
127
    protected $urlVersion = '';
128
    /**
129
     * urlService
130
     * @var string
131
     */
132
    protected $urlService = '';
133
    /**
134
     * @var string
135
     */
136
    protected $urlMethod = '';
137
    /**
138
     * @var string
139
     */
140
    protected $urlOperation = '';
141
    /**
142
     * @var string
143
     */
144
    protected $urlNamespace = '';
145
    /**
146
     * @var string
147
     */
148
    protected $urlAction = '';
149
    /**
150
     * @var \SOAPHeader
151
     */
152
    protected $objHeader;
153
    /**
154
     * @var string
155
     */
156
    protected $urlHeader = '';
157
    /**
158
     * @var array
159
     */
160
    protected $soapnamespaces = [
161
        'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
162
        'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema",
163
        'xmlns:soap' => "http://www.w3.org/2003/05/soap-envelope"
164
    ];
165
    /**
166
     * @var array
167
     */
168
    protected $availableVersions = [
169
        '3.00' => 'PL_CTe_300a'
170
    ];
171
    /**
172
     * @var string
173
     */
174
    protected $timezone;
175
176
    /**
177
     * Constructor
178
     * load configurations,
179
     * load Digital Certificate,
180
     * map all paths,
181
     * set timezone and
182
     * and instanciate Contingency::class
183
     * @param string $configJson content of config in json format
184
     * @param Certificate $certificate
185
     */
186
    public function __construct($configJson, Certificate $certificate)
187
    {
188
        $this->config = json_decode($configJson);
189
        $this->pathwsfiles = realpath(
190
                __DIR__ . '/../../storage'
191
            ) . '/';
192
        $this->version($this->config->versao);
193
        $this->setEnvironmentTimeZone($this->config->siglaUF);
194
        $this->setEnvironmentHttpVersion($this->config->siglaUF);
195
        $this->certificate = $certificate;
196
        $this->setEnvironment($this->config->tpAmb);
197
        $this->contingency = new Contingency();
198
    }
199
200
    /**
201
     * set version in http
202
     *
203
     * @param string $sigla Sigla da uf
204
     * @return void
205
     */
206
    private function setEnvironmentHttpVersion($sigla)
207
    {
208
        if (in_array($sigla, ['SP'])) {
209
            $soap = new SoapCurl();
210
            $soap->httpVersion('1.1');
211
            $this->loadSoapClass($soap);
212
        }
213
    }
214
215
    /**
216
     * Sets environment time zone
217
     * @param string $acronym (ou seja a sigla do estado)
218
     * @return void
219
     */
220
    public function setEnvironmentTimeZone($acronym)
221
    {
222
        $this->timezone = TimeZoneByUF::get($acronym);
223
    }
224
225
    /**
226
     * Set application version
227
     * @param string $ver
228
     */
229
    public function setVerAplic($ver)
230
    {
231
        $this->verAplic = $ver;
232
    }
233
234
    /**
235
     * Load Soap Class
236
     * Soap Class may be \NFePHP\Common\Soap\SoapNative
237
     * or \NFePHP\Common\Soap\SoapCurl
238
     * @param SoapInterface $soap
239
     * @return void
240
     */
241
    public function loadSoapClass(SoapInterface $soap)
242
    {
243
        $this->soap = $soap;
244
        $this->soap->loadCertificate($this->certificate);
245
    }
246
247
    /**
248
     * Set OPENSSL Algorithm using OPENSSL constants
249
     * @param int $algorithm
250
     * @return void
251
     */
252
    public function setSignAlgorithm($algorithm = OPENSSL_ALGO_SHA1)
253
    {
254
        $this->algorithm = $algorithm;
255
    }
256
257
    /**
258
     * Set or get model of document CTe = 57 or CTeOS = 67
259
     * @param int $model
260
     * @return int modelo class parameter
261
     */
262
    public function model($model = null)
263
    {
264
        if ($model == 57 || $model == 67) {
265
            $this->modelo = $model;
266
        }
267
        return $this->modelo;
268
    }
269
270
    /**
271
     * Set or get parameter layout version
272
     * @param string $version
273
     * @return string
274
     * @throws InvalidArgumentException
275
     */
276
    public function version($version = '')
277
    {
278
        if (!empty($version)) {
279
            if (!array_key_exists($version, $this->availableVersions)) {
280
                throw new \InvalidArgumentException('Essa versão de layout não está disponível');
281
            }
282
            $this->versao = $version;
283
            $this->config->schemes = $this->availableVersions[$version];
284
            $this->pathschemes = realpath(
285
                    __DIR__ . '/../../schemes/' . $this->config->schemes
286
                ) . '/';
287
        }
288
        return $this->versao;
289
    }
290
291
    /**
292
     * Recover cUF number from state acronym
293
     * @param string $acronym Sigla do estado
294
     * @return int number cUF
295
     */
296
    public function getcUF($acronym)
297
    {
298
        return UFlist::getCodeByUF($acronym);
299
    }
300
301
    /**
302
     * Recover state acronym from cUF number
303
     * @param int $cUF
304
     * @return string acronym sigla
305
     */
306
    public function getAcronym($cUF)
307
    {
308
        return UFlist::getUFByCode($cUF);
309
    }
310
311
    /**
312
     * Validate cUF from the key content and returns the state acronym
313
     * @param string $chave
314
     * @return string
315
     * @throws InvalidArgumentException
316
     */
317
    public function validKeyByUF($chave)
318
    {
319
        $uf = $this->config->siglaUF;
320
        if ($uf != UFList::getUFByCode(substr($chave, 0, 2))) {
321
            throw new \InvalidArgumentException(
322
                "A chave do CTe indicado [$chave] não pertence a [$uf]."
323
            );
324
        }
325
        return $uf;
326
    }
327
328
    /**
329
     * Sign CTe
330
     * @param string $xml CTe xml content
331
     * @return string singed CTe xml
332
     * @throws RuntimeException
333
     */
334
    public function signCTe($xml)
335
    {
336
        //remove all invalid strings
337
        $xml = Strings::clearXmlString($xml);
338
        $signed = Signer::sign(
339
            $this->certificate,
340
            $xml,
341
            'infCte',
342
            'Id',
343
            $this->algorithm,
344
            $this->canonical
345
        );
346
        $dom = new DOMDocument('1.0', 'UTF-8');
347
        $dom->preserveWhiteSpace = false;
348
        $dom->formatOutput = false;
349
        $dom->loadXML($signed);
350
        //exception will be throw if CTe is not valid
351
        $modelo = $dom->getElementsByTagName('mod')->item(0)->nodeValue;
352
        $method = 'cte';
353
        if ($modelo == 67) {
354
            $method = 'cteOS';
355
        }
356
        $isInfCTeSupl = !empty($dom->getElementsByTagName('infCTeSupl')->item(0));
357
        if (!$isInfCTeSupl) {
358
            $signed = $this->addQRCode($dom);
359
        }
360
        $this->isValid($this->versao, $signed, $method);
361
        $modal = (int)$dom->getElementsByTagName('modal')->item(0)->nodeValue;
362
        if ($modelo != 67) {
363
            switch ($modal) {
364
                case 1:
365
                    //Rodoviário
366
                    $rodo = $this->getModalXML($dom, 'rodo');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
367
                    if ($rodo) {
368
                        $this->isValid($this->versao, $rodo, $method . 'ModalRodoviario');
0 ignored issues
show
Bug introduced by
It seems like $rodo defined by $this->getModalXML($dom, 'rodo') on line 366 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
369
                    }
370
                    break;
371
                case 2:
372
                    //Aéreo
373
                    $aereo = $this->getModalXML($dom, 'aereo');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
374
                    if ($aereo) {
375
                        $this->isValid($this->versao, $aereo, $method . 'ModalAereo');
0 ignored issues
show
Bug introduced by
It seems like $aereo defined by $this->getModalXML($dom, 'aereo') on line 373 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
376
                    }
377
                    break;
378
                case 3:
379
                    //Aquaviário
380
                    $aquav = $this->getModalXML($dom, 'aquav');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
381
                    if ($aquav) {
382
                        $this->isValid($this->versao, $aquav, $method . 'ModalAquaviario');
0 ignored issues
show
Bug introduced by
It seems like $aquav defined by $this->getModalXML($dom, 'aquav') on line 380 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
383
                    }
384
                    break;
385
                case 4:
386
                    //Ferroviário
387
                    $ferrov = $this->getModalXML($dom, 'ferrov');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
388
                    if ($ferrov) {
389
                        $this->isValid($this->versao, $ferrov, $method . 'ModalFerroviario');
0 ignored issues
show
Bug introduced by
It seems like $ferrov defined by $this->getModalXML($dom, 'ferrov') on line 387 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
390
                    }
391
                    break;
392
                case 5:
393
                    //Dutoviário
394
                    $duto = $this->getModalXML($dom, 'duto');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
395
                    if ($duto) {
396
                        $this->isValid($this->versao, $duto, $method . 'ModalDutoviario');
0 ignored issues
show
Bug introduced by
It seems like $duto defined by $this->getModalXML($dom, 'duto') on line 394 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
397
                    }
398
                    break;
399
                case 6:
400
                    //Multimodal
401
                    $multimodal = $this->getModalXML($dom, 'multimodal');
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
402
                    if ($multimodal) {
403
                        $this->isValid($this->versao, $multimodal, $method . 'MultiModal');
0 ignored issues
show
Bug introduced by
It seems like $multimodal defined by $this->getModalXML($dom, 'multimodal') on line 401 can also be of type boolean; however, NFePHP\CTe\Common\Tools::isValid() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
404
                    }
405
                    break;
406
            }
407
        }
408
        return $signed;
409
    }
410
411
    /**
412
     * @param string $Dom CTe xml content
0 ignored issues
show
Bug introduced by
There is no parameter named $Dom. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
413
     * @param string $xml CTe xml content
0 ignored issues
show
Bug introduced by
There is no parameter named $xml. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
414
     * @return string|bool
415
     * @todo
416
     * Retorna o xml do modal especifico
417
     */
418
    public function getModalXML($dom, $modal)
419
    {
420
        $modal = $dom->getElementsByTagName($modal)->item(0);
0 ignored issues
show
Bug introduced by
The method getElementsByTagName cannot be called on $dom (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
421
        if (!empty($modal)) {
422
            $modal->setAttribute("xmlns", "http://www.portalfiscal.inf.br/cte");
423
            return $dom->saveXML($modal);
0 ignored issues
show
Bug introduced by
The method saveXML cannot be called on $dom (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
424
        }
425
        return false;
426
    }
427
428
    /**
429
     * @todo
430
     * Corret NFe fields when in contingency mode is set
431
     * @param string $xml CTe xml content
432
     * @return string
433
     */
434
    protected function correctCTeForContingencyMode($xml)
435
    {
436
        if ($this->contingency->type == '') {
437
            return $xml;
438
        }
439
        $xml = ContingencyCTe::adjust($xml, $this->contingency);
440
        return $this->signCTe($xml);
441
    }
442
443
    /**
444
     * Performs xml validation with its respective
445
     * XSD structure definition document
446
     * NOTE: if dont exists the XSD file will return true
447
     * @param string $version layout version
448
     * @param string $body
449
     * @param string $method
450
     * @return boolean
451
     */
452
    protected function isValid($version, $body, $method)
453
    {
454
        $schema = $this->pathschemes . $method . "_v$version.xsd";
455
        if (!is_file($schema)) {
456
            return true;
457
        }
458
        return Validator::isValid(
459
            $body,
460
            $schema
461
        );
462
    }
463
464
    /**
465
     * Verifies the existence of the service
466
     * @param string $service
467
     * @throws RuntimeException
468
     */
469
    protected function checkContingencyForWebServices($service)
0 ignored issues
show
Unused Code introduced by
The parameter $service is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
470
    {
471
        $permit = [
472
            57 => ['SVSP', 'SVRS'],
473
            67 => ['SVSP', 'SVRS']
474
        ];
475
476
        $type = $this->contingency->type;
477
        $mod = $this->modelo;
478
        if (!empty($type)) {
479
            if (array_search($type, $permit[$mod]) === false) {
480
                throw new RuntimeException(
481
                    "Esse modo de contingência [$type] não é aceito "
482
                    . "para o modelo [$mod]"
483
                );
484
            }
485
        }
486
    }
487
488
    /**
489
     * Alter environment from "homologacao" to "producao" and vice-versa
490
     * @param int $tpAmb
491
     * @return void
492
     */
493
    public function setEnvironment($tpAmb = 2)
494
    {
495
        if (!empty($tpAmb) && ($tpAmb == 1 || $tpAmb == 2)) {
496
            $this->tpAmb = $tpAmb;
497
            $this->ambiente = ($tpAmb == 1) ? 'producao' : 'homologacao';
498
        }
499
    }
500
501
    /**
502
     * Set option for canonical transformation see C14n
503
     * @param array $opt
504
     * @return array
505
     */
506
    public function canonicalOptions($opt = [true, false, null, null])
507
    {
508
        if (!empty($opt) && is_array($opt)) {
509
            $this->canonical = $opt;
510
        }
511
        return $this->canonical;
512
    }
513
514
    /**
515
     * Assembles all the necessary parameters for soap communication
516
     * @param string $service
517
     * @param string $uf
518
     * @param string $tpAmb
519
     * @param bool $ignoreContingency
520
     * @return void
521
     */
522
    protected function servico(
523
        $service,
524
        $uf,
525
        $tpAmb,
526
        $ignoreContingency = false
527
    )
528
    {
529
        $ambiente = $tpAmb == 1 ? "producao" : "homologacao";
530
        $webs = new Webservices($this->getXmlUrlPath());
531
        $sigla = $uf;
532
        if (!$ignoreContingency) {
533
            $contType = $this->contingency->type;
534
            if (!empty($contType) && ($contType == 'SVRS' || $contType == 'SVSP')) {
535
                $sigla = $contType;
536
            }
537
        }
538
        $stdServ = $webs->get($sigla, $ambiente, $this->modelo);
539
        if ($stdServ === false) {
540
            throw new \RuntimeException(
541
                "Nenhum serviço foi localizado para esta unidade "
542
                . "da federação [$sigla], com o modelo [$this->modelo]."
543
            );
544
        }
545
        if (empty($stdServ->$service->url)) {
546
            throw new \RuntimeException(
547
                "Este serviço [$service] não está disponivel para esta "
548
                . "unidade da federação [$uf] ou para este modelo de Nota ["
549
                . $this->modelo
550
                . "]."
551
            );
552
        }
553
        //recuperação do cUF
554
        $this->urlcUF = $this->getcUF($uf);
0 ignored issues
show
Documentation Bug introduced by
The property $urlcUF was declared of type string, but $this->getcUF($uf) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
555
        if ($this->urlcUF > 91) {
556
            //foi solicitado dado de SVRS ou SVSP
557
            $this->urlcUF = $this->getcUF($this->config->siglaUF);
0 ignored issues
show
Documentation Bug introduced by
The property $urlcUF was declared of type string, but $this->getcUF($this->config->siglaUF) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
558
        }
559
        //recuperação da versão
560
        $this->urlVersion = $stdServ->$service->version;
561
        //recuperação da url do serviço
562
        $this->urlService = $stdServ->$service->url;
563
        //recuperação do método
564
        $this->urlMethod = $stdServ->$service->method;
565
        //recuperação da operação
566
        $this->urlOperation = $stdServ->$service->operation;
567
        //montagem do namespace do serviço
568
        $this->urlNamespace = sprintf(
569
            "%s/wsdl/%s",
570
            $this->urlPortal,
571
            $this->urlOperation
572
        );
573
        //montagem do cabeçalho da comunicação SOAP
574
        $this->urlHeader = Header::get(
575
            $this->urlNamespace,
576
            $this->urlcUF,
577
            $this->urlVersion
578
        );
579
        $this->urlAction = "\""
580
            . $this->urlNamespace
581
            . "/"
582
            . $this->urlMethod
583
            . "\"";
584
        //montagem do SOAP Header
585
        $this->objHeader = new \SOAPHeader(
586
            $this->urlNamespace,
587
            'cteCabecMsg',
588
            ['cUF' => $this->urlcUF, 'versaoDados' => $this->urlVersion]
589
        );
590
    }
591
592
    /**
593
     * Send request message to webservice
594
     * @param array $parameters
595
     * @param string $request
596
     * @return string
597
     */
598
    protected function sendRequest($request, array $parameters = [])
599
    {
600
        $this->checkSoap();
601
        return (string)$this->soap->send(
602
            $this->urlService,
603
            $this->urlMethod,
604
            $this->urlAction,
605
            SOAP_1_2,
606
            $parameters,
607
            $this->soapnamespaces,
608
            $request,
609
            $this->objHeader
610
        );
611
    }
612
613
    /**
614
     * Recover path to xml data base with list of soap services
615
     * @return string
616
     */
617
    protected function getXmlUrlPath()
618
    {
619
        $file = $this->pathwsfiles
620
            . DIRECTORY_SEPARATOR
621
            . "wscte_" . $this->versao . "_mod57.xml";
622
        if (!file_exists($file)) {
623
            return '';
624
        }
625
        return file_get_contents($file);
626
    }
627
628
    /**
629
     * Add QRCode Tag to signed XML from a NFCe
630
     * @param DOMDocument $dom
631
     * @return string
632
     */
633
    protected function addQRCode(DOMDocument $dom)
634
    {
635
        $tpAmb = $this->config->tpAmb == 1 ? 'producao' : 'homologacao';
636
        $sigla = $this->config->siglaUF;
637
638
        $webs = new Webservices($this->getXmlUrlPath());
639
        $std = $webs->get($sigla, $tpAmb, $this->modelo);
640
641
        if ($std === false) {
642
            throw new \RuntimeException(
643
                "Nenhum serviço foi localizado para esta unidade "
644
                . "da federação [$sigla], com o modelo [$this->modelo]."
645
            );
646
        }
647
648
        if (empty($std->QRCode->url)) {
649
            throw new \RuntimeException(
650
                "Este serviço [QRCode] não está disponivel para esta "
651
                . "unidade da federação [$sigla] ou para este modelo de Nota ["
652
                . $this->modelo
653
                . "]."
654
            );
655
        }
656
657
        $signed = QRCode::putQRTag(
658
            $dom,
659
            $std->QRCode->url
660
        );
661
662
        return Strings::clearXmlString($signed);
663
    }
664
665
    /**
666
     * Verify if SOAP class is loaded, if not, force load SoapCurl
667
     */
668
    protected function checkSoap()
669
    {
670
        if (empty($this->soap)) {
671
            $this->soap = new SoapCurl($this->certificate);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \NFePHP\Common\Soap\...url($this->certificate) of type object<NFePHP\Common\Soap\SoapCurl> is incompatible with the declared type object<NFePHP\Common\Soap\SoapInterface> of property $soap.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
672
        }
673
    }
674
}
675