summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknut <>2006-07-06 19:45:32 +0000
committerknut <>2006-07-06 19:45:32 +0000
commit97dddf3cf23f7d2829d23efb9d44b746ac7d52cc (patch)
tree23c5984380a250bbe0d1163c055df2404df19649
parent9cc6b7fffd31f4b9ee9aceef9224c84dcf28aeb8 (diff)
Added a TSoapService prototype with a simple demo app
-rw-r--r--.gitattributes11
-rw-r--r--demos/soap/index.php5
-rw-r--r--demos/soap/protected/application.xml10
-rw-r--r--demos/soap/protected/pages/Home.page20
-rw-r--r--demos/soap/protected/pages/Home.php44
-rw-r--r--demos/soap/protected/runtime/global.cache1
-rw-r--r--demos/soap/protected/webservices/SimpleService.php89
-rw-r--r--framework/3rdParty/WsdlGen/Wsdl.php259
-rw-r--r--framework/3rdParty/WsdlGen/WsdlGenerator.php288
-rw-r--r--framework/3rdParty/WsdlGen/WsdlMessage.php80
-rw-r--r--framework/3rdParty/WsdlGen/WsdlOperation.php135
-rw-r--r--framework/Web/Services/TSoapService.php101
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 &copy; 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