Completed
Push — master ( e55be9...5d6262 )
by Roberto
15:27 queued 12:57
created

CurlSoap   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 20
c 6
b 0
f 0
lcom 1
cbo 1
dl 0
loc 279
ccs 0
cts 137
cp 0
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A setProxy() 0 7 1
A getProxy() 0 8 1
C send() 0 71 8
B zCommCurl() 0 44 4
B zDebug() 0 32 3
A clearMsg() 0 9 2
1
<?php
2
3
namespace NFePHP\Esfinge\Soap;
4
5
use RuntimeException;
6
use NFePHP\Esfinge\Files\FilesFolders;
7
8
class CurlSoap
9
{
10
    /**
11
     * soapDebug
12
     * @var string
13
     */
14
    public $soapDebug = '';
15
    /**
16
     * soapTimeout
17
     * @var integer
18
     */
19
    public $soapTimeout = 10;
20
    /**
21
     * lastMsg
22
     * @var string
23
     */
24
    public $lastMsg = '';
25
26
    /**
27
     * errorCurl
28
     * @var string
29
     */
30
    public $errorCurl = '';
31
    /**
32
     * infoCurl
33
     * @var array
34
     */
35
    public $infoCurl = array();
36
    /**
37
     * proxyIP
38
     * @var string
39
     */
40
    private $proxyIP = '';
41
    /**
42
     * proxyPORT
43
     * @var string
44
     */
45
    private $proxyPORT = '';
46
    /**
47
     * proxyUSER
48
     * @var string
49
     */
50
    private $proxyUSER = '';
51
    /**
52
     * proxyPASS
53
     * @var string
54
     */
55
    private $proxyPASS = '';
56
    private $pathlog;
57
    
58
    public function __construct($pathlog, $timeout, $aproxy)
59
    {
60
        $this->pathlog = $pathlog;
61
        $this->soapTimeout = $timeout;
62
        $ipNumber = $aproxy['proxyIp'];
63
        $port = $aproxy['proxyPort'];
64
        $user = $aproxy['proxyUser'];
65
        $pass = $aproxy['proxyPass'];
66
        $this->setProxy($ipNumber, $port, $user, $pass);
67
    }
68
    
69
    /**
70
     * setProxy
71
     * Seta o uso do proxy
72
     * @param string $ipNumber numero IP do proxy server
73
     * @param string $port numero da porta usada pelo proxy
74
     * @param string $user nome do usuário do proxy
75
     * @param string $pass senha de acesso ao proxy
76
     * @return boolean
77
     */
78
    public function setProxy($ipNumber, $port, $user = '', $pass = '')
79
    {
80
        $this->proxyIP = $ipNumber;
81
        $this->proxyPORT = $port;
82
        $this->proxyUSER = $user;
83
        $this->proxyPASS = $pass;
84
    }
85
    
86
    /**
87
     * getProxy
88
     * Retorna os dados de configuração do Proxy em um array
89
     * @return array
90
     */
91
    public function getProxy()
92
    {
93
        $aProxy['ip'] = $this->proxyIP;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$aProxy was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aProxy = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
94
        $aProxy['port'] = $this->proxyPORT;
95
        $aProxy['username'] = $this->proxyUSER;
96
        $aProxy['password'] = $this->proxyPASS;
97
        return $aProxy;
98
    }
99
    
100
    /**
101
     * Envia mensagem ao webservice
102
     * @param string $urlsevice
0 ignored issues
show
Documentation introduced by
There is no parameter named $urlsevice. Did you maybe mean $urlservice?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
103
     * @param string $namespace
104
     * @param string $header
105
     * @param string $body
106
     * @param string $method
107
     * @return boolean|string
108
     */
109
    public function send($urlservice, $namespace, $header, $body, $method)
110
    {
111
        //monta a mensagem ao webservice
112
        $data = '<?xml version="1.0" encoding="utf-8"?>'.'<soap:Envelope ';
113
        $data .= 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ';
114
        $data .= 'xmlns:svc="'.$namespace.'">';
115
        $data .= '<soap:Header>'.$header.'</soap:Header>';
116
        $data .= '<soap:Body>'.$body.'</soap:Body>';
117
        $data .= '</soap:Envelope>';
118
        $data = $this->clearMsg($data);
119
        //grava em propriedade da classe o envelope não compactado
120
        $this->lastMsg = $data;
121
        //salva o envelope em arquivo para efeito de LOG
122
        $mark = date('Ym').DIRECTORY_SEPARATOR.date('d_His_').$method;
123
        $filepath = $mark.'.xml';
124
        FilesFolders::save($this->pathlog, $filepath, $data);
125
        //compacta mensagem com GZip
126
        $data = gzencode($data);
127
        //tamanho da mensagem
128
        $tamanho = strlen($data);
129
        //estabelecimento dos parametros da mensagem
130
        $parametros = [
131
            "Accept-Encoding: gzip, deflate",
132
            "Content-Type: text/xml;charset=UTF-8",
133
            "Content-encoding: gzip",
134
            "Content-length: $tamanho"
135
        ];
136
        //solicita comunicação via cURL
137
        $resposta = $this->zCommCurl($urlservice, $data, $parametros);
138
        if (empty($resposta)) {
139
            $msg = "Não houve retorno do Curl.\n $this->errorCurl";
140
            throw new RuntimeException($msg);
141
        }
142
        //obtem o bloco html da resposta
143
        $ad = explode("\x1f\x8b", $resposta);
144
        $blocoHtml = substr($$ad[0], 0, strlen($ad[0])-2);
145
        $compressPart = "\x1f\x8b" . $ad[1];
146
        $decompressPart = gzdecode($compressPart);
147
        if ($this->infoCurl["http_code"] != '200') {
148
            //se não é igual a 200 houve erro
149
            $msg = $blocoHtml ."\r\n". $decompressPart;
150
            $filepath = $mark.'_ERROR.log';
151
            FilesFolders::save($this->pathlog, $filepath, $data);
152
            throw new RuntimeException($msg);
153
        }
154
        //localiza a primeira marca de tag
155
        $xPos = stripos($decompressPart, "<");
156
        //se não existir não é um xml nem um html
157
        if ($xPos !== false) {
158
            $xml = substr($decompressPart, $xPos, $lenresp-$xPos);
0 ignored issues
show
Bug introduced by
The variable $lenresp does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
159
        } else {
160
            $xml = '';
161
        }
162
        //testa para saber se é um xml mesmo ou é um html
163
        $result = simplexml_load_string($xml, 'SimpleXmlElement', LIBXML_NOERROR+LIBXML_ERR_FATAL+LIBXML_ERR_NONE);
164
        if ($result === false) {
165
            //não é um xml então pode limpar
166
            $xml = '';
167
        }
168
        if ($xml == '') {
169
            $msg = "Não houve retorno de um xml verifique soapDebug!!";
170
            throw new RuntimeException($msg);
171
        }
172
        if ($xml != '' && substr($xml, 0, 5) != '<?xml') {
173
            $xml = '<?xml version="1.0" encoding="utf-8"?>'.$xml;
174
        }
175
        //grava a resposta do TCE/SC
176
        $filepath = $mark.'_response.xml';
177
        FilesFolders::save($this->pathlog, $filepath, $xml);
178
        return $xml;
179
    }
180
    
181
    /**
182
     * Envio via cURL
183
     * @param string $url
184
     * @param string $data
185
     * @param array $parametros
186
     * @return string
187
     */
188
    protected function zCommCurl($url, $data = '', $parametros = array())
189
    {
190
        //incializa cURL
191
        $oCurl = curl_init();
192
        //setting da seção soap
193
        if ($this->proxyIP != '') {
194
            curl_setopt($oCurl, CURLOPT_HTTPPROXYTUNNEL, 1);
195
            curl_setopt($oCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
196
            curl_setopt($oCurl, CURLOPT_PROXY, $this->proxyIP.':'.$this->proxyPORT);
197
            if ($this->proxyPASS != '') {
198
                curl_setopt($oCurl, CURLOPT_PROXYUSERPWD, $this->proxyUSER.':'.$this->proxyPASS);
199
                curl_setopt($oCurl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
200
            }
201
        }
202
        //força a resolução de nomes com IPV4 e não com IPV6, isso
203
        //pode acelerar temporáriamente as falhas ou demoras decorrentes de
204
        //ambiente mal preparados como os da SEFAZ GO, porém pode causar
205
        //problemas no futuro quando os endereços IPV4 deixarem de ser usados
206
        curl_setopt($oCurl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
207
        curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, $this->soapTimeout);
208
        curl_setopt($oCurl, CURLOPT_URL, $url);
209
        curl_setopt($oCurl, CURLOPT_VERBOSE, 1);
210
        curl_setopt($oCurl, CURLOPT_HEADER, 1);
211
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
212
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 0);
213
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
214
        //curl_setopt($oCurl, CURLOPT_BINARYTRANSFER, 1);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% 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...
215
        curl_setopt($oCurl, CURLOPT_POST, 1);
216
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $data);
217
        if (!empty($parametros)) {
218
            curl_setopt($oCurl, CURLOPT_HTTPHEADER, $parametros);
219
        }
220
        //inicia a conexão
221
        $resposta = curl_exec($oCurl);
222
        //obtem as informações da conexão
223
        $info = curl_getinfo($oCurl);
224
        //carrega os dados para debug
225
        $this->zDebug($info, $data, $resposta);
226
        $this->errorCurl = curl_error($oCurl);
227
        //fecha a conexão
228
        curl_close($oCurl);
229
        //retorna resposta
230
        return $resposta;
231
    }
232
    
233
    /**
234
     * zDebug
235
     * @param array $info
236
     * @param string $data
237
     * @param string $resposta
238
     */
239
    private function zDebug($info = array(), $data = '', $resposta = '')
240
    {
241
        $this->infoCurl["url"] = $info["url"];
242
        $this->infoCurl["content_type"] = $info["content_type"];
243
        $this->infoCurl["http_code"] = $info["http_code"];
244
        $this->infoCurl["header_size"] = $info["header_size"];
245
        $this->infoCurl["request_size"] = $info["request_size"];
246
        $this->infoCurl["filetime"] = $info["filetime"];
247
        $this->infoCurl["ssl_verify_result"] = $info["ssl_verify_result"];
248
        $this->infoCurl["redirect_count"] = $info["redirect_count"];
249
        $this->infoCurl["total_time"] = $info["total_time"];
250
        $this->infoCurl["namelookup_time"] = $info["namelookup_time"];
251
        $this->infoCurl["connect_time"] = $info["connect_time"];
252
        $this->infoCurl["pretransfer_time"] = $info["pretransfer_time"];
253
        $this->infoCurl["size_upload"] = $info["size_upload"];
254
        $this->infoCurl["size_download"] = $info["size_download"];
255
        $this->infoCurl["speed_download"] = $info["speed_download"];
256
        $this->infoCurl["speed_upload"] = $info["speed_upload"];
257
        $this->infoCurl["download_content_length"] = $info["download_content_length"];
258
        $this->infoCurl["upload_content_length"] = $info["upload_content_length"];
259
        $this->infoCurl["starttransfer_time"] = $info["starttransfer_time"];
260
        $this->infoCurl["redirect_time"] = $info["redirect_time"];
261
        //coloca as informações em uma variável
262
        $txtInfo ="";
263
        foreach ($info as $key => $content) {
264
            if (is_string($content)) {
265
                $txtInfo .= strtoupper($key).'='.$content."\n";
266
            }
267
        }
268
        //carrega a variavel debug
269
        $this->soapDebug = $data."\n\n".$txtInfo."\n".$resposta;
270
    }
271
    
272
    /**
273
     * clearMsg
274
     * @param string $msg
275
     * @return string
276
     */
277
    protected function clearMsg($msg)
278
    {
279
        $nmsg = str_replace(array(' standalone="no"','default:',':default',"\n","\r","\t"), '', $msg);
280
        $nnmsg = str_replace('> ', '>', $nmsg);
281
        if (strpos($nnmsg, '> ')) {
282
            $nnmsg = $this->clearMsg((string) $nnmsg);
283
        }
284
        return $nnmsg;
285
    }
286
}
287