/**
  * Fetch a class for a qname
  *
  * @param   xml.QName qname
  * @return  var lang.XPClass or NULL if no mapping exists
  */
 public function classFor(QName $qname)
 {
     if (!isset($this->_q2c[$qname->toString()])) {
         return NULL;
     }
     return $this->_classes[$this->_q2c[$qname->toString()]];
 }
Exemplo n.º 2
0
Arquivo: Base.php Projeto: rolwi/koala
 function _serializeValue(&$value, $name = '', $type = false, $elNamespace = null, $typeNamespace = null, $options = array(), $attributes = array(), $artype = '')
 {
     $namespaces = array();
     $arrayType = $array_depth = $xmlout_value = null;
     $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
     $xmlout_type = $xmlns = $ptype = $array_type_ns = '';
     if (!$name || is_numeric($name)) {
         $name = 'item';
     }
     if ($this->_wsdl) {
         list($ptype, $arrayType, $array_type_ns, $array_depth) = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
     }
     if (!$arrayType) {
         $arrayType = $artype;
     }
     if (!$ptype) {
         $ptype = $this->_getType($value);
     }
     if (!$type) {
         $type = $ptype;
     }
     if (strcasecmp($ptype, 'Struct') == 0 || strcasecmp($type, 'Struct') == 0) {
         // Struct
         $vars = null;
         if (is_object($value)) {
             $vars = get_object_vars($value);
         } else {
             $vars =& $value;
         }
         if (is_array($vars)) {
             foreach (array_keys($vars) as $k) {
                 // Hide private vars.
                 if ($k[0] == '_') {
                     continue;
                 }
                 if (is_object($vars[$k])) {
                     if (is_a($vars[$k], 'SOAP_Value')) {
                         $xmlout_value .= $vars[$k]->serialize($this);
                     } else {
                         // XXX get the members and serialize them instead
                         // converting to an array is more overhead than we
                         // should really do.
                         $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace);
                     }
                 } else {
                     $xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
                 }
             }
         }
     } elseif (strcasecmp($ptype, 'Array') == 0 || strcasecmp($type, 'Array') == 0) {
         // Array.
         $typeNamespace = SOAP_SCHEMA_ENCODING;
         $orig_type = $type;
         $type = 'Array';
         $numtypes = 0;
         $value = (array) $value;
         // XXX this will be slow on larger arrays.  Basically, it flattens
         // arrays to allow us to serialize multi-dimensional arrays.  We
         // only do this if arrayType is set, which will typically only
         // happen if we are using WSDL
         if (isset($options['flatten']) || $arrayType && (strchr($arrayType, ',') || strstr($arrayType, ']['))) {
             $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value);
         }
         $array_type = $array_type_prefix = '';
         if ($numtypes != 1) {
             $arrayTypeQName = new QName($arrayType);
             $arrayType = $arrayTypeQName->name;
             $array_types = array();
             $array_val = null;
             // Serialize each array element.
             $ar_size = count($value);
             foreach ($value as $array_val) {
                 if ($this->_isSoapValue($array_val)) {
                     $array_type = $array_val->type;
                     $array_types[$array_type] = 1;
                     $array_type_ns = $array_val->type_namespace;
                     $xmlout_value .= $array_val->serialize($this);
                 } else {
                     $array_type = $this->_getType($array_val);
                     $array_types[$array_type] = 1;
                     $xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
                 }
             }
             $xmlout_offset = ' SOAP-ENC:offset="[0]"';
             if (!$arrayType) {
                 $numtypes = count($array_types);
                 if ($numtypes == 1) {
                     $arrayType = $array_type;
                 }
                 // Using anyType is more interoperable.
                 if ($array_type == 'Struct') {
                     $array_type = '';
                 } elseif ($array_type == 'Array') {
                     $arrayType = 'anyType';
                     $array_type_prefix = 'xsd';
                 } else {
                     if (!$arrayType) {
                         $arrayType = $array_type;
                     }
                 }
             }
         }
         if (!$arrayType || $numtypes > 1) {
             // Should reference what schema we're using.
             $arrayType = 'xsd:anyType';
         } else {
             if ($array_type_ns) {
                 $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
             } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {
                 $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
             }
             if ($array_type_prefix) {
                 $arrayType = $array_type_prefix . ':' . $arrayType;
             }
         }
         $xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
         if ($array_depth != null) {
             for ($i = 0; $i < $array_depth; $i++) {
                 $xmlout_arrayType .= '[]';
             }
         }
         $xmlout_arrayType .= "[{$ar_size}]\"";
     } elseif ($this->_isSoapValue($value)) {
         $xmlout_value = $value->serialize($this);
     } elseif ($type == 'string') {
         $xmlout_value = htmlspecialchars($value);
     } elseif ($type == 'rawstring') {
         $xmlout_value =& $value;
     } elseif ($type == 'boolean') {
         $xmlout_value = $value ? 'true' : 'false';
     } else {
         $xmlout_value =& $value;
     }
     // Add namespaces.
     if ($elNamespace) {
         $elPrefix = $this->_getNamespacePrefix($elNamespace);
         if ($elPrefix) {
             $xmlout_name = "{$elPrefix}:{$name}";
         } else {
             $xmlout_name = $name;
         }
     } else {
         $xmlout_name = $name;
     }
     if ($typeNamespace) {
         $typePrefix = $this->_getNamespacePrefix($typeNamespace);
         if ($typePrefix) {
             $xmlout_type = "{$typePrefix}:{$type}";
         } else {
             $xmlout_type = $type;
         }
     } elseif ($type && isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
         $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
         if ($typePrefix) {
             $xmlout_type = "{$typePrefix}:{$type}";
         } else {
             $xmlout_type = $type;
         }
     }
     // Handle additional attributes.
     $xml_attr = '';
     if (count($attributes)) {
         foreach ($attributes as $k => $v) {
             $kqn = new QName($k);
             $vqn = new QName($v);
             $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';
         }
     }
     // Store the attachment for mime encoding.
     if (isset($options['attachment']) && !PEAR::isError($options['attachment'])) {
         $this->_attachments[] = $options['attachment'];
     }
     if ($this->_section5) {
         if ($xmlout_type) {
             $xmlout_type = " xsi:type=\"{$xmlout_type}\"";
         }
         if (is_null($xmlout_value)) {
             $xml = "\r\n<{$xmlout_name}{$xmlout_type}{$xmlns}{$xmlout_arrayType}" . "{$xml_attr} xsi:nil=\"true\"/>";
         } else {
             $xml = "\r\n<{$xmlout_name}{$xmlout_type}{$xmlns}{$xmlout_arrayType}" . "{$xmlout_offset}{$xml_attr}>{$xmlout_value}</{$xmlout_name}>";
         }
     } else {
         if (is_null($xmlout_value)) {
             $xml = "\r\n<{$xmlout_name}{$xmlns}{$xml_attr}/>";
         } else {
             $xml = "\r\n<{$xmlout_name}{$xmlns}{$xml_attr}>" . $xmlout_value . "</{$xmlout_name}>";
         }
     }
     return $xml;
 }
Exemplo n.º 3
0
 function &__generate($method, &$params, $namespace = false, $soapAction = false)
 {
     $this->fault = null;
     $this->__options['input'] = 'parse';
     $this->__options['result'] = 'parse';
     $this->__options['parameters'] = false;
     if ($params && gettype($params) != 'array') {
         $params = array($params);
     }
     if (gettype($namespace) == 'array') {
         foreach ($namespace as $optname => $opt) {
             $this->__options[strtolower($optname)] = $opt;
         }
         if (isset($this->__options['namespace'])) {
             $namespace = $this->__options['namespace'];
         } else {
             $namespace = false;
         }
     } else {
         // we'll place soapaction into our array for usage in the transport
         $this->__options['soapaction'] = $soapAction;
         $this->__options['namespace'] = $namespace;
     }
     if ($this->__endpointType == 'wsdl') {
         $this->_setSchemaVersion($this->_wsdl->xsd);
         // get portName
         if (!$this->_portName) {
             $this->_portName = $this->_wsdl->getPortName($method);
         }
         if (PEAR::isError($this->_portName)) {
             return $this->_raiseSoapFault($this->_portName);
         }
         // get endpoint
         $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
         if (PEAR::isError($this->_endpoint)) {
             return $this->_raiseSoapFault($this->_endpoint);
         }
         // get operation data
         $opData = $this->_wsdl->getOperationData($this->_portName, $method);
         if (PEAR::isError($opData)) {
             return $this->_raiseSoapFault($opData);
         }
         $namespace = $opData['namespace'];
         $this->__options['style'] = $opData['style'];
         $this->__options['use'] = $opData['input']['use'];
         $this->__options['soapaction'] = $opData['soapAction'];
         // set input params
         if ($this->__options['input'] == 'parse') {
             $this->__options['parameters'] = $opData['parameters'];
             $nparams = array();
             if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) {
                 $i = 0;
                 reset($params);
                 foreach ($opData['input']['parts'] as $name => $part) {
                     $xmlns = '';
                     $attrs = array();
                     // is the name actually a complex type?
                     if (isset($part['element'])) {
                         $xmlns = $this->_wsdl->namespaces[$part['namespace']];
                         $part = $this->_wsdl->elements[$part['namespace']][$part['type']];
                         $name = $part['name'];
                     }
                     if (array_key_exists($name, $params) || $this->_wsdl->getDataHandler($name, $part['namespace'])) {
                         $nparams[$name] =& $params[$name];
                     } else {
                         // we now force an associative array for
                         // parameters if using wsdl.
                         return $this->_raiseSoapFault("The named parameter {$name} is not in the call parameters.");
                     }
                     if (gettype($nparams[$name]) != 'object' || !is_a($nparams[$name], 'soap_value')) {
                         // type is a qname likely, split it apart, and get the type namespace from wsdl
                         $qname = new QName($part['type']);
                         if ($qname->ns) {
                             $type_namespace = $this->_wsdl->namespaces[$qname->ns];
                         } else {
                             if (isset($part['namespace'])) {
                                 $type_namespace = $this->_wsdl->namespaces[$part['namespace']];
                             } else {
                                 $type_namespace = null;
                             }
                         }
                         $qname->namespace = $type_namespace;
                         $type = $qname->name;
                         $pqname = $name;
                         if ($xmlns) {
                             $pqname = '{' . $xmlns . '}' . $name;
                         }
                         $nparams[$name] = new SOAP_Value($pqname, $qname->fqn(), $nparams[$name], $attrs);
                     } else {
                         // wsdl fixups to the soap value.
                     }
                 }
             }
             $params =& $nparams;
             unset($nparams);
         }
     } else {
         $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
     }
     // serialize the message.
     $this->_section5 = isset($this->__options['use']) && $this->__options['use'] == 'literal';
     if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') {
         $this->__options['style'] = 'rpc';
         $this->docparams = true;
         $mqname = new QName($method, $namespace);
         $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params);
         $soap_msg =& $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding, $this->__options);
     } else {
         if (!$params) {
             $mqname = new QName($method, $namespace);
             $mynull = null;
             $params = new SOAP_Value($mqname->fqn(), 'Struct', $mynull);
         } elseif ($this->__options['input'] == 'parse') {
             if (is_array($params)) {
                 $nparams = array();
                 $keys = array_keys($params);
                 foreach ($keys as $k) {
                     if (gettype($params[$k]) != 'object') {
                         $nparams[] = new SOAP_Value($k, false, $params[$k]);
                     } else {
                         $nparams[] =& $params[$k];
                     }
                 }
                 $params =& $nparams;
             }
             if ($this->__options['parameters']) {
                 $mqname = new QName($method, $namespace);
                 $params = new SOAP_Value($mqname->fqn(), 'Struct', $params);
             }
         }
         $soap_msg =& $this->_makeEnvelope($params, $this->headersOut, $this->_encoding, $this->__options);
     }
     unset($this->headersOut);
     if (PEAR::isError($soap_msg)) {
         return $this->_raiseSoapFault($soap_msg);
     }
     // handle Mime or DIME encoding
     // XXX DIME Encoding should move to the transport, do it here for now
     // and for ease of getting it done
     if (count($this->__attachments)) {
         if (isset($this->__options['attachments']) && $this->__options['attachments'] == 'Mime' || isset($this->__options['Mime'])) {
             $soap_msg =& $this->_makeMimeMessage($soap_msg, $this->_encoding);
         } else {
             // default is dime
             $soap_msg =& $this->_makeDIMEMessage($soap_msg, $this->_encoding);
             $this->__options['headers']['Content-Type'] = 'application/dime';
         }
         if (PEAR::isError($soap_msg)) {
             return $this->_raiseSoapFault($soap_msg);
         }
     }
     // instantiate client
     if (is_array($soap_msg)) {
         $soap_data =& $soap_msg['body'];
         if (count($soap_msg['headers'])) {
             if (isset($this->__options['headers'])) {
                 $this->__options['headers'] = array_merge($this->__options['headers'], $soap_msg['headers']);
             } else {
                 $this->__options['headers'] = $soap_msg['headers'];
             }
         }
     } else {
         $soap_data =& $soap_msg;
     }
     return $soap_data;
 }
Exemplo n.º 4
0
 /**
  * Loops through the message, building response structures.
  *
  * @param integer $pos  Position.
  *
  * @return SOAP_Value
  */
 function _buildResponse($pos)
 {
     $response = null;
     if (isset($this->message[$pos]['children'])) {
         $children = explode('|', $this->message[$pos]['children']);
         foreach ($children as $c => $child_pos) {
             if ($this->message[$child_pos]['type'] != null) {
                 $response[] = $this->_buildResponse($child_pos);
             }
         }
         if (isset($this->message[$pos]['arraySize'])) {
             $ardepth = count($this->message[$pos]['arraySize']);
             if ($ardepth > 1) {
                 $ar = array_pad(array(), $ardepth, 0);
                 if (isset($this->message[$pos]['arrayOffset'])) {
                     for ($i = 0; $i < $ardepth; $i++) {
                         $ar[$i] += $this->message[$pos]['arrayOffset'][$i];
                     }
                 }
                 $elc = count($response);
                 for ($i = 0; $i < $elc; $i++) {
                     // Recurse to build a multi dimensional array.
                     $this->_domulti($ardepth, $ar, $newresp, $response[$i]);
                     // Increment our array pointers.
                     $ad = $ardepth - 1;
                     $ar[$ad]++;
                     while ($ad > 0 && $ar[$ad] >= $this->message[$pos]['arraySize'][$ad]) {
                         $ar[$ad] = 0;
                         $ad--;
                         $ar[$ad]++;
                     }
                 }
                 $response = $newresp;
             } elseif (isset($this->message[$pos]['arrayOffset']) && $this->message[$pos]['arrayOffset'][0] > 0) {
                 // Check for padding.
                 $pad = $this->message[$pos]['arrayOffset'][0] + count($response) * -1;
                 $response = array_pad($response, $pad, null);
             }
         }
     }
     // Build attributes.
     $attrs = array();
     foreach ($this->message[$pos]['attrs'] as $atn => $atv) {
         if (!strstr($atn, 'xmlns') && !strpos($atn, ':')) {
             $attrs[$atn] = $atv;
         }
     }
     // Add current node's value.
     if ($response) {
         $nqn = new QName($this->message[$pos]['name'], $this->message[$pos]['namespace']);
         $tqn = new QName($this->message[$pos]['type'], $this->message[$pos]['type_namespace']);
         $response = new SOAP_Value($nqn->fqn(), $tqn->fqn(), $response, $attrs);
         if (isset($this->message[$pos]['arrayType'])) {
             $response->arrayType = $this->message[$pos]['arrayType'];
         }
     } else {
         $nqn = new QName($this->message[$pos]['name'], $this->message[$pos]['namespace']);
         $tqn = new QName($this->message[$pos]['type'], $this->message[$pos]['type_namespace']);
         // Check if value is an empty array
         if ($tqn->name == 'Array') {
             $response =& new SOAP_Value($nqn->fqn(), $tqn->fqn(), array(), $attrs);
         } else {
             $response = new SOAP_Value($nqn->fqn(), $tqn->fqn(), $this->message[$pos]['cdata'], $attrs);
         }
     }
     // Handle header attribute that we need.
     if (array_key_exists('actor', $this->message[$pos])) {
         $response->actor = $this->message[$pos]['actor'];
     }
     if (array_key_exists('mustUnderstand', $this->message[$pos])) {
         $response->mustunderstand = $this->message[$pos]['mustUnderstand'];
     }
     return $response;
 }
Exemplo n.º 5
0
    function _serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array(), $artype='')
    {
        $namespaces = array();
        $arrayType = $array_depth = $xmlout_value = null;
        $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = $xmlout_type = $xmlns = '';
        $ptype = $array_type_ns = '';

        if (!$name || is_numeric($name)) {
            $name = 'item';
        }

        if ($this->_wsdl)
            list($ptype, $arrayType, $array_type_ns, $array_depth)
                    = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);

        if (!$arrayType) $arrayType = $artype;
        if (!$ptype) $ptype = $this->_getType($value);
        if (!$type) $type = $ptype;

        if (strcasecmp($ptype,'Struct') == 0 || strcasecmp($type,'Struct') == 0) {
            // struct
            $vars = NULL;
            if (is_object($value)) {
                $vars = get_object_vars($value);
            } else {
                $vars = &$value;
            }
            if (is_array($vars)) {
                foreach (array_keys($vars) as $k) {
                    if ($k[0]=='_') continue; // hide private vars
                    if (is_object($vars[$k])) {
                        if (is_a($vars[$k],'soap_value')) {
                            $xmlout_value .= $vars[$k]->serialize($this);
                        } else {
                            // XXX get the members and serialize them instead
                            // converting to an array is more overhead than we
                            // should realy do, but php-soap is on it's way.
                            $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5?NULL:$elNamespace);
                        }
                    } else {
                        $xmlout_value .= $this->_serializeValue($vars[$k],$k, false, $this->_section5?NULL:$elNamespace);
                    }
                }
            }
        } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) {
            // array
            $typeNamespace = SOAP_SCHEMA_ENCODING;
            $orig_type = $type;
            $type = 'Array';
            $numtypes = 0;
            // XXX this will be slow on larger array's.  Basicly, it flattens array's to allow us
            // to serialize multi-dimensional array's.  We only do this if arrayType is set,
            // which will typicaly only happen if we are using WSDL
            if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) {
                $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value);
            }

            $array_type = $array_type_prefix = '';
            if ($numtypes != 1) {
                $arrayTypeQName =new QName($arrayType);
                $arrayType = $arrayTypeQName->name;
                $array_types = array();
                $array_val = NULL;

                // serialize each array element
                $ar_size = count($value);
		foreach ($value as $array_val) {
                    if ($this->_isSoapValue($array_val)) {
                        $array_type = $array_val->type;
                        $array_types[$array_type] = 1;
                        $array_type_ns = $array_val->type_namespace;
                        $xmlout_value .= $array_val->serialize($this);
                    } else {
                        $array_type = $this->_getType($array_val);
                        $array_types[$array_type] = 1;
                        $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type, $this->_section5?NULL:$elNamespace);
                    }
                }

                $xmlout_offset = " SOAP-ENC:offset=\"[0]\"";
                if (!$arrayType) {
                    $numtypes = count($array_types);
                    if ($numtypes == 1) $arrayType = $array_type;
                    // using anyType is more interoperable
                    if ($array_type == 'Struct') {
                        $array_type = '';
                    } else if ($array_type == 'Array') {
                        $arrayType = 'anyType';
                        $array_type_prefix = 'xsd';
                    } else
                    if (!$arrayType) $arrayType = $array_type;
                }
            }
            if (!$arrayType || $numtypes > 1) {
                $arrayType = 'xsd:anyType'; // should reference what schema we're using
            } else {
                if ($array_type_ns) {
                    $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
                } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) {
                    $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
                }
                if ($array_type_prefix)
                    $arrayType = $array_type_prefix.':'.$arrayType;
            }

            $xmlout_arrayType = " SOAP-ENC:arrayType=\"" . $arrayType;
            if ($array_depth != null) {
                for ($i = 0; $i < $array_depth; $i++) {
                    $xmlout_arrayType .= '[]';
                }
            }
            $xmlout_arrayType .= "[$ar_size]\"";
        } else if ($this->_isSoapValue($value)) {
            $xmlout_value =& $value->serialize($this);
        } else if ($type == 'string') {
            $xmlout_value = htmlspecialchars($value);
        } else if ($type == 'rawstring') {
            $xmlout_value =& $value;
        } else if ($type == 'boolean') {
            $xmlout_value = $value?'true':'false';
        } else {
            $xmlout_value =& $value;
        }

        // add namespaces
        if ($elNamespace) {
            $elPrefix = $this->_getNamespacePrefix($elNamespace);
            $xmlout_name = "$elPrefix:$name";
        } else {
            $xmlout_name = $name;
        }

        if ($typeNamespace) {
            $typePrefix = $this->_getNamespacePrefix($typeNamespace);
            $xmlout_type = "$typePrefix:$type";
        } else if ($type && array_key_exists($type, $this->_typemap[$this->_XMLSchemaVersion])) {
            $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
            $xmlout_type = "$typePrefix:$type";
        }

        // handle additional attributes
        $xml_attr = '';
        if (count($attributes) > 0) {
            foreach ($attributes as $k => $v) {
                $kqn =new QName($k);
                $vqn =new QName($v);
                $xml_attr .= ' '.$kqn->fqn().'="'.$vqn->fqn().'"';
            }
        }

        // store the attachement for mime encoding
        if (isset($options['attachment']))
            $this->__attachments[] = $options['attachment'];

        if ($this->_section5) {
            if ($xmlout_type) $xmlout_type = " xsi:type=\"$xmlout_type\"";
            if (is_null($xmlout_value)) {
                $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xml_attr/>";
            } else {
                $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xmlout_offset$xml_attr>".
                    $xmlout_value."</$xmlout_name>";
            }
        } else {
            if (is_null($xmlout_value)) {
                $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
            } else {
                $xml = "\r\n<$xmlout_name$xmlns$xml_attr>".
                    $xmlout_value."</$xmlout_name>";
            }
        }
        return $xml;
    }
Exemplo n.º 6
0
 function parseRequest($data = '', $attachments = null)
 {
     /* Parse response, get SOAP_Parser object. */
     $parser = new SOAP_Parser($data, $this->xml_encoding, $attachments);
     if ($parser->fault) {
         /* Fault occurred during message parsing. */
         $this->fault = $parser->fault;
         return null;
     }
     if (!count($parser->root_struct_name)) {
         /* No method specified. */
         $this->_raiseSoapFault('No method specified in request.');
         return null;
     }
     /* Handle message headers. */
     $request_headers = $parser->getHeaders();
     $header_results = array();
     if ($request_headers) {
         if (!is_a($request_headers, 'SOAP_Value')) {
             $this->_raiseSoapFault('Parser did not return SOAP_Value object: ' . $request_headers, '', '', 'Server');
             return null;
         }
         if ($request_headers->value) {
             /* Handle headers now. */
             foreach ($request_headers->value as $header_val) {
                 $f_exists = $this->validateMethod($header_val->name, $header_val->namespace);
                 /* TODO: this does not take into account message routing
                  * yet. */
                 $myactor = !$header_val->actor || $header_val->actor == 'http://schemas.xmlsoap.org/soap/actor/next' || $header_val->actor == $this->endpoint;
                 if (!$f_exists && $header_val->mustunderstand && $myactor) {
                     $this->_raiseSoapFault('I don\'t understand header ' . $header_val->name, '', '', 'MustUnderstand');
                     return null;
                 }
                 /* We only handle the header if it's for us. */
                 $isok = $f_exists && $myactor;
                 if ($isok) {
                     /* Call our header now! */
                     $header_method = $header_val->name;
                     $header_data = array($this->_decode($header_val));
                     /* If there are parameters to pass. */
                     $hr =& $this->callMethod($header_method, $header_data);
                     if (PEAR::isError($hr)) {
                         $this->_raiseSoapFault($hr);
                         return null;
                     }
                     $results = $this->buildResult($hr, $this->return_type, $header_method, $header_val->namespace);
                     $header_results[] = $results[0];
                 }
             }
         }
     }
     /* Handle the method call. */
     /* Evaluate message, getting back a SOAP_Value object. */
     $this->call_methodname = $this->methodname = $parser->root_struct_name[0];
     /* Figure out the method namespace. */
     $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace'];
     if ($this->_wsdl) {
         $this->_setSchemaVersion($this->_wsdl->xsd);
         $dataHandler = $this->_wsdl->getDataHandler($this->methodname, $this->method_namespace);
         if ($dataHandler) {
             $this->call_methodname = $this->methodname = $dataHandler;
         }
         $this->_portName = $this->_wsdl->getPortName($this->methodname);
         if (PEAR::isError($this->_portName)) {
             $this->_raiseSoapFault($this->_portName);
             return null;
         }
         $opData = $this->_wsdl->getOperationData($this->_portName, $this->methodname);
         if (PEAR::isError($opData)) {
             $this->_raiseSoapFault($opData);
             return null;
         }
         $this->_options['style'] = $opData['style'];
         $this->_options['use'] = $opData['output']['use'];
         $this->_options['parameters'] = $opData['parameters'];
     }
     /* Does method exist? */
     if (!$this->methodname || !$this->validateMethod($this->methodname, $this->method_namespace)) {
         $this->_raiseSoapFault('method "' . $this->method_namespace . $this->methodname . '" not defined in service', '', '', 'Server');
         return null;
     }
     if (!($request_val = $parser->getResponse())) {
         return null;
     }
     if (!is_a($request_val, 'SOAP_Value')) {
         $this->_raiseSoapFault('Parser did not return SOAP_Value object: ' . $request_val, '', '', 'Server');
         return null;
     }
     /* Verify that SOAP_Value objects in request match the methods
      * signature. */
     if (!$this->verifyMethod($request_val)) {
         /* verifyMethod() creates the fault. */
         return null;
     }
     /* Need to set special error detection inside the value class to
      * differentiate between no params passed, and an error decoding. */
     $request_data = $this->__decodeRequest($request_val);
     if (PEAR::isError($request_data)) {
         $this->_raiseSoapFault($request_data);
         return null;
     }
     $method_response =& $this->callMethod($this->call_methodname, $request_data);
     if (PEAR::isError($method_response)) {
         $this->_raiseSoapFault($method_response);
         return null;
     }
     if ($this->_options['parameters'] || !$method_response || $this->_options['style'] == 'rpc') {
         /* Get the method result. */
         if (is_null($method_response)) {
             $return_val = null;
         } else {
             $return_val = $this->buildResult($method_response, $this->return_type);
         }
         $qn = new QName($this->methodname . 'Response', $this->method_namespace);
         $methodValue = new SOAP_Value($qn->fqn(), 'Struct', $return_val);
     } else {
         $methodValue =& $method_response;
     }
     return $this->makeEnvelope($methodValue, $header_results, $this->response_encoding);
 }
Exemplo n.º 7
0
 /**
  * Add a namespace node
  *
  * @param name $name
  * @param string $value
  * @param QName $ns
  */
 public function add_ns_node($name, $value, QName $ns)
 {
     $n = $this->node ? new self($this->owner) : $this;
     if ($value) {
         $value = safe_xml($value);
     }
     $nsn = $this->doc->createElementNS($ns->namespace_uri(), $name, $value);
     if ($this->node) {
         $n->node = $this->node->appendChild($nsn);
     } else {
         $n->node = $this->node = $this->doc->appendChild($nsn);
     }
     unset($nsn);
     return $n;
 }
Exemplo n.º 8
0
 /**
  * Generates the complete XML SOAP message for an RPC call.
  *
  * @see call()
  *
  * @param string $method           The method to call.
  * @param array $params            The method parameters.
  * @param string|array $namespace  Namespace or hash with options. Note:
  *                                 most options need to be repeated for
  *                                 SOAP_Value instances.
  * @param string $soapAction
  *
  * @return string  The SOAP message including envelope.
  */
 function _generate($method, $params, $namespace = false, $soapAction = false)
 {
     $this->fault = null;
     $this->_options['input'] = 'parse';
     $this->_options['result'] = 'parse';
     $this->_options['parameters'] = false;
     if ($params && !is_array($params)) {
         $params = array($params);
     }
     if (is_array($namespace)) {
         // Options passed as a hash.
         foreach ($namespace as $optname => $opt) {
             $this->_options[strtolower($optname)] = $opt;
         }
     } else {
         // We'll place $soapAction into our array for usage in the
         // transport.
         if ($soapAction) {
             $this->_options['soapaction'] = $soapAction;
         }
         if ($namespace) {
             $this->_options['namespace'] = $namespace;
         }
     }
     if (isset($this->_options['namespace'])) {
         $namespace = $this->_options['namespace'];
     } else {
         $namespace = false;
     }
     if ($this->_endpointType == 'wsdl') {
         $this->_setSchemaVersion($this->_wsdl->xsd);
         // Get port name.
         if (!$this->_portName) {
             $this->_portName = $this->_wsdl->getPortName($method);
         }
         if (PEAR::isError($this->_portName)) {
             return $this->_raiseSoapFault($this->_portName);
         }
         // Get endpoint.
         $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
         if (PEAR::isError($this->_endpoint)) {
             return $this->_raiseSoapFault($this->_endpoint);
         }
         // Get operation data.
         $opData = $this->_wsdl->getOperationData($this->_portName, $method);
         if (PEAR::isError($opData)) {
             return $this->_raiseSoapFault($opData);
         }
         $namespace = isset($opData['namespace']) ? $opData['namespace'] : '';
         $this->_options['style'] = $opData['style'];
         $this->_options['use'] = $opData['input']['use'];
         $this->_options['soapaction'] = $opData['soapAction'];
         // Set input parameters.
         if ($this->_options['input'] == 'parse') {
             $this->_options['parameters'] = $opData['parameters'];
             $nparams = array();
             if (isset($opData['input']['parts']) && count($opData['input']['parts'])) {
                 foreach ($opData['input']['parts'] as $name => $part) {
                     $xmlns = '';
                     $attrs = array();
                     // Is the name a complex type?
                     if (isset($part['element'])) {
                         $xmlns = $this->_wsdl->namespaces[$part['namespace']];
                         $part = $this->_wsdl->elements[$part['namespace']][$part['type']];
                         $name = $part['name'];
                     }
                     if (isset($params[$name]) || $this->_wsdl->getDataHandler($name, $part['namespace'])) {
                         $nparams[$name] =& $params[$name];
                     } else {
                         // We now force an associative array for
                         // parameters if using WSDL.
                         return $this->_raiseSoapFault("The named parameter {$name} is not in the call parameters.");
                     }
                     if (gettype($nparams[$name]) != 'object' || !$nparams[$name] instanceof SOAP_Value) {
                         // Type is likely a qname, split it apart, and get
                         // the type namespace from WSDL.
                         $qname = new QName($part['type']);
                         if ($qname->ns) {
                             $type_namespace = $this->_wsdl->namespaces[$qname->ns];
                         } elseif (isset($part['namespace'])) {
                             $type_namespace = $this->_wsdl->namespaces[$part['namespace']];
                         } else {
                             $type_namespace = null;
                         }
                         $qname->namespace = $type_namespace;
                         $pqname = $name;
                         if ($xmlns) {
                             $pqname = '{' . $xmlns . '}' . $name;
                         }
                         $nparams[$name] = new SOAP_Value($pqname, $qname->fqn(), $nparams[$name], $attrs);
                     } else {
                         // WSDL fixups to the SOAP value.
                     }
                 }
             }
             $params =& $nparams;
             unset($nparams);
         }
     } else {
         $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
     }
     // Serialize the message.
     $this->_section5 = !isset($this->_options['use']) || $this->_options['use'] != 'literal';
     if (!isset($this->_options['style']) || $this->_options['style'] == 'rpc') {
         $this->_options['style'] = 'rpc';
         $this->docparams = true;
         $mqname = new QName($method, $namespace);
         $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params, array(), $this->_options);
         $soap_msg = $this->makeEnvelope($methodValue, $this->headersOut, $this->_encoding, $this->_options);
     } else {
         if (!$params) {
             $mqname = new QName($method, $namespace);
             $params = new SOAP_Value($mqname->fqn(), 'Struct', null);
         } elseif ($this->_options['input'] == 'parse') {
             if (is_array($params)) {
                 $nparams = array();
                 $keys = array_keys($params);
                 foreach ($keys as $k) {
                     if (gettype($params[$k]) != 'object') {
                         $nparams[] = new SOAP_Value($k, false, $params[$k]);
                     } else {
                         $nparams[] =& $params[$k];
                     }
                 }
                 $params =& $nparams;
             }
             if ($this->_options['parameters']) {
                 $mqname = new QName($method, $namespace);
                 $params = new SOAP_Value($mqname->fqn(), 'Struct', $params);
             }
         }
         $soap_msg = $this->makeEnvelope($params, $this->headersOut, $this->_encoding, $this->_options);
     }
     $this->headersOut = null;
     if (PEAR::isError($soap_msg)) {
         return $this->_raiseSoapFault($soap_msg);
     }
     // Handle MIME or DIME encoding.
     // TODO: DIME encoding should move to the transport, do it here for
     // now and for ease of getting it done.
     if (count($this->_attachments)) {
         if (isset($this->_options['attachments']) && $this->_options['attachments'] == 'Mime' || isset($this->_options['Mime'])) {
             $soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding);
         } else {
             // default is dime
             $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding);
             $this->_options['headers']['Content-Type'] = 'application/dime';
         }
         if (PEAR::isError($soap_msg)) {
             return $this->_raiseSoapFault($soap_msg);
         }
     }
     // Instantiate client.
     if (is_array($soap_msg)) {
         $soap_data = $soap_msg['body'];
         if (count($soap_msg['headers'])) {
             if (isset($this->_options['headers'])) {
                 $this->_options['headers'] = array_merge($this->_options['headers'], $soap_msg['headers']);
             } else {
                 $this->_options['headers'] = $soap_msg['headers'];
             }
         }
     } else {
         $soap_data = $soap_msg;
     }
     return $soap_data;
 }