View source
<?php
function wsclient_soap_wsclient_endpoint_types() {
return array(
'soap' => array(
'label' => t('SOAP'),
'class' => 'WSClientSOAPEndpoint',
),
'soap 1.2' => array(
'label' => t('SOAP 1.2'),
'class' => 'WSClientSOAPEndpoint',
),
);
}
class WSClientSOAPEndpoint extends WSClientEndpoint {
public function client() {
if (!isset($this->client)) {
$options['exceptions'] = TRUE;
if ($this->service->type == 'soap 1.2') {
$options['soap_version'] = SOAP_1_2;
}
if (!empty($this->service->settings['authentication']['basic'])) {
$this->service->settings['options']['login'] = $this->service->settings['authentication']['basic']['username'];
$this->service->settings['options']['password'] = $this->service->settings['authentication']['basic']['password'];
}
if (!empty($this->service->settings['options'])) {
$options += $this->service->settings['options'];
}
try {
$this->client = new SOAPClient($this->url, $options);
} catch (SoapFault $e) {
throw new WSClientException('Error initializing SOAP client for service %name', array(
'%name' => $this->service->name,
));
}
if (!empty($this->service->settings['authentication']['wss'])) {
$this->client
->__setSoapHeaders(new WSSESecurityHeader($this->service->settings['authentication']['wss']['username'], $this->service->settings['authentication']['wss']['password']));
}
elseif (!empty($this->service->global_header_parameters)) {
$header_parameters = $this->service->global_header_parameters;
$data_types = $this->service->datatypes;
$headers = array();
foreach ($header_parameters as $type => $parameter) {
$name_space = $parameter['name space url'];
$data_type = $data_types[$type];
$soap_vars = array();
foreach ($data_type['property info'] as $name => $property) {
$soap_vars[] = new SoapVar($property['default value'], XSD_STRING, NULL, NULL, $name, $name_space);
}
$header_data = new SoapVar($soap_vars, SOAP_ENC_OBJECT, NULL, NULL, $type, $name_space);
$headers[] = new SoapHeader($name_space, $type, $header_data, FALSE);
}
$this->client
->__setSoapHeaders($headers);
}
}
return $this->client;
}
public function initializeMetadata($reset = TRUE) {
$client = $this
->client();
$data_types = wsclient_soap_parse_types($client
->__getTypes());
$operations = wsclient_soap_parse_operations($client
->__getFunctions());
if ($reset) {
$this->service->datatypes = $data_types;
$this->service->operations = $operations;
}
else {
$this->service->datatypes += $data_types;
$this->service->operations += $operations;
}
$this->service
->clearCache();
}
public function call($operation, $arguments) {
$client = $this
->client();
$operation_settings = $this->service->operations[$operation];
if (!empty($operation_settings['header'])) {
$headers = array();
foreach ($operation_settings['header'] as $header_settings) {
if (!empty($header_settings['actor'])) {
$headers[] = new SoapHeader($header_settings['namespace'], $header_settings['name'], $header_settings['data'], $header_settings['mustunderstand'], $header_settings['actor']);
}
else {
$headers[] = new SoapHeader($header_settings['namespace'], $header_settings['name'], $header_settings['data'], $header_settings['mustunderstand']);
}
}
$client
->__setSoapHeaders($headers);
}
try {
$response = $client
->__soapCall($operation, $arguments);
return $response;
} catch (SoapFault $e) {
throw new WSClientException('Error invoking the SOAP service %name, operation %operation: %error', array(
'%name' => $this->service->label,
'%operation' => $operation,
'%error' => $e
->getMessage(),
));
}
}
}
class WSSESecurityHeader extends SoapHeader {
public function __construct($username, $password) {
$wsse_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
$security = new SoapVar(array(
new SoapVar(array(
new SoapVar($username, XSD_STRING, NULL, NULL, 'Username', $wsse_ns),
new SoapVar($password, XSD_STRING, NULL, NULL, 'Password', $wsse_ns),
), SOAP_ENC_OBJECT, NULL, NULL, 'UsernameToken', $wsse_ns),
), SOAP_ENC_OBJECT);
parent::__construct($wsse_ns, 'Security', $security, FALSE);
}
}
function wsclient_soap_form_wsclient_service_form_alter(&$form, &$form_state) {
$form['#submit'][] = 'wsclient_soap_wsclient_service_form_submit';
$form['#validate'][] = 'wsclient_soap_wsclient_service_form_validate';
}
function wsclient_soap_wsclient_service_form_validate($form, $form_state) {
$service = $form_state['wsclient_service'];
if ($form_state['values']['type'] == 'soap' || $form_state['values']['type'] == 'soap 1.2') {
try {
@($endpoint = new SOAPClient($form_state['values']['url']));
} catch (SoapFault $e) {
form_set_error('url', t('Error parsing the WSDL file: %message', array(
'%message' => $e
->getMessage(),
)));
}
}
}
function wsclient_soap_wsclient_service_form_submit($form, &$form_state) {
if (($form_state['values']['type'] == 'soap' || $form_state['values']['type'] == 'soap 1.2') && $form_state['op'] == 'add') {
$service = $form_state['wsclient_service'];
$endpoint = $service
->endpoint();
$endpoint
->initializeMetadata();
$service
->save();
rules_clear_cache();
$service
->clearCache();
drupal_set_message(t('Operations and data types of the SOAP service have been imported automatically. If the service expects data types with properties as lists (multiple values for the property), please check the multiple flag on those properties. This cannot be auto-detected at the moment.'));
}
}
function wsclient_soap_parse_types(array $types) {
$wsclient_types = array();
foreach ($types as $type_string) {
if (strpos($type_string, 'struct') === 0) {
$parts = explode('{', $type_string);
$type_name = trim(substr($parts[0], 6));
$wsclient_types[$type_name] = array(
'label' => $type_name,
);
$property_string = $parts[1];
$property_string = substr($property_string, 0, -1);
$properties = explode(';', $property_string);
array_pop($properties);
$wsclient_types[$type_name]['property info'] = array();
foreach ($properties as $property_string) {
$property_string = trim($property_string);
$parts = explode(' ', $property_string);
$property_type = $parts[0];
$property_name = $parts[1];
$wsclient_types[$type_name]['property info'][$property_name] = array(
'type' => wsclient_soap_type_mapper($property_type),
);
}
}
}
return $wsclient_types;
}
function wsclient_soap_parse_operations(array $operations) {
$wsclient_operations = array();
foreach ($operations as $operation) {
$parts = explode(' ', $operation);
$return_type = wsclient_soap_type_mapper($parts[0]);
$name_parts = explode('(', $parts[1]);
$op_name = $name_parts[0];
$wsclient_operations[$op_name] = array(
'label' => $op_name,
'result' => array(
'type' => $return_type,
'label' => $return_type,
),
);
$parts = explode('(', $operation);
$param_string = substr($parts[1], 0, -1);
if ($param_string) {
$parameters = explode(',', $param_string);
foreach ($parameters as $parameter) {
$parameter = trim($parameter);
$parts = explode(' ', $parameter);
$param_type = $parts[0];
$param_name = substr($parts[1], 1);
$wsclient_operations[$op_name]['parameter'][$param_name] = array(
'type' => wsclient_soap_type_mapper($param_type),
);
}
}
}
return $wsclient_operations;
}
function wsclient_soap_type_mapper($type) {
$primitive_types = array(
'string',
'int',
'long',
'float',
'boolean',
'double',
'short',
'decimal',
);
if (in_array($type, $primitive_types)) {
switch ($type) {
case 'double':
case 'float':
return 'decimal';
case 'int':
case 'long':
case 'short':
return 'integer';
case 'string':
return 'text';
}
}
if (strpos($type, 'ArrayOf') === 0) {
$type = substr($type, 7);
$primitive = strtolower($type);
if (in_array($primitive, $primitive_types)) {
return 'list<' . $primitive . '>';
}
return 'list<' . $type . '>';
}
return $type;
}