Passed
Push — 1.x ( 4c2324...312564 )
by Mikaël
75:29 queued 73:03
created

AbstractSoapClientBase::getLastResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WsdlToPhp\PackageBase;
4
5
abstract class AbstractSoapClientBase implements SoapClientInterface
6
{
7
    /**
8
     * Soapclient called to communicate with the actual SOAP Service
9
     * @var \SoapClient
10
     */
11
    private static $soapClient;
12
    /**
13
     * Contains Soap call result
14
     * @var mixed
15
     */
16
    private $result;
17
    /**
18
     * Contains last errors
19
     * @var array
20
     */
21
    private $lastError;
22
    /**
23
     * Contains output headers
24
     * @var array
25
     */
26
    protected $outputHeaders = [];
27
    /**
28
     * Constructor
29
     * @uses AbstractSoapClientBase::setLastError()
30
     * @uses AbstractSoapClientBase::initSoapClient()
31
     * @param array $wsdlOptions
32
     * @param bool $resetSoapClient allows to disable the SoapClient redefinition
33
     */
34 62
    public function __construct(array $wsdlOptions = [], $resetSoapClient = true)
35
    {
36 62
        $this->setLastError([]);
37
        /**
38
         * Init soap Client
39
         * Set default values
40
         */
41 62
        if ($resetSoapClient) {
42 62
            $this->initSoapClient($wsdlOptions);
43
        }
44 62
    }
45
    /**
46
     * Static method getting current SoapClient
47
     * @return \SoapClient
48
     */
49 56
    public static function getSoapClient()
50
    {
51 56
        return self::$soapClient;
52
    }
53
    /**
54
     * Static method setting current SoapClient
55
     * @param \SoapClient $soapClient
56
     * @return \SoapClient
57
     */
58 52
    public static function setSoapClient(\SoapClient $soapClient)
59
    {
60 52
        return (self::$soapClient = $soapClient);
61
    }
62
    /**
63
     * Method initiating SoapClient
64
     * @uses ApiClassMap::classMap()
65
     * @uses AbstractSoapClientBase::getDefaultWsdlOptions()
66
     * @uses AbstractSoapClientBase::getSoapClientClassName()
67
     * @uses AbstractSoapClientBase::setSoapClient()
68
     * @uses AbstractSoapClientBase::OPTION_PREFIX
69
     * @param array $options WSDL options
70
     * @return void
71
     */
72 62
    public function initSoapClient(array $options)
73
    {
74 62
        self::$soapClient = null;
75 62
        $wsdlOptions = [];
76 62
        $defaultWsdlOptions = static::getDefaultWsdlOptions();
77 62
        foreach ($defaultWsdlOptions as $optionName => $optionValue) {
78 62
            if (array_key_exists($optionName, $options) && !is_null($options[$optionName])) {
79 56
                $wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optionName)] = $options[$optionName];
80 62
            } elseif (!is_null($optionValue)) {
81 62
                $wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optionName)] = $optionValue;
82
            }
83
        }
84 62
        if (self::canInstantiateSoapClientWithOptions($wsdlOptions)) {
85 52
            $wsdlUrl = null;
86 52
            if (array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URL), $wsdlOptions)) {
87 48
                $wsdlUrl = $wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)];
88 48
                unset($wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)]);
89
            }
90 52
            $soapClientClassName = $this->getSoapClientClassName();
91 52
            static::setSoapClient(new $soapClientClassName($wsdlUrl, $wsdlOptions));
92
        }
93 62
    }
94
    /**
95
     * Checks if the provided options are sufficient to instantiate a SoapClient:
96
     *  - WSDL-mode : only the WSDL is required
97
     *  - non-WSDL-mode : URI and LOCATION are required, WSDL url can be empty then
98
     * @uses AbstractSoapClientBase::OPTION_PREFIX
99
     * @param $wsdlOptions
100
     * @return bool
101
     */
102 62
    protected static function canInstantiateSoapClientWithOptions($wsdlOptions)
103
    {
104
        return (
105 62
            array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URL), $wsdlOptions) ||
106
            (
107 14
                array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URI), $wsdlOptions) &&
108 62
                array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_LOCATION), $wsdlOptions)
109
            )
110
        );
111
    }
112
    /**
113
     * Returns the SoapClient class name to use to create the instance of the SoapClient.
114
     * The SoapClient class is determined based on the package name.
115
     * If a class is named as {Api}SoapClient, then this is the class that will be used.
116
     * Be sure that this class inherits from the native PHP SoapClient class and this class has been loaded or can be loaded.
117
     * The goal is to allow the override of the SoapClient without having to modify this generated class.
118
     * Then the overridding SoapClient class can override for example the SoapClient::__doRequest() method if it is needed.
119
     * @uses AbstractSoapClientBase::DEFAULT_SOAP_CLIENT_CLASS
120
     * @return string
121
     */
122 56
    public function getSoapClientClassName($soapClientClassName = null)
123
    {
124 56
        $className = self::DEFAULT_SOAP_CLIENT_CLASS;
125 56
        if (!empty($soapClientClassName) && is_subclass_of($soapClientClassName, '\SoapClient')) {
126 54
            $className = $soapClientClassName;
127
        }
128 56
        return $className;
129
    }
130
    /**
131
     * Method returning all default options values
132
     * @uses AbstractSoapClientBase::WSDL_AUTHENTICATION
133
     * @uses AbstractSoapClientBase::WSDL_CACHE_WSDL
134
     * @uses AbstractSoapClientBase::WSDL_CLASSMAP
135
     * @uses AbstractSoapClientBase::WSDL_COMPRESSION
136
     * @uses AbstractSoapClientBase::WSDL_CONNECTION_TIMEOUT
137
     * @uses AbstractSoapClientBase::WSDL_ENCODING
138
     * @uses AbstractSoapClientBase::WSDL_EXCEPTIONS
139
     * @uses AbstractSoapClientBase::WSDL_FEATURES
140
     * @uses AbstractSoapClientBase::WSDL_LOCAL_CERT
141
     * @uses AbstractSoapClientBase::WSDL_LOCATION
142
     * @uses AbstractSoapClientBase::WSDL_LOGIN
143
     * @uses AbstractSoapClientBase::WSDL_PASSPHRASE
144
     * @uses AbstractSoapClientBase::WSDL_PASSWORD
145
     * @uses AbstractSoapClientBase::WSDL_PROXY_HOST
146
     * @uses AbstractSoapClientBase::WSDL_PROXY_LOGIN
147
     * @uses AbstractSoapClientBase::WSDL_PROXY_PASSWORD
148
     * @uses AbstractSoapClientBase::WSDL_PROXY_PORT
149
     * @uses AbstractSoapClientBase::WSDL_SOAP_VERSION
150
     * @uses AbstractSoapClientBase::WSDL_SSL_METHOD
151
     * @uses AbstractSoapClientBase::WSDL_STREAM_CONTEXT
152
     * @uses AbstractSoapClientBase::WSDL_STYLE
153
     * @uses AbstractSoapClientBase::WSDL_TRACE
154
     * @uses AbstractSoapClientBase::WSDL_TYPEMAP
155
     * @uses AbstractSoapClientBase::WSDL_URL
156
     * @uses AbstractSoapClientBase::WSDL_URI
157
     * @uses AbstractSoapClientBase::WSDL_USE
158
     * @uses AbstractSoapClientBase::WSDL_USER_AGENT
159
     * @uses WSDL_CACHE_NONE
160
     * @uses SOAP_SINGLE_ELEMENT_ARRAYS
161
     * @uses SOAP_USE_XSI_ARRAY_TYPE
162
     * @return array
163
     */
164 62
    public static function getDefaultWsdlOptions()
165
    {
166
        return [
167 62
            self::WSDL_AUTHENTICATION => null,
168 62
            self::WSDL_CACHE_WSDL => WSDL_CACHE_NONE,
169 62
            self::WSDL_CLASSMAP => null,
170 62
            self::WSDL_COMPRESSION => null,
171 62
            self::WSDL_CONNECTION_TIMEOUT => null,
172 62
            self::WSDL_ENCODING => null,
173 62
            self::WSDL_EXCEPTIONS => true,
174 62
            self::WSDL_FEATURES => SOAP_SINGLE_ELEMENT_ARRAYS | SOAP_USE_XSI_ARRAY_TYPE,
175 62
            self::WSDL_LOCAL_CERT => null,
176 62
            self::WSDL_LOCATION => null,
177 62
            self::WSDL_LOGIN => null,
178 62
            self::WSDL_PASSPHRASE => null,
179 62
            self::WSDL_PASSWORD => null,
180 62
            self::WSDL_PROXY_HOST => null,
181 62
            self::WSDL_PROXY_LOGIN => null,
182 62
            self::WSDL_PROXY_PASSWORD => null,
183 62
            self::WSDL_PROXY_PORT => null,
184 62
            self::WSDL_SOAP_VERSION => null,
185 62
            self::WSDL_SSL_METHOD => null,
186 62
            self::WSDL_STREAM_CONTEXT => null,
187 62
            self::WSDL_STYLE => null,
188 62
            self::WSDL_TRACE => true,
189 62
            self::WSDL_TYPEMAP => null,
190 62
            self::WSDL_URL => null,
191 62
            self::WSDL_URI => null,
192 62
            self::WSDL_USE => null,
193 62
            self::WSDL_USER_AGENT => null,
194
        ];
195
    }
196
    /**
197
     * Allows to set the SoapClient location to call
198
     * @uses AbstractSoapClientBase::getSoapClient()
199
     * @uses SoapClient::__setLocation()
200
     * @param string $location
201
     * @return AbstractSoapClientBase
202
     */
203 2
    public function setLocation($location)
204
    {
205 2
        if (static::getSoapClient() instanceof \SoapClient) {
0 ignored issues
show
introduced by
static::getSoapClient() is always a sub-type of SoapClient.
Loading history...
206 2
            static::getSoapClient()->__setLocation($location);
207
        }
208 2
        return $this;
209
    }
210
    /**
211
     * Returns the last request content as a DOMDocument or as a formated XML String
212
     * @see SoapClient::__getLastRequest()
213
     * @uses AbstractSoapClientBase::getSoapClient()
214
     * @uses AbstractSoapClientBase::getFormatedXml()
215
     * @uses SoapClient::__getLastRequest()
216
     * @param bool $asDomDocument
217
     * @return \DOMDocument|string|null
218
     */
219 4
    public function getLastRequest($asDomDocument = false)
220
    {
221 4
        return $this->getLastXml('__getLastRequest', $asDomDocument);
222
    }
223
    /**
224
     * Returns the last response content as a DOMDocument or as a formated XML String
225
     * @see SoapClient::__getLastResponse()
226
     * @uses AbstractSoapClientBase::getSoapClient()
227
     * @uses AbstractSoapClientBase::getFormatedXml()
228
     * @uses SoapClient::__getLastResponse()
229
     * @param bool $asDomDocument
230
     * @return \DOMDocument|string|null
231
     */
232 4
    public function getLastResponse($asDomDocument = false)
233
    {
234 4
        return $this->getLastXml('__getLastResponse', $asDomDocument);
235
    }
236
    /**
237
     * @param string $method
238
     * @param bool $asDomDocument
239
     * @return \DOMDocument|string|null
240
     */
241 8
    protected function getLastXml($method, $asDomDocument = false)
242
    {
243 8
        $xml = null;
244 8
        if (static::getSoapClient() instanceof \SoapClient) {
0 ignored issues
show
introduced by
static::getSoapClient() is always a sub-type of SoapClient.
Loading history...
245 8
            $xml = static::getFormatedXml(static::getSoapClient()->$method(), $asDomDocument);
246
        }
247 8
        return $xml;
248
    }
249
    /**
250
     * Returns the last request headers used by the SoapClient object as the original value or an array
251
     * @see SoapClient::__getLastRequestHeaders()
252
     * @uses AbstractSoapClientBase::getSoapClient()
253
     * @uses AbstractSoapClientBase::convertStringHeadersToArray()
254
     * @uses SoapClient::__getLastRequestHeaders()
255
     * @param bool $asArray allows to get the headers in an associative array
256
     * @return null|string|array
257
     */
258 4
    public function getLastRequestHeaders($asArray = false)
259
    {
260 4
        return $this->getLastHeaders('__getLastRequestHeaders', $asArray);
261
    }
262
    /**
263
     * Returns the last response headers used by the SoapClient object as the original value or an array
264
     * @see SoapClient::__getLastResponseHeaders()
265
     * @uses AbstractSoapClientBase::getSoapClient()
266
     * @uses AbstractSoapClientBase::convertStringHeadersToArray()
267
     * @uses SoapClient::__getLastRequestHeaders()
268
     * @param bool $asArray allows to get the headers in an associative array
269
     * @return null|string|array
270
     */
271 4
    public function getLastResponseHeaders($asArray = false)
272
    {
273 4
        return $this->getLastHeaders('__getLastResponseHeaders', $asArray);
274
    }
275
    /**
276
     * @param string $method
277
     * @param bool $asArray allows to get the headers in an associative array
278
     * @return string[]|null
279
     */
280 8
    protected function getLastHeaders($method, $asArray)
281
    {
282 8
        $headers = static::getSoapClient() instanceof \SoapClient ? static::getSoapClient()->$method() : null;
0 ignored issues
show
introduced by
static::getSoapClient() is always a sub-type of SoapClient.
Loading history...
283 8
        if (is_string($headers) && $asArray) {
284 4
            return static::convertStringHeadersToArray($headers);
285
        }
286 4
        return $headers;
287
    }
288
    /**
289
     * Returns a XML string content as a DOMDocument or as a formated XML string
290
     * @uses \DOMDocument::loadXML()
291
     * @uses \DOMDocument::saveXML()
292
     * @param string $string
293
     * @param bool $asDomDocument
294
     * @return \DOMDocument|string|null
295
     */
296 8
    public static function getFormatedXml($string, $asDomDocument = false)
297
    {
298 8
        return Utils::getFormatedXml($string, $asDomDocument);
299
    }
300
    /**
301
     * Returns an associative array between the headers name and their respective values
302
     * @param string $headers
303
     * @return string[]
304
     */
305 4
    public static function convertStringHeadersToArray($headers)
306
    {
307 4
        $lines = explode("\r\n", $headers);
308 4
        $headers = [];
309 4
        foreach ($lines as $line) {
310 4
            if (strpos($line, ':')) {
311 4
                $headerParts = explode(':', $line);
312 4
                $headers[$headerParts[0]] = trim(implode(':', array_slice($headerParts, 1)));
313
            }
314
        }
315 4
        return $headers;
316
    }
317
    /**
318
     * Sets a SoapHeader to send
319
     * For more information, please read the online documentation on {@link http://www.php.net/manual/en/class.soapheader.php}
320
     * @uses AbstractSoapClientBase::getSoapClient()
321
     * @uses SoapClient::__setSoapheaders()
322
     * @param string $nameSpace SoapHeader namespace
323
     * @param string $name SoapHeader name
324
     * @param mixed $data SoapHeader data
325
     * @param bool $mustUnderstand
326
     * @param string $actor
327
     * @return AbstractSoapClientBase
328
     */
329 6
    public function setSoapHeader($nameSpace, $name, $data, $mustUnderstand = false, $actor = null)
330
    {
331 6
        if (static::getSoapClient()) {
332 6
            $defaultHeaders = (isset(static::getSoapClient()->__default_headers) && is_array(static::getSoapClient()->__default_headers)) ? static::getSoapClient()->__default_headers : [];
0 ignored issues
show
Bug introduced by
The property __default_headers does not seem to exist on SoapClient.
Loading history...
333 6
            foreach ($defaultHeaders as $index => $soapHeader) {
334 2
                if ($soapHeader->name === $name) {
335 2
                    unset($defaultHeaders[$index]);
336 2
                    break;
337
                }
338
            }
339 6
            static::getSoapClient()->__setSoapheaders(null);
340 6
            if (!empty($actor)) {
341 2
                array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand, $actor));
342
            } else {
343 4
                array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand));
344
            }
345 6
            static::getSoapClient()->__setSoapheaders($defaultHeaders);
346
        }
347 6
        return $this;
348
    }
349
    /**
350
     * Sets the SoapClient Stream context HTTP Header name according to its value
351
     * If a context already exists, it tries to modify it
352
     * It the context does not exist, it then creates it with the header name and its value
353
     * @uses AbstractSoapClientBase::getSoapClient()
354
     * @param string $headerName
355
     * @param mixed $headerValue
356
     * @return bool
357
     */
358 12
    public function setHttpHeader($headerName, $headerValue)
359
    {
360 12
        $state = false;
361 12
        if (static::getSoapClient() && !empty($headerName)) {
362 12
            $streamContext = $this->getStreamContext();
363 12
            if ($streamContext === null) {
364
                $options = [];
365
                $options['http'] = [];
366
                $options['http']['header'] = '';
367
            } else {
368 12
                $options = stream_context_get_options($streamContext);
369 12
                if (!array_key_exists('http', $options) || !is_array($options['http'])) {
370
                    $options['http'] = [];
371
                    $options['http']['header'] = '';
372 12
                } elseif (!array_key_exists('header', $options['http'])) {
373
                    $options['http']['header'] = '';
374
                }
375
            }
376 12
            if (count($options) && array_key_exists('http', $options) && is_array($options['http']) && array_key_exists('header', $options['http']) && is_string($options['http']['header'])) {
377 12
                $lines = explode("\r\n", $options['http']['header']);
378
                /**
379
                 * Ensure there is only one header entry for this header name
380
                 */
381 12
                $newLines = [];
382 12
                foreach ($lines as $line) {
383 12
                    if (!empty($line) && strpos($line, $headerName) === false) {
384 12
                        array_push($newLines, $line);
385
                    }
386
                }
387
                /**
388
                 * Add new header entry
389
                 */
390 12
                array_push($newLines, "$headerName: $headerValue");
391
                /**
392
                 * Set the context http header option
393
                 */
394 12
                $options['http']['header'] = implode("\r\n", $newLines);
395
                /**
396
                 * Create context if it does not exist
397
                 */
398 12
                if ($streamContext === null) {
399
                    $state = (static::getSoapClient()->_stream_context = stream_context_create($options)) ? true : false;
0 ignored issues
show
Bug introduced by
The property _stream_context does not seem to exist on SoapClient.
Loading history...
400
                } else {
401
                    /**
402
                     * Set the new context http header option
403
                     */
404 12
                    $state = stream_context_set_option(static::getSoapClient()->_stream_context, 'http', 'header', $options['http']['header']);
405
                }
406
            }
407
        }
408 12
        return $state;
409
    }
410
    /**
411
     * Returns current \SoapClient::_stream_context resource or null
412
     * @return resource|null
413
     */
414 14
    public function getStreamContext()
415
    {
416 14
        return (static::getSoapClient() && isset(static::getSoapClient()->_stream_context) && is_resource(static::getSoapClient()->_stream_context)) ? static::getSoapClient()->_stream_context : null;
0 ignored issues
show
Bug introduced by
The property _stream_context does not seem to exist on SoapClient.
Loading history...
417
    }
418
    /**
419
     * Returns current \SoapClient::_stream_context resource options or empty array
420
     * @return array
421
     */
422 2
    public function getStreamContextOptions()
423
    {
424 2
        $options = [];
425 2
        $context = $this->getStreamContext();
426 2
        if ($context !== null) {
427 2
            $options = stream_context_get_options($context);
428 2
            if (isset($options['http']['header']) && is_string($options['http']['header'])) {
429 2
                $options['http']['header'] = array_filter(array_map('trim', explode(PHP_EOL, $options['http']['header'])));
430
            }
431
        }
432 2
        return $options;
433
    }
434
    /**
435
     * Method returning last errors occured during the calls
436
     * @return array
437
     */
438 2
    public function getLastError()
439
    {
440 2
        return $this->lastError;
441
    }
442
    /**
443
     * Method setting last errors occured during the calls
444
     * @param array $lastError
445
     * @return AbstractSoapClientBase
446
     */
447 62
    private function setLastError($lastError)
448
    {
449 62
        $this->lastError = $lastError;
450 62
        return $this;
451
    }
452
    /**
453
     * Method saving the last error returned by the SoapClient
454
     * @param string $methodName the method called when the error occurred
455
     * @param \SoapFault $soapFault l'objet de l'erreur
456
     * @return AbstractSoapClientBase
457
     */
458 6
    public function saveLastError($methodName, \SoapFault $soapFault)
459
    {
460 6
        $this->lastError[$methodName] = $soapFault;
461 6
        return $this;
462
    }
463
    /**
464
     * Method getting the last error for a certain method
465
     * @param string $methodName method name to get error from
466
     * @return \SoapFault|null
467
     */
468 2
    public function getLastErrorForMethod($methodName)
469
    {
470 2
        return array_key_exists($methodName, $this->lastError) ? $this->lastError[$methodName] : null;
471
    }
472
    /**
473
     * Method returning current result from Soap call
474
     * @return mixed
475
     */
476 2
    public function getResult()
477
    {
478 2
        return $this->result;
479
    }
480
    /**
481
     * Method setting current result from Soap call
482
     * @param mixed $result
483
     * @return AbstractSoapClientBase
484
     */
485 6
    public function setResult($result)
486
    {
487 6
        $this->result = $result;
488 6
        return $this;
489
    }
490
    /**
491
     * @return array
492
     */
493 2
    public function getOutputHeaders()
494
    {
495 2
        return $this->outputHeaders;
496
    }
497
}
498