Drupal 6: Executing a SOAP call from Drupal using nusoap

In this tutorial I'll show how you can make a SOAP call from a Drupal page callback using the nusoap library.

For this example I decided to create a sample soap server instance for testing purposes. I created the following directory structure for my new module: sites/all/modules/custom/nusoap/. I then download the nusoap library (nusoap-0.7.3.zip), extracted the archive, and put the "lib" folder in my module directory (sites/all/modules/custom/nusoap/lib).

In this directory I created a file called "soap-server.php" to contain my soap server instance and added the following code:

<?php
// define namespace
define('NUSOAP_NAME_SPACE', 'erl.dev');

// define path to nusoap library file
$nu_soap_path = 'lib/nusoap.php';

// ensure nu_soap library exsists
if (!file_exists($nu_soap_path)) {
  die('An error has occurred initializing the soap server.');
}

// include nu_soap library
require_once ($nu_soap_path);

// create new soap server instance
$soap_server = new nusoap_server();

// configure wsdl
$soap_server->configureWSDL(NUSOAP_NAME_SPACE, 'urn:'. NUSOAP_NAME_SPACE);

// add a custom data type: person
$soap_server->wsdl->addComplexType(
  'person',
  'complexType',
  'struct',
  'all',
  '',
  array(
    'firstName' => array(
      'name' => 'firstName',
      'type' => 'xsd:string',
    ),
    'lastName' => array(
      'name' => 'lastName',
      'type' => 'xsd:string',
    ),
  )
);

// register method: personTransfer
$soap_server->register(
  // method name
  'personTransfer',
  // input args
  array('person' => 'tns:person'),
  // output args
  array('return' => 'tns:person'),
  // namespace
  'uri:'. NUSOAP_NAME_SPACE,
  // SOAPAction
  'uri:'. NUSOAP_NAME_SPACE .'#personTransfer',
  // style
  'rpc',
  // use
  'encoded'
);

// process raw post data
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$soap_server->service($HTTP_RAW_POST_DATA);

/**
 * Define soap methods
 */
function personTransfer($person = array()) {

  // per testing, modify data
  foreach ($person as $key => $value) {
    $person[$key] = $value . "!";
  };

  return $person;

}
?>

Now if I browse directly to my soap-server.php file (for example: http://drupal.erl.dev/sites/all/modules/custom/nusoap/soap-server.php), I see the following screen:

soap server

Clicking on the WSDL link will show my automatically generated WSDL/XML; clicking on the method name "personTransfer" will show more details about the soap server method. Thanks nusoap!

Next I created the custom Drupal module file:

<?php
// define namespace
define('NUSOAP_NAME_SPACE', 'erl.dev');

/**
 * Implements hook_perm()
 */
function nusoap_perm() {
  return array('access soap');
}

/**
 * Implements hook_menu()
 */
function nusoap_menu() {

  $items = array();

  $items['soap-client'] = array(
    'title' => t('Soap client'),
    'description' => t('Soap client'),
    'page callback' => 'nusoap_page_callback_soap_client',
    'access arguments' => array('access soap'),
    'type' => MENU_CALLBACK
  );

  return $items;

}

/**
 * Implements custom page callback for soap client
 */
function nusoap_page_callback_soap_client() {

  // include nu_soap library
  require_once(drupal_get_path('module', 'nusoap') .'/lib/nusoap.php');

  // define wsdl path
  $wsdl_path = 'http://' . $_SERVER['HTTP_HOST'] . base_path() . drupal_get_path('module', 'nusoap') . '/soap-server.php?wsdl';

  // create new soap client instance
  $soap_client = new nusoap_client($wsdl_path, true);

  // check for error
  $error = $soap_client->getError();
  if ($error) {
    // handle error
  }

  // define method arguments
  $args = array(
    'person' => array(
      'firstName' => 'Eric',
      'lastName' => 'London'
    )
  );

  // call soap server method
  $result = $soap_client->call('personTransfer', $args);

  // debug output:
  $output = "";
  $output .= "<pre>";
  $output .= "SENT: ";
  $output .= print_r($args, true);
  $output .= "RECEIVED: ";
  $output .= print_r($result, true);
  $output .= "</pre>";

  return $output;

}
?>

Browsing to the new page callback (ex: http://drupal.erl.dev/soap-client) shows the following debug output. sweet.

soap client