From 5635c41128cde12777e1a0b27291a53e7f2f3e05 Mon Sep 17 00:00:00 2001 From: Dan Morrison Date: Mon, 16 Mar 2015 17:41:47 +1300 Subject: Issue #2065037 by Dan Morrison, imclean, dman, stella: SOAP 1.2 support added --- wsclient_soap/wsclient_soap.module | 22 ++++++- wsclient_tester/wsclient_tester.inc | 4 +- wsclient_ui/wsclient_ui.inc | 120 ++++++++++++++++++++++++++++++++++++ wsclient_ui/wsclient_ui.module | 4 ++ 4 files changed, 146 insertions(+), 4 deletions(-) diff --git a/wsclient_soap/wsclient_soap.module b/wsclient_soap/wsclient_soap.module index 1afc8e2..b6a9997 100644 --- a/wsclient_soap/wsclient_soap.module +++ b/wsclient_soap/wsclient_soap.module @@ -14,6 +14,10 @@ function wsclient_soap_wsclient_endpoint_types() { 'label' => t('SOAP'), 'class' => 'WSClientSOAPEndpoint', ), + 'soap 1.2' => array( + 'label' => t('SOAP 1.2'), + 'class' => 'WSClientSOAPEndpoint', + ), ); } @@ -25,6 +29,9 @@ 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; + } // Handle Basic HTTP authentication. if (!empty($this->service->settings['authentication']['basic'])) { $this->service->settings['options']['login'] = $this->service->settings['authentication']['basic']['username']; @@ -74,6 +81,17 @@ class WSClientSOAPEndpoint extends WSClientEndpoint { */ public function call($operation, $arguments) { $client = $this->client(); + + // Soap endpoints MAY also have 'headers' set on a per-operation basis. + $operation_settings = $this->service->operations[$operation]; + if (!empty($operation_settings['header'])) { + $headers = array(); + foreach ($operation_settings['header'] as $header_settings) { + $headers[] = new SoapHeader($header_settings['namespace'], $header_settings['name'], $header_settings['data'], $header_settings['mustunderstand'], (empty($header_settings['actor']) ? NULL : $header_settings['actor'])); + } + $client->__setSoapHeaders($headers); + } + try { $response = $client->__soapCall($operation, $arguments); return $response; @@ -98,7 +116,7 @@ function wsclient_soap_form_wsclient_service_form_alter(&$form, &$form_state) { */ function wsclient_soap_wsclient_service_form_validate($form, $form_state) { $service = $form_state['wsclient_service']; - if ($form_state['values']['type'] == 'soap') { + if ($form_state['values']['type'] == 'soap' || $form_state['values']['type'] == 'soap 1.2') { // The url has to point to a valid WSDL file. try { // If initializing the SOAPClient succeeds we're good, otherwise we catch @@ -120,7 +138,7 @@ function wsclient_soap_wsclient_service_form_validate($form, $form_state) { * types of the new SOAP service. */ function wsclient_soap_wsclient_service_form_submit($form, &$form_state) { - if ($form_state['values']['type'] == 'soap' && $form_state['op'] == 'add') { + 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(); diff --git a/wsclient_tester/wsclient_tester.inc b/wsclient_tester/wsclient_tester.inc index a514141..c502654 100644 --- a/wsclient_tester/wsclient_tester.inc +++ b/wsclient_tester/wsclient_tester.inc @@ -113,7 +113,7 @@ function wsclient_tester_prepare_request_callback($form, $form_state) { $args = $form_state['values']['parameters']; } - if ($service->type == 'soap') { + if ($service->type == 'soap' || $service->type == 'soap 1.2') { // The service will have an endpoint that will have a SOAPClient. // Settings on the service->options may be passed to the SOAPClient. // @see WSClientSOAPEndpoint::client() @@ -149,7 +149,7 @@ function wsclient_tester_prepare_request_callback($form, $form_state) { $element['response']['header']['#markup'] = $service->endpoint()->client()->lastResponse->headers; $element['response']['packet']['#markup'] = $service->endpoint()->client()->lastResponse->body; } - elseif ($service->type == 'soap') { + elseif ($service->type=='soap' || $service->type=='soap 1.2') { $element['request']['header']['#markup'] = $service->endpoint()->client()->__getLastRequestHeaders(); $element['request']['packet']['#markup'] = htmlspecialchars(wsclient_tester_prettify_xml($service->endpoint()->client()->__getLastRequest())); $element['response']['header']['#markup'] = $service->endpoint()->client()->__getLastResponseHeaders(); diff --git a/wsclient_ui/wsclient_ui.inc b/wsclient_ui/wsclient_ui.inc index 5ff296a..d2b7618 100644 --- a/wsclient_ui/wsclient_ui.inc +++ b/wsclient_ui/wsclient_ui.inc @@ -361,6 +361,28 @@ function wsclient_ui_operation($form, &$form_state, $service, $operation, $op = '#limit_validation_errors' => array(array('parameters')), '#submit' => array('wsclient_ui_more_submit'), ); + + // SOAP 1.2 etc may also require additional headers. + if ($service->type == 'soap 1.2') { + $form['headers'] = array( + '#tree' => TRUE, + '#theme' => 'wsclient_ui_header_form', + '#title' => t('Soap 1.2 Headers'), + '#description' => t('Some services may also require specific headers to be set, such as "To" for their internal routing, or the SOAP_1_2 "mustunderstand" flag.'), + ); + $weight = 0; + $types = wsclient_ui_types(TRUE); + if (isset($operation['header'])) { + foreach ($operation['header'] as $name => $info) { + $form['headers']['items'][$name] = _wsclient_ui_header_row($info); + $form['headers']['items'][$name]['weight']['#default_value'] = $weight++; + } + } + // Always add an empty line. + $form['headers']['items'][$i] = _wsclient_ui_header_row(array()); + $form['headers']['items'][$i]['weight']['#default_value'] = $weight++; + } + // Exclude the hidden data type for result types. unset($types['hidden']); @@ -477,6 +499,40 @@ function _wsclient_ui_parameter_row($service, $types, $name = '', $info = array( } /** + * Generates a row in the header table. + */ +function _wsclient_ui_header_row($info = array()) { + $parameter['namespace'] = array( + '#type' => 'textfield', + '#size' => 40, + '#default_value' => isset($info['namespace']) ? $info['namespace'] : '', + ); + $parameter['name'] = array( + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($info['name']) ? $info['name'] : '', + ); + $parameter['data'] = array( + '#type' => 'textfield', + '#size' => 40, + '#default_value' => isset($info['data']) ? $info['data'] : '', + ); + $parameter['mustunderstand'] = array( + '#type' => 'checkbox', + '#default_value' => isset($info['mustunderstand']) ? $info['mustunderstand'] : FALSE, + ); + $parameter['actor'] = array( + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($info['actor']) ? $info['actor'] : '', + ); + $parameter['weight'] = array( + '#type' => 'weight', + ); + return $parameter; +} + +/** * Validation callback for machine names of parameters or properties. */ function wsclient_ui_name_validate($element, &$form_state) { @@ -521,6 +577,17 @@ function wsclient_ui_operation_submit($form, &$form_state) { $operation['parameter'][$item['name']]['allow null'] = $item['allow_null']; } } + + // SOAP 1.2 etc may also require additional headers. + if ($service->type == 'soap 1.2' && !empty($form_state['values']['headers'])) { + $operation['header'] = array(); + foreach ($form_state['values']['headers']['items'] as $key => $item) { + if (!empty($item['name'])) { + $operation['header'][$item['name']] = $item; + } + } + } + if (!empty($form_state['values']['result_type'])) { $unmapped_type = _wsclient_ui_unmap_type($form_state['values']['result_type'], $service); $operation['result'] = array( @@ -604,6 +671,59 @@ function theme_wsclient_ui_parameter_form($variables) { } /** + * Themes the operation form for editing the used headers. + * + * Just cloned from theme_wsclient_ui_parameter_form() + * + * @ingroup themeable + */ +function theme_wsclient_ui_header_form($variables) { + $elements = $variables['element']; + + $table['#theme'] = 'table'; + $table['#header'] = array(t('Namespace'), t('Name'), t('Data'), t('Mustunderstand'), t('Actor'), array('data' => t('Weight'), 'class' => array('tabledrag-hide'))); + $table['#attributes']['id'] = 'rules-' . drupal_html_id($elements['#title']) . '-id'; + + foreach (element_children($elements['items']) as $key) { + $element = &$elements['items'][$key]; + // Add special classes to be used for tabledrag.js. + $element['weight']['#attributes']['class'] = array('rules-element-weight'); + + $row = array(); + $row[] = array('data' => $element['namespace']); + $row[] = array('data' => $element['name']); + $row[] = array('data' => $element['data']); + $row[] = array('data' => $element['mustunderstand']); + $row[] = array('data' => $element['actor']); + $row[] = array('data' => $element['weight']); + $row = array('data' => $row) + $element['#attributes']; + $row['class'][] = 'draggable'; + $table['#rows'][] = $row; + } + $elements['items']['#printed'] = TRUE; + if (!empty($table['#rows'])) { + drupal_add_tabledrag($table['#attributes']['id'], 'order', 'sibling', 'rules-element-weight'); + } + + // Theme it like a form item, but with the description above the content. + $attributes['class'][] = 'form-item'; + $attributes['class'][] = 'rules-variables-form'; + + $output = '' . "\n"; + $output .= theme('form_element_label', $variables); + if (!empty($elements['#description'])) { + $output .= '
' . $elements['#description'] . "
\n"; + } + $output .= ' ' . drupal_render($table) . "\n"; + // Add in any further children elements. + foreach (element_children($elements, TRUE) as $key) { + $output .= drupal_render($elements[$key]); + } + $output .= "\n"; + return $output; +} + +/** * Themes the global parameters form for editing the used parameters. * * @ingroup themeable diff --git a/wsclient_ui/wsclient_ui.module b/wsclient_ui/wsclient_ui.module index 4ceafb1..3487e2c 100644 --- a/wsclient_ui/wsclient_ui.module +++ b/wsclient_ui/wsclient_ui.module @@ -64,6 +64,10 @@ function wsclient_ui_theme() { 'render element' => 'element', 'file' => 'wsclient_ui.inc', ), + 'wsclient_ui_header_form' => array( + 'render element' => 'element', + 'file' => 'wsclient_ui.inc', + ), 'wsclient_ui_property_form' => array( 'render element' => 'element', 'file' => 'wsclient_ui.inc', -- 1.9.5 (Apple Git-50.3)