Completed
Push — feature/issue-31 ( 91722f )
by Mikaël
14s queued 10s
created

AbstractSoapClientBase::setHttpHeader()   C

Complexity

Conditions 17
Paths 17

Size

Total Lines 51
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 17.5145

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