Passed
Push — develop ( 047bfd...b0429f )
by Mikaël
03:07 queued 36s
created

AbstractSoapClientBase::setHttpHeader()   C

Complexity

Conditions 17
Paths 17

Size

Total Lines 51
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 17.7578

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