Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Wsdl file.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the BSD License.
7
 *
8
 * Copyright(c) 2005 by Marcus Nyeholt. All rights reserved.
9
 *
10
 * To contact the author write to {@link mailto:tanus@users.sourceforge.net Marcus Nyeholt}
11
 * This file is part of the PRADO framework from {@link http://www.xisc.com}
12
 *
13
 * @author Marcus Nyeholt		<tanus@users.sourceforge.net>
14
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
15
 * @version $Id: Wsdl.php 2393 2008-03-07 17:12:19Z xue $
16
 * @package System.Web.Services.SOAP
17
 */
18
 
19
/**
20
 * Contains the dom object used to build up the wsdl. The
21
 * operations generated by the generator are stored in here until the getWsdl()
22
 * method is called which builds and returns the generated XML string.
23
 * @author 		Marcus Nyeholt		<tanus@users.sourceforge.net>
24
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
25
 * @version 	$Revision$
26
 */
27
class Wsdl
28
{
29
	/**
30
	 * The name of the service (usually the classname)
31
	 * @var 	string
32
	 */
33
	private $serviceName;
34
 
35
	/**
36
	 * The URI to find the service at. If empty, the current
37
	 * uri will be used (minus any query string)
38
	 */
39
	private $serviceUri;
40
 
41
	/**
42
	 * The complex types declarations
43
	 * @var 	ArrayObject
44
	 */
45
	private $types;
46
 
47
 
48
	/**
49
	 * A collection of SOAP operations
50
	 * @var 	array
51
	 */
52
	private $operations=array();
53
 
54
	/**
55
	 * Wsdl DOMDocument that's generated.
56
	 */
57
	private $wsdl = null;
58
 
59
	/**
60
	 * The definitions created for the WSDL
61
	 */
62
	private $definitions = null;
63
 
64
	/**
65
	 * The target namespace variable?
66
	 */
67
	private $targetNamespace ='';
68
 
69
	/**
70
	 * The binding style (default at the moment)
71
	 */
72
	private $bindingStyle = 'rpc';
73
 
74
	/**
75
	 * The binding uri
76
	 */
77
	private $bindingTransport = 'http://schemas.xmlsoap.org/soap/http';
78
 
79
	private $_encoding='';
80
 
81
	private static $_primitiveTypes = array('string', 'int', 'float', 'boolean', 'date', 'time', 'dateTime');
82
 
83
	/**
84
	 * Creates a new Wsdl thing
85
	 * @param 	string		$name the name of the service.
86
	 * @param 	string		$serviceUri		The URI of the service that handles this WSDL
87
	 * @param string character encoding
88
	 */
89
	public function __construct($name, $serviceUri='', $encoding='')
90
	{
91
		$this->_encoding = $encoding;
92
		$this->serviceName = $name;
93
		if ($serviceUri == '') $serviceUri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
94
		$this->serviceUri = str_replace('&amp;', '&', $serviceUri);
95
		$this->types = new ArrayObject();
96
		$this->targetNamespace = 'urn:'.$name.'wsdl';
97
	}
98
 
99
	public function getWsdl()
100
	{
101
		$this->buildWsdl();
102
		return $this->wsdl;
103
	}
104
 
105
	/**
106
	 * Generates the WSDL file into the $this->wsdl variable
107
	 */
108
	protected function buildWsdl()
109
	{
110
		$encoding = $this->_encoding==='' ? '' : 'encoding="'.$this->_encoding.'"';
111
 
112
		$xml = '<?xml version="1.0" '.$encoding.'?>
113
                 <definitions name="'.$this->serviceName.'" targetNamespace="'.$this->targetNamespace.'"
114
                     xmlns="http://schemas.xmlsoap.org/wsdl/"
115
                     xmlns:tns="'.$this->targetNamespace.'"
116
                     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
117
                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
118
					 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
119
                     xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"></definitions>';
120
 
121
		$dom = new DOMDocument();
122
		$dom->loadXml($xml);
123
		$this->definitions = $dom->documentElement;
124
 
125
		$this->addTypes($dom);
126
 
127
		$this->addMessages($dom);
128
		$this->addPortTypes($dom);
129
		$this->addBindings($dom);
130
		$this->addService($dom);
131
 
132
		$this->wsdl = $dom->saveXML();
133
	}
134
 
135
	/**
136
	 * Adds complexType definitions to the document
137
	 * @param		DomDocument 		$dom		The document to add to
138
	 */
139
	public function addTypes(DomDocument $dom)
140
	{
141
		if (!count($this->types)) return;
142
		$types = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/', 'wsdl:types');
143
		$schema = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema');
144
		$schema->setAttribute('targetNamespace', $this->targetNamespace);
145
		foreach($this->types as $type => $elements)
146
		{
147
			$complexType = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
148
			$complexType->setAttribute('name', $type);
149
			if(substr($type, strlen($type) - 5, 5) == 'Array')  // if it's an array
150
			{
151
				$complexContent = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexContent');
152
				$restriction = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
153
				$restriction->setAttribute('base', 'soap-enc:Array');
154
				$attribute = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
155
				$attribute->setAttribute('ref', "soap-enc:arrayType");
156
				$attribute->setAttribute('wsdl:arrayType', $this->getArrayTypePrefix($type) . substr($type, 0, strlen($type) - 5) . '[]');
157
				$restriction->appendChild($attribute);
158
				$complexContent->appendChild($restriction);
159
				$complexType->appendChild($complexContent);
160
			}
161
			else
162
			{
163
				$all = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:all');
164
				foreach($elements as $elem)
165
				{
166
					$e = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
167
					$e->setAttribute('name', $elem['name']);
168
					$e->setAttribute('type', $elem['type']);
169
					$all->appendChild($e);
170
				}
171
				$complexType->appendChild($all);
172
			}
173
			$schema->appendChild($complexType);
174
			$types->appendChild($schema);
175
		}
176
 
177
		$this->definitions->appendChild($types);
178
	}
179
 
180
	/**
181
	 * @return string prefix 'xsd:' for primitive array types, otherwise, 'tns:'
182
	 */
183
	protected function getArrayTypePrefix($type)
184
	{
185
		$elementType = substr($type, 0, strlen($type) - 5);
186
		return in_array($elementType, self::$_primitiveTypes) ? 'xsd:' : 'tns:';
187
	}
188
 
189
	/**
190
	 * Add messages for the service
191
	 * @param		DomDocument 		$dom		The document to add to
192
	 */
193
	protected function addMessages(DomDocument $dom)
194
	{
195
		foreach ($this->operations as $operation) {
196
			$operation->setMessageElements($this->definitions, $dom);
197
		}
198
	}
199
 
200
	/**
201
	 * Add the port types for the service
202
	 * @param		DomDocument 		$dom		The document to add to
203
	 */
204
	protected function addPortTypes(DOMDocument $dom)
205
	{
206
		$portType = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/', 'wsdl:portType');
207
		$portType->setAttribute('name', $this->serviceName.'PortType');
208
 
209
		$this->definitions->appendChild($portType);
210
		foreach ($this->operations as $operation) {
211
			$portOperation = $operation->getPortOperation($dom);
212
			$portType->appendChild($portOperation);
213
		}
214
	}
215
 
216
	/**
217
	 * Add the bindings for the service
218
	 * @param		DomDocument 		$dom		The document to add to
219
	 */
220
	protected function addBindings(DOMDocument $dom)
221
	{
222
		$binding = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/', 'wsdl:binding');
223
		$binding->setAttribute('name', $this->serviceName.'Binding');
224
		$binding->setAttribute('type', 'tns:'.$this->serviceName.'PortType');
225
 
226
		$soapBinding = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:binding');
227
		$soapBinding->setAttribute('style', $this->bindingStyle);
228
		$soapBinding->setAttribute('transport', $this->bindingTransport);
229
		$binding->appendChild($soapBinding);
230
 
231
		$this->definitions->appendChild($binding);
232
 
233
		foreach ($this->operations as $operation) {
234
			$bindingOperation = $operation->getBindingOperation($dom, $this->targetNamespace, $this->bindingStyle);
235
			$binding->appendChild($bindingOperation);
236
		}
237
	}
238
 
239
	/**
240
	 * Add the service definition
241
	 * @param		DomDocument 		$dom		The document to add to
242
	 */
243
	protected function addService(DomDocument $dom)
244
	{
245
		$service = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/', 'wsdl:service');
246
		$service->setAttribute('name', $this->serviceName.'Service');
247
 
248
		$port = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/', 'wsdl:port');
249
		$port->setAttribute('name', $this->serviceName.'Port');
250
		$port->setAttribute('binding', 'tns:'.$this->serviceName.'Binding');
251
 
252
		$soapAddress = $dom->createElementNS('http://schemas.xmlsoap.org/wsdl/soap/', 'soap:address');
253
		$soapAddress->setAttribute('location', $this->serviceUri);
254
		$port->appendChild($soapAddress);
255
 
256
		$service->appendChild($port);
257
 
258
		$this->definitions->appendChild($service);
259
	}
260
 
261
	/**
262
	 * Adds an operation to have port types and bindings output
263
	 * @param 		WsdlOperation		$operation 		The operation to add
264
	 */
265
	public function addOperation(WsdlOperation $operation)
266
	{
267
		$this->operations[] = $operation;
268
	}
269
 
270
	/**
271
	 * Adds complexTypes to the wsdl
272
	 * @param string 	$type 	Name of the type
273
	 * @param Array		$elements	Elements of the type (each one is an associative array('name','type'))
274
	 */
275
	public function addComplexType($type, $elements)
276
	{
277
		$this->types[$type] = $elements;
278
	}
279
}
280
?>