Feature #19791 » 10097.diff
typo3/mod/tools/em/class.em_soap.php (working copy) | ||
---|---|---|
* 'headers' soap headers are used
|
||
* 'prefix' function prefixes are used
|
||
* prefix : optional prefix to be put in front of all methods.
|
||
* implementation : Which type of soap implementation to use :
|
||
* 'detect' automatically detect an implementation.
|
||
* 'phpsoap' PHP builtin SOAP module
|
||
* <http://www.php.net/manual/en/ref.soap.php>
|
||
* 'nusoap' NuSOAP class
|
||
* <http://dietrich.ganx4.com/nusoap>
|
||
* 'pearsoap' PEAR SOAP class
|
||
* <http://pear.php.net/package/SOAP>
|
||
* format : Which type of return structure :
|
||
* 'object' PHP objects
|
||
* 'array' PHP arrays, default
|
||
... | ... | |
var $options = array();
|
||
/**
|
||
* SOAP client depending on the available implementations, preferably the PHP SOAP class
|
||
* SOAP client, instance of PHP SOAP class
|
||
*
|
||
* @var unknown_type
|
||
* @var SoapClient
|
||
*/
|
||
var $client = false;
|
||
var $error = false;
|
||
... | ... | |
}
|
||
}
|
||
if (!$options['implementation'] || $options['implementation'] == 'detect') {
|
||
if (defined('SOAP_1_2')) {
|
||
$options['implementation'] = 'phpsoap';
|
||
} elseif (class_exists('soapclient')) {
|
||
$options['implementation'] = 'nusoap';
|
||
} elseif (class_exists('SOAP_Client')) {
|
||
$options['implementation'] = 'pearsoap';
|
||
}
|
||
}
|
||
$options['format'] = $options['format'] == 'object' ? 'object' : 'array';
|
||
if ($options !== false) {
|
||
$this->options = (array)$options;
|
||
}
|
||
switch ($this->options['implementation']) {
|
||
case 'nusoap':
|
||
$this->client = new soapclient($this->options['wsdl'], true);
|
||
$this->client->getProxy();
|
||
break;
|
||
case 'pearsoap':
|
||
$this->client = new SOAP_Client($this->options['wsdl'], true);
|
||
break;
|
||
case 'phpsoap':
|
||
$this->client = new SoapClient($options['wsdl'],(array)$options['soapoptions']);
|
||
break;
|
||
default:
|
||
$this->client = false;
|
||
if (defined('SOAP_1_2')) {
|
||
$this->client = new SoapClient($options['wsdl'],(array)$options['soapoptions']);
|
||
} else {
|
||
throw new Exception('PHP soap extension not available');
|
||
$this->client = false;
|
||
}
|
||
}
|
||
... | ... | |
*/
|
||
function call($func, $param=array(), $username=false, $password=false) {
|
||
if (!$this->client) {
|
||
$this->error = "Error in Webservices.class.php: No soap client implementation found. ".
|
||
"Make sure a SOAP library such as 'NuSoap.php' is included.";
|
||
$this->error = sprintf(
|
||
'Error in %s: No soap client implementation found. ' .
|
||
'Make sure PHP soap extension is available!', __FILE__
|
||
);
|
||
return false;
|
||
}
|
||
... | ... | |
$this->error = false;
|
||
switch ($this->options['implementation']) {
|
||
case 'nusoap' : return $this->callNuSOAP($func, $param); break;
|
||
case 'pearsoap' : return $this->callPearSOAP($func, $param); break;
|
||
case 'phpsoap' : return $this->callPhpSOAP($func, $param); break;
|
||
}
|
||
return false;
|
||
return $this->callPhpSOAP($func, $param);
|
||
}
|
||
/**
|
||
... | ... | |
/**
|
||
* Enter description here...
|
||
*
|
||
* @param unknown_type $func
|
||
* @param unknown_type $param
|
||
* @return unknown
|
||
*/
|
||
function callPearSOAP($func,$param) {
|
||
if ($this->options['authentication'] == 'headers') {
|
||
if ($this->reactid) {
|
||
$this->client->addHeader(
|
||
new SOAP_Header(
|
||
'HeaderAuthenticate', NULL,
|
||
array('reactid' => $this->reactid), 1
|
||
)
|
||
);
|
||
} elseif ($this->username && $this->password) {
|
||
$this->client->addHeader(
|
||
new SOAP_Header(
|
||
'HeaderLogin', NULL,
|
||
array(
|
||
'username' => $this->username,
|
||
'password' => $this->password
|
||
), 1
|
||
)
|
||
);
|
||
$this->password = false;
|
||
}
|
||
}
|
||
$result = $this->client->call($func, $param);
|
||
if (PEAR::isError($result)) {
|
||
$this->error = $result;
|
||
return false;
|
||
}
|
||
if (is_a($this->client->headersIn['HeaderAuthenticate'],'stdClass')) {
|
||
$this->reactid = $this->client->headersIn['HeaderAuthenticate']->reactid;
|
||
}
|
||
return $this->options['format'] == 'object' ? $result : $this->object2array($result);
|
||
}
|
||
/**
|
||
* Enter description here...
|
||
*
|
||
* @param unknown_type $func
|
||
* @param unknown_type $param
|
||
* @return unknown
|
||
*/
|
||
function callNuSOAP($func,$param) {
|
||
$header = false;
|
||
if ($this->options['authentication'] == 'headers') {
|
||
if ($this->reactid) {
|
||
$header = (
|
||
"<HeaderAuthenticate SOAP-ENV:mustUnderstand='1'>".
|
||
"<reactid>".htmlspecialchars($this->reactid)."</reactid>".
|
||
"</HeaderAuthenticate>"
|
||
);
|
||
} elseif ($this->username && $this->password) {
|
||
$header = (
|
||
"<HeaderLogin SOAP-ENV:mustUnderstand='1'>".
|
||
"<username>".htmlspecialchars($this->username)."</username>".
|
||
"<password>".htmlspecialchars($this->password)."</password>".
|
||
"</HeaderLogin>" //HeaderLogin
|
||
);
|
||
$this->password = false;
|
||
}
|
||
}
|
||
$result = $this->client->call($func, $param, false, false, $header);
|
||
if ($this->error = $this->client->getError()) {
|
||
return false;
|
||
}
|
||
// nusoap header support is very limited
|
||
$headers = $this->client->getHeaders();
|
||
$matches = array();
|
||
if (preg_match('~<([a-z0-9]+:)?reactid[^>]*>([^<]*)</([a-z0-9]+:)?reactid>~is', $headers, $matches)) {
|
||
$this->reactid = $matches[2];
|
||
}
|
||
return $this->options['format'] == 'object' ? $this->array2object($result) : $result;
|
||
}
|
||
/**
|
||
* Enter description here...
|
||
*
|
||
* @param unknown_type $object
|
||
* @return unknown
|
||
*/
|
||
... | ... | |
* @return unknown
|
||
*/
|
||
function lastRequest() {
|
||
switch ($this->options['implementation']) {
|
||
case 'nusoap' : return $this->client->request; break;
|
||
case 'pearsoap' : return $this->client->__getlastrequest(); break;
|
||
case 'phpsoap' : return $this->client->__getLastRequest(); break;
|
||
}
|
||
return false;
|
||
return $this->client->__getLastRequest();
|
||
}
|
||
/**
|
||
... | ... | |
* @return unknown
|
||
*/
|
||
function lastResponse() {
|
||
switch ($this->options['implementation']) {
|
||
case 'nusoap' : return $this->client->response; break;
|
||
case 'pearsoap' : return $this->client->__getlastresponse(); break;
|
||
case 'phpsoap' : return $this->client->__getLastResponse(); break;
|
||
}
|
||
return false;
|
||
return $this->client->__getLastResponse();
|
||
}
|
||
/**
|
||
... | ... | |
* @return unknown
|
||
*/
|
||
function getFunctions() {
|
||
switch ($this->options['implementation']) {
|
||
case 'nusoap' : return array_keys($this->client->operations); break;
|
||
case 'pearsoap' : return false; break;
|
||
case 'phpsoap' : return $this->client->__getFunctions(); break;
|
||
}
|
||
return false;
|
||
return $this->client->__getFunctions();
|
||
}
|
||
}
|
||
typo3/mod/tools/em/class.em_terconnection.php (working copy) | ||
---|---|---|
***************************************************************/
|
||
if (!defined('SOAP_1_2')) {
|
||
require_once('class.nusoap.php');
|
||
# require_once('/usr/share/php/SOAP/Client.php');
|
||
}
|
||
require_once('class.em_soap.php');
|
||
/**
|
||
... | ... | |
$filesData = array();
|
||
foreach ($uArr['FILES'] as $filename => $infoArr) {
|
||
$content = (!defined('SOAP_1_2') && class_exists('soapclient')) ? base64_encode($infoArr['content']) : $infoArr['content']; // bug in NuSOAP - no automatic encoding
|
||
$content = $infoArr['content'];
|
||
$filesData['fileData'][] = array (
|
||
'name' => utf8_encode($infoArr['name']),
|
||
'size' => intval($infoArr['size']),
|
typo3/mod/tools/em/class.nusoap.php (working copy) | ||
---|---|---|
<?php
|
||
/*
|
||
$Id$
|
||
NuSOAP - Web Services Toolkit for PHP
|
||
Copyright (c) 2002 NuSphere Corporation
|
||
This library is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU Lesser General Public
|
||
License as published by the Free Software Foundation; either
|
||
version 2.1 of the License, or (at your option) any later version.
|
||
This library is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
Lesser General Public License for more details.
|
||
You should have received a copy of the GNU Lesser General Public
|
||
License along with this library; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
�����
|
||
If you have any questions or comments, please email:
|
||
Dietrich Ayala
|
||
dietrich@ganx4.com
|
||
http://dietrich.ganx4.com/nusoap
|
||
NuSphere Corporation
|
||
http://www.nusphere.com
|
||
*/
|
||
/* load classes
|
||
// necessary classes
|
||
require_once('class.soapclient.php');
|
||
require_once('class.soap_val.php');
|
||
require_once('class.soap_parser.php');
|
||
require_once('class.soap_fault.php');
|
||
// transport classes
|
||
require_once('class.soap_transport_http.php');
|
||
// optional add-on classes
|
||
require_once('class.xmlschema.php');
|
||
require_once('class.wsdl.php');
|
||
*/
|
||
// class variable emulation
|
||
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
|
||
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
|
||
/**
|
||
*
|
||
* nusoap_base
|
||
*
|
||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||
* @version $Id$
|
||
* @access public
|
||
*/
|
||
class nusoap_base {
|
||
/**
|
||
* Identification for HTTP headers.
|
||
*
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $title = 'NuSOAP';
|
||
/**
|
||
* Version for HTTP headers.
|
||
*
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $version = '0.7.2';
|
||
/**
|
||
* CVS revision for HTTP headers.
|
||
*
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $revision = '$Revision$';
|
||
/**
|
||
* Current error string (manipulated by getError/setError)
|
||
*
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $error_str = '';
|
||
/**
|
||
* Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
|
||
*
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $debug_str = '';
|
||
/**
|
||
* toggles automatic encoding of special characters as entities
|
||
* (should always be true, I think)
|
||
*
|
||
* @var boolean
|
||
* @access private
|
||
*/
|
||
var $charencoding = true;
|
||
/**
|
||
* the debug level for this instance
|
||
*
|
||
* @var integer
|
||
* @access private
|
||
*/
|
||
var $debugLevel;
|
||
/**
|
||
* set schema version
|
||
*
|
||
* @var string
|
||
* @access public
|
||
*/
|
||
var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
|
||
/**
|
||
* charset encoding for outgoing messages
|
||
*
|
||
* @var string
|
||
* @access public
|
||
*/
|
||
var $soap_defencoding = 'ISO-8859-1';
|
||
//var $soap_defencoding = 'UTF-8';
|
||
/**
|
||
* namespaces in an array of prefix => uri
|
||
*
|
||
* this is "seeded" by a set of constants, but it may be altered by code
|
||
*
|
||
* @var array
|
||
* @access public
|
||
*/
|
||
var $namespaces = array(
|
||
'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
||
'xsd' => 'http://www.w3.org/2001/XMLSchema',
|
||
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||
'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
|
||
);
|
||
/**
|
||
* namespaces used in the current context, e.g. during serialization
|
||
*
|
||
* @var array
|
||
* @access private
|
||
*/
|
||
var $usedNamespaces = array();
|
||
/**
|
||
* XML Schema types in an array of uri => (array of xml type => php type)
|
||
* is this legacy yet?
|
||
* no, this is used by the xmlschema class to verify type => namespace mappings.
|
||
* @var array
|
||
* @access public
|
||
*/
|
||
var $typemap = array(
|
||
'http://www.w3.org/2001/XMLSchema' => array(
|
||
'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
|
||
'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
|
||
'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
|
||
// abstract "any" types
|
||
'anyType'=>'string','anySimpleType'=>'string',
|
||
// derived datatypes
|
||
'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
|
||
'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
|
||
'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
|
||
'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
|
||
'http://www.w3.org/2000/10/XMLSchema' => array(
|
||
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
|
||
'float'=>'double','dateTime'=>'string',
|
||
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
|
||
'http://www.w3.org/1999/XMLSchema' => array(
|
||
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
|
||
'float'=>'double','dateTime'=>'string',
|
||
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
|
||
'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
|
||
'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
|
||
'http://xml.apache.org/xml-soap' => array('Map')
|
||
);
|
||
/**
|
||
* XML entities to convert
|
||
*
|
||
* @var array
|
||
* @access public
|
||
* @deprecated
|
||
* @see expandEntities
|
||
*/
|
||
var $xmlEntities = array('quot' => '"','amp' => '&',
|
||
'lt' => '<','gt' => '>','apos' => "'");
|
||
/**
|
||
* constructor
|
||
*
|
||
* @access public
|
||
*/
|
||
function nusoap_base() {
|
||
$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
|
||
}
|
||
/**
|
||
* gets the global debug level, which applies to future instances
|
||
*
|
||
* @return integer Debug level 0-9, where 0 turns off
|
||
* @access public
|
||
*/
|
||
function getGlobalDebugLevel() {
|
||
return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
|
||
}
|
||
/**
|
||
* sets the global debug level, which applies to future instances
|
||
*
|
||
* @param int $level Debug level 0-9, where 0 turns off
|
||
* @access public
|
||
*/
|
||
function setGlobalDebugLevel($level) {
|
||
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
|
||
}
|
||
/**
|
||
* gets the debug level for this instance
|
||
*
|
||
* @return int Debug level 0-9, where 0 turns off
|
||
* @access public
|
||
*/
|
||
function getDebugLevel() {
|
||
return $this->debugLevel;
|
||
}
|
||
/**
|
||
* sets the debug level for this instance
|
||
*
|
||
* @param int $level Debug level 0-9, where 0 turns off
|
||
* @access public
|
||
*/
|
||
function setDebugLevel($level) {
|
||
$this->debugLevel = $level;
|
||
}
|
||
/**
|
||
* adds debug data to the instance debug string with formatting
|
||
*
|
||
* @param string $string debug data
|
||
* @access private
|
||
*/
|
||
function debug($string){
|
||
if ($this->debugLevel > 0) {
|
||
$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
|
||
}
|
||
}
|
||
/**
|
||
* adds debug data to the instance debug string without formatting
|
||
*
|
||
* @param string $string debug data
|
||
* @access public
|
||
*/
|
||
function appendDebug($string){
|
||
if ($this->debugLevel > 0) {
|
||
// it would be nice to use a memory stream here to use
|
||
// memory more efficiently
|
||
$this->debug_str .= $string;
|
||
}
|
||
}
|
||
/**
|
||
* clears the current debug data for this instance
|
||
*
|
||
* @access public
|
||
*/
|
||
function clearDebug() {
|
||
// it would be nice to use a memory stream here to use
|
||
// memory more efficiently
|
||
$this->debug_str = '';
|
||
}
|
||
/**
|
||
* gets the current debug data for this instance
|
||
*
|
||
* @return debug data
|
||
* @access public
|
||
*/
|
||
function &getDebug() {
|
||
// it would be nice to use a memory stream here to use
|
||
// memory more efficiently
|
||
return $this->debug_str;
|
||
}
|
||
/**
|
||
* gets the current debug data for this instance as an XML comment
|
||
* this may change the contents of the debug data
|
||
*
|
||
* @return debug data as an XML comment
|
||
* @access public
|
||
*/
|
||
function &getDebugAsXMLComment() {
|
||
// it would be nice to use a memory stream here to use
|
||
// memory more efficiently
|
||
while (strpos($this->debug_str, '--')) {
|
||
$this->debug_str = str_replace('--', '- -', $this->debug_str);
|
||
}
|
||
return "<!--\n" . $this->debug_str . "\n-->";
|
||
}
|
||
/**
|
||
* expands entities, e.g. changes '<' to '<'.
|
||
*
|
||
* @param string $val The string in which to expand entities.
|
||
* @access private
|
||
*/
|
||
function expandEntities($val) {
|
||
if ($this->charencoding) {
|
||
$val = str_replace('&', '&', $val);
|
||
$val = str_replace("'", ''', $val);
|
||
$val = str_replace('"', '"', $val);
|
||
$val = str_replace('<', '<', $val);
|
||
$val = str_replace('>', '>', $val);
|
||
}
|
||
return $val;
|
||
}
|
||
/**
|
||
* returns error string if present
|
||
*
|
||
* @return mixed error string or false
|
||
* @access public
|
||
*/
|
||
function getError(){
|
||
if($this->error_str != ''){
|
||
return $this->error_str;
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* sets error string
|
||
*
|
||
* @return boolean $string error string
|
||
* @access private
|
||
*/
|
||
function setError($str){
|
||
$this->error_str = $str;
|
||
}
|
||
/**
|
||
* detect if array is a simple array or a struct (associative array)
|
||
*
|
||
* @param mixed $val The PHP array
|
||
* @return string (arraySimple|arrayStruct)
|
||
* @access private
|
||
*/
|
||
function isArraySimpleOrStruct($val) {
|
||
$keyList = array_keys($val);
|
||
foreach ($keyList as $keyListValue) {
|
||
if (!is_int($keyListValue)) {
|
||
return 'arrayStruct';
|
||
}
|
||
}
|
||
return 'arraySimple';
|
||
}
|
||
/**
|
||
* serializes PHP values in accordance w/ section 5. Type information is
|
||
* not serialized if $use == 'literal'.
|
||
*
|
||
* @param mixed $val The value to serialize
|
||
* @param string $name The name (local part) of the XML element
|
||
* @param string $type The XML schema type (local part) for the element
|
||
* @param string $name_ns The namespace for the name of the XML element
|
||
* @param string $type_ns The namespace for the type of the element
|
||
* @param array $attributes The attributes to serialize as name=>value pairs
|
||
* @param string $use The WSDL "use" (encoded|literal)
|
||
* @return string The serialized element, possibly with child elements
|
||
* @access public
|
||
*/
|
||
function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
|
||
$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
|
||
$this->appendDebug('value=' . $this->varDump($val));
|
||
$this->appendDebug('attributes=' . $this->varDump($attributes));
|
||
if(is_object($val) && get_class($val) == 'soapval'){
|
||
return $val->serialize($use);
|
||
}
|
||
// force valid name if necessary
|
||
if (is_numeric($name)) {
|
||
$name = '__numeric_' . $name;
|
||
} elseif (! $name) {
|
||
$name = 'noname';
|
||
}
|
||
// if name has ns, add ns prefix to name
|
||
$xmlns = '';
|
||
if($name_ns){
|
||
$prefix = 'nu'.rand(1000,9999);
|
||
$name = $prefix.':'.$name;
|
||
$xmlns .= " xmlns:$prefix=\"$name_ns\"";
|
||
}
|
||
// if type is prefixed, create type prefix
|
||
if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
|
||
// need to fix this. shouldn't default to xsd if no ns specified
|
||
// w/o checking against typemap
|
||
$type_prefix = 'xsd';
|
||
} elseif($type_ns){
|
||
$type_prefix = 'ns'.rand(1000,9999);
|
||
$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
|
||
}
|
||
// serialize attributes if present
|
||
$atts = '';
|
||
if($attributes){
|
||
foreach($attributes as $k => $v){
|
||
$atts .= " $k=\"".$this->expandEntities($v).'"';
|
||
}
|
||
}
|
||
// serialize null value
|
||
if (is_null($val)) {
|
||
if ($use == 'literal') {
|
||
// TODO: depends on minOccurs
|
||
return "<$name$xmlns $atts/>";
|
||
} else {
|
||
if (isset($type) && isset($type_prefix)) {
|
||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||
} else {
|
||
$type_str = '';
|
||
}
|
||
return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
|
||
}
|
||
}
|
||
// serialize if an xsd built-in primitive type
|
||
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
|
||
if (is_bool($val)) {
|
||
if ($type == 'boolean') {
|
||
$val = $val ? 'true' : 'false';
|
||
} elseif (! $val) {
|
||
$val = 0;
|
||
}
|
||
} else if (is_string($val)) {
|
||
$val = $this->expandEntities($val);
|
||
}
|
||
if ($use == 'literal') {
|
||
return "<$name$xmlns $atts>$val</$name>";
|
||
} else {
|
||
return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
|
||
}
|
||
}
|
||
// detect type and serialize
|
||
$xml = '';
|
||
switch(true) {
|
||
case (is_bool($val) || $type == 'boolean'):
|
||
if ($type == 'boolean') {
|
||
$val = $val ? 'true' : 'false';
|
||
} elseif (! $val) {
|
||
$val = 0;
|
||
}
|
||
if ($use == 'literal') {
|
||
$xml .= "<$name$xmlns $atts>$val</$name>";
|
||
} else {
|
||
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
|
||
}
|
||
break;
|
||
case (is_int($val) || is_long($val) || $type == 'int'):
|
||
if ($use == 'literal') {
|
||
$xml .= "<$name$xmlns $atts>$val</$name>";
|
||
} else {
|
||
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
|
||
}
|
||
break;
|
||
case (is_float($val)|| is_double($val) || $type == 'float'):
|
||
if ($use == 'literal') {
|
||
$xml .= "<$name$xmlns $atts>$val</$name>";
|
||
} else {
|
||
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
|
||
}
|
||
break;
|
||
case (is_string($val) || $type == 'string'):
|
||
$val = $this->expandEntities($val);
|
||
if ($use == 'literal') {
|
||
$xml .= "<$name$xmlns $atts>$val</$name>";
|
||
} else {
|
||
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
|
||
}
|
||
break;
|
||
case is_object($val):
|
||
if (! $name) {
|
||
$name = get_class($val);
|
||
$this->debug("In serialize_val, used class name $name as element name");
|
||
} else {
|
||
$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
|
||
}
|
||
foreach(get_object_vars($val) as $k => $v){
|
||
$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
|
||
}
|
||
$xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
|
||
break;
|
||
break;
|
||
case (is_array($val) || $type):
|
||
// detect if struct or array
|
||
$valueType = $this->isArraySimpleOrStruct($val);
|
||
if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
|
||
$i = 0;
|
||
if(is_array($val) && count($val)> 0){
|
||
foreach($val as $v){
|
||
if(is_object($v) && get_class($v) == 'soapval'){
|
||
$tt_ns = $v->type_ns;
|
||
$tt = $v->type;
|
||
} elseif (is_array($v)) {
|
||
$tt = $this->isArraySimpleOrStruct($v);
|
||
} else {
|
||
$tt = gettype($v);
|
||
}
|
||
$array_types[$tt] = 1;
|
||
// TODO: for literal, the name should be $name
|
||
$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
|
||
++$i;
|
||
}
|
||
if(count($array_types) > 1){
|
||
$array_typename = 'xsd:anyType';
|
||
} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
|
||
if ($tt == 'integer') {
|
||
$tt = 'int';
|
||
}
|
||
$array_typename = 'xsd:'.$tt;
|
||
} elseif(isset($tt) && $tt == 'arraySimple'){
|
||
$array_typename = 'SOAP-ENC:Array';
|
||
} elseif(isset($tt) && $tt == 'arrayStruct'){
|
||
$array_typename = 'unnamed_struct_use_soapval';
|
||
} else {
|
||
// if type is prefixed, create type prefix
|
||
if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
|
||
$array_typename = 'xsd:' . $tt;
|
||
} elseif ($tt_ns) {
|
||
$tt_prefix = 'ns' . rand(1000, 9999);
|
||
$array_typename = "$tt_prefix:$tt";
|
||
$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
|
||
} else {
|
||
$array_typename = $tt;
|
||
}
|
||
}
|
||
$array_type = $i;
|
||
if ($use == 'literal') {
|
||
$type_str = '';
|
||
} else if (isset($type) && isset($type_prefix)) {
|
||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||
} else {
|
||
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
|
||
}
|
||
// empty array
|
||
} else {
|
||
if ($use == 'literal') {
|
||
$type_str = '';
|
||
} else if (isset($type) && isset($type_prefix)) {
|
||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||
} else {
|
||
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
|
||
}
|
||
}
|
||
// TODO: for array in literal, there is no wrapper here
|
||
$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
|
||
} else {
|
||
// got a struct
|
||
if(isset($type) && isset($type_prefix)){
|
||
$type_str = " xsi:type=\"$type_prefix:$type\"";
|
||
} else {
|
||
$type_str = '';
|
||
}
|
||
if ($use == 'literal') {
|
||
$xml .= "<$name$xmlns $atts>";
|
||
} else {
|
||
$xml .= "<$name$xmlns$type_str$atts>";
|
||
}
|
||
foreach($val as $k => $v){
|
||
// Apache Map
|
||
if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
|
||
$xml .= '<item>';
|
||
$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
|
||
$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
|
||
$xml .= '</item>';
|
||
} else {
|
||
$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
|
||
}
|
||
}
|
||
$xml .= "</$name>";
|
||
}
|
||
break;
|
||
default:
|
||
$xml .= 'not detected, got '.gettype($val).' for '.$val;
|
||
break;
|
||
}
|
||
return $xml;
|
||
}
|
||
/**
|
||
* serializes a message
|
||
*
|
||
* @param string $body the XML of the SOAP body
|
||
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
|
||
* @param array $namespaces optional the namespaces used in generating the body and headers
|
||
* @param string $style optional (rpc|document)
|
||
* @param string $use optional (encoded|literal)
|
||
* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
|
||
* @return string the message
|
||
* @access public
|
||
*/
|
||
function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
|
||
// TODO: add an option to automatically run utf8_encode on $body and $headers
|
||
// if $this->soap_defencoding is UTF-8. Not doing this automatically allows
|
||
// one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
|
||
$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
|
||
$this->debug("headers:");
|
||
$this->appendDebug($this->varDump($headers));
|
||
$this->debug("namespaces:");
|
||
$this->appendDebug($this->varDump($namespaces));
|
||
// serialize namespaces
|
||
$ns_string = '';
|
||
foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
|
||
$ns_string .= " xmlns:$k=\"$v\"";
|
||
}
|
||
if($encodingStyle) {
|
||
$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
|
||
}
|
||
// serialize headers
|
||
if($headers){
|
||
if (is_array($headers)) {
|
||
$xml = '';
|
||
foreach ($headers as $header) {
|
||
$xml .= $this->serialize_val($header, false, false, false, false, false, $use);
|
||
}
|
||
$headers = $xml;
|
||
$this->debug("In serializeEnvelope, serialzied array of headers to $headers");
|
||
}
|
||
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
|
||
}
|
||
// serialize envelope
|
||
return
|
||
'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
|
||
'<SOAP-ENV:Envelope'.$ns_string.">".
|
||
$headers.
|
||
"<SOAP-ENV:Body>".
|
||
$body.
|
||
"</SOAP-ENV:Body>".
|
||
"</SOAP-ENV:Envelope>";
|
||
}
|
||
/**
|
||
* formats a string to be inserted into an HTML stream
|
||
*
|
||
* @param string $str The string to format
|
||
* @return string The formatted string
|
||
* @access public
|
||
* @deprecated
|
||
*/
|
||
function formatDump($str){
|
||
$str = htmlspecialchars($str);
|
||
return nl2br($str);
|
||
}
|
||
/**
|
||
* contracts (changes namespace to prefix) a qualified name
|
||
*
|
||
* @param string $qname qname
|
||
* @return string contracted qname
|
||
* @access private
|
||
*/
|
||
function contractQname($qname){
|
||
// get element namespace
|
||
//$this->xdebug("Contract $qname");
|
||
if (strrpos($qname, ':')) {
|
||
// get unqualified name
|
||
$name = substr($qname, strrpos($qname, ':') + 1);
|
||
// get ns
|
||
$ns = substr($qname, 0, strrpos($qname, ':'));
|
||
$p = $this->getPrefixFromNamespace($ns);
|
||
if ($p) {
|
||
return $p . ':' . $name;
|
||
}
|
||
return $qname;
|
||
} else {
|
||
return $qname;
|
||
}
|
||
}
|
||
/**
|
||
* expands (changes prefix to namespace) a qualified name
|
||
*
|
||
* @param string $string qname
|
||
* @return string expanded qname
|
||
* @access private
|
||
*/
|
||
function expandQname($qname){
|
||
// get element prefix
|
||
if(strpos($qname,':') && !ereg('^http://',$qname)){
|
||
// get unqualified name
|
||
$name = substr(strstr($qname,':'),1);
|
||
// get ns prefix
|
||
$prefix = substr($qname,0,strpos($qname,':'));
|
||
if(isset($this->namespaces[$prefix])){
|
||
return $this->namespaces[$prefix].':'.$name;
|
||
} else {
|
||
return $qname;
|
||
}
|
||
} else {
|
||
return $qname;
|
||
}
|
||
}
|
||
/**
|
||
* returns the local part of a prefixed string
|
||
* returns the original string, if not prefixed
|
||
*
|
||
* @param string $str The prefixed string
|
||
* @return string The local part
|
||
* @access public
|
||
*/
|
||
function getLocalPart($str){
|
||
if($sstr = strrchr($str,':')){
|
||
// get unqualified name
|
||
return substr( $sstr, 1 );
|
||
} else {
|
||
return $str;
|
||
}
|
||
}
|
||
/**
|
||
* returns the prefix part of a prefixed string
|
||
* returns false, if not prefixed
|
||
*
|
||
* @param string $str The prefixed string
|
||
* @return mixed The prefix or false if there is no prefix
|
||
* @access public
|
||
*/
|
||
function getPrefix($str){
|
||
if($pos = strrpos($str,':')){
|
||
// get prefix
|
||
return substr($str,0,$pos);
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* pass it a prefix, it returns a namespace
|
||
*
|
||
* @param string $prefix The prefix
|
||
* @return mixed The namespace, false if no namespace has the specified prefix
|
||
* @access public
|
||
*/
|
||
function getNamespaceFromPrefix($prefix){
|
||
if (isset($this->namespaces[$prefix])) {
|
||
return $this->namespaces[$prefix];
|
||
}
|
||
//$this->setError("No namespace registered for prefix '$prefix'");
|
||
return false;
|
||
}
|
||
/**
|
||
* returns the prefix for a given namespace (or prefix)
|
||
* or false if no prefixes registered for the given namespace
|
||
*
|
||
* @param string $ns The namespace
|
||
* @return mixed The prefix, false if the namespace has no prefixes
|
||
* @access public
|
||
*/
|
||
function getPrefixFromNamespace($ns) {
|
||
foreach ($this->namespaces as $p => $n) {
|
||
if ($ns == $n || $ns == $p) {
|
||
$this->usedNamespaces[$p] = $n;
|
||
return $p;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* returns the time in ODBC canonical form with microseconds
|
||
*
|
||
* @return string The time in ODBC canonical form with microseconds
|
||
* @access public
|
||
*/
|
||
function getmicrotime() {
|
||
if (function_exists('gettimeofday')) {
|
||
$tod = gettimeofday();
|
||
$sec = $tod['sec'];
|
||
$usec = $tod['usec'];
|
||
} else {
|
||
$sec = time();
|
||
$usec = 0;
|
||
}
|
||
return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
|
||
}
|
||
/**
|
||
* Returns a string with the output of var_dump
|
||
*
|
||
* @param mixed $data The variable to var_dump
|
||
* @return string The output of var_dump
|
||
* @access public
|
||
*/
|
||
function varDump($data) {
|
||
ob_start();
|
||
var_dump($data);
|
||
$ret_val = ob_get_contents();
|
||
ob_end_clean();
|
||
return $ret_val;
|
||
}
|
||
}
|
||
// XML Schema Datatype Helper Functions
|
||
//xsd:dateTime helpers
|
||
/**
|
||
* convert unix timestamp to ISO 8601 compliant date string
|
||
*
|
||
* @param string $timestamp Unix time stamp
|
||
* @access public
|
||
*/
|
||
function timestamp_to_iso8601($timestamp,$utc=true){
|
||
$datestr = date('Y-m-d\TH:i:sO',$timestamp);
|
||
if($utc){
|
||
$eregStr =
|
||
'([0-9]{4})-'. // centuries & years CCYY-
|
||
'([0-9]{2})-'. // months MM-
|
||
'([0-9]{2})'. // days DD
|
||
'T'. // separator T
|
||
'([0-9]{2}):'. // hours hh:
|
||
'([0-9]{2}):'. // minutes mm:
|
||
'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
|
||
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
|
||
if(ereg($eregStr,$datestr,$regs)){
|
||
return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
|
||
}
|
||
return false;
|
||
} else {
|
||
return $datestr;
|
||
}
|
||
}
|
||
/**
|
||
* convert ISO 8601 compliant date string to unix timestamp
|
||
*
|
||
* @param string $datestr ISO 8601 compliant date string
|
||
* @access public
|
||
*/
|
||
function iso8601_to_timestamp($datestr){
|
||
$eregStr =
|
||
'([0-9]{4})-'. // centuries & years CCYY-
|
||
'([0-9]{2})-'. // months MM-
|
||
'([0-9]{2})'. // days DD
|
||
'T'. // separator T
|
||
'([0-9]{2}):'. // hours hh:
|
||
'([0-9]{2}):'. // minutes mm:
|
||
'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
|
||
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
|
||
if(ereg($eregStr,$datestr,$regs)){
|
||
// not utc
|
||
if($regs[8] != 'Z'){
|
||
$op = substr($regs[8],0,1);
|
||
$h = substr($regs[8],1,2);
|
||
$m = substr($regs[8],strlen($regs[8])-2,2);
|
||
if($op == '-'){
|
||
$regs[4] = $regs[4] + $h;
|
||
$regs[5] = $regs[5] + $m;
|
||
} elseif($op == '+'){
|
||
$regs[4] = $regs[4] - $h;
|
||
$regs[5] = $regs[5] - $m;
|
||
}
|
||
}
|
||
return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
/**
|
||
* sleeps some number of microseconds
|
||
*
|
||
* @param string $usec the number of microseconds to sleep
|
||
* @access public
|
||
* @deprecated
|
||
*/
|
||
function usleepWindows($usec)
|
||
{
|
||
$start = gettimeofday();
|
||
do
|
||
{
|
||
$stop = gettimeofday();
|
||
$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
|
||
+ $stop['usec'] - $start['usec'];
|
||
}
|
||
while ($timePassed < $usec);
|
||
}
|
||
/**
|
||
* Contains information for a SOAP fault.
|
||
* Mainly used for returning faults from deployed functions
|
||
* in a server instance.
|
||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||
* @version $Id$
|
||
* @access public
|
||
*/
|
||
class soap_fault extends nusoap_base {
|
||
/**
|
||
* The fault code (client|server)
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $faultcode;
|
||
/**
|
||
* The fault actor
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $faultactor;
|
||
/**
|
||
* The fault string, a description of the fault
|
||
* @var string
|
||
* @access private
|
||
*/
|
||
var $faultstring;
|
||
/**
|
||
* The fault detail, typically a string or array of string
|
||
* @var mixed
|
||
* @access private
|
||
*/
|
||
var $faultdetail;
|
||
/**
|
||
* constructor
|
||
*
|
||
* @param string $faultcode (client | server)
|
||
* @param string $faultactor only used when msg routed between multiple actors
|
||
* @param string $faultstring human readable error message
|
||
* @param mixed $faultdetail detail, typically a string or array of string
|
||
*/
|
||
function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
|
||
parent::nusoap_base();
|
||
$this->faultcode = $faultcode;
|
||
$this->faultactor = $faultactor;
|
||
$this->faultstring = $faultstring;
|
||
$this->faultdetail = $faultdetail;
|
||
}
|
||
/**
|
||
* serialize a fault
|
||
*
|
||
* @return string The serialization of the fault instance.
|
||
* @access public
|
||
*/
|
||
function serialize(){
|
||
$ns_string = '';
|
||
foreach($this->namespaces as $k => $v){
|
||
$ns_string .= "\n xmlns:$k=\"$v\"";
|
||
}
|
||
$return_msg =
|
||
'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
|
||
'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
|
||
'<SOAP-ENV:Body>'.
|
||
'<SOAP-ENV:Fault>'.
|
||
$this->serialize_val($this->faultcode, 'faultcode').
|
||
$this->serialize_val($this->faultactor, 'faultactor').
|
||
$this->serialize_val($this->faultstring, 'faultstring').
|
||
$this->serialize_val($this->faultdetail, 'detail').
|
||
'</SOAP-ENV:Fault>'.
|
||
'</SOAP-ENV:Body>'.
|
||
'</SOAP-ENV:Envelope>';
|
||
return $return_msg;
|
||
}
|
||
}
|
||
/**
|
||
* parses an XML Schema, allows access to it's data, other utility methods
|
||
* no validation... yet.
|
||
* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
|
||
* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
|
||
* tutorials I refer to :)
|
||
*
|
||
* @author Dietrich Ayala <dietrich@ganx4.com>
|
||
* @version $Id$
|
||
* @access public
|
||
*/
|
||
class XMLSchema extends nusoap_base {
|
||
// files
|
||
var $schema = '';
|
||
var $xml = '';
|
||
// namespaces
|
||
var $enclosingNamespaces;
|
||
// schema info
|
||
var $schemaInfo = array();
|
||
var $schemaTargetNamespace = '';
|
||
// types, elements, attributes defined by the schema
|
||
var $attributes = array();
|
||
var $complexTypes = array();
|
||
var $complexTypeStack = array();
|
||
var $currentComplexType = null;
|
||
var $elements = array();
|
||
var $elementStack = array();
|
||
var $currentElement = null;
|
||
var $simpleTypes = array();
|
||
var $simpleTypeStack = array();
|
||
var $currentSimpleType = null;
|
||
// imports
|
||
var $imports = array();
|
||
// parser vars
|
||
var $parser;
|
||
var $position = 0;
|
||
var $depth = 0;
|
||
var $depth_array = array();
|
||
var $message = array();
|
||
var $defaultNamespace = array();
|
||
/**
|
||
* constructor
|
||
*
|
||
* @param string $schema schema document URI
|
||
* @param string $xml xml document URI
|
||
* @param string $namespaces namespaces defined in enclosing XML
|
||
* @access public
|
||
*/
|
||
function XMLSchema($schema='',$xml='',$namespaces=array()){
|
||
parent::nusoap_base();
|
||
$this->debug('xmlschema class instantiated, inside constructor');
|
||
// files
|
||
$this->schema = $schema;
|
||
$this->xml = $xml;
|
||
// namespaces
|
||
$this->enclosingNamespaces = $namespaces;
|
||
$this->namespaces = array_merge($this->namespaces, $namespaces);
|
||
// parse schema file
|
||
if($schema != ''){
|
||
$this->debug('initial schema file: '.$schema);
|
||
$this->parseFile($schema, 'schema');
|
||
}
|
||
// parse xml file
|
||
if($xml != ''){
|
||
$this->debug('initial xml file: '.$xml);
|
||
$this->parseFile($xml, 'xml');
|
||
}
|
||
}
|
||
/**
|
||
* parse an XML file
|
||
*
|
||
* @param string $xml, path/URL to XML file
|
||
* @param string $type, (schema | xml)
|
||
* @return boolean
|
||
* @access public
|
||
*/
|
||
function parseFile($xml,$type){
|
||
// parse xml file
|
||
if($xml != ""){
|
||
$xmlStr = @join("",@file($xml));
|
||
if($xmlStr == ""){
|
||
$msg = 'Error reading XML from '.$xml;
|
||
$this->setError($msg);
|
||
$this->debug($msg);
|
||
return false;
|
||
} else {
|
||
$this->debug("parsing $xml");
|
||
$this->parseString($xmlStr,$type);
|
||
$this->debug("done parsing $xml");
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* parse an XML string
|
||
*
|
||
* @param string $xml path or URL
|
||
* @param string $type, (schema|xml)
|
||
* @access private
|
||
*/
|
||
function parseString($xml,$type){
|
||
// parse xml string
|
||
if($xml != ""){
|
||
// Create an XML parser.
|
||
$this->parser = xml_parser_create();
|
||
// Set the options for parsing the XML data.
|
||
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
|
||
// Set the object for the parser.
|
||
xml_set_object($this->parser, $this);
|
||
// Set the element handlers for the parser.
|
||
if($type == "schema"){
|
||
xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
|
||
xml_set_character_data_handler($this->parser,'schemaCharacterData');
|
||
} elseif($type == "xml"){
|
||
xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
|
||
xml_set_character_data_handler($this->parser,'xmlCharacterData');
|
||
}
|
||
// Parse the XML file.
|
||
if(!xml_parse($this->parser,$xml,true)){
|
||
// Display an error message.
|
||
$errstr = sprintf('XML error parsing XML schema on line %d: %s',
|
||
xml_get_current_line_number($this->parser),
|
||
xml_error_string(xml_get_error_code($this->parser))
|
||
);
|
||
$this->debug($errstr);
|
||
$this->debug("XML payload:\n" . $xml);
|
||
$this->setError($errstr);
|
||
}
|
||
xml_parser_free($this->parser);
|
||
} else{
|
||
$this->debug('no xml passed to parseString()!!');
|
||
$this->setError('no xml passed to parseString()!!');
|
||
}
|
||
}
|
||
/**
|
||
* start-element handler
|
||
*
|
||
* @param string $parser XML parser object
|
||
* @param string $name element name
|
||
* @param string $attrs associative array of attributes
|
||
* @access private
|
||
*/
|
||
function schemaStartElement($parser, $name, $attrs) {
|
||
// position in the total number of elements, starting from 0
|
||
$pos = $this->position++;
|
||
$depth = $this->depth++;
|
||
// set self as current value for this depth
|
||
$this->depth_array[$depth] = $pos;
|
||
$this->message[$pos] = array('cdata' => '');
|
||
if ($depth > 0) {
|
||
$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
|
||
} else {
|
||
$this->defaultNamespace[$pos] = false;
|
||
}
|
||
// get element prefix
|
||
if($prefix = $this->getPrefix($name)){
|
||
// get unqualified name
|
||
$name = $this->getLocalPart($name);
|
||
} else {
|
||
$prefix = '';
|
||
}
|
||
// loop thru attributes, expanding, and registering namespace declarations
|
||
if(count($attrs) > 0){
|
||
foreach($attrs as $k => $v){
|
||
// if ns declarations, add to class level array of valid namespaces
|
||
if(ereg("^xmlns",$k)){
|
||
//$this->xdebug("$k: $v");
|
||
//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
|
||
if($ns_prefix = substr(strrchr($k,':'),1)){
|
||
//$this->xdebug("Add namespace[$ns_prefix] = $v");
|
||
$this->namespaces[$ns_prefix] = $v;
|
||
} else {
|
||
$this->defaultNamespace[$pos] = $v;
|
||
if (! $this->getPrefixFromNamespace($v)) {
|
||
$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
|
||
}
|
||
}
|
||
if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
|
||
$this->XMLSchemaVersion = $v;
|
||
$this->namespaces['xsi'] = $v.'-instance';
|
||
}
|
||
}
|
||
}
|
||
foreach($attrs as $k => $v){
|
||
// expand each attribute
|
||
$k = strpos($k,':') ? $this->expandQname($k) : $k;
|
||
$v = strpos($v,':') ? $this->expandQname($v) : $v;
|
||
$eAttrs[$k] = $v;
|
||
}
|
||
$attrs = $eAttrs;
|
||
} else {
|
||
$attrs = array();
|
||
}
|
||
// find status, register data
|
||
switch($name){
|
||
case 'all': // (optional) compositor content for a complexType
|
||
case 'choice':
|
||
case 'group':
|
||
case 'sequence':
|
||
//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
|
||
$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
|
||
//if($name == 'all' || $name == 'sequence'){
|
||
// $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
|
||
//}
|
||
break;
|
||
case 'attribute': // complexType attribute
|
||
//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
|
||
$this->xdebug("parsing attribute:");
|
||
$this->appendDebug($this->varDump($attrs));
|
||
if (!isset($attrs['form'])) {
|
||
$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
|
||
}
|
||
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
|
||
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||
if (!strpos($v, ':')) {
|
||
// no namespace in arrayType attribute value...
|
||
if ($this->defaultNamespace[$pos]) {
|
||
// ...so use the default
|
||
$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||
}
|
||
}
|
||
}
|
||
if(isset($attrs['name'])){
|
||
$this->attributes[$attrs['name']] = $attrs;
|
||
$aname = $attrs['name'];
|
||
} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
|
||
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
|
||
$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
|
||
} else {
|
||
$aname = '';
|
||
}
|
||
} elseif(isset($attrs['ref'])){
|
||
$aname = $attrs['ref'];
|