You are here

function soap_parser::start_element in Salesforce Suite 5

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

* start-element handler * *

Parameters

resource $parser XML parser object: * @param string $name element name * @param array $attrs associative array of attributes * @access private

File

includes/nusoap.php, line 5944

Class

soap_parser
soap_parser class parses SOAP XML messages into native PHP values

Code

function start_element($parser, $name, $attrs) {

  // position in a total number of elements, starting from 0
  // update class level pos
  $pos = $this->position++;

  // and set mine
  $this->message[$pos] = array(
    'pos' => $pos,
    'children' => '',
    'cdata' => '',
  );

  // depth = how many levels removed from root?
  // set mine as current global depth and increment global depth value
  $this->message[$pos]['depth'] = $this->depth++;

  // else add self as child to whoever the current parent is
  if ($pos != 0) {
    $this->message[$this->parent]['children'] .= '|' . $pos;
  }

  // set my parent
  $this->message[$pos]['parent'] = $this->parent;

  // set self as current parent
  $this->parent = $pos;

  // set self as current value for this depth
  $this->depth_array[$this->depth] = $pos;

  // get element prefix
  if (strpos($name, ':')) {

    // get ns prefix
    $prefix = substr($name, 0, strpos($name, ':'));

    // get unqualified name
    $name = substr(strstr($name, ':'), 1);
  }

  // set status
  if ($name == 'Envelope') {
    $this->status = 'envelope';
  }
  elseif ($name == 'Header') {
    $this->root_header = $pos;
    $this->status = 'header';
  }
  elseif ($name == 'Body') {
    $this->status = 'body';
    $this->body_position = $pos;

    // set method
  }
  elseif ($this->status == 'body' && $pos == $this->body_position + 1) {
    $this->status = 'method';
    $this->root_struct_name = $name;
    $this->root_struct = $pos;
    $this->message[$pos]['type'] = 'struct';
    $this
      ->debug("found root struct {$this->root_struct_name}, pos {$this->root_struct}");
  }

  // set my status
  $this->message[$pos]['status'] = $this->status;

  // set name
  $this->message[$pos]['name'] = htmlspecialchars($name);

  // set attrs
  $this->message[$pos]['attrs'] = $attrs;

  // loop through atts, logging ns and type declarations
  $attstr = '';
  foreach ($attrs as $key => $value) {
    $key_prefix = $this
      ->getPrefix($key);
    $key_localpart = $this
      ->getLocalPart($key);

    // if ns declarations, add to class level array of valid namespaces
    if ($key_prefix == 'xmlns') {
      if (ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$', $value)) {
        $this->XMLSchemaVersion = $value;
        $this->namespaces['xsd'] = $this->XMLSchemaVersion;
        $this->namespaces['xsi'] = $this->XMLSchemaVersion . '-instance';
      }
      $this->namespaces[$key_localpart] = $value;

      // set method namespace
      if ($name == $this->root_struct_name) {
        $this->methodNamespace = $value;
      }

      // if it's a type declaration, set type
    }
    elseif ($key_localpart == 'type') {
      $value_prefix = $this
        ->getPrefix($value);
      $value_localpart = $this
        ->getLocalPart($value);
      $this->message[$pos]['type'] = $value_localpart;
      $this->message[$pos]['typePrefix'] = $value_prefix;
      if (isset($this->namespaces[$value_prefix])) {
        $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
      }
      else {
        if (isset($attrs['xmlns:' . $value_prefix])) {
          $this->message[$pos]['type_namespace'] = $attrs['xmlns:' . $value_prefix];
        }
      }

      // should do something here with the namespace of specified type?
    }
    elseif ($key_localpart == 'arrayType') {
      $this->message[$pos]['type'] = 'array';

      /* do arrayType ereg here
      			[1]    arrayTypeValue    ::=    atype asize
      			[2]    atype    ::=    QName rank*
      			[3]    rank    ::=    '[' (',')* ']'
      			[4]    asize    ::=    '[' length~ ']'
      			[5]    length    ::=    nextDimension* Digit+
      			[6]    nextDimension    ::=    Digit+ ','
      			*/
      $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\\[([0-9]+),?([0-9]*)\\]';
      if (ereg($expr, $value, $regs)) {
        $this->message[$pos]['typePrefix'] = $regs[1];
        $this->message[$pos]['arrayTypePrefix'] = $regs[1];
        if (isset($this->namespaces[$regs[1]])) {
          $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
        }
        else {
          if (isset($attrs['xmlns:' . $regs[1]])) {
            $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:' . $regs[1]];
          }
        }
        $this->message[$pos]['arrayType'] = $regs[2];
        $this->message[$pos]['arraySize'] = $regs[3];
        $this->message[$pos]['arrayCols'] = $regs[4];
      }

      // specifies nil value (or not)
    }
    elseif ($key_localpart == 'nil') {
      $this->message[$pos]['nil'] = $value == 'true' || $value == '1';

      // some other attribute
    }
    elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
      $this->message[$pos]['xattrs']['!' . $key] = $value;
    }
    if ($key == 'xmlns') {
      $this->default_namespace = $value;
    }

    // log id
    if ($key == 'id') {
      $this->ids[$value] = $pos;
    }

    // root
    if ($key_localpart == 'root' && $value == 1) {
      $this->status = 'method';
      $this->root_struct_name = $name;
      $this->root_struct = $pos;
      $this
        ->debug("found root struct {$this->root_struct_name}, pos {$pos}");
    }

    // for doclit
    $attstr .= " {$key}=\"{$value}\"";
  }

  // get namespace - must be done after namespace atts are processed
  if (isset($prefix)) {
    $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
    $this->default_namespace = $this->namespaces[$prefix];
  }
  else {
    $this->message[$pos]['namespace'] = $this->default_namespace;
  }
  if ($this->status == 'header') {
    if ($this->root_header != $pos) {
      $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "{$name}{$attstr}>";
    }
  }
  elseif ($this->root_struct_name != '') {
    $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "{$name}{$attstr}>";
  }
}