Completed
Push — develop ( 9dd5b1...ebfda4 )
by Mikaël
01:52
created

AbstractSoapClientBase::getStreamContext()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 9.2
cc 4
eloc 2
nc 6
nop 0
crap 4
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 100
    public function __construct(array $wsdlOptions = array(), $resetSoapClient = true)
30
    {
31 100
        $this->setLastError(array());
32
        /**
33
         * Init soap Client
34
         * Set default values
35
         */
36 100
        if ($resetSoapClient) {
37 100
            $this->initSoapClient($wsdlOptions);
38 100
        }
39 100
    }
40
    /**
41
     * Static method getting current SoapClient
42
     * @return \SoapClient
43
     */
44 92
    public static function getSoapClient()
45
    {
46 92
        return self::$soapClient;
47
    }
48
    /**
49
     * Static method setting current SoapClient
50
     * @param \SoapClient $soapClient
51
     * @return \SoapClient
52
     */
53 92
    public static function setSoapClient(\SoapClient $soapClient)
54
    {
55 92
        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
     * @param array $options WSDL options
64
     * @return void
65
     */
66 100
    public function initSoapClient(array $options)
67
    {
68 100
        $wsdlOptions = array();
69 100
        $defaultWsdlOptions = self::getDefaultWsdlOptions();
70 100
        foreach ($defaultWsdlOptions as $optioName => $optionValue) {
71 100
            if (array_key_exists($optioName, $options) && !empty($options[$optioName])) {
72 92
                $wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optioName)] = $options[$optioName];
73 100
            } elseif (!empty($optionValue)) {
74 100
                $wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optioName)] = $optionValue;
75 100
            }
76 100
        }
77 100
        if (array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URL), $wsdlOptions)) {
78 92
            $wsdlUrl = $wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)];
79 92
            unset($wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)]);
80 92
            $soapClientClassName = $this->getSoapClientClassName();
81 92
            self::setSoapClient(new $soapClientClassName($wsdlUrl, $wsdlOptions));
82 92
        }
83 100
    }
84
    /**
85
     * Returns the SoapClient class name to use to create the instance of the SoapClient.
86
     * The SoapClient class is determined based on the package name.
87
     * If a class is named as {Api}SoapClient, then this is the class that will be used.
88
     * Be sure that this class inherits from the native PHP SoapClient class and this class has been loaded or can be loaded.
89
     * The goal is to allow the override of the SoapClient without having to modify this generated class.
90
     * Then the overridding SoapClient class can override for example the SoapClient::__doRequest() method if it is needed.
91
     * @return string
92
     */
93 100
    public function getSoapClientClassName($soapClientClassName = null)
94
    {
95 100
        $className = self::DEFAULT_SOAP_CLIENT_CLASS;
96 100
        if (!empty($soapClientClassName) && is_subclass_of($soapClientClassName, '\SoapClient')) {
97 96
            $className = $soapClientClassName;
98 96
        }
99 100
        return $className;
100
    }
101
    /**
102
     * Method returning all default options values
103
     * @uses AbstractSoapClientBase::WSDL_CLASSMAP
104
     * @uses AbstractSoapClientBase::WSDL_CACHE_WSDL
105
     * @uses AbstractSoapClientBase::WSDL_COMPRESSION
106
     * @uses AbstractSoapClientBase::WSDL_CONNECTION_TIMEOUT
107
     * @uses AbstractSoapClientBase::WSDL_ENCODING
108
     * @uses AbstractSoapClientBase::WSDL_EXCEPTIONS
109
     * @uses AbstractSoapClientBase::WSDL_FEATURES
110
     * @uses AbstractSoapClientBase::WSDL_LOGIN
111
     * @uses AbstractSoapClientBase::WSDL_PASSWORD
112
     * @uses AbstractSoapClientBase::WSDL_SOAP_VERSION
113
     * @uses AbstractSoapClientBase::WSDL_STREAM_CONTEXT
114
     * @uses AbstractSoapClientBase::WSDL_TRACE
115
     * @uses AbstractSoapClientBase::WSDL_TYPEMAP
116
     * @uses AbstractSoapClientBase::WSDL_URL
117
     * @uses AbstractSoapClientBase::VALUE_WSDL_URL
118
     * @uses AbstractSoapClientBase::WSDL_USER_AGENT
119
     * @uses AbstractSoapClientBase::WSDL_PROXY_HOST
120
     * @uses AbstractSoapClientBase::WSDL_PROXY_PORT
121
     * @uses AbstractSoapClientBase::WSDL_PROXY_LOGIN
122
     * @uses AbstractSoapClientBase::WSDL_PROXY_PASSWORD
123
     * @uses AbstractSoapClientBase::WSDL_LOCAL_CERT
124
     * @uses AbstractSoapClientBase::WSDL_PASSPHRASE
125
     * @uses AbstractSoapClientBase::WSDL_AUTHENTICATION
126
     * @uses AbstractSoapClientBase::WSDL_SSL_METHOD
127
     * @uses SOAP_SINGLE_ELEMENT_ARRAYS
128
     * @uses SOAP_USE_XSI_ARRAY_TYPE
129
     * @return array
130
     */
131 100
    public static function getDefaultWsdlOptions()
132
    {
133
        return array(
134 100
                    self::WSDL_CLASSMAP => null,
135 100
                    self::WSDL_CACHE_WSDL => WSDL_CACHE_NONE,
136 100
                    self::WSDL_COMPRESSION => null,
137 100
                    self::WSDL_CONNECTION_TIMEOUT => null,
138 100
                    self::WSDL_ENCODING => null,
139 100
                    self::WSDL_EXCEPTIONS => true,
140 100
                    self::WSDL_FEATURES => SOAP_SINGLE_ELEMENT_ARRAYS | SOAP_USE_XSI_ARRAY_TYPE,
141 100
                    self::WSDL_LOGIN => null,
142 100
                    self::WSDL_PASSWORD => null,
143 100
                    self::WSDL_SOAP_VERSION => null,
144 100
                    self::WSDL_STREAM_CONTEXT => null,
145 100
                    self::WSDL_TRACE => true,
146 100
                    self::WSDL_TYPEMAP => null,
147 100
                    self::WSDL_URL => null,
148 100
                    self::WSDL_USER_AGENT => null,
149 100
                    self::WSDL_PROXY_HOST => null,
150 100
                    self::WSDL_PROXY_PORT => null,
151 100
                    self::WSDL_PROXY_LOGIN => null,
152 100
                    self::WSDL_PROXY_PASSWORD => null,
153 100
                    self::WSDL_LOCAL_CERT => null,
154 100
                    self::WSDL_PASSPHRASE => null,
155 100
                    self::WSDL_AUTHENTICATION => null,
156 100
                    self::WSDL_SSL_METHOD => null);
157
    }
158
    /**
159
     * Allows to set the SoapClient location to call
160
     * @uses AbstractSoapClientBase::getSoapClient()
161
     * @uses SoapClient::__setLocation()
162
     * @param string $location
163
     * @return AbstractSoapClientBase
164
     */
165 4
    public function setLocation($location)
166
    {
167 4
        if (self::getSoapClient() instanceof \SoapClient) {
168 4
            self::getSoapClient()->__setLocation($location);
169 4
        }
170 4
        return $this;
171
    }
172
    /**
173
     * Returns the last request content as a DOMDocument or as a formated XML String
174
     * @see SoapClient::__getLastRequest()
175
     * @uses AbstractSoapClientBase::getSoapClient()
176
     * @uses AbstractSoapClientBase::getFormatedXml()
177
     * @uses SoapClient::__getLastRequest()
178
     * @param bool $asDomDocument
179
     * @return \DOMDocument|string|null
180
     */
181 8
    public function getLastRequest($asDomDocument = false)
182
    {
183 8
        return $this->getLastXml('__getLastRequest', $asDomDocument);
184
    }
185
    /**
186
     * Returns the last response content as a DOMDocument or as a formated XML String
187
     * @see SoapClient::__getLastResponse()
188
     * @uses AbstractSoapClientBase::getSoapClient()
189
     * @uses AbstractSoapClientBase::getFormatedXml()
190
     * @uses SoapClient::__getLastResponse()
191
     * @param bool $asDomDocument
192
     * @return \DOMDocument|string|null
193
     */
194 8
    public function getLastResponse($asDomDocument = false)
195
    {
196 8
        return $this->getLastXml('__getLastResponse', $asDomDocument);
197
    }
198
    /**
199
     * @param string $method
200
     * @param bool $asDomDocument
201
     * @return \DOMDocument|string|null
202
     */
203 16
    protected function getLastXml($method, $asDomDocument = false)
204
    {
205 16
        $xml = null;
206 16
        if (self::getSoapClient() instanceof \SoapClient) {
207 16
            $xml = self::getFormatedXml(self::getSoapClient()->$method(), $asDomDocument);
208 16
        }
209 16
        return $xml;
210
    }
211
    /**
212
     * Returns the last request headers used by the SoapClient object as the original value or an array
213
     * @see SoapClient::__getLastRequestHeaders()
214
     * @uses AbstractSoapClientBase::getSoapClient()
215
     * @uses AbstractSoapClientBase::convertStringHeadersToArray()
216
     * @uses SoapClient::__getLastRequestHeaders()
217
     * @param bool $asArray allows to get the headers in an associative array
218
     * @return null|string|array
219
     */
220 8
    public function getLastRequestHeaders($asArray = false)
221
    {
222 8
        return $this->getLastHeaders('__getLastRequestHeaders', $asArray);
223
    }
224
    /**
225
     * Returns the last response headers used by the SoapClient object as the original value or an array
226
     * @see SoapClient::__getLastResponseHeaders()
227
     * @uses AbstractSoapClientBase::getSoapClient()
228
     * @uses AbstractSoapClientBase::convertStringHeadersToArray()
229
     * @uses SoapClient::__getLastRequestHeaders()
230
     * @param bool $asArray allows to get the headers in an associative array
231
     * @return null|string|array
232
     */
233 8
    public function getLastResponseHeaders($asArray = false)
234
    {
235 8
        return $this->getLastHeaders('__getLastResponseHeaders', $asArray);
236
    }
237
    /**
238
     * @param string $method
239
     * @param bool $asArray allows to get the headers in an associative array
240
     * @return string[]|null
241
     */
242 16
    protected function getLastHeaders($method, $asArray)
243
    {
244 16
        $headers = self::getSoapClient() instanceof \SoapClient ? self::getSoapClient()->$method() : null;
245 16
        if (is_string($headers) && $asArray) {
246 8
            return self::convertStringHeadersToArray($headers);
247
        }
248 8
        return $headers;
249
    }
250
    /**
251
     * Returns a XML string content as a DOMDocument or as a formated XML string
252
     * @uses \DOMDocument::loadXML()
253
     * @uses \DOMDocument::saveXML()
254
     * @param string $string
255
     * @param bool $asDomDocument
256
     * @return \DOMDocument|string|null
257
     */
258 16
    public static function getFormatedXml($string, $asDomDocument = false)
259
    {
260 16
        return Utils::getFormatedXml($string, $asDomDocument);
261
    }
262
    /**
263
     * Returns an associative array between the headers name and their respective values
264
     * @param string $headers
265
     * @return string[]
266
     */
267 8
    public static function convertStringHeadersToArray($headers)
268
    {
269 8
        $lines = explode("\r\n", $headers);
270 8
        $headers = array();
271 8
        foreach ($lines as $line) {
272 8
            if (strpos($line, ':')) {
273 8
                $headerParts = explode(':', $line);
274 8
                $headers[$headerParts[0]] = trim(implode(':', array_slice($headerParts, 1)));
275 8
            }
276 8
        }
277 8
        return $headers;
278
    }
279
    /**
280
     * Sets a SoapHeader to send
281
     * For more information, please read the online documentation on {@link http://www.php.net/manual/en/class.soapheader.php}
282
     * @uses AbstractSoapClientBase::getSoapClient()
283
     * @uses SoapClient::__setSoapheaders()
284
     * @param string $nameSpace SoapHeader namespace
285
     * @param string $name SoapHeader name
286
     * @param mixed $data SoapHeader data
287
     * @param bool $mustUnderstand
288
     * @param string $actor
289
     * @return AbstractSoapClientBase
290
     */
291 12
    public function setSoapHeader($nameSpace, $name, $data, $mustUnderstand = false, $actor = null)
292
    {
293 12
        if (self::getSoapClient()) {
294 12
            $defaultHeaders = (isset(self::getSoapClient()->__default_headers) && is_array(self::getSoapClient()->__default_headers)) ? self::getSoapClient()->__default_headers : array();
0 ignored issues
show
Bug introduced by
The property __default_headers does not seem to exist in SoapClient.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
295 12
            foreach ($defaultHeaders as $index => $soapHeader) {
296 4
                if ($soapHeader->name === $name) {
297 4
                    unset($defaultHeaders[$index]);
298 4
                    break;
299
                }
300 12
            }
301 12
            self::getSoapClient()->__setSoapheaders(null);
302 12
            if (!empty($actor)) {
303 4
                array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand, $actor));
304 4
            } else {
305 8
                array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand));
306
            }
307 12
            self::getSoapClient()->__setSoapheaders($defaultHeaders);
308 12
        }
309 12
        return $this;
310
    }
311
    /**
312
     * Sets the SoapClient Stream context HTTP Header name according to its value
313
     * If a context already exists, it tries to modify it
314
     * It the context does not exist, it then creates it with the header name and its value
315
     * @uses AbstractSoapClientBase::getSoapClient()
316
     * @param string $headerName
317
     * @param mixed $headerValue
318
     * @return bool
319
     */
320 24
    public function setHttpHeader($headerName, $headerValue)
321
    {
322 24
        $state = false;
323 24
        if (self::getSoapClient() && !empty($headerName)) {
324 24
            $streamContext = $this->getStreamContext();
325 24
            if ($streamContext === null) {
326 12
                $options = array();
327 12
                $options['http'] = array();
328 12
                $options['http']['header'] = '';
329 12
            } else {
330 16
                $options = stream_context_get_options($streamContext);
331 16
                if (!array_key_exists('http', $options) || !is_array($options['http'])) {
332 4
                    $options['http'] = array();
333 4
                    $options['http']['header'] = '';
334 16
                } elseif (!array_key_exists('header', $options['http'])) {
335 8
                    $options['http']['header'] = '';
336 8
                }
337
            }
338 24
            if (count($options) && array_key_exists('http', $options) && is_array($options['http']) && array_key_exists('header', $options['http']) && is_string($options['http']['header'])) {
339 24
                $lines = explode("\r\n", $options['http']['header']);
340
                /**
341
                 * Ensure there is only one header entry for this header name
342
                 */
343 24
                $newLines = array();
344 24
                foreach ($lines as $line) {
345 24
                    if (!empty($line) && strpos($line, $headerName) === false) {
346 16
                        array_push($newLines, $line);
347 16
                    }
348 24
                }
349
                /**
350
                 * Add new header entry
351
                 */
352 24
                array_push($newLines, "$headerName: $headerValue");
353
                /**
354
                 * Set the context http header option
355
                 */
356 24
                $options['http']['header'] = implode("\r\n", $newLines);
357
                /**
358
                 * Create context if it does not exist
359
                 */
360 24
                if ($streamContext === null) {
361 12
                    $state = (self::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 in SoapClient.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
362 12
                } else {
363
                    /**
364
                     * Set the new context http header option
365
                     */
366 16
                    $state = stream_context_set_option(self::getSoapClient()->_stream_context, 'http', 'header', $options['http']['header']);
367
                }
368 24
            }
369 24
        }
370 24
        return $state;
371
    }
372
    /**
373
     * Returns current \SoapClient::_stream_context resource or null
374
     * @return resource|null
375
     */
376 28
    public function getStreamContext()
377
    {
378 28
        return (self::getSoapClient() && isset(self::getSoapClient()->_stream_context) && is_resource(self::getSoapClient()->_stream_context)) ? self::getSoapClient()->_stream_context : null;
0 ignored issues
show
Bug introduced by
The property _stream_context does not seem to exist in SoapClient.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
379
    }
380
    /**
381
     * Returns current \SoapClient::_stream_context resource options or empty array
382
     * @return array
383
     */
384 4
    public function getStreamContextOptions()
385
    {
386 4
        $options = array();
387 4
        $context = $this->getStreamContext();
388 4
        if ($context !== null) {
389 4
            $options = stream_context_get_options($context);
390 4
        }
391 4
        return $options;
392
    }
393
    /**
394
     * Method returning last errors occured during the calls
395
     * @return array
396
     */
397 4
    public function getLastError()
398
    {
399 4
        return $this->lastError;
400
    }
401
    /**
402
     * Method setting last errors occured during the calls
403
     * @param array $lastError
404
     * @return AbstractSoapClientBase
405
     */
406 100
    private function setLastError($lastError)
407
    {
408 100
        $this->lastError = $lastError;
409 100
        return $this;
410
    }
411
    /**
412
     * Method saving the last error returned by the SoapClient
413
     * @param string $methoName the method called when the error occurred
414
     * @param \SoapFault $soapFault l'objet de l'erreur
415
     * @return AbstractSoapClientBase
416
     */
417 12
    public function saveLastError($methoName, \SoapFault $soapFault)
418
    {
419 12
        $this->lastError[$methoName] = $soapFault;
420 12
        return $this;
421
    }
422
    /**
423
     * Method getting the last error for a certain method
424
     * @param string $methoName method name to get error from
425
     * @return \SoapFault|null
426
     */
427 4
    public function getLastErrorForMethod($methoName)
428
    {
429 4
        return array_key_exists($methoName, $this->lastError) ? $this->lastError[$methoName] : null;
430
    }
431
    /**
432
     * Method returning current result from Soap call
433
     * @return mixed
434
     */
435 4
    public function getResult()
436
    {
437 4
        return $this->result;
438
    }
439
    /**
440
     * Method setting current result from Soap call
441
     * @param mixed $result
442
     * @return AbstractSoapClientBase
443
     */
444 12
    public function setResult($result)
445
    {
446 12
        $this->result = $result;
447 12
        return $this;
448
    }
449
}
450