Passed
Pull Request — master (#253)
by
unknown
01:57
created

Tools::setSignAlgorithm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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
    /**
173
     * Constructor
174
     * load configurations,
175
     * load Digital Certificate,
176
     * map all paths,
177
     * set timezone and
178
     * and instanciate Contingency::class
179
     * @param string $configJson content of config in json format
180
     * @param Certificate $certificate
181
     */
182
    public function __construct($configJson, Certificate $certificate)
183
    {
184
        $this->config = json_decode($configJson);
185
        $this->pathwsfiles = realpath(
186
            __DIR__ . '/../../storage'
187
        ) . '/';
188
        $this->version($this->config->versao);
189
        $this->setEnvironmentTimeZone($this->config->siglaUF);
190
        $this->certificate = $certificate;
191
        $this->setEnvironment($this->config->tpAmb);
192
        $this->contingency = new Contingency();
193
    }
194
195
    /**
196
     * Sets environment time zone
197
     * @param string $acronym (ou seja a sigla do estado)
198
     * @return void
199
     */
200
    public function setEnvironmentTimeZone($acronym)
201
    {
202
        date_default_timezone_set(TimeZoneByUF::get($acronym));
203
    }
204
205
    /**
206
     * Set application version
207
     * @param string $ver
208
     */
209
    public function setVerAplic($ver)
210
    {
211
        $this->verAplic = $ver;
212
    }
213
214
    /**
215
     * Load Soap Class
216
     * Soap Class may be \NFePHP\Common\Soap\SoapNative
217
     * or \NFePHP\Common\Soap\SoapCurl
218
     * @param SoapInterface $soap
219
     * @return void
220
     */
221
    public function loadSoapClass(SoapInterface $soap)
222
    {
223
        $this->soap = $soap;
224
        $this->soap->loadCertificate($this->certificate);
225
    }
226
227
    /**
228
     * Set OPENSSL Algorithm using OPENSSL constants
229
     * @param int $algorithm
230
     * @return void
231
     */
232
    public function setSignAlgorithm($algorithm = OPENSSL_ALGO_SHA1)
233
    {
234
        $this->algorithm = $algorithm;
235
    }
236
237
    /**
238
     * Set or get model of document CTe = 57 or CTeOS = 67
239
     * @param int $model
240
     * @return int modelo class parameter
241
     */
242
    public function model($model = null)
243
    {
244
        if ($model == 57 || $model == 67) {
245
            $this->modelo = $model;
246
        }
247
        return $this->modelo;
248
    }
249
250
    /**
251
     * Set or get parameter layout version
252
     * @param string $version
253
     * @return string
254
     * @throws InvalidArgumentException
255
     */
256
    public function version($version = '')
257
    {
258
        if (!empty($version)) {
259
            if (!array_key_exists($version, $this->availableVersions)) {
260
                throw new \InvalidArgumentException('Essa versão de layout não está disponível');
261
            }
262
            $this->versao = $version;
263
            $this->config->schemes = $this->availableVersions[$version];
264
            $this->pathschemes = realpath(
265
                __DIR__ . '/../../schemes/' . $this->config->schemes
266
            ) . '/';
267
        }
268
        return $this->versao;
269
    }
270
271
    /**
272
     * Recover cUF number from state acronym
273
     * @param string $acronym Sigla do estado
274
     * @return int number cUF
275
     */
276
    public function getcUF($acronym)
277
    {
278
        return UFlist::getCodeByUF($acronym);
279
    }
280
281
    /**
282
     * Recover state acronym from cUF number
283
     * @param int $cUF
284
     * @return string acronym sigla
285
     */
286
    public function getAcronym($cUF)
287
    {
288
        return UFlist::getUFByCode($cUF);
289
    }
290
291
    /**
292
     * Validate cUF from the key content and returns the state acronym
293
     * @param string $chave
294
     * @return string
295
     * @throws InvalidArgumentException
296
     */
297
    public function validKeyByUF($chave)
298
    {
299
        $uf = $this->config->siglaUF;
300
        if ($uf != UFList::getUFByCode(substr($chave, 0, 2))) {
301
            throw new \InvalidArgumentException(
302
                "A chave do CTe indicado [$chave] não pertence a [$uf]."
303
            );
304
        }
305
        return $uf;
306
    }
307
308
    /**
309
     * Sign CTe
310
     * @param string $xml CTe xml content
311
     * @return string singed CTe xml
312
     * @throws RuntimeException
313
     */
314
    public function signCTe($xml)
315
    {
316
        //remove all invalid strings
317
        $xml = Strings::clearXmlString($xml);
318
        $signed = Signer::sign(
319
            $this->certificate,
320
            $xml,
321
            'infCte',
322
            'Id',
323
            $this->algorithm,
324
            $this->canonical
325
        );
326
        $dom = new DOMDocument('1.0', 'UTF-8');
327
        $dom->preserveWhiteSpace = false;
328
        $dom->formatOutput = false;
329
        $dom->loadXML($signed);
330
        //exception will be throw if CTe is not valid
331
        $modelo = $dom->getElementsByTagName('mod')->item(0)->nodeValue;
332
        $method = 'cte';
333
        if ($modelo == 67) {
334
            $method = 'cteOS';
335
        }
336
        $isInfCTeSupl = !empty($dom->getElementsByTagName('infCTeSupl')->item(0));
337
        if (!$isInfCTeSupl) {
338
            $signed = $this->addQRCode($dom);
339
        }
340
        $this->isValid($this->versao, $signed, $method);
341
        $modal = (int)$dom->getElementsByTagName('modal')->item(0)->nodeValue;
342
        if ($modelo != 67) {
343
            switch ($modal) {
344
                case 1:
345
                    //Rodoviário
346
                    $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...
347
                    if ($rodo) {
348
                        $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 346 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...
349
                    }
350
                    break;
351
                case 2:
352
                    //Aéreo
353
                    $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...
354
                    if ($aereo) {
355
                        $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 353 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...
356
                    }
357
                    break;
358
                case 3:
359
                    //Aquaviário
360
                    $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...
361
                    if ($aquav) {
362
                        $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 360 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...
363
                    }
364
                    break;
365
                case 4:
366
                    //Ferroviário
367
                    $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...
368
                    if ($ferrov) {
369
                        $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 367 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...
370
                    }
371
                    break;
372
                case 5:
373
                    //Dutoviário
374
                    $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...
375
                    if ($duto) {
376
                        $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 374 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...
377
                    }
378
                    break;
379
                case 6:
380
                    //Multimodal
381
                    $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...
382
                    if ($multimodal) {
383
                        $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 381 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...
384
                    }
385
                    break;
386
            }
387
        }
388
        return $signed;
389
    }
390
391
    /**
392
     * @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...
393
     * @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...
394
     * @return string|bool
395
     * @todo
396
     * Retorna o xml do modal especifico
397
     */
398
    public function getModalXML($dom, $modal)
399
    {
400
        $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...
401
        if (!empty($modal)) {
402
            $modal->setAttribute("xmlns", "http://www.portalfiscal.inf.br/cte");
403
            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...
404
        }
405
        return false;
406
    }
407
408
    /**
409
     * @todo
410
     * Corret NFe fields when in contingency mode is set
411
     * @param string $xml CTe xml content
412
     * @return string
413
     */
414
    protected function correctCTeForContingencyMode($xml)
415
    {
416
        if ($this->contingency->type == '') {
417
            return $xml;
418
        }
419
        $xml = ContingencyCTe::adjust($xml, $this->contingency);
420
        return $this->signCTe($xml);
421
    }
422
423
    /**
424
     * Performs xml validation with its respective
425
     * XSD structure definition document
426
     * NOTE: if dont exists the XSD file will return true
427
     * @param string $version layout version
428
     * @param string $body
429
     * @param string $method
430
     * @return boolean
431
     */
432
    protected function isValid($version, $body, $method)
433
    {
434
        $schema = $this->pathschemes . $method . "_v$version.xsd";
435
        if (!is_file($schema)) {
436
            return true;
437
        }
438
        return Validator::isValid(
439
            $body,
440
            $schema
441
        );
442
    }
443
444
    /**
445
     * Verifies the existence of the service
446
     * @param string $service
447
     * @throws RuntimeException
448
     */
449
    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...
450
    {
451
        $permit = [
452
            57 => ['SVSP', 'SVRS'],
453
            67 => ['SVSP', 'SVRS']
454
        ];
455
456
        $type = $this->contingency->type;
457
        $mod = $this->modelo;
458
        if (!empty($type)) {
459
            if (array_search($type, $permit[$mod]) === false) {
460
                throw new RuntimeException(
461
                    "Esse modo de contingência [$type] não é aceito "
462
                        . "para o modelo [$mod]"
463
                );
464
            }
465
        }
466
    }
467
468
    /**
469
     * Alter environment from "homologacao" to "producao" and vice-versa
470
     * @param int $tpAmb
471
     * @return void
472
     */
473
    public function setEnvironment($tpAmb = 2)
474
    {
475
        if (!empty($tpAmb) && ($tpAmb == 1 || $tpAmb == 2)) {
476
            $this->tpAmb = $tpAmb;
477
            $this->ambiente = ($tpAmb == 1) ? 'producao' : 'homologacao';
478
        }
479
    }
480
481
    /**
482
     * Set option for canonical transformation see C14n
483
     * @param array $opt
484
     * @return array
485
     */
486
    public function canonicalOptions($opt = [true, false, null, null])
487
    {
488
        if (!empty($opt) && is_array($opt)) {
489
            $this->canonical = $opt;
490
        }
491
        return $this->canonical;
492
    }
493
494
    /**
495
     * Assembles all the necessary parameters for soap communication
496
     * @param string $service
497
     * @param string $uf
498
     * @param string $tpAmb
499
     * @param bool $ignoreContingency
500
     * @return void
501
     */
502
    protected function servico(
503
        $service,
504
        $uf,
505
        $tpAmb,
506
        $ignoreContingency = false
507
    ) {
508
        $ambiente = $tpAmb == 1 ? "producao" : "homologacao";
509
        $webs = new Webservices($this->getXmlUrlPath());
510
        $sigla = $uf;
511
        if (!$ignoreContingency) {
512
            $contType = $this->contingency->type;
513
            if (
514
                !empty($contType)
515
                && ($contType == 'SVRS' || $contType == 'SVSP')
516
            ) {
517
                $sigla = $contType;
518
            }
519
        }
520
        $stdServ = $webs->get($sigla, $ambiente, $this->modelo);
521
        if ($stdServ === false) {
522
            throw new \RuntimeException(
523
                "Nenhum serviço foi localizado para esta unidade "
524
                    . "da federação [$sigla], com o modelo [$this->modelo]."
525
            );
526
        }
527
        if (empty($stdServ->$service->url)) {
528
            throw new \RuntimeException(
529
                "Este serviço [$service] não está disponivel para esta "
530
                    . "unidade da federação [$uf] ou para este modelo de Nota ["
531
                    . $this->modelo
532
                    . "]."
533
            );
534
        }
535
        //recuperação do cUF
536
        $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...
537
        if ($this->urlcUF > 91) {
538
            //foi solicitado dado de SVRS ou SVSP
539
            $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...
540
        }
541
        //recuperação da versão
542
        $this->urlVersion = $stdServ->$service->version;
543
        //recuperação da url do serviço
544
        $this->urlService = $stdServ->$service->url;
545
        //recuperação do método
546
        $this->urlMethod = $stdServ->$service->method;
547
        //recuperação da operação
548
        $this->urlOperation = $stdServ->$service->operation;
549
        //montagem do namespace do serviço
550
        $this->urlNamespace = sprintf(
551
            "%s/wsdl/%s",
552
            $this->urlPortal,
553
            $this->urlOperation
554
        );
555
        //montagem do cabeçalho da comunicação SOAP
556
        $this->urlHeader = Header::get(
557
            $this->urlNamespace,
558
            $this->urlcUF,
559
            $this->urlVersion
560
        );
561
        $this->urlAction = "\""
562
            . $this->urlNamespace
563
            . "/"
564
            . $this->urlMethod
565
            . "\"";
566
        //montagem do SOAP Header
567
        $this->objHeader = new \SOAPHeader(
568
            $this->urlNamespace,
569
            'cteCabecMsg',
570
            ['cUF' => $this->urlcUF, 'versaoDados' => $this->urlVersion]
571
        );
572
    }
573
574
    /**
575
     * Send request message to webservice
576
     * @param array $parameters
577
     * @param string $request
578
     * @return string
579
     */
580
    protected function sendRequest($request, array $parameters = [])
581
    {
582
        $this->checkSoap();
583
        return (string) $this->soap->send(
584
            $this->urlService,
585
            $this->urlMethod,
586
            $this->urlAction,
587
            SOAP_1_2,
588
            $parameters,
589
            $this->soapnamespaces,
590
            $request,
591
            $this->objHeader
592
        );
593
    }
594
595
    /**
596
     * Recover path to xml data base with list of soap services
597
     * @return string
598
     */
599
    protected function getXmlUrlPath()
600
    {
601
        $file = $this->pathwsfiles
602
            . DIRECTORY_SEPARATOR
603
            . "wscte_" . $this->versao . "_mod57.xml";
604
        if (!file_exists($file)) {
605
            return '';
606
        }
607
        return file_get_contents($file);
608
    }
609
610
    /**
611
     * Add QRCode Tag to signed XML from a NFCe
612
     * @param DOMDocument $dom
613
     * @return string
614
     */
615
    protected function addQRCode(DOMDocument $dom)
616
    {
617
        $tpAmb = $this->config->tpAmb == 1 ? 'producao' : 'homologacao';
618
        $sigla = $this->config->siglaUF;
619
620
        $webs = new Webservices($this->getXmlUrlPath());
621
        $std = $webs->get($sigla, $tpAmb, $this->modelo);
622
623
        if ($std === false) {
624
            throw new \RuntimeException(
625
                "Nenhum serviço foi localizado para esta unidade "
626
                . "da federação [$sigla], com o modelo [$this->modelo]."
627
            );
628
        }
629
630
        if (empty($std->QRCode->url)) {
631
            throw new \RuntimeException(
632
                "Este serviço [QRCode] não está disponivel para esta "
633
                . "unidade da federação [$sigla] ou para este modelo de Nota ["
634
                . $this->modelo
635
                . "]."
636
            );
637
        }
638
639
        $signed = QRCode::putQRTag(
640
            $dom,
641
            $std->QRCode->url
642
        );
643
644
        return Strings::clearXmlString($signed);
645
    }
646
647
    /**
648
     * Verify if SOAP class is loaded, if not, force load SoapCurl
649
     */
650
    protected function checkSoap()
651
    {
652
        if (empty($this->soap)) {
653
            $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...
654
        }
655
    }
656
}
657