Passed
Push — master ( 463105...84cd59 )
by Roberto
04:47
created

SoapBase::loadCertificate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace NFePHP\Common\Soap;
4
5
/**
6
 * Soap base class
7
 *
8
 * @category  NFePHP
9
 * @package   NFePHP\Common\Soap\SoapBase
10
 * @copyright NFePHP Copyright (c) 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-nfse for the canonical source repository
16
 */
17
18
use NFePHP\Common\Certificate;
19
use NFePHP\Common\Soap\SoapInterface;
20
use NFePHP\Common\Exception\SoapException;
21
use NFePHP\Common\Exception\RuntimeException;
22
use NFePHP\Common\Strings;
23
use League\Flysystem\Filesystem;
24
use League\Flysystem\Adapter\Local;
25
use Psr\Log\LoggerInterface;
26
27
abstract class SoapBase implements SoapInterface
28
{
29
    //soap parameters
30
    protected $connection;
31
    protected $soapprotocol = self::SSL_DEFAULT;
32
    protected $soaptimeout = 20;
33
    protected $proxyIP;
34
    protected $proxyPort;
35
    protected $proxyUser;
36
    protected $proxyPass;
37
    protected $prefixes = [1 => 'soapenv', 2 => 'soap'];
38
    //certificate parameters
39
    protected $certificate;
40
    protected $tempdir;
41
    protected $certsdir;
42
    protected $debugdir;
43
    protected $prifile;
44
    protected $pubfile;
45
    protected $certfile;
46
    protected $casefaz; //certificates from webservices
47
    protected $disablesec = false;
48
    //log info
49
    public $responseHead;
50
    public $responseBody;
51
    public $requestHead;
52
    public $requestBody;
53
    public $soaperror;
54
    public $soapinfo = [];
55
    public $debugmode = false;
56
    //flysystem
57
    protected $adapter;
58
    protected $filesystem;
59
60
    /**
61
     * Constructor
62
     * @param Certificate $certificate
63
     * @param LoggerInterface $logger
64
     */
65
    public function __construct(Certificate $certificate = null, LoggerInterface $logger = null)
66
    {
67
        $this->logger = $logger;
0 ignored issues
show
Bug introduced by
The property logger does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
68
        $this->certificate = $certificate;
69
        $this->setTemporaryFolder(sys_get_temp_dir() . '/sped/');
70
    }
71
    
72
    /**
73
     * Destructor
74
     * Clean temporary files
75
     */
76
    public function __destruct()
77
    {
78
        $this->removeTemporarilyFiles($this->certsdir);
79
    }
80
    
81
    /**
82
     * Disables the security checking of host and peer certificates
83
     * @param bool $flag
84
     */
85
    public function disableSecurity($flag = false)
86
    {
87
        $this->disablesec = $flag;
88
    }
89
90
    /**
91
     * Load path to CA and enable to use on SOAP
92
     * @param string $capath
93
     */
94
    public function loadCA($capath)
95
    {
96
        if (is_file($capath)) {
97
            $this->casefaz = $capath;
98
        }
99
    }
100
    
101
    /**
102
     * Set another temporayfolder for saving certificates for SOAP utilization
103
     * @param string $folderRealPath
104
     */
105
    public function setTemporaryFolder($folderRealPath)
106
    {
107
        $this->tempdir = $folderRealPath;
108
        $this->setLocalFolder($folderRealPath);
109
    }
110
    
111
    /**
112
     * Set Local folder for flysystem
113
     * @param string $folder
114
     */
115
    protected function setLocalFolder($folder = '')
116
    {
117
        $this->adapter = new Local($folder);
118
        $this->filesystem = new Filesystem($this->adapter);
119
    }
120
121
    /**
122
     * Set debug mode, this mode will save soap envelopes in temporary directory
123
     * @param bool $value
124
     */
125
    public function setDebugMode($value = false)
126
    {
127
        $this->debugmode = $value;
128
    }
129
    
130
    /**
131
     * Set certificate class for SSL comunications
132
     * @param Certificate $certificate
133
     */
134
    public function loadCertificate(Certificate $certificate)
135
    {
136
        $this->certificate = $certificate;
137
    }
138
    
139
    /**
140
     * Set logger class
141
     * @param LoggerInterface $logger
142
     */
143
    public function loadLogger(LoggerInterface $logger)
144
    {
145
        $this->logger = $logger;
146
    }
147
    
148
    /**
149
     * Set timeout for communication
150
     * @param int $timesecs
151
     */
152
    public function timeout($timesecs)
153
    {
154
        $this->soaptimeout = $timesecs;
155
    }
156
    
157
    /**
158
     * Set security protocol
159
     * @param int $protocol
160
     */
161
    public function protocol($protocol = self::SSL_DEFAULT)
162
    {
163
        $this->soapprotocol = $protocol;
164
    }
165
    
166
    /**
167
     * Set prefixes
168
     * @param string $prefixes
169
     */
170
    public function setSoapPrefix($prefixes)
171
    {
172
        $this->prefixes = $prefixes;
0 ignored issues
show
Documentation Bug introduced by
It seems like $prefixes of type string is incompatible with the declared type array of property $prefixes.

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...
173
    }
174
    
175
    /**
176
     * Set proxy parameters
177
     * @param string $ip
178
     * @param int $port
179
     * @param string $user
180
     * @param string $password
181
     */
182
    public function proxy($ip, $port, $user, $password)
183
    {
184
        $this->proxyIP = $ip;
185
        $this->proxyPort = $port;
186
        $this->proxyUser = $user;
187
        $this->proxyPass = $password;
188
    }
189
    
190
    /**
191
     * Send message to webservice
192
     */
193
    abstract public function send(
194
        $url,
195
        $operation = '',
196
        $action = '',
197
        $soapver = SOAP_1_2,
198
        $parameters = [],
199
        $namespaces = [],
200
        $request = '',
201
        $soapheader = null
202
    );
203
    
204
    /**
205
     * Mount soap envelope
206
     * @param string $request
207
     * @param string $operation
208
     * @param array $namespaces
209
     * @param \SOAPHeader $header
210
     * @return string
211
     */
212
    protected function makeEnvelopeSoap(
213
        $request,
214
        $operation,
0 ignored issues
show
Unused Code introduced by
The parameter $operation 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...
215
        $namespaces,
216
        $soapver = SOAP_1_2,
217
        $header = null
218
    ) {
219
        $prefix = $this->prefixes[$soapver];
220
        $envelope = "<$prefix:Envelope";
221
        foreach ($namespaces as $key => $value) {
222
            $envelope .= " $key=\"$value\"";
223
        }
224
        $envelope .= ">";
225
        $soapheader = "<$prefix:Header/>";
226
        if (!empty($header)) {
227
            $ns = !empty($header->namespace) ? $header->namespace : '';
0 ignored issues
show
Bug introduced by
The property namespace does not seem to exist in SoapHeader.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
228
            $name = $header->name;
0 ignored issues
show
Bug introduced by
The property name does not seem to exist in SoapHeader.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
229
            $soapheader = "<$prefix:Header>";
230
            $soapheader .= "<$name xmlns=\"$ns\">";
231
            foreach ($header->data as $key => $value) {
0 ignored issues
show
Bug introduced by
The property data does not seem to exist in SoapHeader.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
232
                $soapheader .= "<$key>$value</$key>";
233
            }
234
            $soapheader .= "</$name></$prefix:Header>";
235
        }
236
        $envelope .= $soapheader;
237
        $envelope .= "<$prefix:Body>$request</$prefix:Body>"
238
            . "</$prefix:Envelope>";
239
        return $envelope;
240
    }
241
    
242
    /**
243
     * Temporarily saves the certificate keys for use cURL or SoapClient
244
     */
245
    public function saveTemporarilyKeyFiles()
246
    {
247
        if (!is_object($this->certificate)) {
248
            throw new RuntimeException(
249
                'Certificate not found.'
250
            );
251
        }
252
        $this->certsdir = $this->certificate->getCnpj() . '/certs/';
253
        $this->prifile = $this->certsdir. Strings::randomString(10).'.pem';
254
        $this->pubfile = $this->certsdir . Strings::randomString(10).'.pem';
255
        $this->certfile = $this->certsdir . Strings::randomString(10).'.pem';
256
        $ret = true;
257
        $ret &= $this->filesystem->put(
258
            $this->prifile,
259
            $this->certificate->privateKey
260
        );
261
        $ret &= $this->filesystem->put(
262
            $this->pubfile,
263
            $this->certificate->publicKey
264
        );
265
        $ret &= $this->filesystem->put(
266
            $this->certfile,
267
            "{$this->certificate}"
268
        );
269
        if (!$ret) {
270
            throw new RuntimeException(
271
                'Unable to save temporary key files in folder.'
272
            );
273
        }
274
    }
275
    
276
    /**
277
     * Delete all files in folder
278
     */
279
    public function removeTemporarilyFiles($folder)
280
    {
281
        $contents = $this->filesystem->listContents($folder, true);
282
        foreach ($contents as $item) {
283
            if ($item['type'] == 'file') {
284
                $this->filesystem->delete($item['path']);
285
            }
286
        }
287
    }
288
    
289
    /**
290
     * Save request envelope and response for debug reasons
291
     * @param string $operation
292
     * @param string $request
293
     * @param string $response
294
     * @return void
295
     */
296
    public function saveDebugFiles($operation, $request, $response)
297
    {
298
        if (!$this->debugmode) {
299
            return;
300
        }
301
        $this->debugdir = $this->certificate->getCnpj() . '/debug/';
302
        $now = \DateTime::createFromFormat('U.u', microtime(true));
303
        $time = substr($now->format("ymdHisu"), 0, 16);
304
        try {
305
            $this->filesystem->put(
306
                $this->debugdir . $time . "_" . $operation . "_sol.txt",
307
                $request
308
            );
309
            $this->filesystem->put(
310
                $this->debugdir . $time . "_" . $operation . "_res.txt",
311
                $response
312
            );
313
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class NFePHP\Common\Soap\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
314
            throw new RuntimeException(
315
                'Unable to create debug files.'
316
            );
317
        }
318
    }
319
}
320