Passed
Push — 2.x ( 46eeaf...76eded )
by Mikaël
49:59 queued 47:23
created

AbstractSoapClientBase::setHttpHeader()   C

Complexity

Conditions 17
Paths 17

Size

Total Lines 51
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 22.6378

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 17
eloc 27
c 3
b 0
f 0
nc 17
nop 2
dl 0
loc 51
ccs 19
cts 26
cp 0.7308
crap 22.6378
rs 5.2166

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