Initial commit

This commit is contained in:
2026-09-03 11:24:19 +02:00
commit 6ed3153f36
1897 changed files with 538007 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+662
View File
@@ -0,0 +1,662 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
// To use PhpWsdlClient, you need to load it seperatly from PhpWsdl. Or you
// just load this class and let it autoload PhpWsdl
require_once(dirname(__FILE__).'/class.phpwsdl.php');
/**
* A SOAP client class for PhpWsdl
*
* @author Andreas Zimmermann, wan24.de
* @version 2.2
*/
class PhpWsdlClient{
/**
* The version number
*
* @var string
*/
public static $VERSION='2.2';
/**
* Parse a method
* 1: Type
* 2: Method
* 3: Parameters
*
* @var string
*/
public static $methodRx='/^([^\s]+)\s+([^\(]+)\(([^\)]+)?\).*$/';
/**
* Parse a type
* 1: Type
* 2: Name
*
* @var string
*/
public static $typeRx='/^([^\s]+)\s([^\[|\{|\s]+)[\[|\{|\s].*$/s';
/**
* Parse an element
* 1: Type
* 2: Name
*
* @var string
*/
public static $elementRx='/^\s*([^\s]+)\s+([^\s|;]+);.*$/';
/**
* The WSDL URI
*
* @var string
*/
public $WsdlUri;
/**
* The PHP SoapClient object
*
* @var SoapClient
*/
public $Client=null;
/**
* SOAP call options
*
* @var array
*/
public $Options;
/**
* SOAP call request headers
*
* @var array
*/
public $RequestHeaders;
/**
* PHP SoapClient options array
*
* @var array
*/
public $ClientOptions;
/**
* The webservice name
*
* @var string
*/
public $ServiceName=null;
/**
* The SOAP endpoint
*
* @var string
*/
public $EndPoint=null;
/**
* The SOAP namespace
*
* @var string
*/
public $NameSpace=null;
/**
* A PhpWsdl object
*
* @var PhpWsdl
*/
public $Server=null;
/**
* The WSDL
*
* @var string
*/
public $WSDL=null;
/**
* A list of warnings
*
* @var string[]
*/
public $Warnings=Array();
/**
* The http Auth username for fetching the WSDL (and sending SOAP requests, if PhpWsdlClient->UseSoapHttpAuth is TRUE)
* If you need a different login for SOAP requests, use the PhpWsdlClient->ClientOptions array fro the SOAP request
* authentification values (login/password)
*
* @var string
*/
public $HttpUser=null;
/**
* The http Auth password
*
* @var string
*/
public $HttpPassword=null;
/**
* Use http Auth for SOAP requests, too? If FALSE, the login will only be used to fetch the WSDL from the given URI
*
* @var boolean
*/
public $UseSoapHttpAuth=true;
/**
* Enable debugging of the RAW request/response?
*
* @var boolean
*/
public $Debugging=false;
/**
* Constructor
*
* @param string $wsdlUri The WSDL URI
* @param array $options SOAP call options (default: NULL)
* @param array $requestHeaders SOAP call request headers (default: NULL)
*/
public function PhpWsdlClient($wsdlUri,$options=null,$requestHeaders=null,$clientOptions=Array()){
PhpWsdl::Debug('New PhpWsdlClient '.$wsdlUri);
$this->WsdlUri=$wsdlUri;
$this->Options=$options;
$this->RequestHeaders=$requestHeaders;
$this->ClientOptions=array_merge(
Array(
'soap_version' => SOAP_1_1|SOAP_1_2,
'encoding' => 'UTF-8',
'compression' => SOAP_COMPRESSION_ACCEPT|SOAP_COMPRESSION_GZIP|9,
'connection_timeout'=>5
),
$clientOptions
);
$this->GetWsdlFromCache();
}
/**
* Fetch the WSDL (supports http Auth if CURL is enabled)
*
* @param string $wsdlUri The WSDL URI or NULL to use the PhpWsdlClient->WaslUri property (default: NULL)
* @param array $options The CURL options (default: array)
* @return string The WSDL XML
*/
public function FetchWsdl($wsdlUri=null,$options=Array()){
if(is_null($wsdlUri))
$wsdlUri=$this->WsdlUri;
PhpWsdl::Debug('Fetch WSDL from '.$wsdlUri);
if(!is_file($wsdlUri)&&function_exists('curl_init')&&!is_null($this->HttpUser)){
// Fetch with http Auth (credits to faebu :)
PhpWsdl::Debug('Try CURL for http Auth');
$ch=curl_init();
$credit=($this->HttpUser.':'.$this->HttpPassword);
curl_setopt_array($ch,array_merge(
Array(
CURLOPT_URL => $wsdlUri,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => $credit,
CURLOPT_TIMEOUT => 10,
CURLOPT_RETURNTRANSFER => 1
),
$options
));
$wsdl=curl_exec($ch);
if($wsdl===false){
PhpWsdl::Debug('Could not fetch WSDL with CURL: '.curl_error($ch));
@curl_close($ch);
}else{
curl_close($ch);
return $wsdl;
}
}
// Fetch without authentification
return file_get_contents($wsdlUri);
}
/**
* Do a SOAP request
*
* @param string $method The method name
* @param array $param The method parameters
* @param array $options The call options (default: array)
* @param array $requestHeaders The request headers (default: array)
* @return mixed The server response
*/
public function DoRequest($method,$param,$options=Array(),$requestHeaders=Array()){
PhpWsdl::Debug('Sending request '.$method);
$options=array_merge($this->Options,$options);
$requestHeaders=array_merge($this->RequestHeaders,$requestHeaders);
$client=$this->GetClient();
$res=$client->__soapCall($method,$param,$options,$requestHeaders);
if(is_soap_fault($res))
PhpWsdl::Debug('SOAP error #'.$res->faultcode.': '.$res->faultstring);
if($this->Debugging){
PhpWsdl::Debug('Parameters: '.print_r($param,true));
PhpWsdl::Debug('Options: '.print_r($options,true));
PhpWsdl::Debug('Headers: '.print_r($requestHeaders,true));
PhpWsdl::Debug('Result: '.print_r($res,true));
PhpWsdl::Debug('Request: '.$client->__getLastRequest());
PhpWsdl::Debug('Request headers: '.$client->__getLastRequestHeaders());
PhpWsdl::Debug('Response: '.$client->__getLastResponse());
PhpWsdl::Debug('Response headers: '.$client->__getLastResponseHeaders());
}
return $res;
}
/**
* Get the PHP SoapClient object
*
* @param string $uri The WSDL URI or NULL to use the PhpWsdlClient->WsdlUri property (default: NULL)
* @param array $options The additional PHP SoapClient options (default: array)
* @return SoapClient The PHP SoapClient object
*/
public function GetClient($uri=null,$options=Array()){
if(is_null($this->Client)){
if(is_null($uri))
$uri=$this->WsdlUri;
PhpWsdl::Debug('Create a PHP SoapClient object in PhpWsdlClient from '.$uri);
if(!is_null(PhpWsdl::$CacheFolder)){
$wsdlFile=$this->GetCacheFileName($uri);
if(!is_null($this->GetWsdlFromCache($wsdlFile))){
PhpWsdl::Debug('Use cached WSDL from '.$wsdlFile);
$uri=$wsdlFile;
}else{
$wsdl=$this->FetchWsdl($uri);
if($wsdl!==false)
if($this->WriteWsdlToCache($wsdl,$uri,$wsdlFile,true)){
PhpWsdl::Debug('Using cached WSDL from '.$wsdlFile);
$uri=$wsdlFile;
}
}
}
if(
!is_null($this->HttpUser)&&
!isset($this->ClientOptions['login'])&&
!isset($options['login'])&&
$this->UseSoapHttpAuth
){
PhpWsdl::Debug('Using http Auth options');
$options['login']=$this->HttpUser;
$options['password']=$this->HttpPassword;
}
if($this->Debugging){
PhpWsdl::Debug('Debugging enabled');
$options['trace']=true;
}
$this->Client=new SoapClient($uri,array_merge(
$this->ClientOptions,
$options
));
}
return $this->Client;
}
/**
* Create/Fill a PhpWsdl object from WSDL
*
* @param PhpWsdl An existing PhpWsdl object (default: NULL)
* @return PhpWsdl The PhpWsdl object
*/
public function CreateServerFromWsdl($soap=null){
PhpWsdl::Debug('Create/Fill a PhpWsdl object from WSDL');
if(is_null($soap)){
if(!is_null($this->Server)){
PhpWsdl::Debug('Return existing object');
return $this->Server;
}
$soap=PhpWsdl::CreateInstance();
}else{
PhpWsdl::Debug('Use existing object');
}
if(!is_null($soap->GetWsdlFromCache())){
PhpWsdl::Debug('Server created from cached values');
if(is_null($this->Server))
$this->Server=$soap;
return $soap;
}
// Configuration
$soap->WsdlUri=$this->WsdlUri;
$this->ParseWsdl();
if(!is_null($this->ServiceName))
$soap->Name=$this->ServiceName;
if(!is_null($this->NameSpace))
$soap->NameSpace=$this->NameSpace;
$client=$this->GetClient();
// Methods
$fnc=$client->__getFunctions();
$i=-1;
$len=sizeof($fnc);
while(++$i<$len){
$f=$fnc[$i];
list(
$type,
$method,
$temp
)=explode("\t",preg_replace(self::$methodRx,"$1\t$2\t$3",$f));
PhpWsdl::Debug('Found method #'.$i.' '.$method);
if(!is_null($soap->GetMethod($method))){
$this->Warn('WARNING: Double method detected!');
continue;
}
$m=new PhpWsdlMethod($method);
$temp=explode(' ',$temp);
$pLen=sizeof($temp);
for($j=0;$j<$pLen-1;$j++){
list(
$t,
$n
)=Array(
$temp[$j],
$temp[$j+1]
);
PhpWsdl::Debug('Found parameter #'.$j.' '.$n.' type of '.$t);
$m->Param[]=new PhpWsdlParam(substr($n,1),$t);
}
if($type!='void')
$m->Return=new PhpWsdlParam('return',$type);
$soap->Methods[]=$m;
}
// Types
$typ=$client->__getTypes();
$i=-1;
$len=sizeof($typ);
while(++$i<$len){
$t=$typ[$i];
list(
$type,
$name
)=explode("\t",preg_replace(self::$typeRx,"$1\t$2",$t));
PhpWsdl::Debug('Found type #'.$i.' '.$name.' type of '.$type);
if(!is_null($soap->GetType($name))){
$this->Warn('WARNING: Double type detected!');
continue;
}
$arr=strpos($t,'[]')>-1;
if($arr){
PhpWsdl::Debug('Array type');
$y=new PhpWsdlComplex($name);
$y->Type=$type;
$y->IsArray=true;
$soap->Types[]=$y;
}else if($type=='struct'){
PhpWsdl::Debug('Complex type');
$el=Array();
$temp=explode("\n",$t);
$j=0;
$eLen=sizeof($temp)-1;
while(++$j<$eLen){
list(
$p,
$n
)=explode("\t",preg_replace(self::$elementRx,"$1\t$2",$temp[$j]),2);
PhpWsdl::Debug('Found element #'.$j.' '.$n.' type of '.$p);
$el[]=new PhpWsdlElement($n,$p);
}
$y=new PhpWsdlComplex($name,$el);
$y->IsArray=false;
$soap->Types[]=$y;
}else{
$this->Warn('WARNING: Could not create type '.$t);
}
}
if(is_null($this->Server))
$this->Server=$soap;
return $soap;
}
/**
* Parse the WSDL for webservice name, namespace and endpoint URI
*/
public function ParseWsdl(){
if(!is_null($this->ServiceName)&&!is_null($this->EndPoint)&&!is_null($this->NameSpace))
return;
PhpWsdl::Debug('Parse WSDL');
$wsdl=$this->WSDL;
$writeCache=false;
if(is_null($wsdl)){
$wsdl=$this->FetchWsdl();
if($wsdl===false)
throw(new Exception('Could not fetch WSDL'));
$writeCache=true;
}
$xml=new DOMDocument();
if(!$xml->loadXML($wsdl))
throw(new Exception('Invalid WSDL'));
$x=new DOMXPath($xml);
// Namespace
$temp=$x->query("/*[local-name()='definitions']/@targetNamespace");
if($temp->length>0){
$temp=$temp->item(0);
PhpWsdl::Debug('Namespace '.$temp->value);
$this->NameSpace=$temp->value;
}else{
$this->Warn('WARNING: No namespace found');
}
// Webservice name
$temp=$x->query("/*[local-name()='definitions']/*[local-name()='service']/@name");
if($temp->length>0){
$temp=$temp->item(0);
PhpWsdl::Debug('Name '.$temp->value);
$this->ServiceName=$temp->value;
}else{
$this->Warn('WARNING: No name found');
}
// Endpoint URI
$temp=$x->query("/*[local-name()='definitions']/*[local-name()='service']/*[local-name()='port']/*[local-name()='address']/@location");
if($temp->length>0){
$temp=$temp->item(0);
PhpWsdl::Debug('Endpoint '.$temp->value);
$this->EndPoint=$temp->value;
}else{
$this->Warn('WARNING: No endpoint found');
}
// Caching
$this->WriteWsdlToCache($wsdl,null,null,$writeCache);
}
/**
* Create a PHP SOAP client for this webservice
*
* @param string $filename Name of the file to save the PHP code (default: NULL)
* @param array $options The options array for the PhpWsdl->OutputPhp method (default: array)
* @return string The UTF-8 encoded PHP code of the SOAP client
*/
public function CreatePhpSoapClient($filename=null,$options=Array()){
$php=$this->CreateServerFromWsdl()->OutputPhp(false,false,$options);
if(!is_null($filename))
if(file_put_contents($filename,$php)===false)
PhpWsdl::Debug('Could not write file '.$filename);
return $php;
}
/**
* Add a warning message
*
* @param string $str The message
*/
private function Warn($str){
$this->Warnings[]=$str;
PhpWsdl::Debug($str);
}
/**
* Get the cache filename
*
* @param string $wsdluri The WSDL URI or NULL to use the PhpWsdlAjax->WsdlUri property (default: NULL)
* @return string The cache filename or NULL, if caching is disabled
*/
public function GetCacheFileName($wsdluri=null){
$data=Array(
'client' => $this,
'wsdluri' => $wsdluri,
'filename' => (is_null(PhpWsdl::$CacheFolder))?null:PhpWsdl::$CacheFolder.'/client-'.sha1((is_null($wsdluri))?$this->WsdlUri:$wsdluri).'.wsdl'
);
PhpWsdl::CallHook(
'ClientCacheFileNameHook',
$data
);
return $data['filename'];
}
/**
* Determine if the cache file exists
*
* @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
* @return boolean Are the cache files present?
*/
public function CacheFileExists($file=null){
if(is_null($file))
$file=$this->GetCacheFileName();
PhpWsdl::Debug('Check cache file exists '.$file);
return file_exists($file)&&file_exists($file.'.cache');
}
/**
* Determine if the existing cache files are still valid
*
* @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
* @return boolean Valid?
*/
public function IsCacheValid($file=null){
PhpWsdl::Debug('Check cache valid');
if(is_null($file))
$file=$this->GetCacheFileName();
if(!$this->CacheFileExists($file))
return false;
return PhpWsdl::$CacheTime<0||time()-file_get_contents($file.'.cache')<=PhpWsdl::$CacheTime;
}
/**
* Get the WSDL from the cache
*
* @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
* @param boolean $force Force this even if the cache is timed out? (default: FALSE)
* @param boolean $nounserialize Don't unserialize the PhpWsdl* objects? (default: FALSE)
* @return string The cached WSDL
*/
public function GetWsdlFromCache($file=null,$force=false,$nounserialize=false){
PhpWsdl::Debug('Get WSDL from cache');
if(!is_null($this->WSDL))
return $this->WSDL;
if(is_null($file))
$file=$this->GetCacheFileName();
if(!$force){
if(!$this->IsCacheValid($file))
return null;
}else if(!$this->CacheFileExists($file)){
return null;
}
$this->WSDL=file_get_contents($file);
if(!$nounserialize){
PhpWsdl::Debug('Unserialize data');
$data=unserialize(file_get_contents($file.'.obj'));
$this->ServiceName=$data['servicename'];
$this->EndPoint=$data['endpoint'];
$this->NameSpace=$data['namespace'];
PhpWsdl::CallHook(
'ClientReadCacheHook',
Array(
'client' => $this,
'data' => &$data
)
);
if($data['version']!=self::$VERSION){
PhpWsdl::Debug('Could not use cache from version '.$data['version']);
$this->ServiceName=null;
$this->EndPoint=null;
$this->NameSpace=null;
$this->WSDL=null;
return null;
}
}
return $this->WSDL;
}
/**
* Write WSDL to cache
*
* @param string $wsdl The UTF-8 encoded WSDL string (default: NULL)
* @param string $wsdluri The SOAP WSDL URI or NULL to use the default (default: NULL)
* @param string $file The target filename or NULL to use the default (default: NULL)
* @param boolean $force Force refresh (default: FALSE)
* @return boolean Succeed?
*/
public function WriteWsdlToCache($wsdl=null,$wsdluri=null,$file=null,$force=false){
PhpWsdl::Debug('Write WSDL to the cache');
if(is_null($wsdluri))
$wsdluri=$this->WsdlUri;
if($wsdluri==$this->WsdlUri&&!is_null($wsdl))
$this->WSDL=$wsdl;
if(is_null($wsdl)){
if(is_null($this->WSDL)){
PhpWsdl::Debug('No WSDL');
return false;// WSDL not defined
}
$wsdl=$this->WSDL;
}
if(is_null($file)){
$file=$this->GetCacheFileName($wsdluri);
if(is_null($file)){
PhpWsdl::Debug('No cache file');
return false;// No cache file
}
}
$temp=substr($file,0,1);
if($temp!='/'&&$temp!='.'){
if(is_null(PhpWsdl::$CacheFolder)){
PhpWsdl::Debug('No cache folder');
return false;// No cache folder
}
$file=PhpWsdl::$CacheFolder.'/'.$file;
}
if(!$force)
if($this->IsCacheValid($file)){
PhpWsdl::Debug('Cache is still valid');
return true;// Existing cache is still valid
}
PhpWsdl::Debug('Write to '.$file);
if(file_put_contents($file,$wsdl)===false){
PhpWsdl::Debug('Could not write to cache');
return false;// Error writing to cache
}
if(file_put_contents($file.'.cache',time())===false){
PhpWsdl::Debug('Could not write cache time file');
return false;// Error writing to cache
}
$data=Array(
'version' => self::$VERSION,
'servicename' => $this->ServiceName,
'endpoint' => $this->EndPoint,
'namespace' => $this->NameSpace
);
PhpWsdl::CallHook(
'ClientWriteCacheHook',
Array(
'client' => $this,
'data' => &$data
)
);
if(file_put_contents($file.'.obj',serialize($data))===false){
PhpWsdl::Debug('Could not write serialized cache');
return false;
}
return true;
}
/**
* SOAP method call proxy method
*
* @param string $method The method name
* @param array $param The method parameters
* @return mixed The server response
*/
public function __call($method,$param){
return $this->DoRequest($method,$param);
}
}
+305
View File
@@ -0,0 +1,305 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
PhpWsdl::RegisterHook('InterpretKeywordpw_complexHook','internal','PhpWsdlComplex::InterpretComplex');
PhpWsdl::RegisterHook('CreateObjectHook','internalcomplex','PhpWsdlComplex::CreateComplexTypeObject');
/**
* This class creates complex types (classes or arrays)
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlComplex extends PhpWsdlObject{
/**
* The array type
*
* @var string
*/
public $Type=null;
/**
* A list of elements, if this type is a class
*
* @var PhpWsdlElement[]
*/
public $Elements;
/**
* Is this type an array?
*
* @var boolean
*/
public $IsArray;
/**
* Disable definition of arrays with the "Array" postfix in the type name?
*
* @var boolean
*/
public static $DisableArrayPostfix=false;
/**
* Constructor
*
* @param string $name The name
* @param PhpWsdlElement[] $el Optional a list of elements
* @param array $settings Optional the settings hash array (default: NULL)
*/
public function PhpWsdlComplex($name,$el=Array(),$settings=null){
PhpWsdl::Debug('New complex type '.$name);
parent::PhpWsdlObject($name,$settings);
if(!self::$DisableArrayPostfix){
$this->IsArray=substr($name,strlen($name)-5,5)=='Array';
if($this->IsArray)
$this->Type=substr($this->Name,0,strlen($this->Name)-5);
}
$this->Elements=$el;
if(!is_null($settings))
if(isset($settings['isarray']))
$this->IsArray=$settings['isarray'];
}
/**
* Create WSDL for the type
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreateType($pw){
$res=Array();
$res[]='<s:complexType name="'.$this->Name.'">';
if($pw->IncludeDocs&&!$pw->Optimize&&!is_null($this->Docs)){
$res[]='<s:annotation>';
$res[]='<s:documentation><![CDATA['.$this->Docs.']]></s:documentation>';
$res[]='</s:annotation>';
}
if(!$this->IsArray){
PhpWsdl::Debug('Create WSDL definition for type '.$this->Name.' as type');
$res[]='<s:sequence>';
$i=-1;
$len=sizeof($this->Elements);
while(++$i<$len)
$res[]=$this->Elements[$i]->CreateElement($pw);
$res[]='</s:sequence>';
}else{
PhpWsdl::Debug('Create WSDL definition for type '.$this->Name.' as array');
$res[]='<s:complexContent>';
$res[]='<s:restriction base="soapenc:Array">';
$res[]='<s:attribute ref="soapenc:arrayType" wsdl:arrayType="';
$res[sizeof($res)-1].=(in_array($this->Type,PhpWsdl::$BasicTypes))?'s':'tns';
$res[sizeof($res)-1].=':'.$this->Type.'[]" />';
$res[]='</s:restriction>';
$res[]='</s:complexContent>';
}
$res[]='</s:complexType>';
return implode('',$res);
}
/**
* Find an element within this type
*
* @param string $name The name
* @return PhpWsdlElement The element or NULL, if not found
*/
public function GetElement($name){
PhpWsdl::Debug('Find element '.$name);
$i=-1;
$len=sizeof($this->Elements);
while(++$i<$len)
if($this->Elements[$i]->Name==$name){
PhpWsdl::Debug('Found element at index '.$i);
return $this->Elements[$i];
}
return null;
}
/**
* Create the HTML documentation for a complex type
*
* @param array $data
*/
public function CreateTypeHtml($data){
PhpWsdl::Debug('CreateTypeHtml for '.$data['type']->Name);
$res=&$data['res'];
$t=&$data['type'];
$res[]='<h3>'.$t->Name.'</h3>';
$res[]='<a name="'.$t->Name.'"></a>';
$eLen=sizeof($t->Elements);
if($t->IsArray){
// Array type
$res[]='<p>This is an array type of <span class="pre">';
$o=sizeof($res)-1;
if(in_array($t->Type,PhpWsdl::$BasicTypes)){
$res[$o].='<span class="blue">'.$t->Type.'</span>';
}else{
$res[$o].='<a href="#'.$t->Type.'"><span class="lightBlue">'.$t->Type.'</span></a>';
}
$res[$o].='</span>.</p>';
if(!is_null($t->Docs))
$res[]='<p>'.nl2br(htmlentities($t->Docs)).'</p>';
}else if($eLen>0){
// Complex type with elements
if(!is_null($t->Docs))
$res[]='<p>'.nl2br(htmlentities($t->Docs)).'</p>';
$res[]='<ul class="pre">';
$j=-1;
while(++$j<$eLen)
$t->Elements[$j]->CreateElementHtml(array_merge(
$data,
Array(
'element' => $t->Elements[$j]
)
));
$res[]='</ul>';
}else{
// Complex type without elements
$res[]='<p>This type has no elements.</p>';
}
PhpWsdl::CallHook(
'CreateTypeHtmlHook',
$data
);
}
/**
* Create type PHP code
*
* @param array $data The event data
*/
public function CreateTypePhp($data){
if($this->IsArray)
return;
$server=$data['server'];
$res=&$data['res'];
$res[]="/**";
if(!is_null($this->Docs)){
$res[]=" * ".implode("\n * ",explode("\n",$this->Docs));
$res[]=" *";
}
$i=-1;
$eLen=sizeof($this->Elements);
while(++$i<$eLen){
$e=$this->Elements[$i];
$res[]=" * @pw_element ".$e->Type." \$".$e->Name.((!is_null($e->Docs))?" ".implode("\n\t * ",explode("\n",$e->Docs)):"");
}
$res[]=" * @pw_complex ".$this->Name;
$res[]=" */";
$res[]="class ".$this->Name."{";
$i=-1;
while(++$i<$eLen){
$e=$this->Elements[$i];
$res[]="\t/**";
if(!is_null($e->Docs)){
$res[]="\t * ".implode("\n\t * ",explode("\n",$e->Docs));
$res[]="\t *";
}
$res[]="\t * @var ".$e->Type;
$res[]="\t */";
$res[]="\tpublic \$".$this->Elements[$i]->Name.";";
}
$res[]="}";
}
/**
* Interpret a complex type
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretComplex($data){
$info=explode(' ',$data['keyword'][1],3);
if(sizeof($info)<1)
return true;
$server=$data['server'];
$name=$info[0];
PhpWsdl::Debug('Interpret complex type "'.$name.'"');
$type=null;
$docs=null;
if(strpos($name,'[]')>-1){
if(sizeof($info)<2){
PhpWsdl::Debug('WARNING: Invalid array definition!');
return true;
}
$name=substr($name,0,strlen($name)-2);
if(!is_null($server->GetType($name))){
PhpWsdl::Debug('WARNING: Double type detected!');
return true;
}
$type=$info[1];
if($server->ParseDocs)
if(sizeof($info)>2)
$docs=$info[2];
PhpWsdl::Debug('Array "'.$name.'" type of "'.$type.'" definition');
}else{
if(!is_null($server->GetType($name))){
PhpWsdl::Debug('WARNING: Double type detected!');
return true;
}
if(!self::$DisableArrayPostfix&&substr($name,strlen($name)-5)=='Array'){
$type=substr($name,0,strlen($name)-5);
PhpWsdl::Debug('Array "'.$name.'" type of "'.$type.'" definition');
}else{
PhpWsdl::Debug('Complex type definition');
}
if($server->ParseDocs){
$temp=sizeof($info);
if($temp>1)
$docs=($temp>2)?$info[1].' '.$info[2]:$info[1];
}
}
$data['type']=Array(
'id' => 'complex',
'name' => $name,
'type' => $type,
'docs' => $docs
);
return false;
}
/**
* Create complex type object
*
* @param array $data The parser data
* @return boolean Response
*/
public static function CreateComplexTypeObject($data){
if($data['method']!='')
return true;
if(!is_null($data['obj']))
return true;
if(!is_array($data['type']))
return true;
if(!isset($data['type']['id']))
return true;
if($data['type']['id']!='complex')
return true;
if(!is_null($data['docs'])){
$data['settings']['docs']=$data['docs'];
}else{
$data['settings']['docs']=$data['type']['docs'];
}
PhpWsdl::Debug('Add complex type '.$data['type']['name']);
$data['settings']['isarray']=!is_null($data['type']['type']);
$data['obj']=new PhpWsdlComplex($data['type']['name'],$data['elements'],$data['settings']);
$data['obj']->Type=$data['type']['type'];
$data['settings']=Array();
$data['server']->Types[]=$data['obj'];
return true;
}
}
+144
View File
@@ -0,0 +1,144 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
PhpWsdl::RegisterHook('InterpretKeywordpw_elementHook','internal','PhpWsdlElement::InterpretElement');
/**
* An element of a complex type
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlElement extends PhpWsdlParam{
/**
* Can the value be NULL?
*
* @var boolean
*/
public $NillAble=true;
/**
* Minimum number of elements
*
* @var int
*/
public $MinOccurs=1;
/**
* Maximum number of elements
*
* @var int|string
*/
public $MaxOccurs=1;
/**
* Constructor
*
* @param string $name The name
* @param string $type The type name
* @param array $settings Optional the settings hash array (default: NULL)
*/
public function PhpWsdlElement($name,$type,$settings=null){
PhpWsdl::Debug('New complex type element '.$name);
parent::PhpWsdlParam($name,$type,$settings);
$this->NillAble=!in_array($type,PhpWsdl::$NonNillable);
if(!is_null($settings)){
if(isset($settings['nillable']))
$this->NillAble=$settings['nillable']=='1'||$settings['nillable']=='true';
if(isset($settings['minoccurs']))
$this->MinOccurs=$settings['minoccurs'];
if(isset($settings['maxoccurs']))
$this->MaxOccurs=$settings['maxoccurs'];
}
}
/**
* Create the WSDL
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreateElement($pw){
PhpWsdl::Debug('Create WSDL definition for element '.$this->Name);
$res='<s:element minOccurs="'.$this->MinOccurs.'" maxOccurs="'.$this->MaxOccurs.'" nillable="'.(($this->NillAble)?'true':'false').'" name="'.$this->Name.'" type="';
$res.=PhpWsdl::TranslateType($this->Type).'"';
if($pw->IncludeDocs&&!$pw->Optimize&&!is_null($this->Docs)){
$res.='>'."\n";
$res.='<s:annotation>'."\n";
$res.='<s:documentation><![CDATA['.$this->Docs.']]></s:documentation>'."\n";
$res.='</s:annotation>'."\n";
$res.='</s:element>';
}else{
$res.=' />';
}
return $res;
}
/**
* Create the HTML documentation for a complex type element
*
* @param array $data
*/
public function CreateElementHtml($data){
PhpWsdl::Debug('CreateElementHtml for '.$data['element']->Name);
$res=&$data['res'];
$e=&$data['element'];
if(in_array($e->Type,PhpWsdl::$BasicTypes)){
$res[]='<li><span class="blue">'.$e->Type.'</span> <span class="bold">'.$e->Name.'</span>';
}else{
$res[]='<li><a href="#'.$e->Type.'"><span class="lightBlue">'.$e->Type.'</span></a> <span class="bold">'.$e->Name.'</span>';
}
$o=sizeof($res)-1;
$temp=Array(
'nillable = <span class="blue">'.(($e->NillAble)?'true':'false').'</span>',
'minoccurs = <span class="blue">'.$e->MinOccurs.'</span>',
'maxoccurs = <span class="blue">'.$e->MaxOccurs.'</span>',
);
$res[$o].=' ('.implode(', ',$temp).')';
if(!is_null($e->Docs))
$res[$o].='<br><span class="normal">'.nl2br(htmlentities($e->Docs)).'</span>';
$res[$o].='</li>';
PhpWsdl::CallHook(
'CreateElementHtmlHook',
$data
);
}
/**
* Interpret a element keyword
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretElement($data){
$info=explode(' ',$data['keyword'][1],3);
if(sizeof($info)<2)
return true;
$name=substr($info[1],1);
if(substr($name,strlen($name)-1,1)==';')
$name=substr($name,0,strlen($name)-1);
PhpWsdl::Debug('Interpret element '.$name);
if($data['server']->ParseDocs)
if(sizeof($info)>2)
$data['settings']['docs']=trim($info[2]);
$data['elements'][]=new PhpWsdlElement($name,$info[0],$data['settings']);
$data['settings']=Array();
return false;
}
}
+245
View File
@@ -0,0 +1,245 @@
<?php
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
/**
* XML Formatter
*
* @author Zilvinas Saltys <zilvinas.saltys@gmail.com>
* @url http://www.thedeveloperday.com/
* @version 0.3.0
* @package XML_Formatter
*/
/**
* XML_Formatter class responsible for formatting an XML stream
* to an indented human readable format.
*
* @package XML_Formatter
*/
class PhpWsdlFormatter
{
/**
* XML parser
*
* @var resource xml parser
*/
protected $_parser = null;
/**
* Unformatted XML input stream
*
* @var resource input stream
*/
protected $_input = null;
/**
* Formatted XML output stream
*
* @var resource output stream
*/
protected $_output = null;
/**
* Input stream offset index
*
* @var int stream offset index
*/
protected $_offset = 0;
/**
* XML depth index
*
* @var int XML depth index
*/
protected $_depth = 0;
/**
* Closed XML element type flag
*
* @var boolean closed XML element type flag
*/
protected $_empty = false;
/**
* Input stream buffer
*
* @var string input stream buffer
*/
protected $_buffer = "";
/**
* Formatter options
*
* =====> (int) bufferSize:
* - Buffer size in kilobytes
*
* =====> (string) paddingString:
* - Padding string used for indentation
*
* =====> (int) paddingMultiplier:
* - Padding multiplier used to multiply padding string
*
* =====> (boolean) formatCData:
* - Flag whether to format character data. May be useful in some cases.
*
* =====> (boolean) multipleLineCData:
* - Flag whether character data consists of multiple lines.
*
* =====> (int|false) wordwrapCData:
* - Character data wordwrap length
* - If false does not wordwrap character data
*
* =====> (string) inputEOL:
* - Input stream character data end of line string
*
* =====> (string) outputEOL:
* - Output stream character data end of line string
*
* @var array formatter options
*/
protected $_options = array(
"bufferSize" => 4096,
"paddingString" => " ",
"paddingMultiplier" => 4,
"formatCData" => true,
"multipleLineCData" => true,
"wordwrapCData" => 75,
"inputEOL" => "\n",
"outputEOL" => "\n"
);
/**
* Constructor
*
* @param resource $input Input stream
* @param resource $output Output stream
* @return void
*/
public function __construct($input, $output, Array $options = array())
{
$this->_input = $input;
$this->_output = $output;
$this->_options = array_merge($this->_options, $options);
$this->_parser = xml_parser_create();
xml_set_object($this->_parser, $this);
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
xml_parser_set_option($this->_parser, XML_OPTION_SKIP_WHITE, 0);
xml_set_element_handler($this->_parser, "_cbElementStart", "_cbElementEnd");
xml_set_character_data_handler($this->_parser, "_cbCharacterData");
}
/**
* Get padding string relative to XML depth index
*
* @param void
* @return string padding string
*/
protected function _getPaddingStr()
{
return str_repeat($this->_options["paddingString"], $this->_depth * $this->_options["paddingMultiplier"]);
}
/**
* Element start callback
*
* @param resource $parser xml parser
* @param string $name element name
* @param array $attributes element attributes
* @return void
*/
protected function _cbElementStart($parser, $name, Array $attributes)
{
$idx = xml_get_current_byte_index($this->_parser);
$this->_empty = $this->_buffer[$idx - $this->_offset] == '/';
$attrs = "";
foreach ($attributes as $key => $val) {
$attrs .= " " . $key . "=\"" . $val . "\"";
}
fwrite($this->_output, $this->_getPaddingStr() . "<" . $name . $attrs . ($this->_empty ? ' />' : '>') . "\n");
if (!$this->_empty) ++$this->_depth;
}
/**
* Element end callback
*
* @param resource $parser xml parser
* @param string $name element name
* @return void
*/
protected function _cbElementEnd($parser, $name)
{
if (!$this->_empty) {
--$this->_depth;
fwrite($this->_output, $this->_getPaddingStr() . "</" . $name . ">" . "\n");
} else {
$this->_empty = false;
}
}
/**
* Character data callback
*
* @param resource $parser xml parser
* @param string $data character data
* @return void
*/
protected function _cbCharacterData($parser, $data)
{
if (!$this->_options["formatCData"]) {
return;
}
$data = trim($data);
if (strlen($data)) {
$pad = $this->_getPaddingStr();
if ($this->_options["multipleLineCData"]) {
// remove all tabs
$data = str_replace("\t", "", $data);
// append each line with a padding string
$data = implode($this->_options["inputEOL"] . $pad, explode($this->_options["inputEOL"], $data));
}
if ($this->_options["wordwrapCData"]) {
$data = wordwrap($data, $this->_options["wordwrapCData"], $this->_options["outputEOL"] . $pad, false);
}
fwrite($this->_output, $pad . $data . "\n");
}
}
/**
* Main format method
*
* @param void
* @throws Exception
* @return void
*/
public function format()
{
while ($this->_buffer = fread($this->_input, $this->_options["bufferSize"])) {
if (!xml_parse($this->_parser, $this->_buffer, feof($this->_input))) {
throw new Exception(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($this->_parser)),
xml_get_current_line_number($this->_parser)));
return;
}
$this->_offset += strlen($this->_buffer);
}
xml_parser_free($this->_parser);
}
}
+180
View File
@@ -0,0 +1,180 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
// This is my solution to swap hash arrays between client/server. The receiver
// has to rebuild the hash object in the way his programming language supports
// hash arrays. It's just an example solution. To use the types defined here,
// you have to include this file in your source using "require". This file has
// also to be in the list of files that are parsed by PhpWsdl.
//
// A sample unserialized PHP hash array (use the "Serialize" method on this):
//
// Array(
// 'a' => 'Value of a',
// 'b' => 'Value of b'
// )
//
// The resulting serialized array (return this):
//
// Array(
// PhpWsdlHash(
// 'key' => 'a',
// 'value' => 'Value of a'
// ),
// PhpWsdlHash(
// 'key' => 'b',
// 'value' => 'Value of b'
// )
// )
//
// The received serialized array (use the "Deserialize" method on this):
//
// Array(
// object(
// 'key' => 'a',
// 'value' => 'Value of a'
// ),
// object(
// 'key' => 'b',
// 'value' => 'Value of b'
// )
// )
//
// The value type must be unique within an hash array. You can return prepared
// types like StringHashArray, or you define your own ones. To serialize an
// hash array to the target type, use the PhpWsdlHashArrayBuilder class:
//
// return PhpWsdlHashArrayBuilder::Serialize($yourHashVariable);
//
// To deserialize an received object:
//
// $yourHashVariable=PhpWsdlHashArrayBuilder::Deserialize($receivedHashVariable);
//
// Tip: I prefer converting hashes into an INI formatted string. The string
// type is primitive, but it can contain complex information. In nearly every
// programming language you can work with the INI format with predefined
// classes - or it's very easy to write your own.
/**
* Key/Value pair types for string value type
*
* @pw_element string $key Key
* @pw_element string $value Value
* @pw_complex StringHash String hash array type
*/
/**
* @pw_complex StringHashArray Array of string hash array types
*/
/**
* Key/Value pair types for int value type
*
* @pw_element string $key Key
* @pw_element int $value Value
* @pw_complex IntHash Int hash array type
*/
/**
* @pw_complex IntHashArray Array of int hash array types
*/
/**
* Key/Value pair types for boolean value type
*
* @pw_element string $key Key
* @pw_element boolean $value Value
* @pw_complex BooleanHash Boolean hash array type
*/
/**
* @pw_complex BooleanHashArray Array of boolean hash array types
*/
/**
* This class contains static methods to (de)serialize hash arrays
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlHashArrayBuilder{
/**
* Serialize an hash array
*
* @param array $hash The PHP hash array
* @return PhpWsdlHash[] The serialized array
*/
public static function Serialize($hash){
if(is_null($hash))
return null;
$res=Array();
$keys=array_keys($hash);
$i=-1;
$len=sizeof($keys);
while(++$i<$len)
$res[]=new PhpWsdlHash($keys[$i],$hash[$keys[$i]]);
return $res;
}
/**
* Deserialize an hash array
*
* @param array $arr The serialized array
* @return array The deserialized PHP hash array
*/
public static function Deserialize($arr){
if(is_null($arr))
return null;
$res=Array();
$i=-1;
$len=sizeof($arr);
while(++$i<$len)
$res[$arr[$i]->Key]=$arr[$i]->Value;
return $res;
}
}
/**
* This class simply holds a key/value pair
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlHash{
/**
* The key
*
* @var string
*/
public $Key;
/**
* The value
*
* @var mixed
*/
public $Value;
/**
* Constructor
*
* @ignore
* @param string $key The key
* @param mixed $value The value
*/
public function PhpWsdlHash($key,$value){
$this->Key=$key;
$this->Value=$value;
}
}
+369
View File
@@ -0,0 +1,369 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
PhpWsdl::RegisterHook('InterpretKeywordpw_omitfncHook','internal','PhpWsdlMethod::InterpretOmit');
PhpWsdl::RegisterHook('InterpretKeywordignoreHook','internal','PhpWsdlMethod::InterpretOmit');
PhpWsdl::RegisterHook('InterpretKeywordpw_setHook','internal','PhpWsdlMethod::InterpretSetting');
PhpWsdl::RegisterHook('CreateObjectHook','internalmethod','PhpWsdlMethod::CreateMethodObject');
/**
* A method definition object
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlMethod extends PhpWsdlObject{
/**
* A list of parameters
*
* @var PhpWsdlParam[]
*/
public $Param=Array();
/**
* The return value
*
* @var PhpWsdlParam
*/
public $Return=null;
/**
* A global method?
*
* @var boolean
*/
public $IsGlobal=false;
/**
* A new method is global per default?
*
* @var boolean
*/
public static $IsGlobalDefault=false;
/**
* Constructor
*
* @param string $name The name
* @param PhpWsdlParam[] $param Optional the list of parameters (default: NULL)
* @param PhpWsdlParam $return Optional the return value (default: NULL)
* @param array $settings Optional the settings hash array (default: NULL)
*/
public function PhpWsdlMethod($name,$param=null,$return=null,$settings=null){
PhpWsdl::Debug('New method '.$name);
parent::PhpWsdlObject($name,$settings);
if(!is_null($param))
$this->Param=$param;
$this->Return=$return;
$this->IsGlobal=self::$IsGlobalDefault;
if(!is_null($settings))
if(isset($settings['global']))
$this->IsGlobal=$settings['global']=='true'||$settings['global']=='1';
}
/**
* Create the port type WSDL
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreatePortType($pw){
PhpWsdl::Debug('Create WSDL port type for method '.$this->Name);
$res=Array();
$res[]='<wsdl:operation name="'.$this->Name.'"';
$o=sizeof($res)-1;
$pLen=sizeof($this->Param);
if($pLen>1){
$temp=Array();
$i=-1;
while(++$i<$pLen)
$temp[]=$this->Param[$i]->Name;
$res[$o].=' parameterOrder="'.implode(' ',$temp).'"';
}
$res[$o].='>';
if($pw->IncludeDocs&&!$pw->Optimize&&!is_null($this->Docs))
$res[]='<wsdl:documentation><![CDATA['.$this->Docs.']]></wsdl:documentation>';
$res[]='<wsdl:input message="tns:'.$this->Name.'SoapIn" />';
$res[]='<wsdl:output message="tns:'.$this->Name.'SoapOut" />';
$res[]='</wsdl:operation>';
return implode('',$res);
}
/**
* Create the binding WSDL
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreateBinding($pw){
PhpWsdl::Debug('Create WSDL binding for method '.$this->Name);
$res=Array();
$res[]='<wsdl:operation name="'.$this->Name.'">';
$res[]='<soap:operation soapAction="'.$pw->NameSpace.$this->Name.'" />';
$res[]='<wsdl:input>';
$res[]='<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="'.$pw->NameSpace.'"';
$pLen=sizeof($this->Param);
if($pLen>0){
$temp=Array();
$i=-1;
while(++$i<$pLen)
$temp[]=$this->Param[$i]->Name;
$res[sizeof($res)-1].=' parts="'.implode(' ',$temp).'"';
}
$res[sizeof($res)-1].=' />';
$res[]='</wsdl:input>';
$res[]='<wsdl:output>';
$res[]='<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="'.$pw->NameSpace.'"';
if(!is_null($this->Return))
$res[sizeof($res)-1].=' parts="'.$this->Return->Name.'"';
$res[sizeof($res)-1].=' />';
$res[]='</wsdl:output>';
$res[]='</wsdl:operation>';
return implode('',$res);
}
/**
* Create the input/output messages WSDL
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreateMessages($pw){
PhpWsdl::Debug('Create WSDL message for method '.$this->Name);
$pLen=sizeof($this->Param);
$res=Array();
// Request
if($pLen<1){
$res[]='<wsdl:message name="'.$this->Name.'SoapIn" />';
}else{
$res[]='<wsdl:message name="'.$this->Name.'SoapIn">';
$i=-1;
while(++$i<$pLen)
$res[]=$this->Param[$i]->CreatePart($pw);
$res[]='</wsdl:message>';
}
// Response
if(is_null($this->Return)){
$res[]='<wsdl:message name="'.$this->Name.'SoapOut" />';
}else{
$res[]='<wsdl:message name="'.$this->Name.'SoapOut">';
$res[]=$this->Return->CreatePart($pw);
$res[]='</wsdl:message>';
}
return implode('',$res);
}
/**
* Find a parameter of this method
*
* @param string $name The parameter name
* @return PhpWsdlParam The parameter or NULL, if not found
*/
public function GetParam($name){
PhpWsdl::Debug('Find parameter '.$name);
$i=-1;
$len=sizeof($this->Param);
while(++$i<$len)
if($this->Param[$i]->Name==$name){
PhpWsdl::Debug('Found parameter at index '.$i);
return $this->Param[$i];
}
return null;
}
/**
* Create HTML docs
*
* @param array $data Some data
*/
public function CreateMethodHtml($data){
PhpWsdl::Debug('CreateMethodHtml for '.$data['method']->Name);
$res=&$data['res'];
$m=&$data['method'];
$res[]='<h3>'.$m->Name.'</h3>';
$res[]='<a name="'.$m->Name.'"></a>';
$res[]='<p class="pre">';
$o=sizeof($res)-1;
if(!is_null($m->Return)){
$type=$m->Return->Type;
if(in_array($type,PhpWsdl::$BasicTypes)){
$res[$o].='<span class="blue">'.$type.'</span>';
}else{
$res[$o].='<a href="#'.$type.'"><span class="lightBlue">'.$type.'</span></a>';
}
}else{
$res[$o].='void';
}
$res[$o].=' <span class="bold">'.$m->Name.'</span> (';
$pLen=sizeof($m->Param);
$spacer='';
if($pLen>1){
$res[$o].='<br>';
$spacer='&nbsp;&nbsp;&nbsp;&nbsp;';
}
$hasDocs=false;
if($pLen>0){
$j=-1;
while(++$j<$pLen){
$p=$m->Param[$j];
if(in_array($p->Type,PhpWsdl::$BasicTypes)){
$res[]=$spacer.'<span class="blue">'.$p->Type.'</span> <span class="bold">'.$p->Name.'</span>';
}else{
$res[]=$spacer.'<a href="#'.$p->Type.'"><span class="lightBlue">'.$p->Type.'</span></a> <span class="bold">'.$p->Name.'</span>';
}
$o=sizeof($res)-1;
if($j<$pLen-1)
$res[$o].=', ';
if($pLen>1)
$res[$o].='<br>';
if(!$hasDocs)
if(!is_null($p->Docs))
$hasDocs=true;
}
}
$res[].=')</p>';
// Method documentation
if(!is_null($m->Docs))
$res[]='<p>'.nl2br(htmlentities($m->Docs)).'</p>';
// Parameters documentation
if($hasDocs){
$res[]='<ul>';
$j=-1;
while(++$j<$pLen)
$m->Param[$j]->CreateParamHtml(array_merge(
$data,
Array(
'param' => $m->Param[$j]
)
)
);
$res[]='</ul>';
}
// Return value documentation
if(!is_null($m->Return)&&!is_null($m->Return->Docs))
$m->Return->CreateReturnHtml($data);
PhpWsdl::CallHook(
'CreateMethodHtmlHook',
$data
);
}
/**
* Create method PHP
*
* @param array $data The event data
*/
public function CreateMethodPhp($data){
$server=$data['server'];
$res=&$data['res'];
$res[]="\t/**";
if(!is_null($this->Docs)){
$res[]="\t * ".implode("\n\t * ",explode("\n",$this->Docs));
$res[]="\t *";
}
$param=Array();
$i=-1;
$pLen=sizeof($this->Param);
while(++$i<$pLen){
$p=$this->Param[$i];
$param[]='$'.$p->Name;
$res[]="\t * @param ".$p->Type." \$".$p->Name.((!is_null($p->Docs))?" ".implode("\n\t * ",explode("\n",$p->Docs)):"");
}
if(!is_null($this->Return)){
$res[]="\t * @return ".$this->Return->Type.((!is_null($this->Return->Docs))?" ".implode("\n\t * ",explode("\n",$this->Return->Docs)):"");
}
$res[]="\t */";
$res[]="\tpublic function ".$this->Name."(".implode(',',$param)."){";
if(PhpWsdl::CallHook(
'CreateMethodPhpHook',
array_merge(
$data,
Array(
'method' => $this
)
)
)
){
$res[]="\t\treturn self::_Call('".$this->Name."',Array(";
if($pLen>0)
$res[]="\t\t\t".implode(",\n\t\t\t",$param);
$res[]="\t\t));";
}
$res[]="\t}";
}
/**
* Interpret a setting
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretSetting($data){
$info=explode(' ',$data['keyword'][1],2);
if(sizeof($info)<1)
return true;
PhpWsdl::Debug('Interpret setting '.$info[0]);
$info=explode('=',$info[0],2);
if(sizeof($info)>1){
$data['settings'][$info[0]]=$info[1];
}else if(isset($data['settings'][$info[0]])){
unset($data['settings'][$info[0]]);
}
return false;
}
/**
* Interpret omit keyword
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretOmit($data){
PhpWsdl::Debug('Interpret omitfnc/ignore');
$data['omit']=true;
return true;
}
/**
* Create method object
*
* @param array $data The parser data
* @return boolean Response
*/
public static function CreateMethodObject($data){
if(!is_null($data['obj']))
return true;
if($data['method']=='')
return true;
if(!is_null($data['type']))
return true;
PhpWsdl::Debug('Add method '.$data['method']);
$server=$data['server'];
if(!is_null($server->GetMethod($data['method']))){
PhpWsdl::Debug('WARNING: Double method detected!');
return true;
}
if($server->ParseDocs)
if(!is_null($data['docs']))
$data['settings']['docs']=$data['docs'];
$data['obj']=new PhpWsdlMethod($data['method'],$data['param'],$data['return'],$data['settings']);
$data['settings']=Array();
$server->Methods[]=$data['obj'];
return true;
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
/**
* PhpWsdl element object base
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlObject{
/**
* The GUID
*
* @var string
*/
public $GUID;
/**
* The name
*
* @var string
*/
public $Name;
/**
* Documentation
*
* @var string
*/
public $Docs=null;
/**
* Other settings
*
* @var array
*/
public $Settings=null;
/**
* Constructor
*
* @param string $name The name
* @param array $settings Settings array (default: NULL)
*/
public function PhpWsdlObject($name,$settings=null){
$this->GUID=uniqid();
PhpWsdl::Debug('New PhpWsdlObject "'.$name.'" with GUID "'.$this->GUID.'"');
$this->Name=$name;
if(!is_null($settings)){
if(isset($settings['docs']))
$this->Docs=$settings['docs'];
if(isset($settings['settings']))
$this->Settings=$settings['settings'];
}
}
}
+176
View File
@@ -0,0 +1,176 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
PhpWsdl::RegisterHook('InterpretKeywordparamHook','internal','PhpWsdlParam::InterpretParam');
PhpWsdl::RegisterHook('InterpretKeywordreturnHook','internal','PhpWsdlParam::InterpretReturn');
/**
* A parameter or return value definition for a method
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlParam extends PhpWsdlObject{
/**
* The parameter type name
*
* @var string
*/
public $Type;
/**
* Documentation
*
* @var string
*/
public $Docs=null;
/**
* The default name for the return value object
* Use %method% as placeholder for the method name
*
* @var string
*/
public static $DefaultReturnName='return';
/**
* Constructor
*
* @param string $name The name
* @param string $type Optional the type name (default: string)
* @param array $settings Optional the settings hash array (default: NULL)
*/
public function PhpWsdlParam($name,$type='string',$settings=null){
PhpWsdl::Debug('New parameter '.$name);
parent::PhpWsdlObject($name,$settings);
$this->Type=$type;
}
/**
* Create the part WSDL
*
* @param PhpWsdl $pw The PhpWsdl object
* @return string The WSDL
*/
public function CreatePart($pw){
PhpWsdl::Debug('Create WSDL definition for parameter part '.$this->Name);
$res='<wsdl:part name="'.$this->Name.'" type="';
$res.=PhpWsdl::TranslateType($this->Type).'"';
if($pw->IncludeDocs&&!$pw->Optimize&&!is_null($this->Docs)){
$res.='>'."\n";
$res.='<s:documentation><![CDATA['.$this->Docs.']]></s:documentation>'."\n";
$res.='</wsdl:part>';
}else{
$res.=' />';
}
return $res;
}
/**
* Create parameter HTML documentation
*
* @param array $data Some data
*/
public function CreateParamHtml($data){
PhpWsdl::Debug('CreateParamHtml for '.$data['param']->Name);
$res=&$data['res'];
$p=&$data['param'];
if(is_null($p->Docs))
return;
if(in_array($p->Type,PhpWsdl::$BasicTypes)){
$res[]='<li class="pre"><span class="blue">'.$p->Type.'</span> <span class="bold">'.$p->Name.'</span>';
}else{
$res[]='<li class="pre"><a href="#'.$p->Type.'"><span class="lightBlue">'.$p->Type.'</span></a> <span class="bold">'.$p->Name.'</span>';
}
$res[sizeof($res)-1].='<br><span class="normal">'.nl2br(htmlentities($p->Docs)).'</span></li>';
PhpWsdl::CallHook(
'CreateParameterHtmlHook',
$data
);
}
/**
* Create return value HTML documentation
*
* @param array $data Some data
*/
public function CreateReturnHtml($data){
PhpWsdl::Debug('CreateReturnHtml for '.$data['method']->Return->Name);
$res=&$data['res'];
$m=&$data['method'];
$res[]='<p>Return value <span class="pre">';
$o=sizeof($res)-1;
$type=$m->Return->Type;
if(in_array($type,PhpWsdl::$BasicTypes)){
$res[$o].='<span class="blue">'.$type.'</span>';
}else{
$res[$o].='<a href="#'.$type.'"><span class="lightBlue">'.$type.'</span></a>';
}
$res[$o].='</span>'.((!is_null($m->Return->Docs))?': '.nl2br(htmlentities($m->Return->Docs)):'').'</p>';
PhpWsdl::CallHook(
'CreateReturnHtmlHook',
$data
);
}
/**
* Interpret a parameter keyword
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretParam($data){
if($data['method']=='')
return true;
$info=explode(' ',$data['keyword'][1],3);
if(sizeof($info)<2)
return true;
$name=substr($info[1],1);
if(substr($name,strlen($name)-1,1)==';')
$name=substr($name,0,strlen($name)-1);
PhpWsdl::Debug('Interpret parameter '.$name);
if($data['server']->ParseDocs)
if(sizeof($info)>2)
$data['settings']['docs']=trim($info[2]);
$data['param'][]=new PhpWsdlParam($name,$info[0],$data['settings']);
$data['settings']=Array();
return false;
}
/**
* Interpret a return value
*
* @param array $data The parser data
* @return boolean Response
*/
public static function InterpretReturn($data){
if($data['method']=='')
return true;
$info=explode(' ',$data['keyword'][1],2);
if(sizeof($info)<1)
return true;
PhpWsdl::Debug('Interpret return');
if($data['server']->ParseDocs)
if(sizeof($info)>1)
$data['settings']['docs']=trim($info[1]);
$data['return']=new PhpWsdlParam(str_replace('%method%',$data['method'],self::$DefaultReturnName),$info[0],$data['settings']);
$data['settings']=Array();
return false;
}
}
+276
View File
@@ -0,0 +1,276 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
/**
* This class will parse the WSDL definitions from PHP source (or any other string)
*
* @author Andreas Zimmermann, wan24.de
*/
class PhpWsdlParser{
/**
* The PhpWsdl object
*
* @var PhpWsdl
*/
public $Server;
/**
* Regular expression to parse the relevant data from a string
* 1: Comment block
* 4: Method name
*
* @var string
*/
public static $ParseRelevantRx='/\/\*\*([^\*]*\*+(?:[^\*\/][^\*]*\*+)*)\/(\s*(public\s+)?function\s+([^\s|\(]+)\s*\()?/is';
/**
* Regular expression to parse keywords from a string
* 1: Whole line
* 2: Keyword
* 3: Parameters
*
* @var string
*/
public static $ParseKeywordsRx='/^(\s*\*\s*\@([^\s|\n]+)([^\n]*))$/m';
/**
* Regular expression to parse the documentation from the bottom of a comment block string
* 1: Documentation
*
* @var string
*/
public static $ParseDocsRx='/^[^\*|\n]*\*[ |\t]+([^\*|\s|\@|\/|\n][^\n]*)?$/m';
/**
* Constructor
*
* @param PhpWsdl $server The PhpWsdl object
*/
public function PhpWsdlParser($server){
PhpWsdl::Debug('New PhpWsdlParser');
$this->Server=$server;
}
/**
* Parse a string
*
* @param string $str The string to parse
*/
public function Parse($str){
PhpWsdl::Debug('Parse a string');
if(!PhpWsdl::CallHook(
'BeforeParseHook',
Array(
'sender' => $this,
'server' => $this->Server,
'str' => &$str
)
)
)
return;
// Match all relevant strings
$defs=Array();
preg_match_all(PhpWsdlParser::$ParseRelevantRx,$str,$defs);
$i=-1;
$len=sizeof($defs[0]);
PhpWsdl::Debug('Matched '.$len.' relevant strings to parse');
while(++$i<$len){
$def=$defs[1][$i];
$method=$defs[4][$i];
if($method!='')
PhpWsdl::Debug('Method: "'.$method.'"');
// Parse keywords
$keywords=Array();
$temp=Array();
preg_match_all(PhpWsdlParser::$ParseKeywordsRx,$def,$temp);
$j=-1;
$tLen=sizeof($temp[0]);
while(++$j<$tLen)
$keywords[]=Array(
$temp[2][$j],
trim($temp[3][$j])
);
if(PhpWsdl::$Debugging)
PhpWsdl::Debug('Keywords: '.print_r($keywords,true));
// Parse documentation
if($this->Server->ParseDocs){
$docs=Array();
$temp=Array();
preg_match_all(PhpWsdlParser::$ParseDocsRx,$def,$temp);
$j=-1;
$tLen=sizeof($temp[0]);
while(++$j<$tLen)
$docs[]=trim($temp[1][$j]);
$docs=trim(implode("\n",$docs));
if($docs=='')
$docs=null;
if(!is_null($docs))
PhpWsdl::Debug('Docs: '.$docs);
}else{
$docs=null;
}
// Create objects
$this->InterpretDefinition($def,$method,$keywords,$docs);
}
PhpWsdl::CallHook(
'AfterParseHook',
Array(
'sender' => $this,
'server' => $this->Server,
'str' => &$str
)
);
}
/**
* Interpret a WSDL definition
*
* @param string $def WSDL definition
* @param string $method Method name
*/
public function InterpretDefinition($def,$method,$keywords,$docs){
PhpWsdl::Debug('Interpret definition');
if(!PhpWsdl::CallHook(
'BeforeInterpretDefinitionHook',
Array(
'sender' => $this,
'server' => $this->Server,
'def' => &$def,
'method' => &$method,
'keywords' => &$keywords,
'docs' => &$docs
)
)
)
return null;
// Initialize some variables
$param=Array(); // List ob parameter objects
$return=null; // The return value object
$elements=Array(); // List of element objects
$settings=Array(); // Settings hash
$omit=false; // Omit the object
$type=null; // Type identifier
$buffer=Array(); // Other data
// Interpret keywords
$i=-1;
$len=sizeof($keywords);
while(++$i<$len){
$keyword=$keywords[$i];
if(PhpWsdl::$Debugging)
PhpWsdl::Debug('Interpret keyword '.print_r($keyword,true));
// Call the global keyword handler
if(!PhpWsdl::CallHook(
'InterpretKeywordHook',
Array(
'sender' => $this,
'server' => $this->Server,
'def' => &$def,
'method' => &$method,
'keywords' => &$keywords,
'docs' => &$docs,
'param' => &$param,
'elements' => &$elements,
'return' => &$return,
'settings' => &$settings,
'omit' => &$omit,
'keyword' => &$keyword,
'type' => &$type,
'buffer' => &$buffer,
'newkeyword' => &$newkeyword
)
)
)
continue;
if($omit)
return null;
// Call the keyword handler
if(!PhpWsdl::CallHook(
'InterpretKeyword'.$keyword[0].'Hook',
Array(
'sender' => $this,
'server' => $this->Server,
'def' => &$def,
'method' => &$method,
'keywords' => &$keywords,
'docs' => &$docs,
'param' => &$param,
'elements' => &$elements,
'return' => &$return,
'settings' => &$settings,
'omit' => &$omit,
'keyword' => &$keyword,
'type' => &$type,
'buffer' => &$buffer,
'newkeyword' => &$newkeyword
)
)
)
continue;
if($omit)
return null;
PhpWsdl::Debug('Keyword not handled');
}
// Create object
$obj=null;
if(!PhpWsdl::CallHook(
'CreateObjectHook',
Array(
'sender' => $this,
'server' => $this->Server,
'def' => &$def,
'method' => &$method,
'keywords' => &$keywords,
'docs' => &$docs,
'param' => &$param,
'elements' => &$elements,
'return' => &$return,
'settings' => &$settings,
'omit' => &$omit,
'type' => &$type,
'buffer' => &$buffer,
'obj' => &$obj
)
)
)
return null;
if(!PhpWsdl::CallHook(
'AfterInterpretDefinitionHook',
Array(
'sender' => $this,
'server' => $this->Server,
'def' => &$def,
'method' => &$method,
'keywords' => &$keywords,
'docs' => &$docs,
'param' => &$param,
'elements' => &$elements,
'return' => &$return,
'settings' => &$settings,
'omit' => &$omit,
'type' => &$type,
'buffer' => &$buffer,
'obj' => &$obj
)
)
)
return null;
PhpWsdl::Debug('Object '.((is_null($obj))?'not created':'created'));
return $obj;
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
/*
PhpWsdl - Generate WSDL from PHP
Copyright (C) 2011 Andreas Zimmermann, wan24.de
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License along with
this program; if not, see <http://www.gnu.org/licenses/>.
*/
if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
exit;
// This proxy can handle missing parameters with NULL values. This will only
// work, if the PhpWsdl class doesn't promote the WSDL to the SoapServer. But
// then returning complex types won't be easy anymore: You have to encode the
// return value with PHPs SoapVar object by yourself.
class PhpWsdlProxy{
public function __call($method,$param){
if(PhpWsdl::$Debugging)
PhpWsdl::Debug('Proxy call method '.$method.': '.print_r($param,true));
PhpWsdl::$ProxyServer->CreateWsdl();
$m=PhpWsdl::$ProxyServer->GetMethod($method);
if(is_null($m))
throw(new SoapFault('MissingMethod','Method "'.$method.'" not found'));
// Try to fix the missing parameters issue if the SoapServer is not running in WSDL mode
if(!PhpWsdl::$UseProxyWsdl){
$pLen=sizeof($m->Param);
$temp=sizeof($param);
if($pLen!=$temp){
PhpWsdl::Debug('Wrong parameter count ('.$temp.'/'.$pLen.')');
$req=new DOMDocument();
if($req->loadXml(file_get_contents('php://input'))){
$x=new DOMXPath($req);
$temp=$param;
$param=Array();
$pos=0;// Current index in the received parameter array
$i=-1;
while(++$i<$pLen){
$p=$m->Param[$i];
if($x->query("/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='".$m->Name."']/*[local-name()='".$p->Name."']")->length>0){
PhpWsdl::Debug('Parameter "'.$p->Name.'" was received');
$param[]=$temp[$pos];
$pos++;
}else{
PhpWsdl::Debug('Parameter "'.$p->Name.'" was missing');
$param[]=null;
}
}
}else{
PhpWsdl::Debug('Could not parse SOAP request XML');
}
}
}
// Prepare the method call
$call=($m->IsGlobal)
?$method // Global method
:Array( // Class method
PhpWsdl::$ProxyObject,
$method
);
// Call the target method and return the response
PhpWsdl::Debug('Call the target method');
return (sizeof($param)<1)
?call_user_func(
$call
)
:call_user_func_array(
$call,
$param
);
}
}