phpgroupware-cvs
[Top][All Lists]
Advanced

[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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]