[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Phpgroupware-cvs] [18966] generate new soap classes based on current nu
From: |
Dave Hall |
Subject: |
[Phpgroupware-cvs] [18966] generate new soap classes based on current nusoap cvs head checkout and update generator |
Date: |
Tue, 07 Oct 2008 10:31:49 +0000 |
Revision: 18966
http://svn.sv.gnu.org/viewvc/?view=rev&root=phpgroupware&revision=18966
Author: skwashd
Date: 2008-10-07 10:31:48 +0000 (Tue, 07 Oct 2008)
Log Message:
-----------
generate new soap classes based on current nusoap cvs head checkout and update
generator
Modified Paths:
--------------
core/trunk/phpgwapi/doc/soap/nusoap2phpgwapi
core/trunk/phpgwapi/inc/class.nusoap_base.inc.php
core/trunk/phpgwapi/inc/class.phpgw_soapval.inc.php
core/trunk/phpgwapi/inc/class.soap_XMLSchema.inc.php
core/trunk/phpgwapi/inc/class.soap_client.inc.php
core/trunk/phpgwapi/inc/class.soap_fault.inc.php
core/trunk/phpgwapi/inc/class.soap_parser.inc.php
core/trunk/phpgwapi/inc/class.soap_server.inc.php
core/trunk/phpgwapi/inc/class.soap_transport_http.inc.php
core/trunk/phpgwapi/inc/class.soapval.inc.php
core/trunk/phpgwapi/inc/class.wsdl.inc.php
Added Paths:
-----------
core/trunk/phpgwapi/inc/class.nusoap_client.inc.php
Modified: core/trunk/phpgwapi/doc/soap/nusoap2phpgwapi
===================================================================
--- core/trunk/phpgwapi/doc/soap/nusoap2phpgwapi 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/doc/soap/nusoap2phpgwapi 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -9,18 +9,46 @@
exit;
}
-/* The header that we put into each file (btw, that the header for this file
too !!)*/
-$header = "\t/**\n".
- "\t* This file is generated automaticaly from the nusoap library for\n".
- "\t* phpGroupWare, using the nusoap2phpgwapi.php script written for
this purpose by \n".
- "\t* Caeies (address@hidden)\n".
- "\t* @copyright Portions Copyright (C) 2003,2006 Free Software
Foundation, Inc. http://www.fsf.org/\n".
- "\t* @package phpgwapi\n".
- "\t* @subpackage communication\n".
- "\t* Please see original header after this one and
class.nusoap_base.inc.php\n".
- "\t* @version \$Id$\n".
- "\t*/\n\n";
+ /* The header that we put into each file (btw, that the header for this file
too !!)*/
+$header = <<<TXT
+<?php
+ /**
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version \$Id:\$
+ */
+ /*
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+TXT;
+
+$header_count = 32;
+
print "Processing ".$argv[1]."\n";
/* split the tags in the file
@@ -30,37 +58,35 @@
/* system("sed -e 's/?><?php/?>\\n<?php/g' -e 's/class soapval/class
new_soapval/g' -e 's/function soapval/function new_soapval/g' $argv[1] >
./$argv[1].tmp"); */
$f = file_get_contents($argv[1]);
$f = preg_replace('/\?><\?php/', "?>\n<?php", $f);
-$fd = fopen("./$argv[1].tmp","w+");
-fwrite($fd,$f);
-fclose($fd);
+file_put_contents("{$argv[1]}.tmp", $f);
$g = file($argv[0]);
-$l = '';
-$l1 = '';
-$b = False;
+$write = False;
$fd;
-foreach( $g as $line ) {
- if ( ! $b ) {
- $l1 = $l;
- $l = $line;
- } else {
- fwrite($fd,$line);
+foreach( $g as $line )
+{
+ if ( $write )
+ {
+ fwrite($fd, $line);
}
- if ( ereg(strtoupper('soap_client'),$line) ) {
- $b = True;
- $fd = fopen("./$argv[1].tmp","a+");
- fwrite($fd,$l1);
+
+ if ( preg_match('/\/\/ SOAP_CLIENT \\\\/', $line) )
+ {
+ $write = true;
+ $fd = fopen("{$argv[1]}.tmp", 'a+');
+ continue;
}
}
fclose($fd);
-system("sync");
-$f = file($argv[1].".tmp");
+system('sync');
+$f = file("{$argv[1]}.tmp");
unlink($argv[1].".tmp");
$i = 0;
$j = 3;
$a = array();
$current_class ='_not_me_';
-foreach( $f as $line ) {
+foreach( $f as $line )
+{
/* Change the XMLSchema to soap_XMLSchema to avoid collisions */
$line = ereg_replace('XMLSchema |xmlschema ','soap_XMLSchema ',$line);
// $line = ereg_replace('xmlschema[^[:alpha:]]','soap_XMLSchema',$line);
@@ -71,10 +97,14 @@
echo "current class : $current_class\n";
if ( ereg('extends',$line) ) {
trim($tmp[3]);
- $a[$i][2] = "/* Please see class.base_nusoap.inc.php
for more information */\n\n".
- "if
(@!".'$GLOBALS'."['phpgw_info']['flags']['included_classes']['$tmp[3]'])\n".
- "{\n\trequire_once(PHPGW_API_INC.\"/class.$tmp[3].inc.php\");\n\t".
- '$GLOBALS'."['phpgw_info']['flags']['included_classes']['$tmp[3]'] =
True;\n}\n";
+ $a[$i][2] = <<<CODE
+
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.{$tmp[3]}');
+
+CODE;
$line = ereg_replace($tmp[3], "phpgwapi_$tmp[3]", $line);
} else {
$a[$i][2] = "/*\n".
@@ -112,12 +142,16 @@
}
else
{
- print "\n".'WARNING !! : Please take a
look at the \'new\' near line '.($j + 15)."\n";
+ $offset = ($j + $header_lcount);
+ print "\n WARNING !! : Please take a
look at the 'new' near line {$offset} in {$tmp[1]}\n";
}
}
- } else {
+ }
+ else
+ {
/* This is more tricky if the new is inside an eval ..
*/
- print "\n".'WARNING !! : Please take a look at the
\'new\' near line '.($j + 15 )."\n";
+ $offset = ($j + $header_lcount);
+ print "\n WARNING !! : Please take a look at the 'new'
near line {$offset} in {$tmp[1]}\n";
/* This is commented because eval is dangerous
see the soapclient class */
// $line = ereg_replace('\(','\\",',$line);
@@ -139,27 +173,42 @@
}
if ( ereg('^\?>',$line) ) {
$j = 3;
- $i++;
+ ++$i;
}
}
/* Write the final files */
-$k = 0;
-foreach($a as $tab) {
- $fd = fopen($tab[0],"w+");
- for($k = 1; isset($tab[$k]); $k++ )
+foreach($a as $tab)
+{
+ /*
+ This is a bit of a nasty hack
+ The filename comes in as the first element of the array
+ We grab that and store it, then replace it with the standard header
+ It works - but maybe we should reconsider this - skwashd aug08
+ */
+ if (!$tab[0] ) // ignore invalid files
{
- fwrite($fd,$tab[$k]);
- if ( $k == 1 )
- {
- fwrite($fd,$header);
- }
+ continue;
}
- fclose($fd);
+
+ $filename = $tab[0];
+ $tab[0] = $header;
+ unset($tab[1]);
+
+ // now lets get the elements in the right order
+ ksort($tab);
+
+ echo "writing {$filename}: ";
+ file_put_contents($filename, $tab);
+
+ system('sync');
+ echo "done\n";
+
+ $ret = 0;
/* Check if the syntax is ok */
- if ( system("php -l $tab[0]") != 0 )
+ if ( system("php -l $filename", $ret) && $ret != 0 )
{
- print "I miss the $tab[0] file !\n";
+ echo "ERROR in {$filename}!\n\n\n";
}
}
@@ -181,10 +230,10 @@
}
?>
<?php
-/* SOAP_CLIENT */
-/***************************************************************************
-* TOTALY DEPRECATED , DON'T USE
-*/
+// SOAP_CLIENT \\
+ /*
+ * TOTALY DEPRECATED , DON'T USE
+ */
/**
* SOAPx4 client
* @author Edd Dumbill <address@hidden>
Modified: core/trunk/phpgwapi/inc/class.nusoap_base.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.nusoap_base.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.nusoap_base.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,15 +1,36 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
+ /*
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
/*
* @internal : This is an internal class which is used as the base for the Soap
Api
* @access : private
@@ -17,25 +38,31 @@
/*
-$ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+$ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
Copyright (c) 2002 NuSphere Corporation
-This program 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 3 of the License, or
-(at your option) any later version.
+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 program is distributed in the hope that it will be useful,
+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 General Public License for more details.
+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 program. If not, see <http://www.gnu.org/licenses/>.
+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
+The NuSOAP project home is:
+http://sourceforge.net/projects/nusoap/
+
+The primary support for NuSOAP is the Help forum on the project home page.
+
If you have any questions or comments, please email:
Dietrich Ayala
@@ -47,6 +74,20 @@
*/
+/*
+ * Some of the standards implmented in whole or part by NuSOAP:
+ *
+ * SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
+ * WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
+ * SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
+ * XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
+ * Namespaces in XML 1.0
(http://www.w3.org/TR/2006/REC-xml-names-20060816/)
+ * XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
+ * RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format
of Internet Message Bodies
+ * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
+ * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
+ */
+
/* load classes
// necessary classes
@@ -67,14 +108,15 @@
// class variable emulation
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
-$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
+$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
/**
*
* nusoap_base
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
class phpgwapi_nusoap_base {
@@ -91,7 +133,7 @@
* @var string
* @access private
*/
- var $version = '0.7.2';
+ var $version = '1.0rc1';
/**
* CVS revision for HTTP headers.
*
@@ -172,7 +214,7 @@
/**
* XML Schema types in an array of uri => (array of xml type => php type)
* is this legacy yet?
- * no, this is used by the soap_XMLSchema class to verify type =>
namespace mappings.
+ * no, this is used by the nusoap_soap_XMLSchema class to verify type =>
namespace mappings.
* @var array
* @access public
*/
@@ -218,7 +260,7 @@
* @access public
*/
function phpgwapi_nusoap_base() {
- $this->debugLevel =
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+ $this->debugLevel =
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
@@ -228,7 +270,7 @@
* @access public
*/
function getGlobalDebugLevel() {
- return
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+ return
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
@@ -238,7 +280,7 @@
* @access public
*/
function setGlobalDebugLevel($level) {
-
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
+
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
}
/**
@@ -323,7 +365,8 @@
while (strpos($this->debug_str, '--')) {
$this->debug_str = str_replace('--', '- -',
$this->debug_str);
}
- return "<!--\n" . $this->debug_str . "\n-->";
+ $ret = "<!--\n" . $this->debug_str . "\n-->";
+ return $ret;
}
/**
@@ -394,16 +437,22 @@
* @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)
+ * @param boolean $soapval Whether this is called from
soapval.
* @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");
+ function
serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false)
{
+ $this->debug("in serialize_val: name=$name, type=$type,
name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
$this->appendDebug('value=' . $this->varDump($val));
$this->appendDebug('attributes=' . $this->varDump($attributes));
- if(is_object($val) && get_class($val) == 'soapval'){
- return $val->serialize($use);
+ if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
+ $this->debug("serialize_val: serialize soapval");
+ $xml = $val->serialize($use);
+ $this->appendDebug($val->getDebug());
+ $val->clearDebug();
+ $this->debug("serialize_val of soapval returning $xml");
+ return $xml;
}
// force valid name if necessary
if (is_numeric($name)) {
@@ -436,20 +485,26 @@
}
// serialize null value
if (is_null($val)) {
+ $this->debug("serialize_val: serialize null");
if ($use == 'literal') {
// TODO: depends on minOccurs
- return "<$name$xmlns $atts/>";
+ $xml = "<$name$xmlns$atts/>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
} 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\"/>";
+ $xml = "<$name$xmlns$type_str$atts
xsi:nil=\"true\"/>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
}
}
// serialize if an xsd built-in primitive type
if($type != '' &&
isset($this->typemap[$this->XMLSchemaVersion][$type])){
+ $this->debug("serialize_val: serialize xsd built-in primitive
type");
if (is_bool($val)) {
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
@@ -460,65 +515,91 @@
$val = $this->expandEntities($val);
}
if ($use == 'literal') {
- return "<$name$xmlns $atts>$val</$name>";
+ $xml = "<$name$xmlns$atts>$val</$name>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
} else {
- return "<$name$xmlns $atts
xsi:type=\"xsd:$type\">$val</$name>";
+ $xml = "<$name$xmlns
xsi:type=\"xsd:$type\"$atts>$val</$name>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
}
}
// detect type and serialize
$xml = '';
switch(true) {
case (is_bool($val) || $type == 'boolean'):
+ $this->debug("serialize_val: serialize
boolean");
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif (! $val) {
$val = 0;
}
if ($use == 'literal') {
- $xml .= "<$name$xmlns
$atts>$val</$name>";
+ $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'):
+ $this->debug("serialize_val: serialize int");
if ($use == 'literal') {
- $xml .= "<$name$xmlns
$atts>$val</$name>";
+ $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'):
+ $this->debug("serialize_val: serialize float");
if ($use == 'literal') {
- $xml .= "<$name$xmlns
$atts>$val</$name>";
+ $xml .=
"<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns
xsi:type=\"xsd:float\"$atts>$val</$name>";
}
break;
case (is_string($val) || $type == 'string'):
+ $this->debug("serialize_val: serialize string");
$val = $this->expandEntities($val);
if ($use == 'literal') {
- $xml .= "<$name$xmlns
$atts>$val</$name>";
+ $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");
+ $this->debug("serialize_val: serialize object");
+ if (get_class($val) == 'soapval') {
+ $this->debug("serialize_val: serialize soapval
object");
+ $pXml = $val->serialize($use);
+ $this->appendDebug($val->getDebug());
+ $val->clearDebug();
+ } else {
+ 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);
+ }
+ }
+ if(isset($type) && isset($type_prefix)){
+ $type_str = "
xsi:type=\"$type_prefix:$type\"";
} else {
- $this->debug("In serialize_val, do not
override name $name for element name for class " . get_class($val));
+ $type_str = '';
}
- 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);
+ if ($use == 'literal') {
+ $xml .=
"<$name$xmlns$atts>$pXml</$name>";
+ } else {
+ $xml .=
"<$name$xmlns$type_str$atts>$pXml</$name>";
}
- $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)){
+ $this->debug("serialize_val: serialize
array");
$i = 0;
if(is_array($val) && count($val)> 0){
foreach($val as $v){
@@ -580,13 +661,14 @@
$xml =
"<$name$xmlns$type_str$atts>".$xml."</$name>";
} else {
// got a struct
+ $this->debug("serialize_val: serialize
struct");
if(isset($type) && isset($type_prefix)){
$type_str = "
xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>";
+ $xml .= "<$name$xmlns$atts>";
} else {
$xml .=
"<$name$xmlns$type_str$atts>";
}
@@ -605,9 +687,11 @@
}
break;
default:
+ $this->debug("serialize_val: serialize
unknown");
$xml .= 'not detected, got '.gettype($val).'
for '.$val;
break;
}
+ $this->debug("serialize_val returning $xml");
return $xml;
}
@@ -615,7 +699,7 @@
* 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 mixed $headers optional string of XML with SOAP header content,
or array of soapval objects for SOAP headers, or associative array
* @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)
@@ -647,11 +731,15 @@
if($headers){
if (is_array($headers)) {
$xml = '';
- foreach ($headers as $header) {
- $xml .= $this->serialize_val($header, false,
false, false, false, false, $use);
+ foreach ($headers as $k => $v) {
+ if (is_object($v) && get_class($v) ==
'soapval') {
+ $xml .= $this->serialize_val($v, false,
false, false, false, false, $use);
+ } else {
+ $xml .= $this->serialize_val($v, $k,
false, false, false, false, $use);
+ }
}
$headers = $xml;
- $this->debug("In serializeEnvelope, serialzied array of
headers to $headers");
+ $this->debug("In serializeEnvelope, serialized array of
headers to $headers");
}
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
}
@@ -707,7 +795,7 @@
/**
* expands (changes prefix to namespace) a qualified name
*
- * @param string $string qname
+ * @param string $qname qname
* @return string expanded qname
* @access private
*/
@@ -826,6 +914,16 @@
ob_end_clean();
return $ret_val;
}
+
+ /**
+ * represents the object as a string
+ *
+ * @return string
+ * @access public
+ */
+ function __toString() {
+ return $this->varDump($this);
+ }
}
// XML Schema Datatype Helper Functions
@@ -835,11 +933,22 @@
/**
* convert unix timestamp to ISO 8601 compliant date string
*
-* @param string $timestamp Unix time stamp
+* @param int $timestamp Unix time stamp
+* @param boolean $utc Whether the time stamp is UTC or local
+* @return mixed ISO 8601 date string or false
* @access public
*/
function timestamp_to_iso8601($timestamp,$utc=true){
$datestr = date('Y-m-d\TH:i:sO',$timestamp);
+ $pos = strrpos($datestr, "+");
+ if ($pos === FALSE) {
+ $pos = strrpos($datestr, "-");
+ }
+ if ($pos !== FALSE) {
+ if (strlen($datestr) == $pos + 5) {
+ $datestr = substr($datestr, 0, $pos + 3) . ':' .
substr($datestr, -2);
+ }
+ }
if($utc){
$eregStr =
'([0-9]{4})-'. // centuries & years CCYY-
@@ -864,6 +973,7 @@
* convert ISO 8601 compliant date string to unix timestamp
*
* @param string $datestr ISO 8601 compliant date string
+* @return mixed Unix timestamp (int) or false
* @access public
*/
function iso8601_to_timestamp($datestr){
@@ -890,7 +1000,8 @@
$regs[5] = $regs[5] - $m;
}
}
- return strtotime("$regs[1]-$regs[2]-$regs[3]
$regs[4]:$regs[5]:$regs[6]Z");
+ return gmmktime($regs[4], $regs[5], $regs[6], $regs[2],
$regs[3], $regs[1]);
+// return strtotime("$regs[1]-$regs[2]-$regs[3]
$regs[4]:$regs[5]:$regs[6]Z");
} else {
return false;
}
Added: core/trunk/phpgwapi/inc/class.nusoap_client.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.nusoap_client.inc.php
(rev 0)
+++ core/trunk/phpgwapi/inc/class.nusoap_client.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -0,0 +1,1027 @@
+<?php
+ /**
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
+
+ /*
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_base');
+
+
+
+/**
+*
+* [nu]soapclient higher level class for easy usage.
+*
+* usage:
+*
+* // instantiate client with server info
+* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
+*
+* // call method, get results
+* echo $soapclient->call( string methodname [ ,array parameters] );
+*
+* // bye bye client
+* unset($soapclient);
+*
+* @author Dietrich Ayala <address@hidden>
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
+* @access public
+*/
+class phpgwapi_nusoap_client extends phpgwapi_nusoap_base {
+
+ var $username = ''; // Username for HTTP
authentication
+ var $password = ''; // Password for HTTP
authentication
+ var $authtype = ''; // Type of HTTP
authentication
+ var $certRequest = array(); // Certificate for HTTP SSL
authentication
+ var $requestHeaders = false; // SOAP headers in request (text)
+ var $responseHeaders = ''; // SOAP headers from response
(incomplete namespace resolution) (text)
+ var $responseHeader = NULL; // SOAP Header from response
(parsed)
+ var $document = ''; // SOAP body response
portion (incomplete namespace resolution) (text)
+ var $endpoint;
+ var $forceEndpoint = ''; // overrides WSDL endpoint
+ var $proxyhost = '';
+ var $proxyport = '';
+ var $proxyusername = '';
+ var $proxypassword = '';
+ var $portName = ''; // port name to use in
WSDL
+ var $xml_encoding = ''; // character set encoding of
incoming (response) messages
+ var $http_encoding = false;
+ var $timeout = 0; // HTTP connection
timeout
+ var $response_timeout = 30; // HTTP response timeout
+ var $endpointType = ''; // soap|wsdl, empty for WSDL
initialization error
+ var $persistentConnection = false;
+ var $defaultRpcParams = false; // This is no longer used
+ var $request = ''; // HTTP request
+ var $response = ''; // HTTP response
+ var $responseData = ''; // SOAP payload of response
+ var $cookies = array(); // Cookies from response or for
request
+ var $decode_utf8 = true; // toggles whether the parser decodes
element content w/ utf8_decode()
+ var $operations = array(); // WSDL operations, empty for
WSDL initialization error
+ var $curl_options = array(); // User-specified cURL options
+ var $bindingType = ''; // WSDL operation binding type
+ var $use_curl = false; // whether to always try to use
cURL
+
+ /*
+ * fault related variables
+ */
+ /**
+ * @var fault
+ * @access public
+ */
+ var $fault;
+ /**
+ * @var faultcode
+ * @access public
+ */
+ var $faultcode;
+ /**
+ * @var faultstring
+ * @access public
+ */
+ var $faultstring;
+ /**
+ * @var faultdetail
+ * @access public
+ */
+ var $faultdetail;
+
+ /**
+ * constructor
+ *
+ * @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl
instance (object)
+ * @param mixed $wsdl optional, set to 'wsdl' or true if using WSDL
+ * @param string $proxyhost optional
+ * @param string $proxyport optional
+ * @param string $proxyusername optional
+ * @param string $proxypassword optional
+ * @param integer $timeout set the connection timeout
+ * @param integer $response_timeout set the response timeout
+ * @param string $portName optional portName in WSDL document
+ * @access public
+ */
+ function phpgwapi_nusoap_client($endpoint,$wsdl = false,$proxyhost =
false,$proxyport = false,$proxyusername = false, $proxypassword = false,
$timeout = 0, $response_timeout = 30, $portName = ''){
+ parent::phpgwapi_nusoap_base();
+ $this->endpoint = $endpoint;
+ $this->proxyhost = $proxyhost;
+ $this->proxyport = $proxyport;
+ $this->proxyusername = $proxyusername;
+ $this->proxypassword = $proxypassword;
+ $this->timeout = $timeout;
+ $this->response_timeout = $response_timeout;
+ $this->portName = $portName;
+
+ $this->debug("ctor wsdl=$wsdl timeout=$timeout
response_timeout=$response_timeout");
+ $this->appendDebug('endpoint=' . $this->varDump($endpoint));
+
+ // make values
+ if($wsdl){
+ if (is_object($endpoint) && (get_class($endpoint) ==
'wsdl')) {
+ $this->wsdl = $endpoint;
+ $this->endpoint = $this->wsdl->wsdl;
+ $this->wsdlFile = $this->endpoint;
+ $this->debug('existing wsdl instance created
from ' . $this->endpoint);
+ $this->checkWSDL();
+ } else {
+ $this->wsdlFile = $this->endpoint;
+ $this->wsdl = null;
+ $this->debug('will use lazy evaluation of wsdl
from ' . $this->endpoint);
+ }
+ $this->endpointType = 'wsdl';
+ } else {
+ $this->debug("instantiate SOAP with endpoint at
$endpoint");
+ $this->endpointType = 'soap';
+ }
+ }
+
+ /**
+ * calls method, returns PHP native type
+ *
+ * @param string $operation SOAP server URL or path
+ * @param mixed $params An array, associative or simple, of the
parameters
+ * for the method call, or a string
that is the XML
+ * for the call. For rpc style,
this call will
+ * wrap the XML in a tag named after
the method, as
+ * well as the SOAP Envelope and
Body. For document
+ * style, this will only wrap with
the Envelope and Body.
+ * IMPORTANT: when using an array
with document style,
+ * in which case there
+ * is really one parameter, the root of the
fragment
+ * used in the call, which encloses what
programmers
+ * normally think of parameters. A parameter
array
+ * *must* include the wrapper.
+ * @param string $namespace optional method namespace (WSDL can
override)
+ * @param string $soapAction optional SOAPAction value (WSDL can
override)
+ * @param mixed $headers optional string of XML with SOAP header
content, or array of soapval objects for SOAP headers, or associative array
+ * @param boolean $rpcParams optional (no longer used)
+ * @param string $style optional (rpc|document) the style to use
when serializing parameters (WSDL can override)
+ * @param string $use optional (encoded|literal) the use when
serializing parameters (WSDL can override)
+ * @return mixed response from SOAP call
+ * @access public
+ */
+ function
call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
+ $this->operation = $operation;
+ $this->fault = false;
+ $this->setError('');
+ $this->request = '';
+ $this->response = '';
+ $this->responseData = '';
+ $this->faultstring = '';
+ $this->faultcode = '';
+ $this->opData = array();
+
+ $this->debug("call: operation=$operation, namespace=$namespace,
soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use,
endpointType=$this->endpointType");
+ $this->appendDebug('params=' . $this->varDump($params));
+ $this->appendDebug('headers=' . $this->varDump($headers));
+ if ($headers) {
+ $this->requestHeaders = $headers;
+ }
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError())
+ return false;
+ }
+ // serialize parameters
+ if($this->endpointType == 'wsdl' && $opData =
$this->getOperationData($operation)){
+ // use WSDL for operation
+ $this->opData = $opData;
+ $this->debug("found operation");
+ $this->appendDebug('opData=' . $this->varDump($opData));
+ if (isset($opData['soapAction'])) {
+ $soapAction = $opData['soapAction'];
+ }
+ if (! $this->forceEndpoint) {
+ $this->endpoint = $opData['endpoint'];
+ } else {
+ $this->endpoint = $this->forceEndpoint;
+ }
+ $namespace = isset($opData['input']['namespace']) ?
$opData['input']['namespace'] : $namespace;
+ $style = $opData['style'];
+ $use = $opData['input']['use'];
+ // add ns to ns array
+ if($namespace != '' &&
!isset($this->wsdl->namespaces[$namespace])){
+ $nsPrefix = 'ns' . rand(1000, 9999);
+ $this->wsdl->namespaces[$nsPrefix] = $namespace;
+ }
+ $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
+ // serialize payload
+ if (is_string($params)) {
+ $this->debug("serializing param string for WSDL
operation $operation");
+ $payload = $params;
+ } elseif (is_array($params)) {
+ $this->debug("serializing param array for WSDL
operation $operation");
+ $payload =
$this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
+ } else {
+ $this->debug('params must be array or string');
+ $this->setError('params must be array or
string');
+ return false;
+ }
+ $usedNamespaces = $this->wsdl->usedNamespaces;
+ if (isset($opData['input']['encodingStyle'])) {
+ $encodingStyle =
$opData['input']['encodingStyle'];
+ } else {
+ $encodingStyle = '';
+ }
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ if ($errstr = $this->wsdl->getError()) {
+ $this->debug('got wsdl error: '.$errstr);
+ $this->setError('wsdl error: '.$errstr);
+ return false;
+ }
+ } elseif($this->endpointType == 'wsdl') {
+ // operation not in WSDL
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->setError( 'operation '.$operation.' not
present.');
+ $this->debug("operation '$operation' not present.");
+ return false;
+ } else {
+ // no WSDL
+ //$this->namespaces['ns1'] = $namespace;
+ $nsPrefix = 'ns' . rand(1000, 9999);
+ // serialize
+ $payload = '';
+ if (is_string($params)) {
+ $this->debug("serializing param string for
operation $operation");
+ $payload = $params;
+ } elseif (is_array($params)) {
+ $this->debug("serializing param array for
operation $operation");
+ foreach($params as $k => $v){
+ $payload .=
$this->serialize_val($v,$k,false,false,false,false,$use);
+ }
+ } else {
+ $this->debug('params must be array or string');
+ $this->setError('params must be array or
string');
+ return false;
+ }
+ $usedNamespaces = array();
+ if ($use == 'encoded') {
+ $encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
+ } else {
+ $encodingStyle = '';
+ }
+ }
+ // wrap RPC calls with method element
+ if ($style == 'rpc') {
+ if ($use == 'literal') {
+ $this->debug("wrapping RPC request with literal
method element");
+ if ($namespace) {
+ //
http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says
rpc/literal accessor elements should not be in a namespace
+ $payload = "<$nsPrefix:$operation
xmlns:$nsPrefix=\"$namespace\">" .
+ $payload .
+
"</$nsPrefix:$operation>";
+ } else {
+ $payload = "<$operation>" . $payload .
"</$operation>";
+ }
+ } else {
+ $this->debug("wrapping RPC request with encoded
method element");
+ if ($namespace) {
+ $payload = "<$nsPrefix:$operation
xmlns:$nsPrefix=\"$namespace\">" .
+ $payload .
+
"</$nsPrefix:$operation>";
+ } else {
+ $payload = "<$operation>" .
+ $payload .
+ "</$operation>";
+ }
+ }
+ }
+ // serialize envelope
+ $soapmsg =
$this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
+ $this->debug("endpoint=$this->endpoint, soapAction=$soapAction,
namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
+ $this->debug('SOAP message length=' . strlen($soapmsg) . '
contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
+ // send
+ $return =
$this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
+ if($errstr = $this->getError()){
+ $this->debug('Error: '.$errstr);
+ return false;
+ } else {
+ $this->return = $return;
+ $this->debug('sent message successfully and got a(n)
'.gettype($return));
+ $this->appendDebug('return=' . $this->varDump($return));
+
+ // fault?
+ if(is_array($return) && isset($return['faultcode'])){
+ $this->debug('got fault');
+ $this->setError($return['faultcode'].':
'.$return['faultstring']);
+ $this->fault = true;
+ foreach($return as $k => $v){
+ $this->$k = $v;
+ $this->debug("$k = $v<br>");
+ }
+ return $return;
+ } elseif ($style == 'document') {
+ // NOTE: if the response is defined to have
multiple parts (i.e. unwrapped),
+ // we are only going to return the first part
here...sorry about that
+ return $return;
+ } else {
+ // array of return values
+ if(is_array($return)){
+ // multiple 'out' parameters, which we
return wrapped up
+ // in the array
+ if(sizeof($return) > 1){
+ return $return;
+ }
+ // single 'out' parameter (normally the
return value)
+ $return = array_shift($return);
+ $this->debug('return shifted value: ');
+
$this->appendDebug($this->varDump($return));
+ return $return;
+ // nothing returned (ie, echoVoid)
+ } else {
+ return "";
+ }
+ }
+ }
+ }
+
+ /**
+ * check WSDL passed as an instance or pulled from an endpoint
+ *
+ * @access private
+ */
+ function checkWSDL() {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->debug('checkWSDL');
+ // catch errors
+ if ($errstr = $this->wsdl->getError()) {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->debug('got wsdl error: '.$errstr);
+ $this->setError('wsdl error: '.$errstr);
+ } elseif ($this->operations =
$this->wsdl->getOperations($this->portName, 'soap')) {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->bindingType = 'soap';
+ $this->debug('got '.count($this->operations).'
operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
+ } elseif ($this->operations =
$this->wsdl->getOperations($this->portName, 'soap12')) {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->bindingType = 'soap12';
+ $this->debug('got '.count($this->operations).'
operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
+ $this->debug('**************** WARNING: SOAP 1.2
BINDING *****************');
+ } else {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->debug('getOperations returned false');
+ $this->setError('no operations defined in the WSDL
document!');
+ }
+ }
+
+ /**
+ * instantiate wsdl object and parse wsdl file
+ *
+ * @access public
+ */
+ function loadWSDL() {
+ $this->debug('instantiating wsdl class with doc:
'.$this->wsdlFile);
+ $this->wsdl = createObject
("phpgwapi.wsdl",'',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
+ $this->wsdl->setCredentials($this->username, $this->password,
$this->authtype, $this->certRequest);
+ $this->wsdl->fetchWSDL($this->wsdlFile);
+ $this->checkWSDL();
+ }
+
+ /**
+ * get available data pertaining to an operation
+ *
+ * @param string $operation operation name
+ * @return array array of data pertaining to the operation
+ * @access public
+ */
+ function getOperationData($operation){
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError())
+ return false;
+ }
+ if(isset($this->operations[$operation])){
+ return $this->operations[$operation];
+ }
+ $this->debug("No data for operation: $operation");
+ }
+
+ /**
+ * send the SOAP message
+ *
+ * Note: if the operation has multiple return values
+ * the return value of this method will be an array
+ * of those values.
+ *
+ * @param string $msg a SOAPx4 soapmsg object
+ * @param string $soapaction SOAPAction value
+ * @param integer $timeout set connection timeout in seconds
+ * @param integer $response_timeout set response timeout in
seconds
+ * @return mixed native PHP types.
+ * @access private
+ */
+ function send($msg, $soapaction = '', $timeout=0, $response_timeout=30)
{
+ $this->checkCookies();
+ // detect transport
+ switch(true){
+ // http(s)
+ case ereg('^http',$this->endpoint):
+ $this->debug('transporting via HTTP');
+ if($this->persistentConnection == true &&
is_object($this->persistentConnection)){
+ $http =& $this->persistentConnection;
+ } else {
+ $http = createObject
("phpgwapi.soap_transport_http",$this->endpoint, $this->curl_options,
$this->use_curl);
+ if ($this->persistentConnection) {
+
$http->usePersistentConnection();
+ }
+ }
+
$http->setContentType($this->getHTTPContentType(),
$this->getHTTPContentTypeCharset());
+ $http->setSOAPAction($soapaction);
+ if($this->proxyhost && $this->proxyport){
+
$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
+ }
+ if($this->authtype != '') {
+ $http->setCredentials($this->username,
$this->password, $this->authtype, array(), $this->certRequest);
+ }
+ if($this->http_encoding != ''){
+
$http->setEncoding($this->http_encoding);
+ }
+ $this->debug('sending message,
length='.strlen($msg));
+ if(ereg('^http:',$this->endpoint)){
+ //if(strpos($this->endpoint,'http:')){
+ $this->responseData =
$http->send($msg,$timeout,$response_timeout,$this->cookies);
+ } elseif(ereg('^https',$this->endpoint)){
+ //} elseif(strpos($this->endpoint,'https:')){
+ //if(phpversion() == '4.3.0-dev'){
+ //$response =
$http->send($msg,$timeout,$response_timeout);
+ //$this->request = $http->outgoing_payload;
+ //$this->response =
$http->incoming_payload;
+ //} else
+ $this->responseData =
$http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
+ } else {
+ $this->setError('no http/s in endpoint
url');
+ }
+ $this->request = $http->outgoing_payload;
+ $this->response = $http->incoming_payload;
+ $this->appendDebug($http->getDebug());
+ $this->UpdateCookies($http->incoming_cookies);
+
+ // save transport object if using persistent
connections
+ if ($this->persistentConnection) {
+ $http->clearDebug();
+ if
(!is_object($this->persistentConnection)) {
+ $this->persistentConnection =
$http;
+ }
+ }
+
+ if($err = $http->getError()){
+ $this->setError('HTTP Error: '.$err);
+ return false;
+ } elseif($this->getError()){
+ return false;
+ } else {
+ $this->debug('got response, length='.
strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
+ return
$this->parseResponse($http->incoming_headers, $this->responseData);
+ }
+ break;
+ default:
+ $this->setError('no transport found, or
selected transport is not yet supported!');
+ return false;
+ break;
+ }
+ }
+
+ /**
+ * processes SOAP message returned from server
+ *
+ * @param array $headers The HTTP headers
+ * @param string $data unprocessed response data from
server
+ * @return mixed value of the message, decoded into a PHP type
+ * @access private
+ */
+ function parseResponse($headers, $data) {
+ $this->debug('Entering parseResponse() for data of length ' .
strlen($data) . ' headers:');
+ $this->appendDebug($this->varDump($headers));
+ if (!isset($headers['content-type'])) {
+ $this->setError('Response not of type text/xml (no
content-type header)');
+ return false;
+ }
+ if (!strstr($headers['content-type'], 'text/xml')) {
+ $this->setError('Response not of type text/xml: ' .
$headers['content-type']);
+ return false;
+ }
+ if (strpos($headers['content-type'], '=')) {
+ $enc = str_replace('"', '',
substr(strstr($headers["content-type"], '='), 1));
+ $this->debug('Got response encoding: ' . $enc);
+ if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+ $this->xml_encoding = strtoupper($enc);
+ } else {
+ $this->xml_encoding = 'US-ASCII';
+ }
+ } else {
+ // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for
HTTP 1.1
+ $this->xml_encoding = 'ISO-8859-1';
+ }
+ $this->debug('Use encoding: ' . $this->xml_encoding . ' when
creating nusoap_parser');
+ $parser = createObject
("phpgwapi.nusoap_parser",$data,$this->xml_encoding,$this->operation,$this->decode_utf8);
+ // add parser debug data to our debug
+ $this->appendDebug($parser->getDebug());
+ // if parse errors
+ if($errstr = $parser->getError()){
+ $this->setError( $errstr);
+ // destroy the parser object
+ unset($parser);
+ return false;
+ } else {
+ // get SOAP headers
+ $this->responseHeaders = $parser->getHeaders();
+ // get SOAP headers
+ $this->responseHeader = $parser->get_soapheader();
+ // get decoded message
+ $return = $parser->get_soapbody();
+ // add document for doclit support
+ $this->document = $parser->document;
+ // destroy the parser object
+ unset($parser);
+ // return decode message
+ return $return;
+ }
+ }
+
+ /**
+ * sets user-specified cURL options
+ *
+ * @param mixed $option The cURL option (always integer?)
+ * @param mixed $value The cURL option value
+ * @access public
+ */
+ function setCurlOption($option, $value) {
+ $this->debug("setCurlOption option=$option, value=");
+ $this->appendDebug($this->varDump($value));
+ $this->curl_options[$option] = $value;
+ }
+
+ /**
+ * sets the SOAP endpoint, which can override WSDL
+ *
+ * @param string $endpoint The endpoint URL to use, or empty
string or false to prevent override
+ * @access public
+ */
+ function setEndpoint($endpoint) {
+ $this->debug("setEndpoint(\"$endpoint\")");
+ $this->forceEndpoint = $endpoint;
+ }
+
+ /**
+ * set the SOAP headers
+ *
+ * @param mixed $headers String of XML with SOAP header content,
or array of soapval objects for SOAP headers
+ * @access public
+ */
+ function setHeaders($headers){
+ $this->debug("setHeaders headers=");
+ $this->appendDebug($this->varDump($headers));
+ $this->requestHeaders = $headers;
+ }
+
+ /**
+ * get the SOAP response headers (namespace resolution incomplete)
+ *
+ * @return string
+ * @access public
+ */
+ function getHeaders(){
+ return $this->responseHeaders;
+ }
+
+ /**
+ * get the SOAP response Header (parsed)
+ *
+ * @return mixed
+ * @access public
+ */
+ function getHeader(){
+ return $this->responseHeader;
+ }
+
+ /**
+ * set proxy info here
+ *
+ * @param string $proxyhost
+ * @param string $proxyport
+ * @param string $proxyusername
+ * @param string $proxypassword
+ * @access public
+ */
+ function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '',
$proxypassword = '') {
+ $this->proxyhost = $proxyhost;
+ $this->proxyport = $proxyport;
+ $this->proxyusername = $proxyusername;
+ $this->proxypassword = $proxypassword;
+ }
+
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $username
+ * @param string $password
+ * @param string $authtype (basic|digest|certificate|ntlm)
+ * @param array $certRequest (keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost
(optional): see corresponding options in cURL docs)
+ * @access public
+ */
+ function setCredentials($username, $password, $authtype = 'basic',
$certRequest = array()) {
+ $this->debug("setCredentials username=$username
authtype=$authtype certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
+ $this->username = $username;
+ $this->password = $password;
+ $this->authtype = $authtype;
+ $this->certRequest = $certRequest;
+ }
+
+ /**
+ * use HTTP encoding
+ *
+ * @param string $enc HTTP encoding
+ * @access public
+ */
+ function setHTTPEncoding($enc='gzip, deflate'){
+ $this->debug("setHTTPEncoding(\"$enc\")");
+ $this->http_encoding = $enc;
+ }
+
+ /**
+ * Set whether to try to use cURL connections if possible
+ *
+ * @param boolean $use Whether to try to use cURL
+ * @access public
+ */
+ function setUseCURL($use) {
+ $this->debug("setUseCURL($use)");
+ $this->use_curl = $use;
+ }
+
+ /**
+ * use HTTP persistent connections if possible
+ *
+ * @access public
+ */
+ function useHTTPPersistentConnection(){
+ $this->debug("useHTTPPersistentConnection");
+ $this->persistentConnection = true;
+ }
+
+ /**
+ * gets the default RPC parameter setting.
+ * If true, default is that call params are like RPC even for document
style.
+ * Each call() can override this value.
+ *
+ * This is no longer used.
+ *
+ * @return boolean
+ * @access public
+ * @deprecated
+ */
+ function getDefaultRpcParams() {
+ return $this->defaultRpcParams;
+ }
+
+ /**
+ * sets the default RPC parameter setting.
+ * If true, default is that call params are like RPC even for document
style
+ * Each call() can override this value.
+ *
+ * This is no longer used.
+ *
+ * @param boolean $rpcParams
+ * @access public
+ * @deprecated
+ */
+ function setDefaultRpcParams($rpcParams) {
+ $this->defaultRpcParams = $rpcParams;
+ }
+
+ /**
+ * dynamically creates an instance of a proxy class,
+ * allowing user to directly call methods from wsdl
+ *
+ * @return object soap_proxy object
+ * @access public
+ */
+ function getProxy() {
+ $r = rand();
+ $evalStr = $this->_getProxyClassCode($r);
+ //$this->debug("proxy class: $evalStr");
+ if ($this->getError()) {
+ $this->debug("Error from _getProxyClassCode, so return
NULL");
+ return null;
+ }
+ // eval the class
+ eval($evalStr);
+ // instantiate proxy object
+ eval("\$proxy = new nusoap_proxy_$r('');");
+ // transfer current wsdl data to the proxy thereby avoiding
parsing the wsdl twice
+ $proxy->endpointType = 'wsdl';
+ $proxy->wsdlFile = $this->wsdlFile;
+ $proxy->wsdl = $this->wsdl;
+ $proxy->operations = $this->operations;
+ $proxy->defaultRpcParams = $this->defaultRpcParams;
+ // transfer other state
+ $proxy->soap_defencoding = $this->soap_defencoding;
+ $proxy->username = $this->username;
+ $proxy->password = $this->password;
+ $proxy->authtype = $this->authtype;
+ $proxy->certRequest = $this->certRequest;
+ $proxy->requestHeaders = $this->requestHeaders;
+ $proxy->endpoint = $this->endpoint;
+ $proxy->forceEndpoint = $this->forceEndpoint;
+ $proxy->proxyhost = $this->proxyhost;
+ $proxy->proxyport = $this->proxyport;
+ $proxy->proxyusername = $this->proxyusername;
+ $proxy->proxypassword = $this->proxypassword;
+ $proxy->http_encoding = $this->http_encoding;
+ $proxy->timeout = $this->timeout;
+ $proxy->response_timeout = $this->response_timeout;
+ $proxy->persistentConnection = &$this->persistentConnection;
+ $proxy->decode_utf8 = $this->decode_utf8;
+ $proxy->curl_options = $this->curl_options;
+ $proxy->bindingType = $this->bindingType;
+ $proxy->use_curl = $this->use_curl;
+ return $proxy;
+ }
+
+ /**
+ * dynamically creates proxy class code
+ *
+ * @return string PHP/NuSOAP code for the proxy class
+ * @access private
+ */
+ function _getProxyClassCode($r) {
+ $this->debug("in getProxy endpointType=$this->endpointType");
+ $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
+ if ($this->endpointType != 'wsdl') {
+ $evalStr = 'A proxy can only be created for a WSDL
client';
+ $this->setError($evalStr);
+ $evalStr = "echo \"$evalStr\";";
+ return $evalStr;
+ }
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError()) {
+ return "echo \"" . $this->getError() . "\";";
+ }
+ }
+ $evalStr = '';
+ foreach ($this->operations as $operation => $opData) {
+ if ($operation != '') {
+ // create param string and param comment string
+ if (sizeof($opData['input']['parts']) > 0) {
+ $paramStr = '';
+ $paramArrayStr = '';
+ $paramCommentStr = '';
+ foreach ($opData['input']['parts'] as
$name => $type) {
+ $paramStr .= "\$$name, ";
+ $paramArrayStr .= "'$name' =>
\$$name, ";
+ $paramCommentStr .= "$type
\$$name, ";
+ }
+ $paramStr = substr($paramStr, 0,
strlen($paramStr)-2);
+ $paramArrayStr = substr($paramArrayStr,
0, strlen($paramArrayStr)-2);
+ $paramCommentStr =
substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
+ } else {
+ $paramStr = '';
+ $paramArrayStr = '';
+ $paramCommentStr = 'void';
+ }
+ $opData['namespace'] =
!isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
+ $evalStr .= "// $paramCommentStr
+ function " . str_replace('.', '__', $operation) . "($paramStr) {
+ \$params = array($paramArrayStr);
+ return \$this->call('$operation', \$params,
'".$opData['namespace']."', '".(isset($opData['soapAction']) ?
$opData['soapAction'] : '')."');
+ }
+ ";
+ unset($paramStr);
+ unset($paramCommentStr);
+ }
+ }
+ $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
+ '.$evalStr.'
+}';
+ return $evalStr;
+ }
+
+ /**
+ * dynamically creates proxy class code
+ *
+ * @return string PHP/NuSOAP code for the proxy class
+ * @access public
+ */
+ function getProxyClassCode() {
+ $r = rand();
+ return $this->_getProxyClassCode($r);
+ }
+
+ /**
+ * gets the HTTP body for the current request.
+ *
+ * @param string $soapmsg The SOAP payload
+ * @return string The HTTP body, which includes the SOAP payload
+ * @access private
+ */
+ function getHTTPBody($soapmsg) {
+ return $soapmsg;
+ }
+
+ /**
+ * gets the HTTP content type for the current request.
+ *
+ * Note: getHTTPBody must be called before this.
+ *
+ * @return string the HTTP content type for the current request.
+ * @access private
+ */
+ function getHTTPContentType() {
+ return 'text/xml';
+ }
+
+ /**
+ * gets the HTTP content type charset for the current request.
+ * returns false for non-text content types.
+ *
+ * Note: getHTTPBody must be called before this.
+ *
+ * @return string the HTTP content type charset for the current request.
+ * @access private
+ */
+ function getHTTPContentTypeCharset() {
+ return $this->soap_defencoding;
+ }
+
+ /*
+ * whether or not parser should decode utf8 element content
+ *
+ * @return always returns true
+ * @access public
+ */
+ function decodeUTF8($bool){
+ $this->decode_utf8 = $bool;
+ return true;
+ }
+
+ /**
+ * adds a new Cookie into $this->cookies array
+ *
+ * @param string $name Cookie Name
+ * @param string $value Cookie Value
+ * @return boolean if cookie-set was successful returns true, else
false
+ * @access public
+ */
+ function setCookie($name, $value) {
+ if (strlen($name) == 0) {
+ return false;
+ }
+ $this->cookies[] = array('name' => $name, 'value' => $value);
+ return true;
+ }
+
+ /**
+ * gets all Cookies
+ *
+ * @return array with all internal cookies
+ * @access public
+ */
+ function getCookies() {
+ return $this->cookies;
+ }
+
+ /**
+ * checks all Cookies and delete those which are expired
+ *
+ * @return boolean always return true
+ * @access private
+ */
+ function checkCookies() {
+ if (sizeof($this->cookies) == 0) {
+ return true;
+ }
+ $this->debug('checkCookie: check ' . sizeof($this->cookies) . '
cookies');
+ $curr_cookies = $this->cookies;
+ $this->cookies = array();
+ foreach ($curr_cookies as $cookie) {
+ if (! is_array($cookie)) {
+ $this->debug('Remove cookie that is not an
array');
+ continue;
+ }
+ if ((isset($cookie['expires'])) && (!
empty($cookie['expires']))) {
+ if (strtotime($cookie['expires']) > time()) {
+ $this->cookies[] = $cookie;
+ } else {
+ $this->debug('Remove expired cookie ' .
$cookie['name']);
+ }
+ } else {
+ $this->cookies[] = $cookie;
+ }
+ }
+ $this->debug('checkCookie: '.sizeof($this->cookies).' cookies
left in array');
+ return true;
+ }
+
+ /**
+ * updates the current cookies with a new set
+ *
+ * @param array $cookies new cookies with which to update current
ones
+ * @return boolean always return true
+ * @access private
+ */
+ function UpdateCookies($cookies) {
+ if (sizeof($this->cookies) == 0) {
+ // no existing cookies: take whatever is new
+ if (sizeof($cookies) > 0) {
+ $this->debug('Setting new cookie(s)');
+ $this->cookies = $cookies;
+ }
+ return true;
+ }
+ if (sizeof($cookies) == 0) {
+ // no new cookies: keep what we've got
+ return true;
+ }
+ // merge
+ foreach ($cookies as $newCookie) {
+ if (!is_array($newCookie)) {
+ continue;
+ }
+ if ((!isset($newCookie['name'])) ||
(!isset($newCookie['value']))) {
+ continue;
+ }
+ $newName = $newCookie['name'];
+
+ $found = false;
+ for ($i = 0; $i < count($this->cookies); $i++) {
+ $cookie = $this->cookies[$i];
+ if (!is_array($cookie)) {
+ continue;
+ }
+ if (!isset($cookie['name'])) {
+ continue;
+ }
+ if ($newName != $cookie['name']) {
+ continue;
+ }
+ $newDomain = isset($newCookie['domain']) ?
$newCookie['domain'] : 'NODOMAIN';
+ $domain = isset($cookie['domain']) ?
$cookie['domain'] : 'NODOMAIN';
+ if ($newDomain != $domain) {
+ continue;
+ }
+ $newPath = isset($newCookie['path']) ?
$newCookie['path'] : 'NOPATH';
+ $path = isset($cookie['path']) ?
$cookie['path'] : 'NOPATH';
+ if ($newPath != $path) {
+ continue;
+ }
+ $this->cookies[$i] = $newCookie;
+ $found = true;
+ $this->debug('Update cookie ' . $newName . '='
. $newCookie['value']);
+ break;
+ }
+ if (! $found) {
+ $this->debug('Add cookie ' . $newName . '=' .
$newCookie['value']);
+ $this->cookies[] = $newCookie;
+ }
+ }
+ return true;
+ }
+}
+
+if (!extension_loaded('soap')) {
+ /**
+ * For backwards compatiblity, define soapclient unless the PHP
SOAP extension is loaded.
+ */
+ class soapclient extends nusoap_client {
+ }
+}
+?>
Property changes on: core/trunk/phpgwapi/inc/class.nusoap_client.inc.php
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Modified: core/trunk/phpgwapi/inc/class.phpgw_soapval.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.phpgw_soapval.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.phpgw_soapval.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,13 +32,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
-
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['phpgwapi_soapval'])
-{
- require_once(PHPGW_API_INC."/class.phpgwapi_soapval.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['phpgwapi_soapval']
= True;
-}
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.phpgwapi_soapval');
/**
* SOAPx4 value object
* @author Edd Dumbill <address@hidden>
@@ -43,7 +47,7 @@
* @copyright Portions Copyright (C) 2003,2004 Free Software Foundation,
Inc. http://www.fsf.org/
* @package phpgwapi
* @subpackage communication
- * @version $ I d : nusoap2phpgwapi,v 1.3 2006/09/24 13:01:46 Caeies Exp
$
+ * @version $ I d : nusoap2phpgwapi 18363 2007-11-30 13:25:06Z sigurdne $
* @internal This project began based on code from the 2 projects below,
* @internal and still contains some original code. The licenses of both
must be respected.
* @internal XML-RPC for PHP; SOAP for PHP
Modified: core/trunk/phpgwapi/inc/class.soap_XMLSchema.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_XMLSchema.inc.php 2008-10-06
11:15:02 UTC (rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_XMLSchema.inc.php 2008-10-07
10:31:48 UTC (rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,28 +32,23 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_soap_XMLSchema');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
-* 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 :)
+* parses an XML Schema, allows access to it's data, other utility methods.
+* imperfect, no validation... yet, but quite functional.
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
-class phpgwapi_soap_XMLSchema extends phpgwapi_nusoap_base {
+class phpgwapi_nusoap_soap_XMLSchema extends phpgwapi_nusoap_base {
// files
var $schema = '';
@@ -85,9 +87,9 @@
* @param string $namespaces namespaces defined in enclosing XML
* @access public
*/
- function
phpgwapi_soap_XMLSchema($schema='',$xml='',$namespaces=array()){
+ function
phpgwapi_nusoap_soap_XMLSchema($schema='',$xml='',$namespaces=array()){
parent::phpgwapi_nusoap_base();
- $this->debug('soap_XMLSchema class instantiated, inside
constructor');
+ $this->debug('nusoap_soap_XMLSchema class instantiated, inside
constructor');
// files
$this->schema = $schema;
$this->xml = $xml;
@@ -113,8 +115,8 @@
/**
* parse an XML file
*
- * @param string $xml, path/URL to XML file
- * @param string $type, (schema | xml)
+ * @param string $xml path/URL to XML file
+ * @param string $type (schema | xml)
* @return boolean
* @access public
*/
@@ -141,7 +143,7 @@
* parse an XML string
*
* @param string $xml path or URL
- * @param string $type, (schema|xml)
+ * @param string $type (schema|xml)
* @access private
*/
function parseString($xml,$type){
@@ -185,6 +187,21 @@
}
/**
+ * gets a type name for an unnamed type
+ *
+ * @param string Element name
+ * @return string A type name for an unnamed type
+ * @access private
+ */
+ function CreateTypeName($ename) {
+ $scope = '';
+ for ($i = 0; $i < count($this->complexTypeStack); $i++) {
+ $scope .= $this->complexTypeStack[$i] . '_';
+ }
+ return $scope . $ename . '_ContainedType';
+ }
+
+ /**
* start-element handler
*
* @param string $parser XML parser object
@@ -263,6 +280,7 @@
$this->xdebug("parsing attribute:");
$this->appendDebug($this->varDump($attrs));
if (!isset($attrs['form'])) {
+ // TODO: handle globals
$attrs['form'] =
$this->schemaInfo['attributeFormDefault'];
}
if
(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
@@ -312,10 +330,13 @@
}
break;
case 'complexContent': // (optional) content for a
complexType
+ $this->xdebug("do nothing for element $name");
break;
case 'complexType':
array_push($this->complexTypeStack,
$this->currentComplexType);
if(isset($attrs['name'])){
+ // TODO: what is the scope of named
complexTypes that appear
+ // nested within other c
complexTypes?
$this->xdebug('processing named
complexType '.$attrs['name']);
//$this->currentElement = false;
$this->currentComplexType =
$attrs['name'];
@@ -334,9 +355,10 @@
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
- }else{
- $this->xdebug('processing unnamed
complexType for element '.$this->currentElement);
- $this->currentComplexType =
$this->currentElement . '_ContainedType';
+ } else {
+ $name =
$this->CreateTypeName($this->currentElement);
+ $this->xdebug('processing unnamed
complexType for element ' . $this->currentElement . ' named ' . $name);
+ $this->currentComplexType = $name;
//$this->currentElement = false;
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
@@ -357,11 +379,13 @@
break;
case 'element':
array_push($this->elementStack,
$this->currentElement);
- // elements defined as part of a complex type
should
- // not really be added to $this->elements, but
for some
- // reason, they are
if (!isset($attrs['form'])) {
- $attrs['form'] =
$this->schemaInfo['elementFormDefault'];
+ if ($this->currentComplexType) {
+ $attrs['form'] =
$this->schemaInfo['elementFormDefault'];
+ } else {
+ // global
+ $attrs['form'] = 'qualified';
+ }
}
if(isset($attrs['type'])){
$this->xdebug("processing typed element
".$attrs['name']." of type ".$attrs['type']);
@@ -383,24 +407,25 @@
$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
}
$this->currentElement = $attrs['name'];
- $this->elements[ $attrs['name'] ] =
$attrs;
- $this->elements[ $attrs['name']
]['typeClass'] = 'element';
$ename = $attrs['name'];
} elseif(isset($attrs['ref'])){
$this->xdebug("processing element as
ref to ".$attrs['ref']);
$this->currentElement = "ref to
".$attrs['ref'];
$ename =
$this->getLocalPart($attrs['ref']);
} else {
- $this->xdebug("processing untyped
element ".$attrs['name']);
+ $type =
$this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
+ $this->xdebug("processing untyped
element " . $attrs['name'] . ' type ' . $type);
$this->currentElement = $attrs['name'];
- $this->elements[ $attrs['name'] ] =
$attrs;
- $this->elements[ $attrs['name']
]['typeClass'] = 'element';
- $attrs['type'] =
$this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
- $this->elements[ $attrs['name']
]['type'] = $attrs['type'];
+ $attrs['type'] =
$this->schemaTargetNamespace . ':' . $type;
$ename = $attrs['name'];
}
- if(isset($ename) && $this->currentComplexType){
+ if (isset($ename) && $this->currentComplexType)
{
+ $this->xdebug("add element $ename to
complexType $this->currentComplexType");
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
+ } elseif (!isset($attrs['ref'])) {
+ $this->xdebug("add element $ename to
elements array");
+ $this->elements[ $attrs['name'] ] =
$attrs;
+ $this->elements[ $attrs['name']
]['typeClass'] = 'element';
}
break;
case 'enumeration': // restriction value list
member
@@ -414,22 +439,36 @@
case 'extension': // simpleContent or
complexContent type extension
$this->xdebug('extension ' . $attrs['base']);
if ($this->currentComplexType) {
-
$this->complexTypes[$this->currentComplexType]['extensionBase'] =
$attrs['base'];
+ $ns = $this->getPrefix($attrs['base']);
+ if ($ns == '') {
+
$this->complexTypes[$this->currentComplexType]['extensionBase'] =
$this->schemaTargetNamespace . ':' . $attrs['base'];
+ } elseif
($this->getNamespaceFromPrefix($ns)) {
+
$this->complexTypes[$this->currentComplexType]['extensionBase'] =
$attrs['base'];
+ }
}
break;
case 'import':
if (isset($attrs['schemaLocation'])) {
- //$this->xdebug('import namespace ' .
$attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
+ $this->xdebug('import namespace ' .
$attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
$this->imports[$attrs['namespace']][] = array('location'
=> $attrs['schemaLocation'], 'loaded' => false);
} else {
- //$this->xdebug('import namespace ' .
$attrs['namespace']);
+ $this->xdebug('import namespace ' .
$attrs['namespace']);
$this->imports[$attrs['namespace']][] = array('location'
=> '', 'loaded' => true);
if (!
$this->getPrefixFromNamespace($attrs['namespace'])) {
$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
}
}
break;
+ case 'include':
+ if (isset($attrs['schemaLocation'])) {
+ $this->xdebug('include into namespace '
. $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
+ $this->imports[$this->schemaTargetNamespace][] =
array('location' => $attrs['schemaLocation'], 'loaded' => false);
+ } else {
+ $this->xdebug('ignoring invalid XML
Schema construct: include without schemaLocation attribute');
+ }
+ break;
case 'list': // simpleType value list
+ $this->xdebug("do nothing for element $name");
break;
case 'restriction': // simpleType, simpleContent or
complexContent value restriction
$this->xdebug('restriction ' . $attrs['base']);
@@ -456,6 +495,7 @@
}
break;
case 'simpleContent': // (optional) content for a
complexType
+ $this->xdebug("do nothing for element $name");
break;
case 'simpleType':
array_push($this->simpleTypeStack,
$this->currentSimpleType);
@@ -466,17 +506,19 @@
$this->simpleTypes[ $attrs['name']
]['typeClass'] = 'simpleType';
$this->simpleTypes[ $attrs['name']
]['phpType'] = 'scalar';
} else {
- $this->xdebug('processing unnamed
simpleType for element '.$this->currentElement);
- $this->currentSimpleType =
$this->currentElement . '_ContainedType';
+ $name =
$this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
+ $this->xdebug('processing unnamed
simpleType for element ' . $this->currentElement . ' named ' . $name);
+ $this->currentSimpleType = $name;
//$this->currentElement = false;
$this->simpleTypes[$this->currentSimpleType] = $attrs;
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
}
break;
case 'union': // simpleType type list
+ $this->xdebug("do nothing for element $name");
break;
default:
- //$this->xdebug("do not have anything to do for
element $name");
+ $this->xdebug("do not have any logic to process
element $name");
}
}
@@ -610,13 +652,13 @@
// simple types
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
foreach($this->simpleTypes as $typeName => $eParts){
- $xml .= " <$schemaPrefix:simpleType
name=\"$typeName\">\n <$schemaPrefix:restriction
base=\"".$this->contractQName($eParts['type'])."\"/>\n";
+ $xml .= " <$schemaPrefix:simpleType
name=\"$typeName\">\n <$schemaPrefix:restriction
base=\"".$this->contractQName($eParts['type'])."\">\n";
if (isset($eParts['enumeration'])) {
foreach ($eParts['enumeration'] as $e) {
$xml .= "
<$schemaPrefix:enumeration value=\"$e\"/>\n";
}
}
- $xml .= " </$schemaPrefix:simpleType>";
+ $xml .= " </$schemaPrefix:restriction>\n
</$schemaPrefix:simpleType>";
}
}
// elements
@@ -632,7 +674,13 @@
}
}
// finish 'er up
- $el = "<$schemaPrefix:schema
targetNamespace=\"$this->schemaTargetNamespace\"\n";
+ $attr = '';
+ foreach ($this->schemaInfo as $k => $v) {
+ if ($k == 'elementFormDefault' || $k ==
'attributeFormDefault') {
+ $attr .= " $k=\"$v\"";
+ }
+ }
+ $el = "<$schemaPrefix:schema$attr
targetNamespace=\"$this->schemaTargetNamespace\"\n";
foreach (array_diff($this->usedNamespaces,
$this->enclosingNamespaces) as $nsp => $ns) {
$el .= " xmlns:$nsp=\"$ns\"";
}
@@ -656,8 +704,8 @@
* returns false if no type exists, or not w/ the given namespace
* else returns a string that is either a native php type, or 'struct'
*
- * @param string $type, name of defined type
- * @param string $ns, namespace of type
+ * @param string $type name of defined type
+ * @param string $ns namespace of type
* @return mixed
* @access public
* @deprecated
@@ -688,7 +736,7 @@
*
* For simpleType or element, the array has different keys.
*
- * @param string
+ * @param string $type
* @return mixed
* @access public
* @see addComplexType
@@ -697,10 +745,17 @@
*/
function getTypeDef($type){
//$this->debug("in getTypeDef for type $type");
- if(isset($this->complexTypes[$type])){
+ if (substr($type, -1) == '^') {
+ $is_element = 1;
+ $type = substr($type, 0, -1);
+ } else {
+ $is_element = 0;
+ }
+
+ if((! $is_element) && isset($this->complexTypes[$type])){
$this->xdebug("in getTypeDef, found complexType $type");
return $this->complexTypes[$type];
- } elseif(isset($this->simpleTypes[$type])){
+ } elseif((! $is_element) && isset($this->simpleTypes[$type])){
$this->xdebug("in getTypeDef, found simpleType $type");
if (!isset($this->simpleTypes[$type]['phpType'])) {
// get info for type to tack onto the simple
type
@@ -736,6 +791,9 @@
if (isset($etype['elements'])) {
$this->elements[$type]['elements'] = $etype['elements'];
}
+ if (isset($etype['extensionBase'])) {
+
$this->elements[$type]['extensionBase'] = $etype['extensionBase'];
+ }
} elseif ($ns ==
'http://www.w3.org/2001/XMLSchema') {
$this->xdebug("in getTypeDef, element
$type is an XSD type");
$this->elements[$type]['phpType'] =
'scalar';
@@ -759,7 +817,7 @@
/**
* returns a sample serialization of a given type, or false if no type by
the given name
*
- * @param string $type, name of type
+ * @param string $type name of type
* @return mixed
* @access public
* @deprecated
@@ -769,7 +827,7 @@
if($typeDef = $this->getTypeDef($type)){
$str .= '<'.$type;
if(is_array($typeDef['attrs'])){
- foreach($attrs as $attName => $data){
+ foreach($typeDef['attrs'] as $attName => $data){
$str .= " $attName=\"{type = ".$data['type']."}\"";
}
}
@@ -794,8 +852,8 @@
* returns HTML form elements that allow a user
* to enter values for creating an instance of the given type.
*
- * @param string $name, name for type instance
- * @param string $type, name of type
+ * @param string $name name for type instance
+ * @param string $type name of type
* @return string
* @access public
* @deprecated
@@ -897,7 +955,7 @@
* @param string $phpType (should always be scalar)
* @param array $enumeration array of values
* @access public
- * @see xmlschema
+ * @see nusoap_xmlschema
* @see getTypeDef
*/
function addSimpleType($name, $restrictionBase='',
$typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
@@ -917,7 +975,7 @@
* adds an element to the schema
*
* @param array $attrs attributes that must include name and type
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
@@ -932,6 +990,10 @@
}
}
+/**
+ * Backward compatibility
+ */
+class phpgwapi_soap_XMLSchema extends phpgwapi_nusoap_soap_XMLSchema {
+}
-
?>
Modified: core/trunk/phpgwapi/inc/class.soap_client.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_client.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_client.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,12 +32,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
-
- phpgw::import_class('phpgwapi.phpgwapi_soap_transport_http');
-/***************************************************************************
-* TOTALY DEPRECATED , DON'T USE
-*/
+ /*
+ * Include dependency
+ */
+
phpgw::import_class('phpgwapi.phpgwapi_soap_transport_http');
+ /*
+ * TOTALY DEPRECATED , DON'T USE
+ */
/**
* SOAPx4 client
* @author Edd Dumbill <address@hidden>
Modified: core/trunk/phpgwapi/inc/class.soap_fault.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_fault.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_fault.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,25 +32,22 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_fault');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
* Contains information for a SOAP fault.
* Mainly used for returning faults from deployed functions
* in a server instance.
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
-class phpgwapi_soap_fault extends phpgwapi_nusoap_base {
+class phpgwapi_nusoap_fault extends phpgwapi_nusoap_base {
/**
* The fault code (client|server)
* @var string
@@ -77,7 +81,7 @@
* @param string $faultstring human readable error message
* @param mixed $faultdetail detail, typically a string or array of string
*/
- function
phpgwapi_soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
+ function
phpgwapi_nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
parent::phpgwapi_nusoap_base();
$this->faultcode = $faultcode;
$this->faultactor = $faultactor;
@@ -112,6 +116,10 @@
}
}
+/**
+ * Backward compatibility
+ */
+class phpgwapi_soap_fault extends phpgwapi_nusoap_fault {
+}
-
?>
Modified: core/trunk/phpgwapi/inc/class.soap_parser.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_parser.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_parser.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,25 +32,23 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_parser');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
*
-* soap_parser class parses SOAP XML messages into native PHP values
+* nusoap_parser class parses SOAP XML messages into native PHP values
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
-class phpgwapi_soap_parser extends phpgwapi_nusoap_base {
+class phpgwapi_nusoap_parser extends phpgwapi_nusoap_base {
var $xml = '';
var $xml_encoding = '';
@@ -67,7 +72,8 @@
var $fault_detail = '';
var $depth_array = array();
var $debug_flag = true;
- var $soapresponse = NULL;
+ var $soapresponse = NULL; // parsed SOAP Body
+ var $soapheader = NULL; // parsed SOAP Header
var $responseHeaders = ''; // incoming SOAP headers (text)
var $body_position = 0;
// for multiref parsing:
@@ -87,7 +93,7 @@
* @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
* @access public
*/
- function
phpgwapi_soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
+ function
phpgwapi_nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
parent::phpgwapi_nusoap_base();
$this->xml = $xml;
$this->xml_encoding = $encoding;
@@ -119,7 +125,7 @@
} else {
$this->debug('No XML declaration');
}
- $this->debug('Entering soap_parser(),
length='.strlen($xml).', encoding='.$encoding);
+ $this->debug('Entering nusoap_parser(),
length='.strlen($xml).', encoding='.$encoding);
// Create an XML parser - why not xml_parser_create_ns?
$this->parser = xml_parser_create($this->xml_encoding);
// Set the options for parsing the XML data.
@@ -145,10 +151,10 @@
$this->debug('parsed successfully, found root
struct: '.$this->root_struct.' of name '.$this->root_struct_name);
// get final value
$this->soapresponse =
$this->message[$this->root_struct]['result'];
- // get header value: no, because this is
documented as XML string
-// if($this->root_header != '' &&
isset($this->message[$this->root_header]['result'])){
-// $this->responseHeaders =
$this->message[$this->root_header]['result'];
-// }
+ // get header value
+ if($this->root_header != '' &&
isset($this->message[$this->root_header]['result'])){
+ $this->soapheader =
$this->message[$this->root_header]['result'];
+ }
// resolve hrefs/ids
if(sizeof($this->multirefs) > 0){
foreach($this->multirefs as $id =>
$hrefs){
@@ -209,10 +215,10 @@
// set status
if($name == 'Envelope'){
$this->status = 'envelope';
- } elseif($name == 'Header'){
+ } elseif($name == 'Header' && $this->status = 'envelope'){
$this->root_header = $pos;
$this->status = 'header';
- } elseif($name == 'Body'){
+ } elseif($name == 'Body' && $this->status = 'envelope'){
$this->status = 'body';
$this->body_position = $pos;
// set method
@@ -458,21 +464,42 @@
}
/**
- * get the parsed message
+ * get the parsed message (SOAP Body)
*
* @return mixed
* @access public
+ * @deprecated use get_soapbody instead
*/
function get_response(){
return $this->soapresponse;
}
/**
- * get the parsed headers
+ * get the parsed SOAP Body (NULL if there was none)
*
- * @return string XML or empty if no headers
+ * @return mixed
* @access public
*/
+ function get_soapbody(){
+ return $this->soapresponse;
+ }
+
+ /**
+ * get the parsed SOAP Header (NULL if there was none)
+ *
+ * @return mixed
+ * @access public
+ */
+ function get_soapheader(){
+ return $this->soapheader;
+ }
+
+ /**
+ * get the unparsed SOAP Header
+ *
+ * @return string XML or empty if no Header
+ * @access public
+ */
function getHeaders(){
return $this->responseHeaders;
}
@@ -638,6 +665,10 @@
}
}
+/**
+ * Backward compatibility
+ */
+class phpgwapi_soap_parser extends phpgwapi_nusoap_parser {
+}
-
?>
Modified: core/trunk/phpgwapi/inc/class.soap_server.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_server.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_server.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,28 +32,24 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_server');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
*
-* soap_server allows the user to create a SOAP server
+* nusoap_server allows the user to create a SOAP server
* that is capable of receiving messages and returning responses
*
-* NOTE: WSDL functionality is experimental
-*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
-class phpgwapi_soap_server extends phpgwapi_nusoap_base {
+class phpgwapi_nusoap_server extends phpgwapi_nusoap_base {
/**
* HTTP headers of request
* @var array
@@ -66,6 +69,12 @@
*/
var $requestHeaders = '';
/**
+ * SOAP Headers from request (parsed)
+ * @var mixed
+ * @access public
+ */
+ var $requestHeader = NULL;
+ /**
* SOAP body request portion (incomplete namespace resolution; special
characters not escaped) (text)
* @var string
* @access public
@@ -127,8 +136,8 @@
*/
var $response = '';
/**
- * SOAP headers for response (text)
- * @var string
+ * SOAP headers for response (text or array of soapval or associative
array)
+ * @var mixed
* @access public
*/
var $responseHeaders = '';
@@ -197,7 +206,7 @@
* @param mixed $wsdl file path or URL (string), or wsdl instance (object)
* @access public
*/
- function phpgwapi_soap_server($wsdl=false){
+ function phpgwapi_nusoap_server($wsdl=false){
parent::phpgwapi_nusoap_base();
// turn on debugging?
global $debug;
@@ -214,13 +223,13 @@
}
if (isset($debug)) {
- $this->debug("In soap_server, set debug_flag=$debug
based on global flag");
+ $this->debug("In nusoap_server, set debug_flag=$debug
based on global flag");
$this->debug_flag = $debug;
} elseif (isset($_SERVER['QUERY_STRING'])) {
$qs = explode('&', $_SERVER['QUERY_STRING']);
foreach ($qs as $v) {
if (substr($v, 0, 6) == 'debug=') {
- $this->debug("In soap_server, set
debug_flag=" . substr($v, 6) . " based on query string #1");
+ $this->debug("In nusoap_server, set
debug_flag=" . substr($v, 6) . " based on query string #1");
$this->debug_flag = substr($v, 6);
}
}
@@ -228,7 +237,7 @@
$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
foreach ($qs as $v) {
if (substr($v, 0, 6) == 'debug=') {
- $this->debug("In soap_server, set
debug_flag=" . substr($v, 6) . " based on query string #2");
+ $this->debug("In nusoap_server, set
debug_flag=" . substr($v, 6) . " based on query string #2");
$this->debug_flag = substr($v, 6);
}
}
@@ -236,7 +245,7 @@
// wsdl
if($wsdl){
- $this->debug("In soap_server, WSDL is specified");
+ $this->debug("In nusoap_server, WSDL is specified");
if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
$this->wsdl = $wsdl;
$this->externalWSDLURL = $this->wsdl->wsdl;
@@ -263,6 +272,14 @@
function service($data){
global $HTTP_SERVER_VARS;
+ if (isset($_SERVER['REQUEST_METHOD'])) {
+ $rm = $_SERVER['REQUEST_METHOD'];
+ } elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
+ $rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
+ } else {
+ $rm = '';
+ }
+
if (isset($_SERVER['QUERY_STRING'])) {
$qs = $_SERVER['QUERY_STRING'];
} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
@@ -270,19 +287,38 @@
} else {
$qs = '';
}
- $this->debug("In service, query string=$qs");
+ $this->debug("In service, request method=$rm query string=$qs
strlen(\$data)=" . strlen($data));
- if (ereg('wsdl', $qs) ){
+ if ($rm == 'POST') {
+ $this->debug("In service, invoke the request");
+ $this->parse_request($data);
+ if (! $this->fault) {
+ $this->invoke_method();
+ }
+ if (! $this->fault) {
+ $this->serialize_return();
+ }
+ $this->send_response();
+ } elseif (ereg('wsdl', $qs) ){
$this->debug("In service, this is a request for WSDL");
- if($this->externalWSDLURL){
- if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
+ if ($this->externalWSDLURL){
+ if (strpos($this->externalWSDLURL, "http://") !== false) { //
assume URL
+ $this->debug("In service, re-direct for WSDL");
header('Location: '.$this->externalWSDLURL);
} else { // assume file
+ $this->debug("In service, use file passthru for
WSDL");
header("Content-Type: text/xml\r\n");
+ $pos = strpos($this->externalWSDLURL,
"file://");
+ if ($pos === false) {
+ $filename = $this->externalWSDLURL;
+ } else {
+ $filename =
substr($this->externalWSDLURL, $pos + 7);
+ }
$fp = fopen($this->externalWSDLURL, 'r');
fpassthru($fp);
}
} elseif ($this->wsdl) {
+ $this->debug("In service, serialize WSDL");
header("Content-Type: text/xml;
charset=ISO-8859-1\r\n");
print $this->wsdl->serialize($this->debug_flag);
if ($this->debug_flag) {
@@ -291,22 +327,17 @@
print $this->getDebugAsXMLComment();
}
} else {
+ $this->debug("In service, there is no WSDL");
header("Content-Type: text/html;
charset=ISO-8859-1\r\n");
print "This service does not provide WSDL";
}
- } elseif ($data == '' && $this->wsdl) {
- $this->debug("In service, there is no data, so return
Web description");
+ } elseif ($this->wsdl) {
+ $this->debug("In service, return Web description");
print $this->wsdl->webDescription();
} else {
- $this->debug("In service, invoke the request");
- $this->parse_request($data);
- if (! $this->fault) {
- $this->invoke_method();
- }
- if (! $this->fault) {
- $this->serialize_return();
- }
- $this->send_response();
+ $this->debug("In service, no Web description");
+ header("Content-Type: text/html;
charset=ISO-8859-1\r\n");
+ print "This service does not provide a Web description";
}
}
@@ -356,9 +387,9 @@
$this->debug("In parse_http_headers, use _SERVER");
foreach ($_SERVER as $k => $v) {
if (substr($k, 0, 5) == 'HTTP_') {
- $k = str_replace(' ', '-',
strtolower(str_replace('_', ' ', substr($k, 5))));
$k = strtolower(substr($k, 5));
+ $k = str_replace(' ', '-',
strtolower(str_replace('_', ' ', substr($k, 5))));
} else {
- $k = str_replace(' ', '-',
strtolower(str_replace('_', ' ', $k)));
$k = strtolower($k);
+ $k = str_replace(' ', '-',
strtolower(str_replace('_', ' ', $k)));
}
if ($k == 'soapaction') {
// get SOAPAction header
@@ -588,7 +619,7 @@
}
if ($this->methodparams) {
foreach ($this->methodparams as $param) {
- if (is_array($param)) {
+ if (is_array($param) ||
is_object($param)) {
$this->fault('SOAP-ENV:Client',
'NuSOAP does not handle complexType parameters correctly when using eval;
call_user_func_array must be available');
return;
}
@@ -611,11 +642,15 @@
$instance = new $class ();
$call_arg = array(&$instance, $method);
}
- $this->methodreturn = call_user_func_array($call_arg,
array_values($this->methodparams));
+ if (is_array($this->methodparams)) {
+ $this->methodreturn =
call_user_func_array($call_arg, array_values($this->methodparams));
+ } else {
+ $this->methodreturn =
call_user_func_array($call_arg, array());
+ }
}
$this->debug('in invoke_method, methodreturn:');
$this->appendDebug($this->varDump($this->methodreturn));
- $this->debug("in invoke_method, called method
$this->methodname, received $this->methodreturn of type
".gettype($this->methodreturn));
+ $this->debug("in invoke_method, called method
$this->methodname, received data of type ".gettype($this->methodreturn));
}
/**
@@ -632,7 +667,7 @@
function serialize_return() {
$this->debug('Entering serialize_return methodname: ' .
$this->methodname . ' methodURI: ' . $this->methodURI);
// if fault
- if (isset($this->methodreturn) &&
(get_class($this->methodreturn) == 'soap_fault')) {
+ if (isset($this->methodreturn) &&
((get_class($this->methodreturn) == 'soap_fault') ||
(get_class($this->methodreturn) == 'nusoap_fault'))) {
$this->debug('got a fault object from method');
$this->fault = $this->methodreturn;
return;
@@ -643,11 +678,15 @@
$this->debug('got a(n) '.gettype($this->methodreturn).'
from method');
$this->debug('serializing return value');
if($this->wsdl){
- // weak attempt at supporting multiple output
params
- if(sizeof($this->opData['output']['parts']) >
1){
+ if (sizeof($this->opData['output']['parts']) >
1) {
+ $this->debug('more than one output
part, so use the method return unchanged');
$opParams = $this->methodreturn;
- } else {
- // TODO: is this really necessary?
+ } elseif (sizeof($this->opData['output']['parts'])
== 1) {
+ $this->debug('exactly one output part,
so wrap the method return in a simple array');
+ // TODO: verify that it is not already
wrapped!
+ //foreach ($this->opData['output']['parts'] as
$name => $type) {
+ // $this->debug('wrap in element
named ' . $name);
+ //}
$opParams = array($this->methodreturn);
}
$return_val =
$this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
@@ -676,9 +715,18 @@
if ($this->opData['style'] == 'rpc') {
$this->debug('style is rpc for serialization:
use is ' . $this->opData['output']['use']);
if ($this->opData['output']['use'] ==
'literal') {
- $payload =
'<'.$this->methodname.'Response
xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
+ //
http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says
rpc/literal accessor elements should not be in a namespace
+ if ($this->methodURI) {
+ $payload =
'<ns1:'.$this->methodname.'Response
xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+ } else {
+ $payload =
'<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
+ }
} else {
- $payload =
'<ns1:'.$this->methodname.'Response
xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+ if ($this->methodURI) {
+ $payload =
'<ns1:'.$this->methodname.'Response
xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+ } else {
+ $payload =
'<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
+ }
}
} else {
$this->debug('style is not rpc for
serialization: assume document');
@@ -699,7 +747,7 @@
$encodingStyle = '';
}
// Added: In case we use a WSDL, return a serialized
env. WITH the usedNamespaces.
- $this->responseSOAP =
$this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
+ $this->responseSOAP =
$this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
} else {
$this->responseSOAP =
$this->serializeEnvelope($payload,$this->responseHeaders);
}
@@ -815,7 +863,12 @@
* @access private
*/
function parseRequest($headers, $data) {
- $this->debug('Entering parseRequest() for data of length ' .
strlen($data) . ' and type ' . $headers['content-type']);
+ $this->debug('Entering parseRequest() for data of length ' .
strlen($data) . ' headers:');
+ $this->appendDebug($this->varDump($headers));
+ if (!isset($headers['content-type'])) {
+ $this->setError('Request not of type text/xml (no
content-type header)');
+ return false;
+ }
if (!strstr($headers['content-type'], 'text/xml')) {
$this->setError('Request not of type text/xml');
return false;
@@ -832,9 +885,9 @@
// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for
HTTP 1.1
$this->xml_encoding = 'ISO-8859-1';
}
- $this->debug('Use encoding: ' . $this->xml_encoding . ' when
creating soap_parser');
+ $this->debug('Use encoding: ' . $this->xml_encoding . ' when
creating nusoap_parser');
// parse response, get soap parser obj
- $parser = createObject
("phpgwapi.soap_parser",$data,$this->xml_encoding,'',$this->decode_utf8);
+ $parser = createObject
("phpgwapi.nusoap_parser",$data,$this->xml_encoding,'',$this->decode_utf8);
// parser debug
$this->debug("parser debug: \n".$parser->getDebug());
// if fault occurred during message parsing
@@ -847,10 +900,12 @@
$this->methodURI = $parser->root_struct_namespace;
$this->methodname = $parser->root_struct_name;
$this->debug('methodname: '.$this->methodname.'
methodURI: '.$this->methodURI);
- $this->debug('calling parser->get_response()');
- $this->methodparams = $parser->get_response();
+ $this->debug('calling parser->get_soapbody()');
+ $this->methodparams = $parser->get_soapbody();
// get SOAP headers
$this->requestHeaders = $parser->getHeaders();
+ // get SOAP Header
+ $this->requestHeader = $parser->get_soapheader();
// add document for doclit support
$this->document = $parser->document;
}
@@ -940,13 +995,20 @@
if (isset($_SERVER)) {
$SERVER_NAME = $_SERVER['SERVER_NAME'];
$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ?
$_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+ $HTTPS = isset($_SERVER['HTTPS']) ?
$_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ?
$HTTP_SERVER_VARS['HTTPS'] : 'off');
} elseif (isset($HTTP_SERVER_VARS)) {
$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
$SCRIPT_NAME =
isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] :
$HTTP_SERVER_VARS['SCRIPT_NAME'];
+ $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ?
$HTTP_SERVER_VARS['HTTPS'] : 'off';
} else {
$this->setError("Neither _SERVER nor
HTTP_SERVER_VARS is available");
}
- $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
+ if ($HTTPS == '1' || $HTTPS == 'on') {
+ $SCHEME = 'https';
+ } else {
+ $SCHEME = 'http';
+ }
+ $soapaction =
"$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
}
if(false == $style) {
$style = "rpc";
@@ -954,7 +1016,7 @@
if(false == $use) {
$use = "encoded";
}
- if ($use == 'encoded' && $encodingStyle = '') {
+ if ($use == 'encoded' && $encodingStyle == '') {
$encodingStyle =
'http://schemas.xmlsoap.org/soap/encoding/';
}
@@ -985,7 +1047,7 @@
if ($faultdetail == '' && $this->debug_flag) {
$faultdetail = $this->getDebug();
}
- $this->fault = createObject
("phpgwapi.soap_fault",$faultcode,$faultactor,$faultstring,$faultdetail);
+ $this->fault = createObject
("phpgwapi.nusoap_fault",$faultcode,$faultactor,$faultstring,$faultdetail);
$this->fault->soap_defencoding = $this->soap_defencoding;
}
@@ -1017,6 +1079,11 @@
} else {
$this->setError("Neither _SERVER nor HTTP_SERVER_VARS
is available");
}
+ // If server name has port number attached then strip it (else
port number gets duplicated in WSDL output) (occurred using lighttpd and
FastCGI)
+ $colon = strpos($SERVER_NAME,":");
+ if ($colon) {
+ $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
+ }
if ($SERVER_PORT == 80) {
$SERVER_PORT = '';
} else {
@@ -1048,7 +1115,10 @@
if ($schemaTargetNamespace != $namespace) {
$this->wsdl->namespaces['types'] =
$schemaTargetNamespace;
}
- $this->wsdl->schemas[$schemaTargetNamespace][0] = createObject
("phpgwapi.soap_XMLSchema",'', '', $this->wsdl->namespaces);
+ $this->wsdl->schemas[$schemaTargetNamespace][0] = createObject
("phpgwapi.nusoap_soap_XMLSchema",'', '', $this->wsdl->namespaces);
+ if ($style == 'document') {
+
$this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault']
= 'qualified';
+ }
$this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace
= $schemaTargetNamespace;
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0]
= array('location' => '', 'loaded' => true);
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0]
= array('location' => '', 'loaded' => true);
@@ -1064,6 +1134,10 @@
}
}
+/**
+ * Backward compatibility
+ */
+class phpgwapi_soap_server extends phpgwapi_nusoap_server {
+}
-
?>
Modified: core/trunk/phpgwapi/inc/class.soap_transport_http.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soap_transport_http.inc.php 2008-10-06
11:15:02 UTC (rev 18965)
+++ core/trunk/phpgwapi/inc/class.soap_transport_http.inc.php 2008-10-07
10:31:48 UTC (rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,22 +32,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_base');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
* transport class for sending/receiving data via HTTP and HTTPS
* NOTE: PHP must be compiled with the CURL extension for HTTPS support
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
class phpgwapi_soap_transport_http extends phpgwapi_nusoap_base {
@@ -60,38 +65,97 @@
var $incoming_cookies = array();
var $outgoing_payload = '';
var $incoming_payload = '';
+ var $response_status_line; // HTTP response status line
var $useSOAPAction = true;
var $persistentConnection = false;
var $ch = false; // cURL handle
+ var $ch_options = array(); // cURL custom options
+ var $use_curl = false; // force cURL use
+ var $proxy = null; // proxy information
(associative array)
var $username = '';
var $password = '';
var $authtype = '';
var $digestRequest = array();
- var $certRequest = array(); // keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost
(optional)
+ var $certRequest = array(); // keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer
(optional), verifyhost (optional)
// cainfofile:
certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
// sslcertfile:
SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
// sslkeyfile:
SSL key file, e.g. '$pathToPemFiles/mykey.pem'
// passphrase:
SSL key password/passphrase
+ //
certpassword: SSL certificate password
// verifypeer:
default is 1
// verifyhost:
default is 1
/**
* constructor
+ *
+ * @param string $url The URL to which to connect
+ * @param array $curl_options User-specified cURL options
+ * @param boolean $use_curl Whether to try to force cURL use
+ * @access public
*/
- function phpgwapi_soap_transport_http($url){
+ function phpgwapi_soap_transport_http($url, $curl_options = NULL,
$use_curl = false){
parent::phpgwapi_nusoap_base();
+ $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
+ $this->appendDebug($this->varDump($curl_options));
$this->setURL($url);
+ if (is_array($curl_options)) {
+ $this->ch_options = $curl_options;
+ }
+ $this->use_curl = $use_curl;
ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
- $this->outgoing_headers['User-Agent'] =
$this->title.'/'.$this->version.' ('.$rev[1].')';
- $this->debug('set User-Agent: ' .
$this->outgoing_headers['User-Agent']);
+ $this->setHeader('User-Agent',
$this->title.'/'.$this->version.' ('.$rev[1].')');
}
+ /**
+ * sets a cURL option
+ *
+ * @param mixed $option The cURL option (always integer?)
+ * @param mixed $value The cURL option value
+ * @access private
+ */
+ function setCurlOption($option, $value) {
+ $this->debug("setCurlOption option=$option, value=");
+ $this->appendDebug($this->varDump($value));
+ curl_setopt($this->ch, $option, $value);
+ }
+
+ /**
+ * sets an HTTP header
+ *
+ * @param string $name The name of the header
+ * @param string $value The value of the header
+ * @access private
+ */
+ function setHeader($name, $value) {
+ $this->outgoing_headers[$name] = $value;
+ $this->debug("set header $name: $value");
+ }
+
+ /**
+ * unsets an HTTP header
+ *
+ * @param string $name The name of the header
+ * @access private
+ */
+ function unsetHeader($name) {
+ if (isset($this->outgoing_headers[$name])) {
+ $this->debug("unset header $name");
+ unset($this->outgoing_headers[$name]);
+ }
+ }
+
+ /**
+ * sets the URL to which to connect
+ *
+ * @param string $url The URL to which to connect
+ * @access private
+ */
function setURL($url) {
$this->url = $url;
$u = parse_url($url);
foreach($u as $k => $v){
- $this->debug("$k = $v");
+ $this->debug("parsed URL $k = $v");
$this->$k = $v;
}
@@ -114,17 +178,38 @@
// build headers
if (!isset($u['port'])) {
- $this->outgoing_headers['Host'] = $this->host;
+ $this->setHeader('Host', $this->host);
} else {
- $this->outgoing_headers['Host'] =
$this->host.':'.$this->port;
+ $this->setHeader('Host', $this->host.':'.$this->port);
}
- $this->debug('set Host: ' . $this->outgoing_headers['Host']);
if (isset($u['user']) && $u['user'] != '') {
$this->setCredentials(urldecode($u['user']),
isset($u['pass']) ? urldecode($u['pass']) : '');
}
}
-
+
+ /**
+ * gets the I/O method to use
+ *
+ * @return string I/O method to use (socket|curl|unknown)
+ * @access private
+ */
+ function io_method() {
+ if ($this->use_curl || ($this->scheme == 'https') ||
($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme ==
'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
+ return 'curl';
+ if (($this->scheme == 'http' || $this->scheme == 'ssl') &&
$this->authtype != 'ntlm' && (!is_array($this->proxy) ||
$this->proxy['authtype'] != 'ntlm'))
+ return 'socket';
+ return 'unknown';
+ }
+
+ /**
+ * establish an HTTP connection
+ *
+ * @param integer $timeout set connection timeout in seconds
+ * @param integer $response_timeout set response timeout in
seconds
+ * @return boolean true if connected, false if not
+ * @access private
+ */
function connect($connection_timeout=0,$response_timeout=30){
// For PHP 4.3 with OpenSSL, change https scheme to ssl, then
treat like
// "regular" socket.
@@ -139,7 +224,15 @@
// }
// }
$this->debug("connect connection_timeout $connection_timeout,
response_timeout $response_timeout, scheme $this->scheme, host $this->host,
port $this->port");
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
+ if (!is_array($this->proxy)) {
+ $host = $this->host;
+ $port = $this->port;
+ } else {
+ $host = $this->proxy['host'];
+ $port = $this->proxy['port'];
+ }
+
// use persistent connection
if($this->persistentConnection && isset($this->fp) &&
is_resource($this->fp)){
if (!feof($this->fp)) {
@@ -152,9 +245,7 @@
// munge host if using OpenSSL
if ($this->scheme == 'ssl') {
- $host = 'ssl://' . $this->host;
- } else {
- $host = $this->host;
+ $host = 'ssl://' . $host;
}
$this->debug('calling fsockopen with host ' . $host . '
connection_timeout ' . $connection_timeout);
@@ -184,82 +275,157 @@
$this->debug('socket connected');
return true;
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
if (!extension_loaded('curl')) {
- $this->setError('CURL Extension, or OpenSSL extension
w/ PHP version >= 4.3 is required for HTTPS');
+// $this->setError('cURL Extension, or OpenSSL extension
w/ PHP version >= 4.3 is required for HTTPS');
+ $this->setError('The PHP cURL Extension is required for
HTTPS or NLTM. You will need to re-build or update your PHP to included
cURL.');
return false;
}
- $this->debug('connect using https');
+ // Avoid warnings when PHP does not have these options
+ if (defined('CURLOPT_CONNECTIONTIMEOUT'))
+ $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
+ else
+ $CURLOPT_CONNECTIONTIMEOUT = 78;
+ if (defined('CURLOPT_HTTPAUTH'))
+ $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
+ else
+ $CURLOPT_HTTPAUTH = 107;
+ if (defined('CURLOPT_PROXYAUTH'))
+ $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
+ else
+ $CURLOPT_PROXYAUTH = 111;
+ if (defined('CURLAUTH_BASIC'))
+ $CURLAUTH_BASIC = CURLAUTH_BASIC;
+ else
+ $CURLAUTH_BASIC = 1;
+ if (defined('CURLAUTH_DIGEST'))
+ $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
+ else
+ $CURLAUTH_DIGEST = 2;
+ if (defined('CURLAUTH_NTLM'))
+ $CURLAUTH_NTLM = CURLAUTH_NTLM;
+ else
+ $CURLAUTH_NTLM = 8;
+
+ $this->debug('connect using cURL');
// init CURL
$this->ch = curl_init();
// set url
- $hostURL = ($this->port != '') ?
"https://$this->host:$this->port" : "https://$this->host";
+ $hostURL = ($this->port != '') ?
"$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
// add path
$hostURL .= $this->path;
- curl_setopt($this->ch, CURLOPT_URL, $hostURL);
+ $this->setCurlOption(CURLOPT_URL, $hostURL);
// follow location headers (re-directs)
- curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
+ if (ini_get('safe_mode') || ini_get('open_basedir')) {
+ $this->debug('safe_mode or open_basedir set, so do not
set CURLOPT_FOLLOWLOCATION');
+ $this->debug('safe_mode = ');
+
$this->appendDebug($this->varDump(ini_get('safe_mode')));
+ $this->debug('open_basedir = ');
+
$this->appendDebug($this->varDump(ini_get('open_basedir')));
+ } else {
+ $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
+ }
// ask for headers in the response output
- curl_setopt($this->ch, CURLOPT_HEADER, 1);
+ $this->setCurlOption(CURLOPT_HEADER, 1);
// ask for the response output as the return value
- curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
+ $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
// encode
// We manage this ourselves through headers and encoding
// if(function_exists('gzuncompress')){
-// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
+// $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
// }
// persistent connection
if ($this->persistentConnection) {
+ // I believe the following comment is now bogus, having
applied to
+ // the code when it used CURLOPT_CUSTOMREQUEST to send
the request.
// The way we send data, we cannot use persistent
connections, since
// there will be some "junk" at the end of our request.
- //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
+ //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
$this->persistentConnection = false;
- $this->outgoing_headers['Connection'] = 'close';
- $this->debug('set Connection: ' .
$this->outgoing_headers['Connection']);
+ $this->setHeader('Connection', 'close');
}
- // set timeout
+ // set timeouts
if ($connection_timeout != 0) {
- curl_setopt($this->ch, CURLOPT_TIMEOUT,
$connection_timeout);
+ $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT,
$connection_timeout);
}
- // TODO: cURL has added a connection timeout separate from the
response timeout
- //if ($connection_timeout != 0) {
- // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT,
$connection_timeout);
- //}
- //if ($response_timeout != 0) {
- // curl_setopt($this->ch, CURLOPT_TIMEOUT,
$response_timeout);
- //}
+ if ($response_timeout != 0) {
+ $this->setCurlOption(CURLOPT_TIMEOUT,
$response_timeout);
+ }
- // recent versions of cURL turn on peer/host checking by
default,
- // while PHP binaries are not compiled with a default location
for the
- // CA cert bundle, so disable peer/host checking.
-//curl_setopt($this->ch, CURLOPT_CAINFO,
'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
-
- // support client certificates (thanks Tobias Boes, Doug
Anarino, Eryan Ariobowo)
- if ($this->authtype == 'certificate') {
- if (isset($this->certRequest['cainfofile'])) {
- curl_setopt($this->ch, CURLOPT_CAINFO,
$this->certRequest['cainfofile']);
+ if ($this->scheme == 'https') {
+ $this->debug('set cURL SSL verify options');
+ // recent versions of cURL turn on peer/host checking
by default,
+ // while PHP binaries are not compiled with a default
location for the
+ // CA cert bundle, so disable peer/host checking.
+ //$this->setCurlOption(CURLOPT_CAINFO,
'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
+ $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
+ $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
+
+ // support client certificates (thanks Tobias Boes,
Doug Anarino, Eryan Ariobowo)
+ if ($this->authtype == 'certificate') {
+ $this->debug('set cURL certificate options');
+ if (isset($this->certRequest['cainfofile'])) {
+ $this->setCurlOption(CURLOPT_CAINFO,
$this->certRequest['cainfofile']);
+ }
+ if (isset($this->certRequest['verifypeer'])) {
+
$this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
+ } else {
+
$this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
+ }
+ if (isset($this->certRequest['verifyhost'])) {
+
$this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
+ } else {
+
$this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
+ }
+ if (isset($this->certRequest['sslcertfile'])) {
+ $this->setCurlOption(CURLOPT_SSLCERT,
$this->certRequest['sslcertfile']);
+ }
+ if (isset($this->certRequest['sslkeyfile'])) {
+ $this->setCurlOption(CURLOPT_SSLKEY,
$this->certRequest['sslkeyfile']);
+ }
+ if (isset($this->certRequest['passphrase'])) {
+
$this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
+ }
+ if (isset($this->certRequest['certpassword'])) {
+
$this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
+ }
}
- if (isset($this->certRequest['verifypeer'])) {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER,
$this->certRequest['verifypeer']);
- } else {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER,
1);
+ }
+ if ($this->authtype && ($this->authtype != 'certificate')) {
+ if ($this->username) {
+ $this->debug('set cURL username/password');
+ $this->setCurlOption(CURLOPT_USERPWD,
"$this->username:$this->password");
}
- if (isset($this->certRequest['verifyhost'])) {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST,
$this->certRequest['verifyhost']);
- } else {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST,
1);
+ if ($this->authtype == 'basic') {
+ $this->debug('set cURL for Basic
authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH,
$CURLAUTH_BASIC);
}
- if (isset($this->certRequest['sslcertfile'])) {
- curl_setopt($this->ch, CURLOPT_SSLCERT,
$this->certRequest['sslcertfile']);
+ if ($this->authtype == 'digest') {
+ $this->debug('set cURL for digest
authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH,
$CURLAUTH_DIGEST);
}
- if (isset($this->certRequest['sslkeyfile'])) {
- curl_setopt($this->ch, CURLOPT_SSLKEY,
$this->certRequest['sslkeyfile']);
+ if ($this->authtype == 'ntlm') {
+ $this->debug('set cURL for NTLM
authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH,
$CURLAUTH_NTLM);
}
- if (isset($this->certRequest['passphrase'])) {
- curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD ,
$this->certRequest['passphrase']);
+ }
+ if (is_array($this->proxy)) {
+ $this->debug('set cURL proxy options');
+ if ($this->proxy['port'] != '') {
+ $this->setCurlOption(CURLOPT_PROXY,
$this->proxy['host'].':'.$this->proxy['port']);
+ } else {
+ $this->setCurlOption(CURLOPT_PROXY,
$this->proxy['host']);
}
+ if ($this->proxy['username'] ||
$this->proxy['password']) {
+ $this->debug('set cURL proxy authentication
options');
+ $this->setCurlOption(CURLOPT_PROXYUSERPWD,
$this->proxy['username'].':'.$this->proxy['password']);
+ if ($this->proxy['authtype'] == 'basic') {
+
$this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
+ }
+ if ($this->proxy['authtype'] == 'ntlm') {
+
$this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
+ }
+ }
}
$this->debug('cURL connection set up');
return true;
@@ -269,9 +435,9 @@
return false;
}
}
-
+
/**
- * send the SOAP message via HTTP
+ * sends the SOAP request and gets the SOAP response via HTTP[S]
*
* @param string $data message data
* @param integer $timeout set connection timeout in seconds
@@ -302,7 +468,7 @@
// get response
$respdata = $this->getResponse();
} else {
- $this->setError('Too many tries to get an OK
response');
+ $this->setError("Too many tries to get an OK
response ($this->response_status_line)");
}
}
$this->debug('end of send()');
@@ -311,14 +477,15 @@
/**
- * send the SOAP message via HTTPS 1.0 using CURL
+ * sends the SOAP request and gets the SOAP response via HTTPS using CURL
*
- * @param string $msg message data
+ * @param string $data message data
* @param integer $timeout set connection timeout in seconds
* @param integer $response_timeout set response timeout in
seconds
* @param array $cookies cookies to send
* @return string data
* @access public
+ * @deprecated
*/
function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
return $this->send($data, $timeout, $response_timeout,
$cookies);
@@ -329,16 +496,19 @@
*
* @param string $username
* @param string $password
- * @param string $authtype (basic, digest, certificate)
+ * @param string $authtype (basic|digest|certificate|ntlm)
* @param array $digestRequest (keys must be nonce, nc, realm,
qop)
- * @param array $certRequest (keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost
(optional): see corresponding options in cURL docs)
+ * @param array $certRequest (keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer
(optional), verifyhost (optional): see corresponding options in cURL docs)
* @access public
*/
function setCredentials($username, $password, $authtype = 'basic',
$digestRequest = array(), $certRequest = array()) {
- $this->debug("Set credentials for authtype $authtype");
+ $this->debug("setCredentials username=$username
authtype=$authtype digestRequest=");
+ $this->appendDebug($this->varDump($digestRequest));
+ $this->debug("certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
// cf. RFC 2617
if ($authtype == 'basic') {
- $this->outgoing_headers['Authorization'] = 'Basic
'.base64_encode(str_replace(':','',$username).':'.$password);
+ $this->setHeader('Authorization', 'Basic
'.base64_encode(str_replace(':','',$username).':'.$password));
} elseif ($authtype == 'digest') {
if (isset($digestRequest['nonce'])) {
$digestRequest['nc'] =
isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
@@ -352,7 +522,7 @@
$HA1 = md5($A1);
// A2 = Method ":" digest-uri-value
- $A2 = 'POST:' . $this->digest_uri;
+ $A2 = $this->request_method . ':' .
$this->digest_uri;
// H(A2)
$HA2 = md5($A2);
@@ -379,21 +549,24 @@
$hashedDigest = md5($unhashedDigest);
- $this->outgoing_headers['Authorization'] =
'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '",
nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce .
'", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' .
$digestRequest['qop'] . '", response="' . $hashedDigest . '"';
+ $opaque = '';
+ if (isset($digestRequest['opaque'])) {
+ $opaque = ', opaque="' .
$digestRequest['opaque'] . '"';
+ }
+
+ $this->setHeader('Authorization', 'Digest
username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="'
. $nonce . '", uri="' . $this->digest_uri . $opaque . '", cnonce="' . $cnonce .
'", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' .
$digestRequest['qop'] . '", response="' . $hashedDigest . '"');
}
} elseif ($authtype == 'certificate') {
$this->certRequest = $certRequest;
+ $this->debug('Authorization header not set for
certificate');
+ } elseif ($authtype == 'ntlm') {
+ // do nothing
+ $this->debug('Authorization header not set for ntlm');
}
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
$this->digestRequest = $digestRequest;
-
- if (isset($this->outgoing_headers['Authorization'])) {
- $this->debug('set Authorization: ' .
substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
- } else {
- $this->debug('Authorization header not set');
- }
}
/**
@@ -403,8 +576,7 @@
* @access public
*/
function setSOAPAction($soapaction) {
- $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
- $this->debug('set SOAPAction: ' .
$this->outgoing_headers['SOAPAction']);
+ $this->setHeader('SOAPAction', '"' . $soapaction . '"');
}
/**
@@ -416,12 +588,10 @@
function setEncoding($enc='gzip, deflate') {
if (function_exists('gzdeflate')) {
$this->protocol_version = '1.1';
- $this->outgoing_headers['Accept-Encoding'] = $enc;
- $this->debug('set Accept-Encoding: ' .
$this->outgoing_headers['Accept-Encoding']);
+ $this->setHeader('Accept-Encoding', $enc);
if (!isset($this->outgoing_headers['Connection'])) {
- $this->outgoing_headers['Connection'] = 'close';
+ $this->setHeader('Connection', 'close');
$this->persistentConnection = false;
- $this->debug('set Connection: ' .
$this->outgoing_headers['Connection']);
}
set_magic_quotes_runtime(0);
// deprecated
@@ -432,23 +602,59 @@
/**
* set proxy info here
*
- * @param string $proxyhost
+ * @param string $proxyhost use an empty string to remove proxy
* @param string $proxyport
* @param string $proxyusername
* @param string $proxypassword
+ * @param string $proxyauthtype (basic|ntlm)
* @access public
*/
- function setProxy($proxyhost, $proxyport, $proxyusername = '',
$proxypassword = '') {
- $this->uri = $this->url;
- $this->host = $proxyhost;
- $this->port = $proxyport;
- if ($proxyusername != '' && $proxypassword != '') {
- $this->outgoing_headers['Proxy-Authorization'] = '
Basic '.base64_encode($proxyusername.':'.$proxypassword);
- $this->debug('set Proxy-Authorization: ' .
$this->outgoing_headers['Proxy-Authorization']);
+ function setProxy($proxyhost, $proxyport, $proxyusername = '',
$proxypassword = '', $proxyauthtype = 'basic') {
+ if ($proxyhost) {
+ $this->proxy = array(
+ 'host' => $proxyhost,
+ 'port' => $proxyport,
+ 'username' => $proxyusername,
+ 'password' => $proxypassword,
+ 'authtype' => $proxyauthtype
+ );
+ if ($proxyusername != '' && $proxypassword != '' &&
$proxyauthtype = 'basic') {
+ $this->setHeader('Proxy-Authorization', ' Basic
'.base64_encode($proxyusername.':'.$proxypassword));
+ }
+ } else {
+ $this->debug('remove proxy');
+ $proxy = null;
+ unsetHeader('Proxy-Authorization');
}
}
+
/**
+ * Test if the given string starts with a header that is to be skipped.
+ * Skippable headers result from chunked transfer and proxy requests.
+ *
+ * @param string $data The string to check.
+ * @returns boolean Whether a skippable header was found.
+ * @access private
+ */
+ function isSkippableCurlHeader(&$data) {
+ $skipHeaders = array( 'HTTP/1.1 100',
+ 'HTTP/1.0 301',
+ 'HTTP/1.1 301',
+ 'HTTP/1.0 302',
+ 'HTTP/1.1 302',
+ 'HTTP/1.0 401',
+ 'HTTP/1.1 401',
+ 'HTTP/1.0 200
Connection established');
+ foreach ($skipHeaders as $hd) {
+ $prefix = substr($data, 0, strlen($hd));
+ if ($prefix == $hd) return true;
+ }
+
+ return false;
+ }
+
+ /**
* decode a string that is encoded w/ "chunked' transfer encoding
* as defined in RFC2068 19.4.6
*
@@ -507,16 +713,31 @@
return $new;
}
- /*
- * Writes payload, including HTTP headers, to
$this->outgoing_payload.
+ /**
+ * Writes the payload, including HTTP headers, to
$this->outgoing_payload.
+ *
+ * @param string $data HTTP body
+ * @param string $cookie_str data for HTTP Cookie header
+ * @return void
+ * @access private
*/
function buildPayload($data, $cookie_str = '') {
+ // Note: for cURL connections, $this->outgoing_payload is
ignored,
+ // as is the Content-Length header, but these are still created
as
+ // debugging guides.
+
// add content-length header
- $this->outgoing_headers['Content-Length'] = strlen($data);
- $this->debug('set Content-Length: ' .
$this->outgoing_headers['Content-Length']);
+ if ($this->request_method != 'GET') {
+ $this->setHeader('Content-Length', strlen($data));
+ }
// start building outgoing payload:
- $req = "$this->request_method $this->uri
HTTP/$this->protocol_version";
+ if ($this->proxy) {
+ $uri = $this->url;
+ } else {
+ $uri = $this->uri;
+ }
+ $req = "$this->request_method $uri
HTTP/$this->protocol_version";
$this->debug("HTTP request: $req");
$this->outgoing_payload = "$req\r\n";
@@ -541,6 +762,14 @@
$this->outgoing_payload .= $data;
}
+ /**
+ * sends the SOAP request via HTTP[S]
+ *
+ * @param string $data message data
+ * @param array $cookies cookies to send
+ * @return boolean true if OK, false if problem
+ * @access private
+ */
function sendRequest($data, $cookies = NULL) {
// build cookie string
$cookie_str = $this->getCookiesForRequest($cookies,
(($this->scheme == 'ssl') || ($this->scheme == 'https')));
@@ -548,7 +777,7 @@
// build payload
$this->buildPayload($data, $cookie_str);
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
// send payload
if(!fputs($this->fp, $this->outgoing_payload,
strlen($this->outgoing_payload))) {
$this->setError('couldn\'t write message data to
socket');
@@ -557,33 +786,51 @@
}
$this->debug('wrote data to socket, length = ' .
strlen($this->outgoing_payload));
return true;
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
// set payload
- // TODO: cURL does say this should only be the verb, and in
fact it
+ // cURL does say this should only be the verb, and in fact it
// turns out that the URI and HTTP version are appended to
this, which
- // some servers refuse to work with
- //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST,
$this->outgoing_payload);
+ // some servers refuse to work with (so we no longer use this
method!)
+ //$this->setCurlOption(CURLOPT_CUSTOMREQUEST,
$this->outgoing_payload);
+ $curl_headers = array();
foreach($this->outgoing_headers as $k => $v){
- $curl_headers[] = "$k: $v";
+ if ($k == 'Connection' || $k == 'Content-Length' || $k
== 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
+ $this->debug("Skip cURL header $k: $v");
+ } else {
+ $curl_headers[] = "$k: $v";
+ }
}
if ($cookie_str != '') {
$curl_headers[] = 'Cookie: ' . $cookie_str;
}
- curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
+ $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
+ $this->debug('set cURL HTTP headers');
if ($this->request_method == "POST") {
- curl_setopt($this->ch, CURLOPT_POST, 1);
- curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+ $this->setCurlOption(CURLOPT_POST, 1);
+ $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
+ $this->debug('set cURL POST data');
} else {
}
+ // insert custom user-set cURL options
+ foreach ($this->ch_options as $key => $val) {
+ $this->setCurlOption($key, $val);
+ }
+
$this->debug('set cURL payload');
return true;
}
}
+ /**
+ * gets the SOAP response via HTTP[S]
+ *
+ * @return string the response (also sets member variables like
incoming_payload)
+ * @access private
+ */
function getResponse(){
$this->incoming_payload = '';
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
// loop until headers have been retrieved
$data = '';
while (!isset($lb)){
@@ -619,8 +866,8 @@
$lb = "\n";
}
}
- // remove 100 header
- if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
+ // remove 100 headers
+ if (isset($lb) && ereg('^HTTP/1.1 100',$data)) {
unset($lb);
$data = '';
}//
@@ -746,7 +993,7 @@
// $this->incoming_payload = $header_data.$lb.$lb.$data;
// }
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
// send and receive
$this->debug('send and receive with cURL');
$this->incoming_payload = curl_exec($this->ch);
@@ -772,14 +1019,28 @@
$this->debug('No cURL error, closing cURL');
curl_close($this->ch);
- // remove 100 header(s)
- while (ereg('^HTTP/1.1 100',$data)) {
+ // try removing skippable headers
+ $savedata = $data;
+ while ($this->isSkippableCurlHeader($data)) {
+ $this->debug("Found HTTP header to skip");
if ($pos = strpos($data,"\r\n\r\n")) {
$data = ltrim(substr($data,$pos));
} elseif($pos = strpos($data,"\n\n") ) {
$data = ltrim(substr($data,$pos));
}
}
+
+ if ($data == '') {
+ // have nothing left; just remove 100 header(s)
+ $data = $savedata;
+ while (ereg('^HTTP/1.1 100',$data)) {
+ if ($pos = strpos($data,"\r\n\r\n")) {
+ $data = ltrim(substr($data,$pos));
+ } elseif($pos = strpos($data,"\n\n") ) {
+ $data = ltrim(substr($data,$pos));
+ }
+ }
+ }
// separate content from HTTP headers
if ($pos = strpos($data,"\r\n\r\n")) {
@@ -819,14 +1080,15 @@
}
}
- $arr = explode(' ', $header_array[0], 3);
+ $this->response_status_line = $header_array[0];
+ $arr = explode(' ', $this->response_status_line, 3);
$http_version = $arr[0];
$http_status = intval($arr[1]);
$http_reason = count($arr) > 2 ? $arr[2] : '';
// see if we need to resend the request with http digest
authentication
- if (isset($this->incoming_headers['location']) && $http_status
== 301) {
- $this->debug("Got 301 $http_reason with Location: " .
$this->incoming_headers['location']);
+ if (isset($this->incoming_headers['location']) && ($http_status
== 301 || $http_status == 302)) {
+ $this->debug("Got $http_status $http_reason with
Location: " . $this->incoming_headers['location']);
$this->setURL($this->incoming_headers['location']);
$this->tryagain = true;
return false;
@@ -936,19 +1198,30 @@
return $data;
}
+ /**
+ * sets the content-type for the SOAP message to be sent
+ *
+ * @param string $type the content type, MIME style
+ * @param mixed $charset character set used for encoding (or
false)
+ * @access public
+ */
function setContentType($type, $charset = false) {
- $this->outgoing_headers['Content-Type'] = $type . ($charset ?
'; charset=' . $charset : '');
- $this->debug('set Content-Type: ' .
$this->outgoing_headers['Content-Type']);
+ $this->setHeader('Content-Type', $type . ($charset ? ';
charset=' . $charset : ''));
}
+ /**
+ * specifies that an HTTP persistent connection should be used
+ *
+ * @return boolean whether the request was honored by this method.
+ * @access public
+ */
function usePersistentConnection(){
if (isset($this->outgoing_headers['Accept-Encoding'])) {
return false;
}
$this->protocol_version = '1.1';
$this->persistentConnection = true;
- $this->outgoing_headers['Connection'] = 'Keep-Alive';
- $this->debug('set Connection: ' .
$this->outgoing_headers['Connection']);
+ $this->setHeader('Connection', 'Keep-Alive');
return true;
}
Modified: core/trunk/phpgwapi/inc/class.soapval.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.soapval.inc.php 2008-10-06 11:15:02 UTC
(rev 18965)
+++ core/trunk/phpgwapi/inc/class.soapval.inc.php 2008-10-07 10:31:48 UTC
(rev 18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,9 +32,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
- phpgw::import_class('phpgwapi.nusoap_base');
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_base');
+
+
/**
* For creating serializable abstractions of native PHP types. This class
* allows element name/namespace, XSD type, and XML attributes to be
@@ -36,7 +47,7 @@
* xsd:anyType and user-defined types.
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
class phpgwapi_soapval extends phpgwapi_nusoap_base {
@@ -112,7 +123,7 @@
* @access public
*/
function serialize($use='encoded') {
- return
$this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
+ return $this->serialize_val($this->value, $this->name,
$this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
}
/**
Modified: core/trunk/phpgwapi/inc/class.wsdl.inc.php
===================================================================
--- core/trunk/phpgwapi/inc/class.wsdl.inc.php 2008-10-06 11:15:02 UTC (rev
18965)
+++ core/trunk/phpgwapi/inc/class.wsdl.inc.php 2008-10-07 10:31:48 UTC (rev
18966)
@@ -1,17 +1,24 @@
<?php
/**
- * This file is generated automaticaly from the nusoap library for
- * phpGroupWare, using the nusoap2phpgwapi.php script written for this
purpose by
- * Caeies (address@hidden)
- * @copyright Portions Copyright (C) 2003,2006 Free Software Foundation,
Inc. http://www.fsf.org/
- * @package phpgwapi
- * @subpackage communication
- * Please see original header after this one and
class.nusoap_base.inc.php
- * @version $Id$
- */
+ * phpGroupWare - SOAP
+ *
+ * @link http://sourceforge.net/projects/nusoap/ This code is taken
from the NuSOAP library
+ *
+ * @internal This file was automatically generated by the
nusoap2phpgwapi.php
+ * script written. Please see original header after this one and
+ * class.nusoap_base.inc.php for more information
+ *
+ * @author Caeies (conversion script) <address@hidden>
+ * @copyright Portions Copyright (C) 2003-2008 Free Software
Foundation, Inc. http://www.fsf.org/
+ *
+ * @package phpgwapi
+ * @subpackage communication
+ *
+ * @version $Id:$
+ */
/*
- This program is free software: you can redistribute it and/or modify
+ This program 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 3 of the License, or
(at your option) any later version.
@@ -25,21 +32,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Please see class.base_nusoap.inc.php for more information */
+ /*
+ * Include dependency
+ */
+ phpgw::import_class('phpgwapi.nusoap_base');
-if (@!$GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'])
-{
- require_once(PHPGW_API_INC."/class.nusoap_base.inc.php");
- $GLOBALS['phpgw_info']['flags']['included_classes']['nusoap_base'] =
True;
-}
-
/**
-* parses a WSDL file, allows access to it's data, other utility methods
+* parses a WSDL file, allows access to it's data, other utility methods.
+* also builds WSDL structures programmatically.
*
* @author Dietrich Ayala <address@hidden>
-* @version $ I d : nusoap.php,v 1.95 2006/02/02 15:52:34 snichol Exp $
+* @author Scott Nichol <address@hidden>
+* @version $ I d : nusoap.php,v 1.121 2008/03/14 20:52:11 snichol Exp $
* @access public
*/
class phpgwapi_wsdl extends phpgwapi_nusoap_base {
@@ -77,6 +83,13 @@
var $proxypassword = '';
var $timeout = 0;
var $response_timeout = 30;
+ var $curl_options = array(); // User-specified cURL options
+ var $use_curl = false; // whether to always try to use
cURL
+ // for HTTP authentication
+ var $username = ''; // Username for HTTP
authentication
+ var $password = ''; // Password for HTTP
authentication
+ var $authtype = ''; // Type of HTTP
authentication
+ var $certRequest = array(); // Certificate for HTTP SSL
authentication
/**
* constructor
@@ -88,82 +101,96 @@
* @param string $proxypassword
* @param integer $timeout set the connection timeout
* @param integer $response_timeout set the response timeout
+ * @param array $curl_options user-specified cURL options
+ * @param boolean $use_curl try to use cURL
* @access public
*/
- function phpgwapi_wsdl($wsdl =
'',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
+ function phpgwapi_wsdl($wsdl =
'',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
parent::phpgwapi_nusoap_base();
- $this->wsdl = $wsdl;
+ $this->debug("ctor wsdl=$wsdl timeout=$timeout
response_timeout=$response_timeout");
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
$this->timeout = $timeout;
$this->response_timeout = $response_timeout;
-
+ if (is_array($curl_options))
+ $this->curl_options = $curl_options;
+ $this->use_curl = $use_curl;
+ $this->fetchWSDL($wsdl);
+ }
+
+ /**
+ * fetches the WSDL document and parses it
+ *
+ * @access public
+ */
+ function fetchWSDL($wsdl) {
+ $this->debug("parse and process WSDL path=$wsdl");
+ $this->wsdl = $wsdl;
// parse wsdl file
- if ($wsdl != "") {
- $this->debug('initial wsdl URL: ' . $wsdl);
- $this->parseWSDL($wsdl);
+ if ($this->wsdl != "") {
+ $this->parseWSDL($this->wsdl);
}
// imports
// TODO: handle imports more properly, grabbing them in-line and
nesting them
- $imported_urls = array();
- $imported = 1;
- while ($imported > 0) {
- $imported = 0;
- // Schema imports
- foreach ($this->schemas as $ns => $list) {
- foreach ($list as $xs) {
- $wsdlparts =
parse_url($this->wsdl); // this is bogusly simple!
- foreach ($xs->imports as $ns2 => $list2) {
- for ($ii = 0; $ii < count($list2);
$ii++) {
- if (! $list2[$ii]['loaded']) {
-
$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
- $url =
$list2[$ii]['location'];
- if
($url != '') {
-
$urlparts = parse_url($url);
-
if (!isset($urlparts['host'])) {
-
$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] .
(isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
-
substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1)
.$urlparts['path'];
-
}
-
if (! in_array($url, $imported_urls)) {
-
$this->parseWSDL($url);
-
$imported++;
-
$imported_urls[] = $url;
- }
- } else {
-
$this->debug("Unexpected scenario: empty URL for unloaded import");
+ $imported_urls = array();
+ $imported = 1;
+ while ($imported > 0) {
+ $imported = 0;
+ // Schema imports
+ foreach ($this->schemas as $ns => $list) {
+ foreach ($list as $xs) {
+ $wsdlparts = parse_url($this->wsdl);
// this is bogusly simple!
+ foreach ($xs->imports as $ns2 => $list2) {
+ for ($ii = 0; $ii < count($list2); $ii++) {
+ if (! $list2[$ii]['loaded']) {
+
$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
+ $url = $list2[$ii]['location'];
+ if ($url != '')
{
+
$urlparts = parse_url($url);
+ if
(!isset($urlparts['host'])) {
+
$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] .
(isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
+
substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') +
1) .$urlparts['path'];
}
+ if (!
in_array($url, $imported_urls)) {
+
$this->parseWSDL($url);
+ $imported++;
+
$imported_urls[] = $url;
+ }
+ } else {
+
$this->debug("Unexpected scenario: empty URL for unloaded import");
}
}
- }
- }
- }
- // WSDL imports
- $wsdlparts = parse_url($this->wsdl); // this
is bogusly simple!
- foreach ($this->import as $ns => $list) {
- for ($ii = 0; $ii < count($list); $ii++) {
- if (! $list[$ii]['loaded']) {
- $this->import[$ns][$ii]['loaded'] =
true;
- $url = $list[$ii]['location'];
- if ($url != '') {
- $urlparts =
parse_url($url);
- if
(!isset($urlparts['host'])) {
- $url =
$wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port'])
? ':' . $wsdlparts['port'] : '') .
-
substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1)
.$urlparts['path'];
- }
- if (!
in_array($url, $imported_urls)) {
- $this->parseWSDL($url);
- $imported++;
- $imported_urls[] = $url;
- }
- } else {
-
$this->debug("Unexpected scenario: empty URL for unloaded import");
+ }
+ }
+ }
+ }
+ // WSDL imports
+ $wsdlparts = parse_url($this->wsdl); // this is
bogusly simple!
+ foreach ($this->import as $ns => $list) {
+ for ($ii = 0; $ii < count($list); $ii++) {
+ if (! $list[$ii]['loaded']) {
+ $this->import[$ns][$ii]['loaded'] = true;
+ $url = $list[$ii]['location'];
+ if ($url != '') {
+ $urlparts =
parse_url($url);
+ if
(!isset($urlparts['host'])) {
+ $url =
$wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port'])
? ':' . $wsdlparts['port'] : '') .
+
substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1)
.$urlparts['path'];
}
+ if (! in_array($url,
$imported_urls)) {
+ $this->parseWSDL($url);
+ $imported++;
+ $imported_urls[] = $url;
+ }
+ } else {
+
$this->debug("Unexpected scenario: empty URL for unloaded import");
}
}
- }
- }
+ }
+ }
+ }
// add new data to operation data
foreach($this->bindings as $binding => $bindingData) {
if (isset($bindingData['operations']) &&
is_array($bindingData['operations'])) {
@@ -183,7 +210,8 @@
if(isset($this->messages[
$this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
$this->bindings[$binding]['operations'][$operation]['output']['parts'] =
$this->messages[
$this->bindings[$binding]['operations'][$operation]['output']['message'] ];
}
- if (isset($bindingData['style'])) {
+ // Set operation style if necessary, but do not override
one already provided
+ if (isset($bindingData['style']) &&
!isset($this->bindings[$binding]['operations'][$operation]['style'])) {
$this->bindings[$binding]['operations'][$operation]['style'] =
$bindingData['style'];
}
$this->bindings[$binding]['operations'][$operation]['transport'] =
isset($bindingData['transport']) ? $bindingData['transport'] : '';
@@ -192,7 +220,7 @@
}
}
}
- }
+ }
/**
* parses the wsdl document
@@ -200,8 +228,9 @@
* @param string $wsdl path or URL
* @access private
*/
- function parseWSDL($wsdl = '')
- {
+ function parseWSDL($wsdl = '') {
+ $this->debug("parse WSDL at path=$wsdl");
+
if ($wsdl == '') {
$this->debug('no wsdl passed to parseWSDL()!!');
$this->setError('no wsdl passed to parseWSDL()!!');
@@ -214,12 +243,15 @@
if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http'
|| $wsdl_props['scheme'] == 'https')) {
$this->debug('getting WSDL http(s) URL ' . $wsdl);
// get wsdl
- $tr = createObject ("phpgwapi.soap_transport_http",$wsdl);
+ $tr = createObject ("phpgwapi.soap_transport_http",$wsdl,
$this->curl_options, $this->use_curl);
$tr->request_method = 'GET';
$tr->useSOAPAction = false;
if($this->proxyhost && $this->proxyport){
$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
}
+ if ($this->authtype != '') {
+ $tr->setCredentials($this->username,
$this->password, $this->authtype, array(), $this->certRequest);
+ }
$tr->setEncoding('gzip, deflate');
$wsdl_string = $tr->send('', $this->timeout,
$this->response_timeout);
//$this->debug("WSDL request\n" .
$tr->outgoing_payload);
@@ -227,7 +259,7 @@
$this->appendDebug($tr->getDebug());
// catch errors
if($err = $tr->getError() ){
- $errstr = 'HTTP ERROR: '.$err;
+ $errstr = 'Getting ' . $wsdl . ' - HTTP ERROR:
'.$err;
$this->debug($errstr);
$this->setError($errstr);
unset($tr);
@@ -310,7 +342,7 @@
$this->debug('Parsing WSDL schema');
// $this->debug("startElement for $name ($attrs[name]). status =
$this->status (".$this->getLocalPart($name).")");
$this->status = 'schema';
- $this->currentSchema = createObject ("phpgwapi.soap_XMLSchema",'',
'', $this->namespaces);
+ $this->currentSchema = createObject
("phpgwapi.nusoap_soap_XMLSchema",'', '', $this->namespaces);
$this->currentSchema->schemaStartElement($parser, $name, $attrs);
$this->appendDebug($this->currentSchema->getDebug());
$this->currentSchema->clearDebug();
@@ -364,12 +396,12 @@
case 'message':
if ($name == 'part') {
if (isset($attrs['type'])) {
- $this->debug("msg " . $this->currentMessage
. ": found part $attrs[name]: " . implode(',', $attrs));
+ $this->debug("msg " . $this->currentMessage
. ": found part (with type) $attrs[name]: " . implode(',', $attrs));
$this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
}
if (isset($attrs['element'])) {
- $this->debug("msg " . $this->currentMessage
. ": found part $attrs[name]: " . implode(',', $attrs));
-
$this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
+ $this->debug("msg " . $this->currentMessage
. ": found part (with element) $attrs[name]: " . implode(',', $attrs));
+
$this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] .
'^';
}
}
break;
@@ -553,6 +585,24 @@
$this->documentation .= $data;
}
}
+
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $username
+ * @param string $password
+ * @param string $authtype (basic|digest|certificate|ntlm)
+ * @param array $certRequest (keys must be cainfofile (optional),
sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer
(optional), verifyhost (optional): see corresponding options in cURL docs)
+ * @access public
+ */
+ function setCredentials($username, $password, $authtype = 'basic',
$certRequest = array()) {
+ $this->debug("setCredentials username=$username
authtype=$authtype certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
+ $this->username = $username;
+ $this->password = $password;
+ $this->authtype = $authtype;
+ $this->certRequest = $certRequest;
+ }
function getBindingData($binding)
{
@@ -564,37 +614,48 @@
/**
* returns an assoc array of operation names => operation data
*
- * @param string $bindingType eg: soap, smtp, dime (only soap is
currently supported)
+ * @param string $portName WSDL port name
+ * @param string $bindingType eg: soap, smtp, dime (only soap and
soap12 are currently supported)
* @return array
* @access public
*/
- function getOperations($bindingType = 'soap')
- {
+ function getOperations($portName = '', $bindingType = 'soap') {
$ops = array();
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
+ } else {
+ $this->debug("getOperations bindingType $bindingType
may not be supported");
}
+ $this->debug("getOperations for port '$portName' bindingType
$bindingType");
// loop thru ports
foreach($this->ports as $port => $portData) {
- // binding type of port matches parameter
- if ($portData['bindingType'] == $bindingType) {
- //$this->debug("getOperations for port $port");
- //$this->debug("port data: " .
$this->varDump($portData));
- //$this->debug("bindings: " .
$this->varDump($this->bindings[ $portData['binding'] ]));
- // merge bindings
- if (isset($this->bindings[ $portData['binding']
]['operations'])) {
- $ops = array_merge ($ops,
$this->bindings[ $portData['binding'] ]['operations']);
+ $this->debug("getOperations checking port $port
bindingType " . $portData['bindingType']);
+ if ($portName == '' || $port == $portName) {
+ // binding type of port matches parameter
+ if ($portData['bindingType'] == $bindingType) {
+ $this->debug("getOperations found port
$port bindingType $bindingType");
+ //$this->debug("port data: " .
$this->varDump($portData));
+ //$this->debug("bindings: " .
$this->varDump($this->bindings[ $portData['binding'] ]));
+ // merge bindings
+ if (isset($this->bindings[
$portData['binding'] ]['operations'])) {
+ $ops = array_merge ($ops,
$this->bindings[ $portData['binding'] ]['operations']);
+ }
}
}
- }
+ }
+ if (count($ops) == 0) {
+ $this->debug("getOperations found no operations for
port '$portName' bindingType $bindingType");
+ }
return $ops;
}
/**
* returns an associative array of data necessary for calling an
operation
*
- * @param string $operation , name of operation
- * @param string $bindingType , type of binding eg: soap
+ * @param string $operation name of operation
+ * @param string $bindingType type of binding eg: soap, soap12
* @return array
* @access public
*/
@@ -602,6 +663,8 @@
{
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
}
// loop thru ports
foreach($this->ports as $port => $portData) {
@@ -624,13 +687,15 @@
* returns an associative array of data necessary for calling an
operation
*
* @param string $soapAction soapAction for operation
- * @param string $bindingType type of binding eg: soap
+ * @param string $bindingType type of binding eg: soap, soap12
* @return array
* @access public
*/
function getOperationDataForSoapAction($soapAction, $bindingType =
'soap') {
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType =
'http://schemas.xmlsoap.org/wsdl/soap12/';
}
// loop thru ports
foreach($this->ports as $port => $portData) {
@@ -658,11 +723,11 @@
* 'attrs' => array() // refs to attributes array
* )
*
- * @param $type string the type
- * @param $ns string namespace (not prefix) of the type
+ * @param string $type the type
+ * @param string $ns namespace (not prefix) of the type
* @return mixed
* @access public
- * @see xmlschema
+ * @see nusoap_xmlschema
*/
function getTypeDef($type, $ns) {
$this->debug("in getTypeDef: type=$type, ns=$ns");
@@ -670,6 +735,15 @@
$ns = $this->namespaces['tns'];
$this->debug("in getTypeDef: type namespace forced to
$ns");
}
+ if (!isset($this->schemas[$ns])) {
+ foreach ($this->schemas as $ns0 => $schema0) {
+ if (strcasecmp($ns, $ns0) == 0) {
+ $this->debug("in getTypeDef: replacing
schema namespace $ns with $ns0");
+ $ns = $ns0;
+ break;
+ }
+ }
+ }
if (isset($this->schemas[$ns])) {
$this->debug("in getTypeDef: have schema for namespace
$ns");
for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
@@ -678,6 +752,7 @@
$this->appendDebug($xs->getDebug());
$xs->clearDebug();
if ($t) {
+ $this->debug("in getTypeDef: found type
$type");
if (!isset($t['phpType'])) {
// get info for type to tack
onto the element
$uqType = substr($t['type'],
strrpos($t['type'], ':') + 1);
@@ -695,11 +770,14 @@
if
(isset($etype['attrs'])) {
$t['attrs'] =
$etype['attrs'];
}
+ } else {
+ $this->debug("did not
find type for [element] $type");
}
}
return $t;
}
}
+ $this->debug("in getTypeDef: did not find type $type");
} else {
$this->debug("in getTypeDef: do not have schema for
namespace $ns");
}
@@ -738,8 +816,9 @@
background-color: #ccccff; width: 20%; margin-left:
20px; margin-top: 20px; }
.title {
font-family: arial; font-size: 26px; color: #ffffff;
- background-color: #999999; width: 105%; margin-left:
0px;
- padding-top: 10px; padding-bottom: 10px; padding-left:
15px;}
+ background-color: #999999; width: 100%;
+ margin-left: 0px; margin-right: 0px;
+ padding-top: 10px; padding-bottom: 10px;}
.hidden {
position: absolute; visibility: hidden; z-index: 200;
left: 250px; top: 100px;
font-family: arial; overflow: hidden; width: 600;
@@ -904,13 +983,17 @@
}
}
$ns =
$this->getNamespaceFromPrefix($typePrefix);
- $typeDef =
$this->getTypeDef($this->getLocalPart($partType), $ns);
+ $localPart =
$this->getLocalPart($partType);
+ $typeDef =
$this->getTypeDef($localPart, $ns);
if ($typeDef['typeClass'] ==
'element') {
$elementortype =
'element';
+ if (substr($localPart,
-1) == '^') {
+ $localPart =
substr($localPart, 0, -1);
+ }
} else {
$elementortype = 'type';
}
- $xml .= "\n" . ' <part name="'
. $partName . '" ' . $elementortype . '="' . $typePrefix . ':' .
$this->getLocalPart($partType) . '" />';
+ $xml .= "\n" . ' <part name="'
. $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart .
'" />';
}
}
$xml .= '</message>';
@@ -969,9 +1052,87 @@
$xml .= "\n" . '</service>';
return $xml . "\n</definitions>";
}
-
+
/**
+ * determine whether a set of parameters are unwrapped
+ * when they are expect to be wrapped, Microsoft-style.
+ *
+ * @param string $type the type (element name) of the wrapper
+ * @param array $parameters the parameter values for the SOAP call
+ * @return boolean whether they parameters are unwrapped (and should be
wrapped)
+ * @access private
+ */
+ function parametersMatchWrapped($type, &$parameters) {
+ $this->debug("in parametersMatchWrapped type=$type,
parameters=");
+ $this->appendDebug($this->varDump($parameters));
+
+ // split type into namespace:unqualified-type
+ if (strpos($type, ':')) {
+ $uqType = substr($type, strrpos($type, ':') + 1);
+ $ns = substr($type, 0, strrpos($type, ':'));
+ $this->debug("in parametersMatchWrapped: got a prefixed
type: $uqType, $ns");
+ if ($this->getNamespaceFromPrefix($ns)) {
+ $ns = $this->getNamespaceFromPrefix($ns);
+ $this->debug("in parametersMatchWrapped:
expanded prefixed type: $uqType, $ns");
+ }
+ } else {
+ // TODO: should the type be compared to types in XSD,
and the namespace
+ // set to XSD if the type matches?
+ $this->debug("in parametersMatchWrapped: No namespace
for type $type");
+ $ns = '';
+ $uqType = $type;
+ }
+
+ // get the type information
+ if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
+ $this->debug("in parametersMatchWrapped: $type
($uqType) is not a supported type.");
+ return false;
+ }
+ $this->debug("in parametersMatchWrapped: found typeDef=");
+ $this->appendDebug($this->varDump($typeDef));
+ if (substr($uqType, -1) == '^') {
+ $uqType = substr($uqType, 0, -1);
+ }
+ $phpType = $typeDef['phpType'];
+ $arrayType = (isset($typeDef['arrayType']) ?
$typeDef['arrayType'] : '');
+ $this->debug("in parametersMatchWrapped: uqType: $uqType, ns:
$ns, phptype: $phpType, arrayType: $arrayType");
+
+ // we expect a complexType or element of complexType
+ if ($phpType != 'struct') {
+ $this->debug("in parametersMatchWrapped: not a struct");
+ return false;
+ }
+
+ // see whether the parameter names match the elements
+ if (isset($typeDef['elements']) &&
is_array($typeDef['elements'])) {
+ $elements = 0;
+ $matches = 0;
+ foreach ($typeDef['elements'] as $name => $attrs) {
+ if (isset($parameters[$name])) {
+ $this->debug("in
parametersMatchWrapped: have parameter named $name");
+ $matches++;
+ } else {
+ $this->debug("in
parametersMatchWrapped: do not have parameter named $name");
+ }
+ $elements++;
+ }
+
+ $this->debug("in parametersMatchWrapped: $matches
parameter names match $elements wrapped parameter names");
+ if ($matches == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ // since there are no elements for the type, if the user passed
no
+ // parameters, the parameters match wrapped.
+ $this->debug("in parametersMatchWrapped: no elements type
$ns:$uqType");
+ return count($parameters) == 0;
+ }
+
+ /**
* serialize PHP values according to a WSDL message definition
+ * contrary to the method name, this is not limited to RPC
*
* TODO
* - multi-ref serialization
@@ -980,12 +1141,12 @@
* @param string $operation operation name
* @param string $direction (input|output)
* @param mixed $parameters parameter value(s)
+ * @param string $bindingType (soap|soap12)
* @return mixed parameters serialized as XML or false on error (e.g.
operation not found)
* @access public
*/
- function serializeRPCParameters($operation, $direction, $parameters)
- {
- $this->debug("in serializeRPCParameters: operation=$operation,
direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
+ function serializeRPCParameters($operation, $direction, $parameters,
$bindingType = 'soap') {
+ $this->debug("in serializeRPCParameters: operation=$operation,
direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion,
bindingType=$bindingType");
$this->appendDebug('parameters=' . $this->varDump($parameters));
if ($direction != 'input' && $direction != 'output') {
@@ -993,12 +1154,12 @@
$this->setError('The value of the \$direction argument
needs to be either "input" or "output"');
return false;
}
- if (!$opData = $this->getOperationData($operation)) {
- $this->debug('Unable to retrieve WSDL data for
operation: ' . $operation);
- $this->setError('Unable to retrieve WSDL data for
operation: ' . $operation);
+ if (!$opData = $this->getOperationData($operation,
$bindingType)) {
+ $this->debug('Unable to retrieve WSDL data for
operation: ' . $operation . ' bindingType: ' . $bindingType);
+ $this->setError('Unable to retrieve WSDL data for
operation: ' . $operation . ' bindingType: ' . $bindingType);
return false;
}
- $this->debug('opData:');
+ $this->debug('in serializeRPCParameters: opData:');
$this->appendDebug($this->varDump($opData));
// Get encoding style for output and set to current
@@ -1011,14 +1172,36 @@
// set input params
$xml = '';
if (isset($opData[$direction]['parts']) &&
sizeof($opData[$direction]['parts']) > 0) {
-
+ $parts = &$opData[$direction]['parts'];
+ $part_count = sizeof($parts);
+ $style = $opData['style'];
$use = $opData[$direction]['use'];
- $this->debug('have ' .
count($opData[$direction]['parts']) . ' part(s) to serialize');
+ $this->debug("have $part_count part(s) to serialize
using $style/$use");
if (is_array($parameters)) {
$parametersArrayType =
$this->isArraySimpleOrStruct($parameters);
- $this->debug('have ' . count($parameters) . '
parameter(s) provided as ' . $parametersArrayType . ' to serialize');
- foreach($opData[$direction]['parts'] as $name
=> $type) {
- $this->debug('serializing part
"'.$name.'" of type "'.$type.'"');
+ $parameter_count = count($parameters);
+ $this->debug("have $parameter_count
parameter(s) provided as $parametersArrayType to serialize");
+ // check for Microsoft-style wrapped parameters
+ if ($style == 'document' && $use == 'literal'
&& $part_count == 1 && isset($parts['parameters'])) {
+ $this->debug('check whether the caller
has wrapped the parameters');
+ if ($direction == 'output' &&
$parametersArrayType == 'arraySimple' && $parameter_count == 1) {
+ // TODO: consider checking here
for double-wrapping, when
+ // service function wraps, then
NuSOAP wraps again
+ $this->debug("change simple
array to associative with 'parameters' element");
+ $parameters['parameters'] =
$parameters[0];
+ unset($parameters[0]);
+ }
+ if (($parametersArrayType ==
'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) {
+ $this->debug('check whether
caller\'s parameters match the wrapped ones');
+ if
($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
+ $this->debug('wrap the
parameters for the caller');
+ $parameters =
array('parameters' => $parameters);
+ $parameter_count = 1;
+ }
+ }
+ }
+ foreach ($parts as $name => $type) {
+ $this->debug("serializing part $name of
type $type");
// Track encoding style
if
(isset($opData[$direction]['encodingStyle']) && $encodingStyle !=
$opData[$direction]['encodingStyle']) {
$encodingStyle =
$opData[$direction]['encodingStyle'];
@@ -1056,9 +1239,10 @@
* - multi-ref serialization
* - validate PHP values against type definitions, return errors if
invalid
*
- * @param string $ type name
- * @param mixed $ param value
- * @return mixed new param or false if initial value didn't validate
+ * @param string $operation operation name
+ * @param string $direction (input|output)
+ * @param mixed $parameters parameter value(s)
+ * @return mixed parameters serialized as XML or false on error (e.g.
operation not found)
* @access public
* @deprecated
*/
@@ -1288,7 +1472,15 @@
} else {
$this->debug("in serializeType: found typeDef");
$this->appendDebug('typeDef=' .
$this->varDump($typeDef));
+ if (substr($uqType, -1) == '^') {
+ $uqType = substr($uqType, 0, -1);
+ }
}
+ if (!isset($typeDef['phpType'])) {
+ $this->setError("$type ($uqType) has no phpType.");
+ $this->debug("in serializeType: $type ($uqType) has no
phpType.");
+ return false;
+ }
$phpType = $typeDef['phpType'];
$this->debug("in serializeType: uqType: $uqType, ns: $ns,
phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ?
$typeDef['arrayType'] : '') );
// if php type == struct, map value to the <all> element names
@@ -1443,7 +1635,21 @@
* @access private
*/
function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
{
+ $this->debug("serializeComplexTypeAttributes for XML Schema
type $ns:$uqType");
$xml = '';
+ if (isset($typeDef['extensionBase'])) {
+ $nsx = $this->getPrefix($typeDef['extensionBase']);
+ $uqTypex =
$this->getLocalPart($typeDef['extensionBase']);
+ if ($this->getNamespaceFromPrefix($nsx)) {
+ $nsx = $this->getNamespaceFromPrefix($nsx);
+ }
+ if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
+ $this->debug("serialize attributes for
extension base $nsx:$uqTypex");
+ $xml .=
$this->serializeComplexTypeAttributes($typeDefx, $value, $nsx, $uqTypex);
+ } else {
+ $this->debug("extension base $nsx:$uqTypex is
not a supported type");
+ }
+ }
if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
$this->debug("serialize attributes for XML Schema type
$ns:$uqType");
if (is_array($value)) {
@@ -1476,19 +1682,6 @@
} else {
$this->debug("no attributes to serialize for XML Schema
type $ns:$uqType");
}
- if (isset($typeDef['extensionBase'])) {
- $ns = $this->getPrefix($typeDef['extensionBase']);
- $uqType =
$this->getLocalPart($typeDef['extensionBase']);
- if ($this->getNamespaceFromPrefix($ns)) {
- $ns = $this->getNamespaceFromPrefix($ns);
- }
- if ($typeDef = $this->getTypeDef($uqType, $ns)) {
- $this->debug("serialize attributes for
extension base $ns:$uqType");
- $xml .=
$this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
- } else {
- $this->debug("extension base $ns:$uqType is not
a supported type");
- }
- }
return $xml;
}
@@ -1505,7 +1698,21 @@
* @access private
*/
function serializeComplexTypeElements($typeDef, $value, $ns, $uqType,
$use='encoded', $encodingStyle=false) {
+ $this->debug("in serializeComplexTypeElements for XML Schema
type $ns:$uqType");
$xml = '';
+ if (isset($typeDef['extensionBase'])) {
+ $nsx = $this->getPrefix($typeDef['extensionBase']);
+ $uqTypex =
$this->getLocalPart($typeDef['extensionBase']);
+ if ($this->getNamespaceFromPrefix($nsx)) {
+ $nsx = $this->getNamespaceFromPrefix($nsx);
+ }
+ if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
+ $this->debug("serialize elements for extension
base $nsx:$uqTypex");
+ $xml .=
$this->serializeComplexTypeElements($typeDefx, $value, $nsx, $uqTypex, $use,
$encodingStyle);
+ } else {
+ $this->debug("extension base $nsx:$uqTypex is
not a supported type");
+ }
+ }
if (isset($typeDef['elements']) &&
is_array($typeDef['elements'])) {
$this->debug("in serializeComplexTypeElements,
serialize elements for XML Schema type $ns:$uqType");
if (is_array($value)) {
@@ -1576,40 +1783,29 @@
} else {
$this->debug("no elements to serialize for XML Schema
type $ns:$uqType");
}
- if (isset($typeDef['extensionBase'])) {
- $ns = $this->getPrefix($typeDef['extensionBase']);
- $uqType =
$this->getLocalPart($typeDef['extensionBase']);
- if ($this->getNamespaceFromPrefix($ns)) {
- $ns = $this->getNamespaceFromPrefix($ns);
- }
- if ($typeDef = $this->getTypeDef($uqType, $ns)) {
- $this->debug("serialize elements for extension
base $ns:$uqType");
- $xml .=
$this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use,
$encodingStyle);
- } else {
- $this->debug("extension base $ns:$uqType is not
a supported type");
- }
- }
return $xml;
}
/**
* adds an XML Schema complex type to the WSDL types
*
- * @param string name
- * @param string typeClass (complexType|simpleType|attribute)
- * @param string phpType: currently supported are array and struct (php
assoc array)
- * @param string compositor (all|sequence|choice)
- * @param string restrictionBase namespace:name
(http://schemas.xmlsoap.org/soap/encoding/:Array)
- * @param array elements = array ( name => array(name=>'',type=>'') )
- * @param array attrs =
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
- * @param string arrayType: namespace:name (xsd:string)
- * @see xmlschema
+ * @param string $name
+ * @param string $typeClass (complexType|simpleType|attribute)
+ * @param string $phpType currently supported are array and struct (php
assoc array)
+ * @param string $compositor (all|sequence|choice)
+ * @param string $restrictionBase namespace:name
(http://schemas.xmlsoap.org/soap/encoding/:Array)
+ * @param array $elements e.g. array ( name => array(name=>'',type=>'') )
+ * @param array $attrs e.g.
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
+ * @param string $arrayType as namespace:name (xsd:string)
+ * @see nusoap_xmlschema
* @access public
*/
function
addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='')
{
if (count($elements) > 0) {
+ $eElements = array();
foreach($elements as $n => $e){
// expand each element
+ $ee = array();
foreach ($e as $k => $v) {
$k = strpos($k,':') ? $this->expandQname($k) : $k;
$v = strpos($v,':') ? $this->expandQname($v) : $v;
@@ -1648,7 +1844,7 @@
* @param string $typeClass (should always be simpleType)
* @param string $phpType (should always be scalar)
* @param array $enumeration array of values
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addSimpleType($name, $restrictionBase='',
$typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
@@ -1662,7 +1858,7 @@
* adds an element to the WSDL types
*
* @param array $attrs attributes that must include name and type
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
@@ -1692,19 +1888,19 @@
if ($style == 'document') {
$elements = array();
foreach ($in as $n => $t) {
- $elements[$n] = array('name' => $n, 'type' =>
$t);
+ $elements[$n] = array('name' => $n, 'type' =>
$t, 'form' => 'unqualified');
}
$this->addComplexType($name . 'RequestType',
'complexType', 'struct', 'all', '', $elements);
$this->addElement(array('name' => $name, 'type' =>
$name . 'RequestType'));
- $in = array('parameters' => 'tns:' . $name);
+ $in = array('parameters' => 'tns:' . $name . '^');
$elements = array();
foreach ($out as $n => $t) {
- $elements[$n] = array('name' => $n, 'type' =>
$t);
+ $elements[$n] = array('name' => $n, 'type' =>
$t, 'form' => 'unqualified');
}
$this->addComplexType($name . 'ResponseType',
'complexType', 'struct', 'all', '', $elements);
- $this->addElement(array('name' => $name . 'Response',
'type' => $name . 'ResponseType'));
- $out = array('parameters' => 'tns:' . $name .
'Response');
+ $this->addElement(array('name' => $name . 'Response',
'type' => $name . 'ResponseType', 'form' => 'qualified'));
+ $out = array('parameters' => 'tns:' . $name .
'Response' . '^');
}
// get binding
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Phpgroupware-cvs] [18966] generate new soap classes based on current nusoap cvs head checkout and update generator,
Dave Hall <=