You are here

function soap_server::invoke_method in Salesforce Suite 5

Same name in this branch
  1. 5 includes/nusoap.php \soap_server::invoke_method()
  2. 5 includes/nusoap.orig.php \soap_server::invoke_method()
Same name and namespace in other branches
  1. 5.2 includes/nusoap.php \soap_server::invoke_method()
  2. 5.2 includes/nusoap.orig.php \soap_server::invoke_method()

* invokes a PHP function for the requested SOAP method * * The following fields are set by this function (when successful) * * methodreturn * * Note that the PHP function that is called may also set the following * fields to affect the response sent to the client * * responseHeaders * outgoing_headers * * This sets the fault field on error * * @access private

2 calls to soap_server::invoke_method()
soap_server::service in includes/nusoap.php
* processes request and returns response * *
soap_server::service in includes/nusoap.orig.php
* processes request and returns response * *

File

includes/nusoap.php, line 3491

Class

soap_server
soap_server allows the user to create a SOAP server that is capable of receiving messages and returning responses

Code

function invoke_method() {
  $this
    ->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
  if ($this->wsdl) {
    if ($this->opData = $this->wsdl
      ->getOperationData($this->methodname)) {
      $this
        ->debug('in invoke_method, found WSDL operation=' . $this->methodname);
      $this
        ->appendDebug('opData=' . $this
        ->varDump($this->opData));
    }
    elseif ($this->opData = $this->wsdl
      ->getOperationDataForSoapAction($this->SOAPAction)) {

      // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
      $this
        ->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
      $this
        ->appendDebug('opData=' . $this
        ->varDump($this->opData));
      $this->methodname = $this->opData['name'];
    }
    else {
      $this
        ->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
      $this
        ->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
      return;
    }
  }
  else {
    $this
      ->debug('in invoke_method, no WSDL to validate method');
  }

  // if a . is present in $this->methodname, we see if there is a class in scope,
  // which could be referred to. We will also distinguish between two deliminators,
  // to allow methods to be called a the class or an instance
  $class = '';
  $method = '';
  if (strpos($this->methodname, '..') > 0) {
    $delim = '..';
  }
  else {
    if (strpos($this->methodname, '.') > 0) {
      $delim = '.';
    }
    else {
      $delim = '';
    }
  }
  if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {

    // get the class and method name
    $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
    $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
    $this
      ->debug("in invoke_method, class={$class} method={$method} delim={$delim}");
  }

  // does method exist?
  if ($class == '') {
    if (!function_exists($this->methodname)) {
      $this
        ->debug("in invoke_method, function '{$this->methodname}' not found!");
      $this->result = 'fault: method not found';
      $this
        ->fault('Client', "method '{$this->methodname}' not defined in service");
      return;
    }
  }
  else {
    $method_to_compare = substr(phpversion(), 0, 2) == '4.' ? strtolower($method) : $method;
    if (!in_array($method_to_compare, get_class_methods($class))) {
      $this
        ->debug("in invoke_method, method '{$this->methodname}' not found in class '{$class}'!");
      $this->result = 'fault: method not found';
      $this
        ->fault('Client', "method '{$this->methodname}' not defined in service");
      return;
    }
  }

  // evaluate message, getting back parameters
  // verify that request parameters match the method's signature
  if (!$this
    ->verify_method($this->methodname, $this->methodparams)) {

    // debug
    $this
      ->debug('ERROR: request not verified against method signature');
    $this->result = 'fault: request failed validation against method signature';

    // return fault
    $this
      ->fault('Client', "Operation '{$this->methodname}' not defined in service.");
    return;
  }

  // if there are parameters to pass
  $this
    ->debug('in invoke_method, params:');
  $this
    ->appendDebug($this
    ->varDump($this->methodparams));
  $this
    ->debug("in invoke_method, calling '{$this->methodname}'");
  if (!function_exists('call_user_func_array')) {
    if ($class == '') {
      $this
        ->debug('in invoke_method, calling function using eval()');
      $funcCall = "\$this->methodreturn = {$this->methodname}(";
    }
    else {
      if ($delim == '..') {
        $this
          ->debug('in invoke_method, calling class method using eval()');
        $funcCall = "\$this->methodreturn = " . $class . "::" . $method . "(";
      }
      else {
        $this
          ->debug('in invoke_method, calling instance method using eval()');

        // generate unique instance name
        $instname = "\$inst_" . time();
        $funcCall = $instname . " = new " . $class . "(); ";
        $funcCall .= "\$this->methodreturn = " . $instname . "->" . $method . "(";
      }
    }
    if ($this->methodparams) {
      foreach ($this->methodparams as $param) {
        if (is_array($param)) {
          $this
            ->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
          return;
        }
        $funcCall .= "\"{$param}\",";
      }
      $funcCall = substr($funcCall, 0, -1);
    }
    $funcCall .= ');';
    $this
      ->debug('in invoke_method, function call: ' . $funcCall);
    @eval($funcCall);
  }
  else {
    if ($class == '') {
      $this
        ->debug('in invoke_method, calling function using call_user_func_array()');
      $call_arg = "{$this->methodname}";

      // straight assignment changes $this->methodname to lower case after call_user_func_array()
    }
    elseif ($delim == '..') {
      $this
        ->debug('in invoke_method, calling class method using call_user_func_array()');
      $call_arg = array(
        $class,
        $method,
      );
    }
    else {
      $this
        ->debug('in invoke_method, calling instance method using call_user_func_array()');
      $instance = new $class();
      $call_arg = array(
        &$instance,
        $method,
      );
    }
    $this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
  }
  $this
    ->debug('in invoke_method, methodreturn:');
  $this
    ->appendDebug($this
    ->varDump($this->methodreturn));
  $this
    ->debug("in invoke_method, called method {$this->methodname}, received {$this->methodreturn} of type " . gettype($this->methodreturn));
}