xxxxxxxxxx
namespace WsdlToPhp\PackageBase;
abstract class AbstractSoapClientBase implements SoapClientInterface
{
/**
* Soapclient called to communicate with the actual SOAP Service
* @var \SoapClient
*/
private $soapClient;
/**
* Contains Soap call result
* @var mixed
*/
private $result;
/**
* Contains last errors
* @var array
*/
private $lastError;
/**
* Contains output headers
* @var array
*/
protected $outputHeaders = [];
/**
* Constructor
* @uses AbstractSoapClientBase::setLastError()
* @uses AbstractSoapClientBase::initSoapClient()
* @param array $wsdlOptions
*/
public function __construct(array $wsdlOptions = [])
{
$this->setLastError([]);
/**
* Init soap Client
* Set default values
*/
$this->initSoapClient($wsdlOptions);
}
/**
* Method getting current SoapClient
* @return \SoapClient
*/
public function getSoapClient()
{
return $this->soapClient;
}
/**
* Method setting current SoapClient
* @param \SoapClient $soapClient
* @return \SoapClient
*/
public function setSoapClient(\SoapClient $soapClient)
{
return ($this->soapClient = $soapClient);
}
/**
* Method initiating SoapClient
* @uses ApiClassMap::classMap()
* @uses AbstractSoapClientBase::getDefaultWsdlOptions()
* @uses AbstractSoapClientBase::getSoapClientClassName()
* @uses AbstractSoapClientBase::setSoapClient()
* @uses AbstractSoapClientBase::OPTION_PREFIX
* @param array $options WSDL options
* @return void
*/
public function initSoapClient(array $options)
{
$wsdlOptions = [];
$defaultWsdlOptions = static::getDefaultWsdlOptions();
foreach ($defaultWsdlOptions as $optionName => $optionValue) {
if (array_key_exists($optionName, $options) && !is_null($options[$optionName])) {
$wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optionName)] = $options[$optionName];
} elseif (!is_null($optionValue)) {
$wsdlOptions[str_replace(self::OPTION_PREFIX, '', $optionName)] = $optionValue;
}
}
if (self::canInstantiateSoapClientWithOptions($wsdlOptions)) {
$wsdlUrl = null;
if (array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URL), $wsdlOptions)) {
$wsdlUrl = $wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)];
unset($wsdlOptions[str_replace(self::OPTION_PREFIX, '', self::WSDL_URL)]);
}
$soapClientClassName = $this->getSoapClientClassName();
$this->setSoapClient(new $soapClientClassName($wsdlUrl, $wsdlOptions));
}
}
/**
* Checks if the provided options are sufficient to instantiate a SoapClient:
* - WSDL-mode : only the WSDL is required
* - non-WSDL-mode : URI and LOCATION are required, WSDL url can be empty then
* @uses AbstractSoapClientBase::OPTION_PREFIX
* @param $wsdlOptions
* @return bool
*/
protected static function canInstantiateSoapClientWithOptions($wsdlOptions)
{
return (
array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URL), $wsdlOptions) ||
(
array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_URI), $wsdlOptions) &&
array_key_exists(str_replace(self::OPTION_PREFIX, '', self::WSDL_LOCATION), $wsdlOptions)
)
);
}
/**
* Returns the SoapClient class name to use to create the instance of the SoapClient.
* The SoapClient class is determined based on the package name.
* If a class is named as {Api}SoapClient, then this is the class that will be used.
* Be sure that this class inherits from the native PHP SoapClient class and this class has been loaded or can be loaded.
* The goal is to allow the override of the SoapClient without having to modify this generated class.
* Then the overridding SoapClient class can override for example the SoapClient::__doRequest() method if it is needed.
* @uses AbstractSoapClientBase::DEFAULT_SOAP_CLIENT_CLASS
* @return string
*/
public function getSoapClientClassName($soapClientClassName = null)
{
$className = self::DEFAULT_SOAP_CLIENT_CLASS;
if (!empty($soapClientClassName) && is_subclass_of($soapClientClassName, '\SoapClient')) {
$className = $soapClientClassName;
}
return $className;
}
/**
* Method returning all default options values
* @uses AbstractSoapClientBase::WSDL_AUTHENTICATION
* @uses AbstractSoapClientBase::WSDL_CACHE_WSDL
* @uses AbstractSoapClientBase::WSDL_CLASSMAP
* @uses AbstractSoapClientBase::WSDL_COMPRESSION
* @uses AbstractSoapClientBase::WSDL_CONNECTION_TIMEOUT
* @uses AbstractSoapClientBase::WSDL_ENCODING
* @uses AbstractSoapClientBase::WSDL_EXCEPTIONS
* @uses AbstractSoapClientBase::WSDL_FEATURES
* @uses AbstractSoapClientBase::WSDL_LOCAL_CERT
* @uses AbstractSoapClientBase::WSDL_LOCATION
* @uses AbstractSoapClientBase::WSDL_LOGIN
* @uses AbstractSoapClientBase::WSDL_PASSPHRASE
* @uses AbstractSoapClientBase::WSDL_PASSWORD
* @uses AbstractSoapClientBase::WSDL_PROXY_HOST
* @uses AbstractSoapClientBase::WSDL_PROXY_LOGIN
* @uses AbstractSoapClientBase::WSDL_PROXY_PASSWORD
* @uses AbstractSoapClientBase::WSDL_PROXY_PORT
* @uses AbstractSoapClientBase::WSDL_SOAP_VERSION
* @uses AbstractSoapClientBase::WSDL_SSL_METHOD
* @uses AbstractSoapClientBase::WSDL_STREAM_CONTEXT
* @uses AbstractSoapClientBase::WSDL_STYLE
* @uses AbstractSoapClientBase::WSDL_TRACE
* @uses AbstractSoapClientBase::WSDL_TYPEMAP
* @uses AbstractSoapClientBase::WSDL_URL
* @uses AbstractSoapClientBase::WSDL_URI
* @uses AbstractSoapClientBase::WSDL_USE
* @uses AbstractSoapClientBase::WSDL_USER_AGENT
* @uses WSDL_CACHE_NONE
* @uses SOAP_SINGLE_ELEMENT_ARRAYS
* @uses SOAP_USE_XSI_ARRAY_TYPE
* @return array
*/
public static function getDefaultWsdlOptions()
{
return [
self::WSDL_AUTHENTICATION => null,
self::WSDL_CACHE_WSDL => WSDL_CACHE_NONE,
self::WSDL_CLASSMAP => null,
self::WSDL_COMPRESSION => null,
self::WSDL_CONNECTION_TIMEOUT => null,
self::WSDL_ENCODING => null,
self::WSDL_EXCEPTIONS => true,
self::WSDL_FEATURES => SOAP_SINGLE_ELEMENT_ARRAYS | SOAP_USE_XSI_ARRAY_TYPE,
self::WSDL_LOCAL_CERT => null,
self::WSDL_LOCATION => null,
self::WSDL_LOGIN => null,
self::WSDL_PASSPHRASE => null,
self::WSDL_PASSWORD => null,
self::WSDL_PROXY_HOST => null,
self::WSDL_PROXY_LOGIN => null,
self::WSDL_PROXY_PASSWORD => null,
self::WSDL_PROXY_PORT => null,
self::WSDL_SOAP_VERSION => null,
self::WSDL_SSL_METHOD => null,
self::WSDL_STREAM_CONTEXT => null,
self::WSDL_STYLE => null,
self::WSDL_TRACE => true,
self::WSDL_TYPEMAP => null,
self::WSDL_URL => null,
self::WSDL_URI => null,
self::WSDL_USE => null,
self::WSDL_USER_AGENT => null,
];
}
/**
* Allows to set the SoapClient location to call
* @uses AbstractSoapClientBase::getSoapClient()
* @uses SoapClient::__setLocation()
* @param string $location
* @return AbstractSoapClientBase
*/
public function setLocation($location)
{
if ($this->getSoapClient() instanceof \SoapClient) {
$this->getSoapClient()->__setLocation($location);
}
return $this;
}
/**
* Returns the last request content as a DOMDocument or as a formated XML String
* @see SoapClient::__getLastRequest()
* @uses AbstractSoapClientBase::getSoapClient()
* @uses AbstractSoapClientBase::getFormatedXml()
* @uses SoapClient::__getLastRequest()
* @param bool $asDomDocument
* @return \DOMDocument|string|null
*/
public function getLastRequest($asDomDocument = false)
{
return $this->getLastXml('__getLastRequest', $asDomDocument);
}
/**
* Returns the last response content as a DOMDocument or as a formated XML String
* @see SoapClient::__getLastResponse()
* @uses AbstractSoapClientBase::getSoapClient()
* @uses AbstractSoapClientBase::getFormatedXml()
* @uses SoapClient::__getLastResponse()
* @param bool $asDomDocument
* @return \DOMDocument|string|null
*/
public function getLastResponse($asDomDocument = false)
{
return $this->getLastXml('__getLastResponse', $asDomDocument);
}
/**
* @param string $method
* @param bool $asDomDocument
* @return \DOMDocument|string|null
*/
protected function getLastXml($method, $asDomDocument = false)
{
$xml = null;
if ($this->getSoapClient() instanceof \SoapClient) {
$xml = static::getFormatedXml($this->getSoapClient()->$method(), $asDomDocument);
}
return $xml;
}
/**
* Returns the last request headers used by the SoapClient object as the original value or an array
* @see SoapClient::__getLastRequestHeaders()
* @uses AbstractSoapClientBase::getSoapClient()
* @uses AbstractSoapClientBase::convertStringHeadersToArray()
* @uses SoapClient::__getLastRequestHeaders()
* @param bool $asArray allows to get the headers in an associative array
* @return null|string|array
*/
public function getLastRequestHeaders($asArray = false)
{
return $this->getLastHeaders('__getLastRequestHeaders', $asArray);
}
/**
* Returns the last response headers used by the SoapClient object as the original value or an array
* @see SoapClient::__getLastResponseHeaders()
* @uses AbstractSoapClientBase::getSoapClient()
* @uses AbstractSoapClientBase::convertStringHeadersToArray()
* @uses SoapClient::__getLastRequestHeaders()
* @param bool $asArray allows to get the headers in an associative array
* @return null|string|array
*/
public function getLastResponseHeaders($asArray = false)
{
return $this->getLastHeaders('__getLastResponseHeaders', $asArray);
}
/**
* @param string $method
* @param bool $asArray allows to get the headers in an associative array
* @return string[]|null
*/
protected function getLastHeaders($method, $asArray)
{
$headers = $this->getSoapClient() instanceof \SoapClient ? $this->getSoapClient()->$method() : null;
if (is_string($headers) && $asArray) {
return static::convertStringHeadersToArray($headers);
}
return $headers;
}
/**
* Returns a XML string content as a DOMDocument or as a formated XML string
* @uses \DOMDocument::loadXML()
* @uses \DOMDocument::saveXML()
* @param string $string
* @param bool $asDomDocument
* @return \DOMDocument|string|null
*/
public static function getFormatedXml($string, $asDomDocument = false)
{
@trigger_error(sprintf('%s() will be renamed to getFormattedXml in WsdlToPhp/PackageBase 3.0.', __METHOD__), E_USER_DEPRECATED);
return Utils::getFormatedXml($string, $asDomDocument);
}
/**
* Returns an associative array between the headers name and their respective values
* @param string $headers
* @return string[]
*/
public static function convertStringHeadersToArray($headers)
{
$lines = explode("\r\n", $headers);
$headers = [];
foreach ($lines as $line) {
if (strpos($line, ':')) {
$headerParts = explode(':', $line);
$headers[$headerParts[0]] = trim(implode(':', array_slice($headerParts, 1)));
}
}
return $headers;
}
/**
* Sets a SoapHeader to send
* For more information, please read the online documentation on {@link http://www.php.net/manual/en/class.soapheader.php}
* @uses AbstractSoapClientBase::getSoapClient()
* @uses SoapClient::__setSoapheaders()
* @param string $nameSpace SoapHeader namespace
* @param string $name SoapHeader name
* @param mixed $data SoapHeader data
* @param bool $mustUnderstand
* @param string $actor
* @return AbstractSoapClientBase
*/
public function setSoapHeader($nameSpace, $name, $data, $mustUnderstand = false, $actor = null)
{
if ($this->getSoapClient()) {
$defaultHeaders = (isset($this->getSoapClient()->__default_headers) && is_array($this->getSoapClient()->__default_headers)) ? $this->getSoapClient()->__default_headers : [];
foreach ($defaultHeaders as $index => $soapHeader) {
if ($soapHeader->name === $name) {
unset($defaultHeaders[$index]);
break;
}
}
$this->getSoapClient()->__setSoapheaders(null);
if (!empty($actor)) {
array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand, $actor));
} else {
array_push($defaultHeaders, new \SoapHeader($nameSpace, $name, $data, $mustUnderstand));
}
$this->getSoapClient()->__setSoapheaders($defaultHeaders);
}
return $this;
}
/**
* Sets the SoapClient Stream context HTTP Header name according to its value
* If a context already exists, it tries to modify it
* It the context does not exist, it then creates it with the header name and its value
* @uses AbstractSoapClientBase::getSoapClient()
* @param string $headerName
* @param mixed $headerValue
* @return bool
*/
public function setHttpHeader($headerName, $headerValue)
{
$state = false;
if ($this->getSoapClient() && !empty($headerName)) {
$streamContext = $this->getStreamContext();
if ($streamContext === null) {
$options = [];
$options['http'] = [];
$options['http']['header'] = '';
} else {
$options = stream_context_get_options($streamContext);
if (!array_key_exists('http', $options) || !is_array($options['http'])) {
$options['http'] = [];
$options['http']['header'] = '';
} elseif (!array_key_exists('header', $options['http'])) {
$options['http']['header'] = '';
}
}
if (count($options) && array_key_exists('http', $options) && is_array($options['http']) && array_key_exists('header', $options['http']) && is_string($options['http']['header'])) {
$lines = explode("\r\n", $options['http']['header']);
/**
* Ensure there is only one header entry for this header name
*/
$newLines = [];
foreach ($lines as $line) {
if (!empty($line) && strpos($line, $headerName) === false) {
array_push($newLines, $line);
}
}
/**
* Add new header entry
*/
array_push($newLines, "$headerName: $headerValue");
/**
* Set the context http header option
*/
$options['http']['header'] = implode("\r\n", $newLines);
/**
* Create context if it does not exist
*/
if ($streamContext === null) {
$state = ($this->getSoapClient()->_stream_context = stream_context_create($options)) ? true : false;
} else {
/**
* Set the new context http header option
*/
$state = stream_context_set_option($this->getSoapClient()->_stream_context, 'http', 'header', $options['http']['header']);
}
}
}
return $state;
}
/**
* Returns current \SoapClient::_stream_context resource or null
* @return resource|null
*/
public function getStreamContext()
{
return ($this->getSoapClient() && isset($this->getSoapClient()->_stream_context) && is_resource($this->getSoapClient()->_stream_context)) ? $this->getSoapClient()->_stream_context : null;
}
/**
* Returns current \SoapClient::_stream_context resource options or empty array
* @return array
*/
public function getStreamContextOptions()
{
$options = [];
$context = $this->getStreamContext();
if ($context !== null) {
$options = stream_context_get_options($context);
if (isset($options['http']['header']) && is_string($options['http']['header'])) {
$options['http']['header'] = array_filter(array_map('trim', explode(PHP_EOL, $options['http']['header'])));
}
}
return $options;
}
/**
* Method returning last errors occured during the calls
* @return array
*/
public function getLastError()
{
return $this->lastError;
}
/**
* Method setting last errors occured during the calls
* @param array $lastError
* @return AbstractSoapClientBase
*/
private function setLastError($lastError)
{
$this->lastError = $lastError;
return $this;
}
/**
* Method saving the last error returned by the SoapClient
* @param string $methodName the method called when the error occurred
* @param \SoapFault $soapFault l'objet de l'erreur
* @return AbstractSoapClientBase
*/
public function saveLastError($methodName, \SoapFault $soapFault)
{
$this->lastError[$methodName] = $soapFault;
return $this;
}
/**
* Method getting the last error for a certain method
* @param string $methodName method name to get error from
* @return \SoapFault|null
*/
public function getLastErrorForMethod($methodName)
{
return array_key_exists($methodName, $this->lastError) ? $this->lastError[$methodName] : null;
}
/**
* Method returning current result from Soap call
* @return mixed
*/
public function getResult()
{
return $this->result;
}
/**
* Method setting current result from Soap call
* @param mixed $result
* @return AbstractSoapClientBase
*/
public function setResult($result)
{
$this->result = $result;
return $this;
}
/**
* @return array
*/
public function getOutputHeaders()
{
return $this->outputHeaders;
}
/**
* Default string representation of current object. Don't want to expose any sensible data
* @return string
*/
public function __toString()
{
return get_called_class();
}
}
Don't be shy, don't hesitate to contact us for any subject, we'll be glad to help.
This platform is provided to give developpers and non developpers a way to easily consume SOAP Web Services or share their own SOAP Web Services with extra features powered by the platform.
© 2025 Providr.IO