You are here

function wsdl::serializeType in Salesforce Suite 5

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

* serializes a PHP value according a given type definition * *

Parameters

string $name name of value (part or element): * @param string $type XML schema type of value (type or element) * @param mixed $value a native PHP value (parameter value) * @param string $use use for part (encoded|literal) * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style) * @param boolean $unqualified a kludge for what should be XML namespace form handling * @return string value serialized as an XML string * @access private

6 calls to wsdl::serializeType()
wsdl::serializeComplexTypeElements in includes/nusoap.php
* serializes the elements for a complexType * *
wsdl::serializeComplexTypeElements in includes/nusoap.orig.php
* serializes the elements for a complexType * *
wsdl::serializeParameters in includes/nusoap.php
* serialize a PHP value according to a WSDL message definition * * TODO * - multi-ref serialization * - validate PHP values against type definitions, return errors if invalid * *
wsdl::serializeParameters in includes/nusoap.orig.php
* serialize a PHP value according to a WSDL message definition * * TODO * - multi-ref serialization * - validate PHP values against type definitions, return errors if invalid * *
wsdl::serializeRPCParameters in includes/nusoap.php
* serialize PHP values according to a WSDL message definition * * TODO * - multi-ref serialization * - validate PHP values against type definitions, return errors if invalid * *

... See full list

File

includes/nusoap.php, line 5171

Class

wsdl
parses a WSDL file, allows access to it's data, other utility methods

Code

function serializeType($name, $type, $value, $use = 'encoded', $encodingStyle = false, $unqualified = false) {
  $this
    ->debug("in serializeType: name={$name}, type={$type}, use={$use}, encodingStyle={$encodingStyle}, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
  $this
    ->appendDebug("value=" . $this
    ->varDump($value));
  if ($use == 'encoded' && $encodingStyle) {
    $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
  }

  // RCHOI: if no value, don't print anything in message
  if ($value == null) {
    return;
  }

  // RCHOI: if you see an sObjects and it's value is a soapval, serialize directly
  if (is_object($value) && (strtolower(get_class($value)) == 'sobject' || strtolower(get_class($value)) == 'leadconvert')) {
    return $value
      ->serialize();
  }

  // if a soapval has been supplied, let its type override the WSDL
  if (is_object($value) && get_class($value) == 'soapval') {
    if ($value->type_ns) {
      $type = $value->type_ns . ':' . $value->type;
      $forceType = true;
      $this
        ->debug("in serializeType: soapval overrides type to {$type}");
    }
    elseif ($value->type) {
      $type = $value->type;
      $forceType = true;
      $this
        ->debug("in serializeType: soapval overrides type to {$type}");
    }
    else {
      $forceType = false;
      $this
        ->debug("in serializeType: soapval does not override type");
    }
    $attrs = $value->attributes;
    $value = $value->value;
    $this
      ->debug("in serializeType: soapval overrides value to {$value}");
    if ($attrs) {
      if (!is_array($value)) {
        $value['!'] = $value;
      }
      foreach ($attrs as $n => $v) {
        $value['!' . $n] = $v;
      }
      $this
        ->debug("in serializeType: soapval provides attributes");
    }
  }
  else {
    $forceType = false;
  }
  $xml = '';
  if (strpos($type, ':')) {
    $uqType = substr($type, strrpos($type, ':') + 1);
    $ns = substr($type, 0, strrpos($type, ':'));
    $this
      ->debug("in serializeType: got a prefixed type: {$uqType}, {$ns}");
    if ($this
      ->getNamespaceFromPrefix($ns)) {
      $ns = $this
        ->getNamespaceFromPrefix($ns);
      $this
        ->debug("in serializeType: expanded prefixed type: {$uqType}, {$ns}");
    }
    if ($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/') {
      $this
        ->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
      if ($unqualified && $use == 'literal') {
        $elementNS = " xmlns=\"\"";
      }
      else {
        $elementNS = '';
      }
      if (is_null($value)) {
        if ($use == 'literal') {

          // TODO: depends on minOccurs
          $xml = "<{$name}{$elementNS}/>";
        }
        else {

          // TODO: depends on nillable, which should be checked before calling this method
          $xml = "<{$name}{$elementNS} xsi:nil=\"true\" xsi:type=\"" . $this
            ->getPrefixFromNamespace($ns) . ":{$uqType}\"/>";
        }
        $this
          ->debug("in serializeType: returning: {$xml}");
        return $xml;
      }
      if ($uqType == 'boolean') {
        if (is_string($value) && $value == 'false' || !$value) {
          $value = 'false';
        }
        else {
          $value = 'true';
        }
      }
      if ($uqType == 'string' && gettype($value) == 'string') {
        $value = $this
          ->expandEntities($value);
      }
      if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
        $value = sprintf("%.0lf", $value);
      }

      // it's a scalar
      // TODO: what about null/nil values?
      // check type isn't a custom type extending xmlschema namespace
      if (!$this
        ->getTypeDef($uqType, $ns)) {
        if ($use == 'literal') {
          if ($forceType) {
            $xml = "<{$name}{$elementNS} xsi:type=\"" . $this
              ->getPrefixFromNamespace($ns) . ":{$uqType}\">{$value}</{$name}>";
          }
          else {
            $xml = "<{$name}{$elementNS}>{$value}</{$name}>";
          }
        }
        else {
          $xml = "<{$name}{$elementNS} xsi:type=\"" . $this
            ->getPrefixFromNamespace($ns) . ":{$uqType}\"{$encodingStyle}>{$value}</{$name}>";
        }
        $this
          ->debug("in serializeType: returning: {$xml}");
        return $xml;
      }
      $this
        ->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
    }
    else {
      if ($ns == 'http://xml.apache.org/xml-soap') {
        $this
          ->debug('in serializeType: appears to be Apache SOAP type');
        if ($uqType == 'Map') {
          $tt_prefix = $this
            ->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
          if (!$tt_prefix) {
            $this
              ->debug('in serializeType: Add namespace for Apache SOAP type');
            $tt_prefix = 'ns' . rand(1000, 9999);
            $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';

            // force this to be added to usedNamespaces
            $tt_prefix = $this
              ->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
          }
          $contents = '';
          foreach ($value as $k => $v) {
            $this
              ->debug("serializing map element: key {$k}, value {$v}");
            $contents .= '<item>';
            $contents .= $this
              ->serialize_val($k, 'key', false, false, false, false, $use);
            $contents .= $this
              ->serialize_val($v, 'value', false, false, false, false, $use);
            $contents .= '</item>';
          }
          if ($use == 'literal') {
            if ($forceType) {
              $xml = "<{$name} xsi:type=\"" . $tt_prefix . ":{$uqType}\">{$contents}</{$name}>";
            }
            else {
              $xml = "<{$name}>{$contents}</{$name}>";
            }
          }
          else {
            $xml = "<{$name} xsi:type=\"" . $tt_prefix . ":{$uqType}\"{$encodingStyle}>{$contents}</{$name}>";
          }
          $this
            ->debug("in serializeType: returning: {$xml}");
          return $xml;
        }
        $this
          ->debug('in serializeType: Apache SOAP type, but only support Map');
      }
    }
  }
  else {

    // TODO: should the type be compared to types in XSD, and the namespace
    // set to XSD if the type matches?
    $this
      ->debug("in serializeType: No namespace for type {$type}");
    $ns = '';
    $uqType = $type;
  }
  if (!($typeDef = $this
    ->getTypeDef($uqType, $ns))) {
    $this
      ->setError("{$type} ({$uqType}) is not a supported type.");
    $this
      ->debug("in serializeType: {$type} ({$uqType}) is not a supported type.");
    return false;
  }
  else {
    $this
      ->debug("in serializeType: found typeDef");
    $this
      ->appendDebug('typeDef=' . $this
      ->varDump($typeDef));
  }
  $phpType = $typeDef['phpType'];
  $this
    ->debug("in serializeType: uqType: {$uqType}, ns: {$ns}, phptype: {$phpType}, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : ''));

  // if php type == struct, map value to the <all> element names
  if ($phpType == 'struct') {
    if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
      $elementName = $uqType;
      if (isset($typeDef['form']) && $typeDef['form'] == 'qualified') {
        $elementNS = " xmlns=\"{$ns}\"";
      }
      else {
        $elementNS = " xmlns=\"\"";
      }
    }
    else {
      $elementName = $name;
      if ($unqualified) {
        $elementNS = " xmlns=\"\"";
      }
      else {
        $elementNS = '';
      }
    }
    if (is_null($value)) {
      if ($use == 'literal') {

        // TODO: depends on minOccurs
        $xml = "<{$elementName}{$elementNS}/>";
      }
      else {
        $xml = "<{$elementName}{$elementNS} xsi:nil=\"true\" xsi:type=\"" . $this
          ->getPrefixFromNamespace($ns) . ":{$uqType}\"/>";
      }
      $this
        ->debug("in serializeType: returning: {$xml}");
      return $xml;
    }
    if (is_object($value)) {
      $value = get_object_vars($value);
    }
    if (is_array($value)) {
      $elementAttrs = $this
        ->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
      if ($use == 'literal') {
        if ($forceType) {
          $xml = "<{$elementName}{$elementNS}{$elementAttrs} xsi:type=\"" . $this
            ->getPrefixFromNamespace($ns) . ":{$uqType}\">";
        }
        else {
          $xml = "<{$elementName}{$elementNS}{$elementAttrs}>";
        }
      }
      else {
        $xml = "<{$elementName}{$elementNS}{$elementAttrs} xsi:type=\"" . $this
          ->getPrefixFromNamespace($ns) . ":{$uqType}\"{$encodingStyle}>";
      }
      $xml .= $this
        ->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
      $xml .= "</{$elementName}>";
    }
    else {
      $this
        ->debug("in serializeType: phpType is struct, but value is not an array");
      $this
        ->setError("phpType is struct, but value is not an array: see debug output for details");
      $xml = '';
    }
  }
  elseif ($phpType == 'array') {
    if (isset($typeDef['form']) && $typeDef['form'] == 'qualified') {
      $elementNS = " xmlns=\"{$ns}\"";
    }
    else {
      if ($unqualified) {
        $elementNS = " xmlns=\"\"";
      }
      else {
        $elementNS = '';
      }
    }
    if (is_null($value)) {
      if ($use == 'literal') {

        // TODO: depends on minOccurs
        $xml = "<{$name}{$elementNS}/>";
      }
      else {
        $xml = "<{$name}{$elementNS} xsi:nil=\"true\" xsi:type=\"" . $this
          ->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . ":Array\" " . $this
          ->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . ':arrayType="' . $this
          ->getPrefixFromNamespace($this
          ->getPrefix($typeDef['arrayType'])) . ':' . $this
          ->getLocalPart($typeDef['arrayType']) . "[0]\"/>";
      }
      $this
        ->debug("in serializeType: returning: {$xml}");
      return $xml;
    }
    if (isset($typeDef['multidimensional'])) {
      $nv = array();
      foreach ($value as $v) {
        $cols = ',' . sizeof($v);
        $nv = array_merge($nv, $v);
      }
      $value = $nv;
    }
    else {
      $cols = '';
    }
    if (is_array($value) && sizeof($value) >= 1) {
      $rows = sizeof($value);
      $contents = '';
      foreach ($value as $k => $v) {
        $this
          ->debug("serializing array element: {$k}, {$v} of type: {$typeDef['arrayType']}");

        //if (strpos($typeDef['arrayType'], ':') ) {
        if (!in_array($typeDef['arrayType'], $this->typemap['http://www.w3.org/2001/XMLSchema'])) {
          $contents .= $this
            ->serializeType('item', $typeDef['arrayType'], $v, $use);
        }
        else {
          $contents .= $this
            ->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
        }
      }
    }
    else {
      $rows = 0;
      $contents = null;
    }

    // TODO: for now, an empty value will be serialized as a zero element
    // array.  Revisit this when coding the handling of null/nil values.
    if ($use == 'literal') {
      $xml = "<{$name}{$elementNS}>" . $contents . "</{$name}>";
    }
    else {
      $xml = "<{$name}{$elementNS} xsi:type=\"" . $this
        ->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . ':Array" ' . $this
        ->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') . ':arrayType="' . $this
        ->getPrefixFromNamespace($this
        ->getPrefix($typeDef['arrayType'])) . ":" . $this
        ->getLocalPart($typeDef['arrayType']) . "[{$rows}{$cols}]\">" . $contents . "</{$name}>";
    }
  }
  elseif ($phpType == 'scalar') {
    if (isset($typeDef['form']) && $typeDef['form'] == 'qualified') {
      $elementNS = " xmlns=\"{$ns}\"";
    }
    else {
      if ($unqualified) {
        $elementNS = " xmlns=\"\"";
      }
      else {
        $elementNS = '';
      }
    }
    if ($use == 'literal') {
      if ($forceType) {
        $xml = "<{$name}{$elementNS} xsi:type=\"" . $this
          ->getPrefixFromNamespace($ns) . ":{$uqType}\">{$value}</{$name}>";
      }
      else {
        $xml = "<{$name}{$elementNS}>{$value}</{$name}>";
      }
    }
    else {
      $xml = "<{$name}{$elementNS} xsi:type=\"" . $this
        ->getPrefixFromNamespace($ns) . ":{$uqType}\"{$encodingStyle}>{$value}</{$name}>";
    }
  }
  $this
    ->debug("in serializeType: returning: {$xml}");
  return $xml;
}