diff options
-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 |