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