Completed
Pull Request — master (#83)
by
unknown
11:11
created

Tools::servico()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 8
nop 3
dl 0
loc 60
rs 8.5616
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace NFePHP\MDFe\Common;
4
5
/**
6
 * Class base responsible for communication with SEFAZ
7
 *
8
 * @author    Cleiton Perin <cperin20 at gmail dot com>
9
 * @package   NFePHP\MDFe\Common\Tools
10
 * @copyright NFePHP Copyright (c) 2008-2019
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
 * @category  NFePHP
15
 * @link      http://github.com/nfephp-org/sped-mdfe 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\MDFe\Factories\Header;
29
use NFePHP\MDFe\Factories\QRCode;
30
use RuntimeException;
31
32
class Tools
33
{
34
    /**
35
     * config class
36
     * @var \stdClass
37
     */
38
    public $config;
39
    /**
40
     * Path to storage folder
41
     * @var string
42
     */
43
    public $pathwsfiles = '';
44
    /**
45
     * Path to schemes folder
46
     * @var string
47
     */
48
    public $pathschemes = '';
49
    /**
50
     * ambiente
51
     * @var string
52
     */
53
    public $ambiente = 'homologacao';
54
    /**
55
     * Environment
56
     * @var int
57
     */
58
    public $tpAmb = 2;
59
    /**
60
     * soap class
61
     * @var SoapInterface
62
     */
63
    public $soap;
64
    /**
65
     * Application version
66
     * @var string
67
     */
68
    public $verAplic = '';
69
    /**
70
     * last soap request
71
     * @var string
72
     */
73
    public $lastRequest = '';
74
    /**
75
     * last soap response
76
     * @var string
77
     */
78
    public $lastResponse = '';
79
    /**
80
     * certificate class
81
     * @var Certificate
82
     */
83
    protected $certificate;
84
    /**
85
     * Sign algorithm from OPENSSL
86
     * @var int
87
     */
88
    protected $algorithm = OPENSSL_ALGO_SHA1;
89
    /**
90
     * Canonical conversion options
91
     * @var array
92
     */
93
    protected $canonical = [true, false, null, null];
94
    /**
95
     * Model of MDFe 58
96
     * @var int
97
     */
98
    protected $modelo = 58;
99
    /**
100
     * Version of layout
101
     * @var string
102
     */
103
    protected $versao = '3.00';
104
    /**
105
     * urlPortal
106
     * Instância do WebService
107
     *
108
     * @var string
109
     */
110
    protected $urlPortal = 'http://www.portalfiscal.inf.br/mdfe';
111
    /**
112
     * urlcUF
113
     * @var string
114
     */
115
    protected $urlcUF = '';
116
    /**
117
     * urlVersion
118
     * @var string
119
     */
120
    protected $urlVersion = '';
121
    /**
122
     * urlService
123
     * @var string
124
     */
125
    protected $urlService = '';
126
    /**
127
     * @var string
128
     */
129
    protected $urlMethod = '';
130
    /**
131
     * @var string
132
     */
133
    protected $urlOperation = '';
134
    /**
135
     * @var string
136
     */
137
    protected $urlNamespace = '';
138
    /**
139
     * @var string
140
     */
141
    protected $urlAction = '';
142
    /**
143
     * @var \SOAPHeader
144
     */
145
    protected $objHeader;
146
    /**
147
     * @var string
148
     */
149
    protected $urlHeader = '';
150
    /**
151
     * @var array
152
     */
153
    protected $soapnamespaces = [
154
        'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
155
        'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema",
156
        'xmlns:soap' => "http://www.w3.org/2003/05/soap-envelope"
157
    ];
158
    /**
159
     * @var array
160
     */
161
    protected $availableVersions = [
162
        '3.00' => 'PL_MDFe_300a'
163
    ];
164
165
    /**
166
     * Constructor
167
     * load configurations,
168
     * load Digital Certificate,
169
     * map all paths,
170
     * set timezone and
171
     * @param string $configJson content of config in json format
172
     * @param Certificate $certificate
173
     */
174
    public function __construct($configJson, Certificate $certificate)
175
    {
176
        $this->config = json_decode($configJson);
177
        $this->pathwsfiles = realpath(
178
            __DIR__ . '/../../storage'
179
        ) . '/';
180
        $this->version($this->config->versao);
181
        $this->setEnvironmentTimeZone($this->config->siglaUF);
182
        $this->certificate = $certificate;
183
        $this->setEnvironment($this->config->tpAmb);
184
    }
185
186
    /**
187
     * Sets environment time zone
188
     * @param string $acronym (ou seja a sigla do estado)
189
     * @return void
190
     */
191
    public function setEnvironmentTimeZone($acronym)
192
    {
193
        date_default_timezone_set(TimeZoneByUF::get($acronym));
194
    }
195
196
    /**
197
     * Set application version
198
     * @param string $ver
199
     */
200
    public function setVerAplic($ver)
201
    {
202
        $this->verAplic = $ver;
203
    }
204
205
    /**
206
     * Load Soap Class
207
     * Soap Class may be \NFePHP\Common\Soap\SoapNative
208
     * or \NFePHP\Common\Soap\SoapCurl
209
     * @param SoapInterface $soap
210
     * @return void
211
     */
212
    public function loadSoapClass(SoapInterface $soap)
213
    {
214
        $this->soap = $soap;
215
        $this->soap->loadCertificate($this->certificate);
216
    }
217
218
    /**
219
     * Set OPENSSL Algorithm using OPENSSL constants
220
     * @param int $algorithm
221
     * @return void
222
     */
223
    public function setSignAlgorithm($algorithm = OPENSSL_ALGO_SHA1)
224
    {
225
        $this->algorithm = $algorithm;
226
    }
227
228
    /**
229
     * Set or get parameter layout version
230
     * @param string $version
231
     * @return string
232
     * @throws InvalidArgumentException
233
     */
234
    public function version($version = '')
235
    {
236
        if (!empty($version)) {
237
            if (!array_key_exists($version, $this->availableVersions)) {
238
                throw new \InvalidArgumentException('Essa versão de layout não está disponível');
239
            }
240
            $this->versao = $version;
241
            $this->config->schemes = $this->availableVersions[$version];
242
            $this->pathschemes = realpath(
243
                __DIR__ . '/../../schemes/' . $this->config->schemes
244
            ) . '/';
245
        }
246
        return $this->versao;
247
    }
248
249
    /**
250
     * Recover cUF number from state acronym
251
     * @param string $acronym Sigla do estado
252
     * @return int number cUF
253
     */
254
    public function getcUF($acronym)
255
    {
256
        return UFlist::getCodeByUF($acronym);
257
    }
258
259
    /**
260
     * Recover state acronym from cUF number
261
     * @param int $cUF
262
     * @return string acronym sigla
263
     */
264
    public function getAcronym($cUF)
265
    {
266
        return UFlist::getUFByCode($cUF);
267
    }
268
269
    /**
270
     * Validate cUF from the key content and returns the state acronym
271
     * @param string $chave
272
     * @return string
273
     * @throws InvalidArgumentException
274
     */
275
    public function validKeyByUF($chave)
276
    {
277
        $uf = $this->config->siglaUF;
278
        if ($uf != UFList::getUFByCode(substr($chave, 0, 2))) {
279
            throw new \InvalidArgumentException(
280
                "A chave do MDFe indicado [$chave] não pertence a [$uf]."
281
            );
282
        }
283
        return $uf;
284
    }
285
286
    /**
287
     * Sign MDFe
288
     * @param string $xml MDFe xml content
289
     * @return string singed MDFe xml
290
     * @throws RuntimeException
291
     */
292
    public function signMDFe($xml)
293
    {
294
        //remove all invalid strings
295
        $xml = Strings::clearXmlString($xml);
296
        $signed = Signer::sign(
297
            $this->certificate,
298
            $xml,
299
            'infMDFe',
300
            'Id',
301
            $this->algorithm,
302
            $this->canonical
303
        );
304
        $dom = new DOMDocument('1.0', 'UTF-8');
305
        $dom->preserveWhiteSpace = false;
306
        $dom->formatOutput = false;
307
        $dom->loadXML($signed);
308
        //exception will be throw if MDFe is not valid
309
        $method = 'mdfe';
310
        $infMDFeSupl = !empty($dom->getElementsByTagName('infMDFeSupl')->item(0));
311
        if (!$infMDFeSupl) {
312
            $signed = $this->addQRCode($dom);
313
        }
314
        $this->isValid($this->versao, $signed, $method);
315
        return $signed;
316
    }
317
318
    /**
319
     * Performs xml validation with its respective
320
     * XSD structure definition document
321
     * NOTE: if dont exists the XSD file will return true
322
     * @param string $version layout version
323
     * @param string $body
324
     * @param string $method
325
     * @return boolean
326
     */
327
    protected function isValid($version, $body, $method)
328
    {
329
        $schema = $this->pathschemes . $method . "_v$version.xsd";
330
        if (!is_file($schema)) {
331
            return true;
332
        }
333
        return Validator::isValid(
334
            $body,
335
            $schema
336
        );
337
    }
338
339
    /**
340
     * Alter environment from "homologacao" to "producao" and vice-versa
341
     * @param int $tpAmb
342
     * @return void
343
     */
344
    public function setEnvironment($tpAmb = 2)
345
    {
346
        if (!empty($tpAmb) && ($tpAmb == 1 || $tpAmb == 2)) {
347
            $this->tpAmb = $tpAmb;
348
            $this->ambiente = ($tpAmb == 1) ? 'producao' : 'homologacao';
349
        }
350
    }
351
352
    /**
353
     * Set option for canonical transformation see C14n
354
     * @param array $opt
355
     * @return array
356
     */
357
    public function canonicalOptions($opt = [true, false, null, null])
358
    {
359
        if (!empty($opt) && is_array($opt)) {
360
            $this->canonical = $opt;
361
        }
362
        return $this->canonical;
363
    }
364
365
    /**
366
     * Assembles all the necessary parameters for soap communication
367
     * @param string $service
368
     * @param string $uf
369
     * @param string $tpAmb
370
     * @return void
371
     */
372
    protected function servico(
373
        $service,
374
        $uf,
375
        $tpAmb
376
    ) {
377
378
        $ambiente = $tpAmb == 1 ? "producao" : "homologacao";
379
        $webs = new Webservices($this->getXmlUrlPath());
380
        $sigla = $uf;
381
        $stdServ = $webs->get($sigla, $ambiente, $this->modelo);
382
        if ($stdServ === false) {
383
            throw new \RuntimeException(
384
                "Nenhum serviço foi localizado para esta unidade "
385
                . "da federação [$sigla]."
386
            );
387
        }
388
        if (empty($stdServ->$service->url)) {
389
            throw new \RuntimeException(
390
                "Este serviço [$service] não está disponivel para esta "
391
                . "unidade da federação [$uf] ou para este modelo"
392
            );
393
        }
394
        //recuperação do cUF
395
        $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...
396
        if ($this->urlcUF > 91) {
397
            //foi solicitado dado de SVRS ou SVSP
398
            $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...
399
        }
400
        //recuperação da versão
401
        $this->urlVersion = $stdServ->$service->version;
402
        //recuperação da url do serviço
403
        $this->urlService = $stdServ->$service->url;
404
        //recuperação do método
405
        $this->urlMethod = $stdServ->$service->method;
406
        //recuperação da operação
407
        $this->urlOperation = $stdServ->$service->operation;
408
        //montagem do namespace do serviço
409
        $this->urlNamespace = sprintf(
410
            "%s/wsdl/%s",
411
            $this->urlPortal,
412
            $this->urlOperation
413
        );
414
        //montagem do cabeçalho da comunicação SOAP
415
        $this->urlHeader = Header::get(
416
            $this->urlNamespace,
417
            $this->urlcUF,
418
            $this->urlVersion
419
        );
420
        $this->urlAction = "\""
421
            . $this->urlNamespace
422
            . "/"
423
            . $this->urlMethod
424
            . "\"";
425
        //montagem do SOAP Header
426
        $this->objHeader = new \SOAPHeader(
427
            $this->urlNamespace,
428
            'mdfeCabecMsg',
429
            ['cUF' => $this->urlcUF, 'versaoDados' => $this->urlVersion]
430
        );
431
    }
432
433
    /**
434
     * Send request message to webservice
435
     * @param array $parameters
436
     * @param string $request
437
     * @return string
438
     */
439
    protected function sendRequest($request, array $parameters = [])
440
    {
441
        $this->checkSoap();
442
        return (string)$this->soap->send(
443
            $this->urlService,
444
            $this->urlMethod,
445
            $this->urlAction,
446
            SOAP_1_2,
447
            $parameters,
448
            $this->soapnamespaces,
449
            $request,
450
            $this->objHeader
451
        );
452
    }
453
454
    /**
455
     * Recover path to xml data base with list of soap services
456
     * @return string
457
     */
458
    protected function getXmlUrlPath()
459
    {
460
        $file = $this->pathwsfiles
461
            . DIRECTORY_SEPARATOR
462
            . "wsmdfe_" . $this->versao . ".xml";
463
        if (!file_exists($file)) {
464
            return '';
465
        }
466
        return file_get_contents($file);
467
    }
468
469
    /**
470
     * Add QRCode Tag to signed XML from a NFCe
471
     * @param DOMDocument $dom
472
     * @return string
473
     */
474
    protected function addQRCode(DOMDocument $dom)
475
    {
476
        $signed = QRCode::putQRTag(
477
            $dom
478
        );
479
        return Strings::clearXmlString($signed);
480
    }
481
482
    /**
483
     * Verify if SOAP class is loaded, if not, force load SoapCurl
484
     */
485
    protected function checkSoap()
486
    {
487
        if (empty($this->soap)) {
488
            $this->soap = new SoapCurl($this->certificate);
489
        }
490
    }
491
}
492