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