diff options
| author | knut <> | 2006-07-06 19:45:32 +0000 | 
|---|---|---|
| committer | knut <> | 2006-07-06 19:45:32 +0000 | 
| commit | 97dddf3cf23f7d2829d23efb9d44b746ac7d52cc (patch) | |
| tree | 23c5984380a250bbe0d1163c055df2404df19649 | |
| parent | 9cc6b7fffd31f4b9ee9aceef9224c84dcf28aeb8 (diff) | |
Added a TSoapService prototype with a simple demo app
| -rw-r--r-- | .gitattributes | 11 | ||||
| -rw-r--r-- | demos/soap/index.php | 5 | ||||
| -rw-r--r-- | demos/soap/protected/application.xml | 10 | ||||
| -rw-r--r-- | demos/soap/protected/pages/Home.page | 20 | ||||
| -rw-r--r-- | demos/soap/protected/pages/Home.php | 44 | ||||
| -rw-r--r-- | demos/soap/protected/runtime/global.cache | 1 | ||||
| -rw-r--r-- | demos/soap/protected/webservices/SimpleService.php | 89 | ||||
| -rw-r--r-- | framework/3rdParty/WsdlGen/Wsdl.php | 259 | ||||
| -rw-r--r-- | framework/3rdParty/WsdlGen/WsdlGenerator.php | 288 | ||||
| -rw-r--r-- | framework/3rdParty/WsdlGen/WsdlMessage.php | 80 | ||||
| -rw-r--r-- | framework/3rdParty/WsdlGen/WsdlOperation.php | 135 | ||||
| -rw-r--r-- | framework/Web/Services/TSoapService.php | 101 | 
12 files changed, 1043 insertions, 0 deletions
| diff --git a/.gitattributes b/.gitattributes index b2a8f8f0..10012892 100644 --- a/.gitattributes +++ b/.gitattributes @@ -997,6 +997,12 @@ demos/quickstart/themes/PradoSoft/mantissample.jpg -text  demos/quickstart/themes/PradoSoft/pradologo.gif -text  demos/quickstart/themes/PradoSoft/style.css -text  demos/quickstart/themes/Simple/style.css -text +demos/soap/index.php -text +demos/soap/protected/application.xml -text +demos/soap/protected/pages/Home.page -text +demos/soap/protected/pages/Home.php -text +demos/soap/protected/runtime/global.cache -text +demos/soap/protected/webservices/SimpleService.php -text  demos/sqlmap-sample/index.php -text  demos/sqlmap-sample/protected/application.xml -text  demos/sqlmap-sample/protected/business-objects/Person.php -text @@ -1056,6 +1062,10 @@ framework/3rdParty/TinyMCE/license.txt -text  framework/3rdParty/TinyMCE/readme.txt -text  framework/3rdParty/TinyMCE/tiny_mce.md5 -text  framework/3rdParty/TinyMCE/tiny_mce.tar -text +framework/3rdParty/WsdlGen/Wsdl.php -text +framework/3rdParty/WsdlGen/WsdlGenerator.php -text +framework/3rdParty/WsdlGen/WsdlMessage.php -text +framework/3rdParty/WsdlGen/WsdlOperation.php -text  framework/3rdParty/adodb/ADOdb_Active_Record.php -text  framework/3rdParty/adodb/adodb-csvlib.inc.php -text  framework/3rdParty/adodb/adodb-errorhandler.inc.php -text @@ -1572,6 +1582,7 @@ framework/Web/Javascripts/rico/rico.js -text  framework/Web/Services/IFeedContentProvider.php -text  framework/Web/Services/TFeedService.php -text  framework/Web/Services/TPageService.php -text +framework/Web/Services/TSoapService.php -text  framework/Web/TAssetManager.php -text  framework/Web/THttpRequest.php -text  framework/Web/THttpResponse.php -text diff --git a/demos/soap/index.php b/demos/soap/index.php new file mode 100644 index 00000000..009011f8 --- /dev/null +++ b/demos/soap/index.php @@ -0,0 +1,5 @@ +<?php +require_once '../../framework/prado.php'; +$application = new TApplication(); +$application->run(); +?>
\ No newline at end of file diff --git a/demos/soap/protected/application.xml b/demos/soap/protected/application.xml new file mode 100644 index 00000000..e59c5b84 --- /dev/null +++ b/demos/soap/protected/application.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<application id="soap" mode="Debug"> +  <paths> +    <using namespace="Application.webservices.*" /> +  </paths> +  <services> +    <service id="page" class="TPageService"/> +    <service id="soap" class="System.Web.Services.TSoapService"/> +  </services> +</application>
\ No newline at end of file diff --git a/demos/soap/protected/pages/Home.page b/demos/soap/protected/pages/Home.page new file mode 100644 index 00000000..732022e9 --- /dev/null +++ b/demos/soap/protected/pages/Home.page @@ -0,0 +1,20 @@ +<html> +<head> +  <title>TSoapService Demo</title> +</head> +<body> +<h1>TSoapService Demo</h1> +<p>Welcome to the TSoapService demo. See <a href="index.php?soap=SimpleService&wsdl">service description</a>.</p> + +<com:TForm> +<h2>Soap Calculator</h2> +<com:TTextBox ID="a" Columns="3"/> + <com:TTextBox ID="b" Columns="3"/> = <com:TTextBox ID="result" Columns="3"/> <com:TButton Text="Compute" OnClick="onCompute"/> + +<h2>Highlight source code</h2> +<com:TButton Text="Highlight this" OnClick="onHighlight"/> <br/> +<br/> +<com:TLabel ID="SourceCode"/> + +</com:TForm> +</body> +</html>
\ No newline at end of file diff --git a/demos/soap/protected/pages/Home.php b/demos/soap/protected/pages/Home.php new file mode 100644 index 00000000..98fbe6c6 --- /dev/null +++ b/demos/soap/protected/pages/Home.php @@ -0,0 +1,44 @@ +<?php + +class Home extends TPage { + +  private $_client; +   +  public function onInit($param) { +    // TODO: configure wsdl +    $wsdl = 'http://localhost/prado/svn/trunk/demos/soap/index.php?soap=SimpleService&wsdl'; +    $location = 'http://localhost/prado/svn/trunk/demos/soap/index.php?soap=SimpleService'; +    // TODO: use TSoapClient +    //$this->_client = new SoapClient($wsdl, array('soap_version' => SOAP_1_1, +    //'use' => '', +    //						   'style' => '')); + +    // TODO: use classmap +    $this->_client = new SoapClient(null, array('location' => $location, 'uri' => 'urn:SimpleService', 'soap_version' => SOAP_1_2)); +  } + +  public function onCompute($sender, $param) { +    $a = $this->a->Text; +    $b = $this->b->Text; + +    try { +      $result = $this->_client->add($a, $b); +    } catch(SoapFault $e) { // TODO: Prado wrapper for SoapFault (TSoapFaultException) +      print $e; +    } +    //var_dump($result); +    $this->result->Text = $result; +  } + +  public function onHighlight($sender, $param) { +    try { +      $result = $this->_client->__soapCall('highlight', array(file_get_contents(__FILE__))); +    } catch(SoapFault $e) { // TODO: Prado wrapper for SoapFault (TSoapFaultException) +      print $e; +    } +    $this->SourceCode->Text = $result; +  } + +} + +?>
\ No newline at end of file diff --git a/demos/soap/protected/runtime/global.cache b/demos/soap/protected/runtime/global.cache new file mode 100644 index 00000000..0520dc3a --- /dev/null +++ b/demos/soap/protected/runtime/global.cache @@ -0,0 +1 @@ +a:1:{s:35:"prado:securitymanager:validationkey";s:38:"16373386985182982755332313631333778405";}
\ No newline at end of file diff --git a/demos/soap/protected/webservices/SimpleService.php b/demos/soap/protected/webservices/SimpleService.php new file mode 100644 index 00000000..e59546bb --- /dev/null +++ b/demos/soap/protected/webservices/SimpleService.php @@ -0,0 +1,89 @@ +<?php +class SimpleService +{ +	private $errors = array(); +	 +	/** +	 * Highlights a string as php code +	 * @param string $input The php code to highlight +	 * @return string The highlighted text. +	 * @soapmethod +	 */ +	public function highlight($input) +	{ +		return highlight_string($input, true); +	} +	 +	/** +	 * Given a left side, operation, and right side of an operation, will +	 * return the result of computing the equation. +	 * @param string $leftSide The left side of an equation +	 * @param string $operation The operation to perform  +	 * @param string $rightSide The right side of the equation +	 * @return ComputationResult The result of the computation +	 * @soapmethod +	 */ +	public function compute($leftSide, $operation, $rightSide) +	{ +		$result = new ComputationResult(); +		$result->equation = "$leftSide $operation $rightSide"; +		$result->result = $this->evaluateExpression($leftSide, $operation, $rightSide); +		if (count($this->errors)) { +			$result->success = false; +			$result->errors = $this->errors; +		} +		else { +			$result->success = true; +		} +		 +		return $result;	 +	} + +	/** +	 * Simply add two operands +	 * @param int $a +	 * @param int $b +	 * @return int The result +	 * @soapmethod +	 */ +	public function add($a, $b) { +	  return $a + $b; +	} +	 +	/** +	 * This method evaluates the expression. It should be capable of handling any $op  +	 * passed to it. +	 * @return string the result of the evaluation +	 */ +	private function evaluateExpression($left, $op, $right) +	{ +		// Now, because we don't want to eval random code on the server that this is running +		// on, we're just going to highlight the string +		$evaluation = highlight_string("$left $op $right;", true); +		return $evaluation; +	} +} + +class ComputationResult +{ +	/** +	 * @var string The initial equation +	 */ +	public $equation; +	 +	/** +	 * @var string The computed result +	 */ +	public $result; +	 +	/** +	 * @var boolean Whether the computation succeeded +	 */ +	public $success; +	 +	/** +	 * @var array any errors that occured in the processing. +	 */ +	public $errors; +} +?>
\ No newline at end of file diff --git a/framework/3rdParty/WsdlGen/Wsdl.php b/framework/3rdParty/WsdlGen/Wsdl.php new file mode 100644 index 00000000..e960bbf5 --- /dev/null +++ b/framework/3rdParty/WsdlGen/Wsdl.php @@ -0,0 +1,259 @@ +<?php +/** + * Wsdl file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the BSD License. + * + * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved. + * + * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt} + * This file is part of the PRADO framework from {@link http://www.xisc.com} + * + * @author Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version $Revision$ + * @package System.Web.Services.SOAP + */ + +/** + * Contains the dom object used to build up the wsdl. The  + * operations generated by the generator are stored in here until the getWsdl() + * method is called which builds and returns the generated XML string. + * @author 		Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version 	$Revision$ + */ +class Wsdl +{ +	/** +	 * The name of the service (usually the classname) +	 * @var 	string +	 */ +	private $serviceName; +	 +	/** +	 * The URI to find the service at. If empty, the current +	 * uri will be used (minus any query string) +	 */ +	private $serviceUri; +	 +	/** +	 * The complex types declarations +	 * @var 	ArrayObject +	 */ +	private $types; +	 +	 +	/** +	 * A collection of SOAP operations +	 * @var 	ArrayObject +	 */ +	private $operations; +	 +	/** +	 * Wsdl DOMDocument that's generated. +	 */ +	private $wsdl = null; +	 +	/** +	 * The definitions created for the WSDL +	 */ +	private $definitions = null; +	 +	/** +	 * The target namespace variable? +	 */ +	private $targetNamespace =''; +	 +	/** +	 * The binding style (default at the moment) +	 */ +	private $bindingStyle = 'rpc'; +	 +	/** +	 * The binding uri +	 */ +	private $bindingTransport = 'http://schemas.xmlsoap.org/soap/http'; +	 +	/** +	 * Creates a new Wsdl thing +	 * @param 	string		$name the name of the service. +	 * @param 	string		$serviceUri		The URI of the service that handles this WSDL +	 */ +	public function __construct($name, $serviceUri='') +	{ +		$this->serviceName = $name; +		if ($serviceUri == '') $serviceUri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; +		$this->serviceUri = $serviceUri; +		$this->types = new ArrayObject(); +		$this->targetNamespace = 'urn:'.$name.'wsdl'; +	} +	 +	public function getWsdl() +	{ +		$this->buildWsdl(); +		return $this->wsdl; +	} +	 +	/** +	 * Generates the WSDL file into the $this->wsdl variable +	 */ +	protected function buildWsdl() +	{ +		$xml = '<?xml version="1.0" ?> +                 <definitions name="'.$this->serviceName.'" targetNamespace="'.$this->targetNamespace.'" +                     xmlns="http://schemas.xmlsoap.org/wsdl/" +                     xmlns:tns="'.$this->targetNamespace.'" +                     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" +                     xmlns:xsd="http://www.w3.org/2001/XMLSchema" +                     xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"></definitions>';		 + +		$dom = DOMDocument::loadXml($xml); +		$this->definitions = $dom->documentElement; +		 +		$this->addTypes($dom); +	 +		$this->addMessages($dom); +		$this->addPortTypes($dom); +		$this->addBindings($dom); +		$this->addService($dom); +		 +		$this->wsdl = $dom->saveXML(); +	} +	 +	/** +	 * Adds complexType definitions to the document +	 * @param		DomDocument 		$dom		The document to add to +	 */ +	public function addTypes(DomDocument $dom) +	{ +		if (!count($this->types)) return;				 +		$types = $dom->createElement('types');		 +		$schema = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema'); +		$schema->setAttribute('targetNamespace', $this->targetNamespace); +		foreach($this->types as $type => $elements)  +		{ +			$complexType = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); +			$complexType->setAttribute('name', $type);		 +			if(substr($type, strlen($type) - 5, 5) == 'Array')  // if it's an array +			{   +				$complexContent = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexContent'); +				$restriction = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); +				$restriction->setAttribute('base', 'SOAP-ENC:Array'); +				$attribute = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); +				$attribute->setAttribute('ref', "SOAP-ENC:arrayType"); +				$attribute->setAttribute('arrayType', 'tns:' . substr($type, 0, strlen($type) - 5) . '[]'); +				$restriction->appendChild($attribute); +				$complexContent->appendChild($restriction); +				$complexType->appendChild($complexContent);							 +			}  +			else  +			{ +				$all = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:all'); +				foreach($elements as $elem)  +				{ +					$e = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); +					$e->setAttribute('name', $elem['name']);				 +					$e->setAttribute('type', $elem['type']); +					$all->appendChild($e);	 +				} +				$complexType->appendChild($all); +			}			 +			$schema->appendChild($complexType); +			$types->appendChild($schema);						 +		} +				 +		$this->definitions->appendChild($types); +	} +	 +	/** +	 * Add messages for the service +	 * @param		DomDocument 		$dom		The document to add to +	 */ +	protected function addMessages(DomDocument $dom) +	{ +		foreach ($this->operations as $operation) { +			$operation->setMessageElements($this->definitions, $dom); +		} +	} +	 +	/** +	 * Add the port types for the service +	 * @param		DomDocument 		$dom		The document to add to +	 */ +	protected function addPortTypes(DOMDocument $dom) +	{ +		$portType = $dom->createElement('portType'); +		$portType->setAttribute('name', $this->serviceName.'PortType'); +		 +		$this->definitions->appendChild($portType); +		foreach ($this->operations as $operation) { +			$portOperation = $operation->getPortOperation($dom); +			$portType->appendChild($portOperation); +		} +	} +	 +	/** +	 * Add the bindings for the service +	 * @param		DomDocument 		$dom		The document to add to +	 */ +	protected function addBindings(DOMDocument $dom) +	{ +		$binding = $dom->createElement('binding'); +		$binding->setAttribute('name', $this->serviceName.'Binding'); +		$binding->setAttribute('type', 'tns:'.$this->serviceName.'PortType'); +		 +		$soapBinding = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:binding'); +		$soapBinding->setAttribute('style', $this->bindingStyle); +		$soapBinding->setAttribute('transport', $this->bindingTransport); +		$binding->appendChild($soapBinding); +		 +		$this->definitions->appendChild($binding); +		 +		foreach ($this->operations as $operation) { +			$bindingOperation = $operation->getBindingOperation($dom, $this->targetNamespace, $this->bindingStyle); +			$binding->appendChild($bindingOperation); +		} +	} +	 +	/** +	 * Add the service definition +	 * @param		DomDocument 		$dom		The document to add to +	 */ +	protected function addService(DomDocument $dom) +	{ +		$service = $dom->createElement('service'); +		$service->setAttribute('name', $this->serviceName.'Service'); +		 +		$port = $dom->createElement('port'); +		$port->setAttribute('name', $this->serviceName.'Port'); +		$port->setAttribute('binding', 'tns:'.$this->serviceName.'Binding'); +		 +		$soapAddress = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:address'); +		$soapAddress->setAttribute('location', $this->serviceUri); +		$port->appendChild($soapAddress); +		 +		$service->appendChild($port); +		 +		$this->definitions->appendChild($service);		 +	} +	 +	/** +	 * Adds an operation to have port types and bindings output +	 * @param 		WsdlOperation		$operation 		The operation to add +	 */ +	public function addOperation(WsdlOperation $operation) +	{ +		$this->operations[] = $operation; +	} +	 +	/** +	 * Adds complexTypes to the wsdl +	 * @param string 	$type 	Name of the type +	 * @param Array		$elements	Elements of the type (each one is an associative array('name','type'))	 +	 */ +	public function addComplexType($type, $elements) +	{ +		$this->types[$type] = $elements;	 +	} +} +?>
\ No newline at end of file diff --git a/framework/3rdParty/WsdlGen/WsdlGenerator.php b/framework/3rdParty/WsdlGen/WsdlGenerator.php new file mode 100644 index 00000000..958f5da4 --- /dev/null +++ b/framework/3rdParty/WsdlGen/WsdlGenerator.php @@ -0,0 +1,288 @@ +<?php +/** + * WsdlGenerator file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the BSD License. + * + * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved. + * + * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt} + * This file is part of the PRADO framework from {@link http://www.xisc.com} + * + * @author Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version $Revision$ + * @package System.Web.Services.SOAP + */ + +require_once(dirname(__FILE__).'/Wsdl.php'); +require_once(dirname(__FILE__).'/WsdlMessage.php'); +require_once(dirname(__FILE__).'/WsdlOperation.php'); + +/** + * Generator for the wsdl.  + * Special thanks to Cristian Losada for implementing the Complex Types section of the WSDL. + * @author 		Marcus Nyeholt		<tanus@users.sourceforge.net> + * @author 		Cristian Losada		<cristian@teaxul.com> + * @version 	$Revision$ + */ +class WsdlGenerator +{ +	/** +	 * The instance. +	 * var		WsdlGenerator +	 */ +	private static $instance; +	 +	/** +	 * The name of this service (the classname) +	 * @var 	string +	 */ +	private $serviceName = ''; +	 +	/** +	 * The complex types to use in the wsdl +	 * @var 	Array +	 */ +	private $types = array(); +	 +	/** +	 * The operations available in this wsdl +	 * @var 	ArrayObject +	 */ +	private $operations; +	 +	/** +	 * The wsdl object. +	 * @var 	object +	 */ +	private $wsdlDocument; +	 +	/** +	 * The actual wsdl string +	 * @var 	string +	 */ +	private $wsdl = ''; +	 +	/** +	 * The singleton instance for the generator +	 */ +	public static function getInstance() +	{ +		if (is_null(self::$instance)) { +			self::$instance = new WsdlGenerator(); +		} +		return self::$instance; +	} +	 +	/** +	 * Get the Wsdl generated +	 * @return 	string		The Wsdl for this wsdl +	 */ +	public function getWsdl() +	{ +		return $this->wsdl; +	} +	 +	/** +	 * Generates WSDL for a passed in class, and saves it in the current object. The +	 * WSDL can then be retrieved by calling  +	 * @param 	string		$className		The name of the class to generate for +	 * @param 	string		$serviceUri		The URI of the service that handles this WSDL +	 * @return 	void +	 */ +	public function generateWsdl($className, $serviceUri='') +	{ +		$this->wsdlDocument = new Wsdl($className, $serviceUri); +					 +		$classReflect = new ReflectionClass($className);		 +		$methods = $classReflect->getMethods(); +		 +		foreach ($methods as $method) { +			// Only process public methods +			if ($method->isPublic()) { +				$this->processMethod($method); +			} +		} +		 +		foreach($this->types as $type => $elements) { +			$this->wsdlDocument->addComplexType($type, $elements); +		} +				 +		$this->wsdl = $this->wsdlDocument->getWsdl(); +	} +	 +	/** +	 * Static method that generates and outputs the generated wsdl +	 * @param 		string		$className		The name of the class to export +	 * @param 		string		$serviceUri		The URI of the service that handles this WSDL +	 */ +	public static function generate($className, $serviceUri='') +	{ +		$generator = WsdlGenerator::getInstance(); +		$generator->generateWsdl($className, $serviceUri);		 +		//header('Content-type: text/xml'); +		return $generator->getWsdl(); +		//exit(); +		 +	} +	 +	/** +	 * Process a method found in the passed in class. +	 * @param 		ReflectionMethod		$method		The method to process +	 */ +	protected function processMethod(ReflectionMethod $method) +	{ +		$comment = $method->getDocComment(); +		 +		if (strpos($comment, '@soapmethod') === false) { +			return; +		} +		$comment = preg_replace("/(^[\\s]*\\/\\*\\*) +                                 |(^[\\s]\\*\\/) +                                 |(^[\\s]*\\*?\\s) +                                 |(^[\\s]*) +                                 |(^[\\t]*)/ixm", "", $comment); + +	    $comment = str_replace("\r", "", $comment); +	    $comment = preg_replace("/([\\t])+/", "\t", $comment); +	    $commentLines = explode("\n", $comment); +	     +		$methodDoc = ''; +		$params = array(); +		$return = array(); +		$gotDesc = false; +		$gotParams = false; +		 +		foreach ($commentLines as $line) { +			if ($line == '') continue; +			if ($line{0} == '@') { +				$gotDesc = true; +				if (preg_match('/^@param\s+([\w\[\]()]+)\s+\$([\w()]+)\s*(.*)/i', $line, $match)) { +					$param = array(); +					$param['type'] = $this->convertType($match[1]);					 +					$param['name'] = $match[2]; +					$param['desc'] = $match[3];					 +					$params[] = $param; +				} +				else if (preg_match('/^@return\s+([\w\[\]()]+)\s*(.*)/i', $line, $match)) {			 +					$gotParams = true; +					$return['type'] = $this->convertType($match[1]); +					$return['desc'] = $match[2]; +					$return['name'] = 'return'; +				} +			} +			else { +				if (!$gotDesc) { +					$methodDoc .= trim($line); +				} +				else if (!$gotParams) { +					$params[count($params)-1]['desc'] .= trim($line); +				} +				else { +					if ($line == '*/') continue; +					$return['desc'] .= trim($line); +				} +			} +		} +		 +		$methodName = $method->getName(); +		$operation = new WsdlOperation($methodName, $methodDoc); +		 +		$operation->setInputMessage(new WsdlMessage($methodName.'Request', $params)); +		$operation->setOutputMessage(new WsdlMessage($methodName.'Response', array($return))); +		 +		$this->wsdlDocument->addOperation($operation); +		 +	} +	 +	/** +	 * Converts from a PHP type into a WSDL type. This is borrowed from  +	 * Cerebral Cortex (let me know and I'll remove asap). +	 * +	 * TODO: date and dateTime +	 * @param 		string		$type		The php type to convert +	 * @return 		string					The XSD type. +	 */ +	private function convertType($type) +	{ +		 switch ($type) { +             case 'string': +             case 'str': +                 return 'xsd:string'; +                 break; +             case 'int': +             case 'integer': +                 return 'xsd:int'; +                 break; +             case 'float': +             case 'double': +                 return 'xsd:float'; +                 break; +             case 'boolean': +             case 'bool': +                 return 'xsd:boolean'; +                 break; +             case 'array': +                 return 'soap-enc:Array'; +                 break; +             case 'object': +                 return 'xsd:struct'; +                 break; +             case 'mixed': +                 return 'xsd:anyType'; +                 break; +             case 'void': +                 return ''; +             default:     +             	 if(strpos($type, '[]'))  // if it is an array +             	 {  +             	 	$className = substr($type, 0, strlen($type) - 2); +             	 	$type = $className . 'Array'; +             	 	$this->types[$type] = ''; +             	 	$this->convertType($className); +             	 }  +             	 else  +             	 { +             	 	 if(!isset($this->types[$type]))  +	             		$this->extractClassProperties($type); +             	 }             	  +                 return 'tns:' . $type;    +         } +	} +	 +	/** +	 * Extract the type and the name of all properties of the $className class and saves it in the $types array +	 * This method extract properties from PHPDoc formatted comments for variables. Unfortunately the reflectionproperty +	 * class doesn't have a getDocComment method to extract comments about it, so we have to extract the information +	 * about the variables manually. Thanks heaps to Cristian Losada for implementing this. +	 * @param string $className The name of the class   +	 */ +	private function extractClassProperties($className)  +	{ +		// Lets get the class' file so we can read the full contents of it. +		$classReflect = new ReflectionClass($className); +		 +		if (!file_exists($classReflect->getFileName())) { +			throw new Exception('Could not find class file for '.$className); +		} +		 +		$file = file_get_contents($classReflect->getFileName()); +		if ($file == '') { +			throw new Exception("File {$classReflect->getFileName()} could not be opened"); +		} +		 +		$pos = strpos($file, 'class ' . $className); +		$pos = strpos($file, '@var', $pos) + 5; +		for($t = 0; $pos > 5; $t++)  +		{	 +			$type = $this->convertType(substr($file, $pos, strpos($file, ' ', $pos) - $pos)); +			$pos = strpos($file, '$', $pos) + 1; +			$name = substr($file, $pos, strpos($file, ';', $pos) - $pos);			 +			$this->types[$className][$t] = array('type' => $type, 'name' => $name);   +			$pos = strpos($file, '@var', $pos) + 5; +		} +	} +	 +} +?>
\ No newline at end of file diff --git a/framework/3rdParty/WsdlGen/WsdlMessage.php b/framework/3rdParty/WsdlGen/WsdlMessage.php new file mode 100644 index 00000000..5cb9e13f --- /dev/null +++ b/framework/3rdParty/WsdlGen/WsdlMessage.php @@ -0,0 +1,80 @@ +<?php +/** + * WsdlMessage file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the BSD License. + * + * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved. + * + * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt} + * This file is part of the PRADO framework from {@link http://www.xisc.com} + * + * @author Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version $Revision$ + * @package System.Web.Services.SOAP + */ + +/** + * Represents a WSDL message. This is bound to the portTypes + * for this service + * @author 		Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version 	$Revision$ + */ +class WsdlMessage +{ +	/** +	 * The name of this message +	 * @var 	string +	 */ +	private $name; +	 +	/** +	 * Represents the parameters for this message +	 * @var 	array +	 */ +	private $parts; +	 +	/** +	 * Creates a new message +	 * @param 	string		$messageName	The name of the message +	 * @param 	string		$parts			The parts of this message +	 */ +	public function __construct($messageName, $parts) +	{ +		$this->name = $messageName; +		$this->parts = $parts; +		 +	} +	 +	/** +	 * Gets the name of this message +	 * @return 		string		The name +	 */ +	public function getName() +	{ +		return $this->name; +	} +	 +	/** +	 * Return the message as a DOM element +	 * @param 		DOMDocument		$wsdl		The wsdl document the messages will be children of +	 */ +	public function getMessageElement(DOMDocument $dom) +	{ +		$message = $dom->createElement('message'); +		$message->setAttribute('name', $this->name); +		 +		foreach ($this->parts as $part) { +			if (isset($part['name'])) { +				$partElement = $dom->createElement('part'); +				$partElement->setAttribute('name', $part['name']); +				$partElement->setAttribute('type', $part['type']); +				$message->appendChild($partElement); +			} +		} +		 +		return $message; +	} +} +?>
\ No newline at end of file diff --git a/framework/3rdParty/WsdlGen/WsdlOperation.php b/framework/3rdParty/WsdlGen/WsdlOperation.php new file mode 100644 index 00000000..38cee0d8 --- /dev/null +++ b/framework/3rdParty/WsdlGen/WsdlOperation.php @@ -0,0 +1,135 @@ +<?php +/** + * WsdlOperation file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the BSD License. + * + * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved. + * + * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt} + * This file is part of the PRADO framework from {@link http://www.xisc.com} + * + * @author Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version $Revision$ + * @package System.Web.Services.SOAP + */ + +/** + * Represents a WSDL Operation. This is exported for the portTypes and bindings + * section of the soap service + * @author 		Marcus Nyeholt		<tanus@users.sourceforge.net> + * @version 	$Revision$ + */ +class WsdlOperation +{ +	/** +	 * The name of the operation +	 */ +	private $operationName; +	 +	/** +	 * Documentation for the operation +	 */ +	private $documentation; +	 +	/** +	 * The input wsdl message +	 */ +	private $inputMessage; +	 +	/** +	 * The output wsdl message +	 */ +	private $outputMessage; +	 +	public function __construct($name, $doc='') +	{ +		$this->operationName = $name; +		$this->documentation = $doc; +	} +	 +	public function setInputMessage(WsdlMessage $msg) +	{ +		$this->inputMessage = $msg; +	} +	 +	public function setOutputMessage(WsdlMessage $msg) +	{ +		$this->outputMessage = $msg; +	} +	 +	/** +	 * Sets the message elements for this operation into the wsdl document +	 * @param 	DOMElement 		$wsdl		The parent domelement for the messages +	 * @param 	DomDocument		$dom		The dom document to create the messages as children of +	 */ +	public function setMessageElements(DOMElement $wsdl, DOMDocument $dom) +	{ +		 +		$input = $this->inputMessage->getMessageElement($dom); +		$output = $this->outputMessage->getMessageElement($dom); +		 +		$wsdl->appendChild($input); +		$wsdl->appendChild($output); +	} +	 +	/** +	 * Get the port operations for this operation +	 * @param 	DomDocument		$dom		The dom document to create the messages as children of +	 * @return 	DomElement					The dom element representing this port. +	 */ +	public function getPortOperation(DomDocument $dom) +	{ +		$operation = $dom->createElement('operation'); +		$operation->setAttribute('name', $this->operationName); +		 +		$documentation = $dom->createElement('documentation', htmlentities($this->documentation)); +		$input = $dom->createElement('input'); +		$input->setAttribute('message', 'tns:'.$this->inputMessage->getName()); +		$output = $dom->createElement('output'); +		$output->setAttribute('message', 'tns:'.$this->outputMessage->getName()); +		 +		$operation->appendChild($documentation); +		$operation->appendChild($input); +		$operation->appendChild($output); +		 +		return $operation; +	} +	 +	/** +	 * Build the binding operations. +	 * TODO: Still quite incomplete with all the things being stuck in, I don't understand +	 * a lot of it, and it's mostly copied from the output of nusoap's wsdl output. +	 * @param 	DomDocument		$dom		The dom document to create the binding as children of +	 * @param 	string			$namespace	The namespace this binding is in. +	 * @return 	DomElement					The dom element representing this binding. +	 */ +	public function getBindingOperation(DomDocument $dom, $namespace, $style='rpc') +	{ +		$operation = $dom->createElement('operation'); +		$operation->setAttribute('name', $this->operationName); +		 +		$soapOperation = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:operation'); +		$method = $this->operationName; +		$soapOperation->setAttribute('soapAction', $namespace.'#'.$method); +		$soapOperation->setAttribute('style', $style); +		 +		$input = $dom->createElement('input'); +		$output = $dom->createElement('output'); +		 +		$soapBody = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:body'); +		$soapBody->setAttribute('use', 'encoded'); +		$soapBody->setAttribute('namespace', $namespace); +		$soapBody->setAttribute('encodingStyle', 'http://schemas.xmlsoap.org/soap/encoding/'); +		$input->appendChild($soapBody); +		$output->appendChild(clone $soapBody); +		 +		$operation->appendChild($soapOperation); +		$operation->appendChild($input); +		$operation->appendChild($output); +		 +		return $operation; +	} +} +?>
\ No newline at end of file diff --git a/framework/Web/Services/TSoapService.php b/framework/Web/Services/TSoapService.php new file mode 100644 index 00000000..a2db2e27 --- /dev/null +++ b/framework/Web/Services/TSoapService.php @@ -0,0 +1,101 @@ +<?php +/** + * TSoapService class file + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @link http://www.pradosoft.com + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web.Services + */ + +//Prado::using('System.Web.Services.TWebService'); + +require_once dirname(__FILE__).'/../../3rdParty/WsdlGen/WsdlGenerator.php'; + +/** + * TSoapService class + * + * TSoapService provides + * + * @author Knut Urdalen <knut.urdalen@gmail.com> + * @package System.Web.Services + * @since 3.1 + */ +class TSoapService extends TService { + +  private $_class; + +  private $_server; // reference to the SOAP server + +  /** +   * Constructor. +   * Sets default service ID to 'soap'. +   */ +  public function __construct() { +    $this->setID('soap'); +  } + +  /** +   * Initializes the service. +   * This method is required by IService interface and is invoked by application. +   * @param TXmlElement service configuration +   */ +  public function init($config) { +    // nothing to do here +  } + +  /** +   * Runs the service. +   *  +   * This will serve a WSDL-file of the Soap server if 'wsdl' is provided as a key in +   * the URL, else if will serve the Soap server. +   */ +  public function run() { +    Prado::trace("Running SOAP service",'System.Web.Services.TSoapService'); + +    $this->setSoapServer($this->getRequest()->getServiceParameter()); +    Prado::using($this->getSoapServer()); // Load class + +    // TODO: Fix protocol and host +    $uri = 'http://'.$_SERVER['HTTP_HOST'].$this->getRequest()->getRequestUri(); + +    //print_r($this->getRequest()); +    if($this->getRequest()->itemAt('wsdl') !== null) { // Show WSDL-file +      // TODO: Check WSDL cache +      // Solution: Use Application Mode 'Debug' = no caching, 'Performance' = use cachez +      $uri = str_replace('&wsdl', '', $uri); // throw away the 'wsdl' key (this is a bit dirty) +      $uri = str_replace('wsdl', '', $uri); // throw away the 'wsdl' key (this is a bit dirty) +      $wsdl = WsdlGenerator::generate($this->_class, $uri); +      $this->getResponse()->setContentType('text/xml'); +      $this->getResponse()->write($wsdl); +    } else { // Provide service +      // TODO: use TSoapServer +      $this->_server = new SoapServer($uri.'&wsdl'); +      $this->_server->setClass($this->getSoapServer()); +      $this->_server->handle(); +    } +  } + +  /** +   * @return TSoapServer +   */ +  public function getSoapServer() { +    return $this->_class; +  } + +  /** +   * @param TSoapServer $class +   */ +  public function setSoapServer($class) { +    // TODO: ensure $class instanceof TSoapServer +    $this->_class = $class; +  } + +  public function getPersistence() { + +  } +   +} + +?>
\ No newline at end of file | 
