Completed
Pull Request — master (#9)
by Roberto
04:28
created

CurlSoap::send()   F

Complexity

Conditions 13
Paths 448

Size

Total Lines 87
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 87
ccs 0
cts 57
cp 0
rs 3.5085
cc 13
eloc 51
nc 448
nop 5
crap 182

How to fix   Long Method    Complexity   

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\Esfinge\Soap;
4
5
use RuntimeException;
6
7
class CurlSoap
8
{
9
    /**
10
     * soapDebug
11
     * @var string
12
     */
13
    public $soapDebug = '';
14
    /**
15
     * soapTimeout
16
     * @var integer
17
     */
18
    public $soapTimeout = 10;
19
    /**
20
     * lastMsg
21
     * @var string
22
     */
23
    public $lastMsg = '';
24
25
    /**
26
     * errorCurl
27
     * @var string
28
     */
29
    public $errorCurl = '';
30
    /**
31
     * infoCurl
32
     * @var array
33
     */
34
    public $infoCurl = array();
35
    /**
36
     * proxyIP
37
     * @var string
38
     */
39
    private $proxyIP = '';
40
    /**
41
     * proxyPORT
42
     * @var string
43
     */
44
    private $proxyPORT = '';
45
    /**
46
     * proxyUSER
47
     * @var string
48
     */
49
    private $proxyUSER = '';
50
    /**
51
     * proxyPASS
52
     * @var string
53
     */
54
    private $proxyPASS = '';
55
    
56
    public function __construct($timeout, $aproxy)
57
    {
58
        $this->soapTimeout = $timeout;
59
        $ipNumber = $aproxy['proxyIp'];
60
        $port = $aproxy['proxyPort'];
61
        $user = $aproxy['proxyUser'];
62
        $pass = $aproxy['proxyPass'];
63
        $this->setProxy($ipNumber, $port, $user, $pass);
64
    }
65
    
66
    /**
67
     * setProxy
68
     * Seta o uso do proxy
69
     * @param string $ipNumber numero IP do proxy server
70
     * @param string $port numero da porta usada pelo proxy
71
     * @param string $user nome do usuário do proxy
72
     * @param string $pass senha de acesso ao proxy
73
     * @return boolean
74
     */
75
    public function setProxy($ipNumber, $port, $user = '', $pass = '')
76
    {
77
        $this->proxyIP = $ipNumber;
78
        $this->proxyPORT = $port;
79
        $this->proxyUSER = $user;
80
        $this->proxyPASS = $pass;
81
    }
82
    
83
    /**
84
     * getProxy
85
     * Retorna os dados de configuração do Proxy em um array
86
     * @return array
87
     */
88
    public function getProxy()
89
    {
90
        $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...
91
        $aProxy['port'] = $this->proxyPORT;
92
        $aProxy['username'] = $this->proxyUSER;
93
        $aProxy['password'] = $this->proxyPASS;
94
        return $aProxy;
95
    }
96
    
97
    /**
98
     * Envia mensagem ao webservice
99
     * @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...
100
     * @param string $namespace
101
     * @param string $header
102
     * @param string $body
103
     * @param string $method
104
     * @return boolean|string
105
     */
106
    public function send($urlservice, $namespace, $header, $body, $method)
0 ignored issues
show
Unused Code introduced by
The parameter $urlservice 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...
Unused Code introduced by
The parameter $namespace 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...
107
    {
108
        //monta a mensagem ao webservice
109
        $data = '<?xml version="1.0" encoding="utf-8"?>'.'<soap:Envelope ';
110
        $data .= 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
111
        $data .= 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ';
112
        $data .= 'xmlns:soap="http://www.w3.org/2003/05/soap-envelope">';
113
        $data .= '<soap:Header>'.$header.'</soap:Header>';
114
        $data .= '<soap:Body>'.$body.'</soap:Body>';
115
        $data .= '</soap:Envelope>';
116
        $data = $this->clearMsg($data);
117
        $this->lastMsg = $data;
118
        //tamanho da mensagem
119
        $tamanho = strlen($data);
120
        //estabelecimento dos parametros da mensagem
121
        //$parametros = array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
122
        //    'Content-Type: application/soap+xml;charset=utf-8;action="'.$namespace."/".$method.'"',
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
123
        //    'SOAPAction: "'.$method.'"',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
124
        //    "Content-length: $tamanho");
125
        //"application/fastinfoset, */*"
126
        //"Accept-Encoding", "gzip, deflate"
127
    //"Content-encoding", "gzip"
128
    //"Content-type", "application/octet-stream"
129
        $parametros = array(
0 ignored issues
show
Unused Code introduced by
$parametros is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
130
            'Content-Type: application/octet-stream',
131
            'Accept-Encoding: gzip, deflate',
132
            'Content-encoding: gzip',
133
            'SOAPAction: "'.$method.'"',
134
            "Content-length: $tamanho");
135
        //solicita comunicação via cURL
136
        //###########################################
137
        //
138
        if ($method == 'cancelarTransferencia') {
139
            $resposta = file_get_contents('../tests/fixtures/responseCancelarTransferencia.xml');
140
        }
141
        if ($method == 'finalizarTransferencia') {
142
            $resposta = file_get_contents('../tests/fixtures/responseFinalizarTransferencia.xml');
143
        }
144
        if ($method == 'iniciarTransferencia') {
145
            $resposta = file_get_contents('../tests/fixtures/responseIniciarTransferencia.xml');
146
        }
147
        if ($method == 'obterToken') {
148
            $resposta = file_get_contents('../tests/fixtures/responseObterToken.xml');
149
        }
150
        if ($method == 'obterSituacaoToken') {
151
            $resposta = file_get_contents('../tests/fixtures/responseObterSituacaoToken.xml');
152
        }
153
        $this->infoCurl["http_code"] = '200';
154
        //###########################################
155
        //$resposta = $this->zCommCurl($urlservice, $data, $parametros);
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
156
        if (empty($resposta)) {
157
            $msg = "Não houve retorno do Curl.\n $this->errorCurl";
158
            throw new RuntimeException($msg);
159
        }
160
        //obtem o bloco html da resposta
161
        $xPos = stripos($resposta, "<");
162
        $blocoHtml = substr($resposta, 0, $xPos);
163
        if ($this->infoCurl["http_code"] != '200') {
164
            //se não é igual a 200 houve erro
165
            $msg = $blocoHtml;
166
            throw new RuntimeException($msg);
167
        }
168
        //obtem o tamanho da resposta
169
        $lenresp = strlen($resposta);
170
        //localiza a primeira marca de tag
171
        $xPos = stripos($resposta, "<");
172
        //se não existir não é um xml nem um html
173
        if ($xPos !== false) {
174
            $xml = substr($resposta, $xPos, $lenresp-$xPos);
175
        } else {
176
            $xml = '';
177
        }
178
        //testa para saber se é um xml mesmo ou é um html
179
        $result = simplexml_load_string($xml, 'SimpleXmlElement', LIBXML_NOERROR+LIBXML_ERR_FATAL+LIBXML_ERR_NONE);
180
        if ($result === false) {
181
            //não é um xml então pode limpar
182
            $xml = '';
183
        }
184
        if ($xml == '') {
185
            $msg = "Não houve retorno de um xml verifique soapDebug!!";
186
            throw new RuntimeException($msg);
187
        }
188
        if ($xml != '' && substr($xml, 0, 5) != '<?xml') {
189
            $xml = '<?xml version="1.0" encoding="utf-8"?>'.$xml;
190
        }
191
        return $xml;
192
    }
193
    
194
    protected function zCommCurl($url, $data = '', $parametros = array())
195
    {
196
        //incializa cURL
197
        $oCurl = curl_init();
198
        //setting da seção soap
199
        if ($this->proxyIP != '') {
200
            curl_setopt($oCurl, CURLOPT_HTTPPROXYTUNNEL, 1);
201
            curl_setopt($oCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
202
            curl_setopt($oCurl, CURLOPT_PROXY, $this->proxyIP.':'.$this->proxyPORT);
203
            if ($this->proxyPASS != '') {
204
                curl_setopt($oCurl, CURLOPT_PROXYUSERPWD, $this->proxyUSER.':'.$this->proxyPASS);
205
                curl_setopt($oCurl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
206
            }
207
        }
208
        //força a resolução de nomes com IPV4 e não com IPV6, isso
209
        //pode acelerar temporáriamente as falhas ou demoras decorrentes de
210
        //ambiente mal preparados como os da SEFAZ GO, porém pode causar
211
        //problemas no futuro quando os endereços IPV4 deixarem de ser usados
212
        curl_setopt($oCurl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
213
        curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, $this->soapTimeout);
214
        curl_setopt($oCurl, CURLOPT_URL, $url);
215
        curl_setopt($oCurl, CURLOPT_VERBOSE, 1);
216
        curl_setopt($oCurl, CURLOPT_HEADER, 1);
217
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
218
        curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 0);
219
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
220
        curl_setopt($oCurl, CURLOPT_POST, 1);
221
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $data);
222
        if (!empty($parametros)) {
223
            curl_setopt($oCurl, CURLOPT_HTTPHEADER, $parametros);
224
        }
225
        //inicia a conexão
226
        $resposta = curl_exec($oCurl);
227
        //obtem as informações da conexão
228
        $info = curl_getinfo($oCurl);
229
        //carrega os dados para debug
230
        $this->zDebug($info, $data, $resposta);
231
        $this->errorCurl = curl_error($oCurl);
232
        //fecha a conexão
233
        curl_close($oCurl);
234
        //retorna resposta
235
        return $resposta;
236
    }
237
    
238
    /**
239
     * zDebug
240
     * @param array $info
241
     * @param string $data
242
     * @param string $resposta
243
     */
244
    private function zDebug($info = array(), $data = '', $resposta = '')
245
    {
246
        $this->infoCurl["url"] = $info["url"];
247
        $this->infoCurl["content_type"] = $info["content_type"];
248
        $this->infoCurl["http_code"] = $info["http_code"];
249
        $this->infoCurl["header_size"] = $info["header_size"];
250
        $this->infoCurl["request_size"] = $info["request_size"];
251
        $this->infoCurl["filetime"] = $info["filetime"];
252
        $this->infoCurl["ssl_verify_result"] = $info["ssl_verify_result"];
253
        $this->infoCurl["redirect_count"] = $info["redirect_count"];
254
        $this->infoCurl["total_time"] = $info["total_time"];
255
        $this->infoCurl["namelookup_time"] = $info["namelookup_time"];
256
        $this->infoCurl["connect_time"] = $info["connect_time"];
257
        $this->infoCurl["pretransfer_time"] = $info["pretransfer_time"];
258
        $this->infoCurl["size_upload"] = $info["size_upload"];
259
        $this->infoCurl["size_download"] = $info["size_download"];
260
        $this->infoCurl["speed_download"] = $info["speed_download"];
261
        $this->infoCurl["speed_upload"] = $info["speed_upload"];
262
        $this->infoCurl["download_content_length"] = $info["download_content_length"];
263
        $this->infoCurl["upload_content_length"] = $info["upload_content_length"];
264
        $this->infoCurl["starttransfer_time"] = $info["starttransfer_time"];
265
        $this->infoCurl["redirect_time"] = $info["redirect_time"];
266
        //coloca as informações em uma variável
267
        $txtInfo ="";
268
        foreach ($info as $key => $content) {
269
            if (is_string($content)) {
270
                $txtInfo .= strtoupper($key).'='.$content."\n";
271
            }
272
        }
273
        //carrega a variavel debug
274
        $this->soapDebug = $data."\n\n".$txtInfo."\n".$resposta;
275
    }
276
    
277
    /**
278
     * clearMsg
279
     * @param string $msg
280
     * @return string
281
     */
282
    protected function clearMsg($msg)
283
    {
284
        $nmsg = str_replace(array(' standalone="no"','default:',':default',"\n","\r","\t"), '', $msg);
285
        $nnmsg = str_replace('> ', '>', $nmsg);
286
        if (strpos($nnmsg, '> ')) {
287
            $nnmsg = $this->clearMsg((string) $nnmsg);
288
        }
289
        return $nnmsg;
290
    }
291
}
292