* Remove obsolete warning in Extension Manager
[Packages/TYPO3.CMS.git] / typo3 / mod / tools / em / class.em_soap.php
1 <?php
2 /* **************************************************************
3 * Copyright notice
4 *
5 * (c) webservices.nl
6 * (c) 2006 Karsten Dambekalns <karsten@typo3.org>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28 /* $Id$ */
29
30 /**
31 * Enter description here...
32 *
33 */
34 class em_soap {
35 /**
36 * valid options passed to the constructor :
37 * wsdl : The WSDL location, can be a local file location or
38 * an URL.
39 * soapoptions : Associative array of SOAP options to be passed to
40 * the SOAP implementation constructor, only used for
41 * the phpsoap implement.
42 * authentication : method of authentication :
43 * 'headers' soap headers are used
44 * 'prefix' function prefixes are used
45 * prefix : optional prefix to be put in front of all methods.
46 * implementation : Which type of soap implementation to use :
47 * 'detect' automatically detect an implementation.
48 * 'phpsoap' PHP builtin SOAP module
49 * <http://www.php.net/manual/en/ref.soap.php>
50 * 'nusoap' NuSOAP class
51 * <http://dietrich.ganx4.com/nusoap>
52 * 'pearsoap' PEAR SOAP class
53 * <http://pear.php.net/package/SOAP>
54 * format : Which type of return structure :
55 * 'object' PHP objects
56 * 'array' PHP arrays, default
57 */
58 var $options = array();
59
60 /**
61 * SOAP client depending on the available implementations, preferably the PHP SOAP class
62 *
63 * @var unknown_type
64 */
65 var $client = false;
66 var $error = false;
67
68 var $username = false;
69 var $password = false;
70 var $reactid = false;
71
72 /**
73 * Enter description here...
74 *
75 * @param array $options
76 * @param string $username
77 * @param string $password
78 * @return [type] ...
79 */
80 function init($options=false, $username=false, $password=false) {
81 if ($username !== false) {
82 if ($password === false) {
83 $this->reactid = $username;
84 } else {
85 $this->username = $username;
86 $this->password = $password;
87 }
88 }
89
90 if (!$options['implementation'] || $options['implementation'] == 'detect') {
91 if (defined('SOAP_1_2')) {
92 $options['implementation'] = 'phpsoap';
93 } elseif (class_exists('soapclient')) {
94 $options['implementation'] = 'nusoap';
95 } elseif (class_exists('SOAP_Client')) {
96 $options['implementation'] = 'pearsoap';
97 }
98 }
99
100 $options['format'] = $options['format'] == 'object' ? 'object' : 'array';
101
102 if ($options !== false) {
103 $this->options = (array)$options;
104 }
105
106 switch ($this->options['implementation']) {
107 case 'nusoap':
108 $this->client =& new soapclient($this->options['wsdl'], true);
109 $this->client->getProxy();
110 break;
111 case 'pearsoap':
112 $this->client =& new SOAP_Client($this->options['wsdl'], true);
113 break;
114 case 'phpsoap':
115 $this->client =& new SoapClient($options['wsdl'],(array)$options['soapoptions']);
116 break;
117 default:
118 $this->client = false;
119 }
120 }
121
122 /**
123 * Enter description here...
124 *
125 * @param string $username
126 * @param string $password
127 * @return mixed false on failure, $reactid on success
128 */
129 function login($username, $password) {
130 $reactid = $this->call('login', array('username' => $username, 'password' => $password));
131
132 if ($this->error) {
133 return false;
134 }
135
136 $this->reactid = $reactid;
137 $this->username = $username;
138 $this->password = false;
139
140 return $reactid;
141 }
142
143 /**
144 * Enter description here...
145 *
146 * @return unknown
147 */
148 function logout() {
149 $this->call('logout');
150 $this->reactid = false;
151 if ($this->error) {
152 return false;
153 }
154 return true;
155 }
156
157
158 /**
159 * Enter description here...
160 *
161 * @param unknown_type $func
162 * @param unknown_type $param
163 * @param unknown_type $username
164 * @param unknown_type $password
165 * @return unknown
166 */
167 function call($func, $param=array(), $username=false, $password=false) {
168 if (!$this->client) {
169 $this->error = "Error in Webservices.class.php: No soap client implementation found. ".
170 "Make sure a SOAP library such as 'NuSoap.php' is included.";
171 return false;
172 }
173
174 if ($username !== false) {
175 if ($password === false) {
176 $this->reactid = $username;
177 } else {
178 $this->username = $username;
179 $this->password = $password;
180 }
181 }
182
183 if ($this->options['authentication'] == 'prefix') {
184 $param = array_merge(array('reactid' => $this->reactid), $param);
185 }
186
187 if ($this->options['prefix']) {
188 $func = $this->options['prefix'].ucfirst($func);
189 }
190
191 $this->error = false;
192
193 switch ($this->options['implementation']) {
194 case 'nusoap' : return $this->callNuSOAP($func, $param); break;
195 case 'pearsoap' : return $this->callPearSOAP($func, $param); break;
196 case 'phpsoap' : return $this->callPhpSOAP($func, $param); break;
197 }
198
199 return false;
200 }
201
202 /**
203 * Enter description here...
204 *
205 * @param unknown_type $func
206 * @param unknown_type $param
207 * @return unknown
208 */
209 function callPhpSOAP($func, $param) {
210 $header = null;
211 if ($this->options['authentication'] == 'headers') {
212 if ($this->reactid) {
213 $header =& new SoapHeader(
214 '','HeaderAuthenticate',
215 (object)array('reactid' => $this->reactid), 1
216 );
217 } elseif ($this->username && $this->password) {
218 $header =& new SoapHeader(
219 '','HeaderLogin',
220 (object)array(
221 'username' => $this->username,
222 'password' => $this->password
223 ), 1
224 );
225 $this->password = false;
226 }
227 }
228
229 $result = $this->client->__soapCall($func, $param, NULL, $header);
230
231 if (is_soap_fault($result)) {
232 $this->error = $result;
233 return false;
234 }
235
236 if (is_a($this->client->headersIn['HeaderAuthenticate'],'stdClass')) {
237 $this->reactid = $this->client->headersIn['HeaderAuthenticate']->reactid;
238 }
239
240 return $this->options['format'] == 'object' ? $result : $this->object2array($result);
241 }
242
243 /**
244 * Enter description here...
245 *
246 * @param unknown_type $func
247 * @param unknown_type $param
248 * @return unknown
249 */
250 function callPearSOAP($func,$param) {
251 if ($this->options['authentication'] == 'headers') {
252 if ($this->reactid) {
253 $this->client->addHeader(
254 new SOAP_Header(
255 'HeaderAuthenticate', NULL,
256 array('reactid' => $this->reactid), 1
257 )
258 );
259 } elseif ($this->username && $this->password) {
260 $this->client->addHeader(
261 new SOAP_Header(
262 'HeaderLogin', NULL,
263 array(
264 'username' => $this->username,
265 'password' => $this->password
266 ), 1
267 )
268 );
269 $this->password = false;
270 }
271 }
272
273
274 $result = $this->client->call($func, $param);
275
276 if (PEAR::isError($result)) {
277 $this->error = $result;
278 return false;
279 }
280
281 if (is_a($this->client->headersIn['HeaderAuthenticate'],'stdClass')) {
282 $this->reactid = $this->client->headersIn['HeaderAuthenticate']->reactid;
283 }
284
285 return $this->options['format'] == 'object' ? $result : $this->object2array($result);
286 }
287
288 /**
289 * Enter description here...
290 *
291 * @param unknown_type $func
292 * @param unknown_type $param
293 * @return unknown
294 */
295 function callNuSOAP($func,$param) {
296 $header = false;
297 if ($this->options['authentication'] == 'headers') {
298 if ($this->reactid) {
299 $header = (
300 "<HeaderAuthenticate SOAP-ENV:mustUnderstand='1'>".
301 "<reactid>".htmlspecialchars($this->reactid)."</reactid>".
302 "</HeaderAuthenticate>"
303 );
304 } elseif ($this->username && $this->password) {
305 $header = (
306 "<HeaderLogin SOAP-ENV:mustUnderstand='1'>".
307 "<username>".htmlspecialchars($this->username)."</username>".
308 "<password>".htmlspecialchars($this->password)."</password>".
309 "</HeaderLogin>" //HeaderLogin
310 );
311 $this->password = false;
312 }
313 }
314
315 $result = $this->client->call($func, $param, false, false, $header);
316
317 if ($this->error = $this->client->getError()) {
318 return false;
319 }
320
321 // nusoap header support is very limited
322 $headers = $this->client->getHeaders();
323 $matches = array();
324 if (preg_match('~<([a-z0-9]+:)?reactid[^>]*>([^<]*)</([a-z0-9]+:)?reactid>~is', $headers, $matches)) {
325 $this->reactid = $matches[2];
326 }
327
328 return $this->options['format'] == 'object' ? $this->array2object($result) : $result;
329 }
330
331 /**
332 * Enter description here...
333 *
334 * @param unknown_type $object
335 * @return unknown
336 */
337 function object2array($object) {
338 if (!is_object($object) && !is_array($object)) {
339 return $object;
340 }
341
342 $array = (array)$object;
343 foreach ($array as $key => $value) {
344 $array[$key] = $this->object2array($value);
345 }
346 return $array;
347 }
348
349 /**
350 * Enter description here...
351 *
352 * @param unknown_type $array
353 * @return unknown
354 */
355 function array2object($array) {
356 if (!is_array($array)) {
357 return $array;
358 }
359
360 foreach ($array as $key => $value) {
361 $array[$key] = $this->array2object($value);
362 }
363 return (object)$array;
364 }
365
366 /**
367 * Enter description here...
368 *
369 * @return unknown
370 */
371 function lastRequest() {
372 switch ($this->options['implementation']) {
373 case 'nusoap' : return $this->client->request; break;
374 case 'pearsoap' : return $this->client->__getlastrequest(); break;
375 case 'phpsoap' : return $this->client->__getLastRequest(); break;
376 }
377
378 return false;
379 }
380
381 /**
382 * Enter description here...
383 *
384 * @return unknown
385 */
386 function lastResponse() {
387 switch ($this->options['implementation']) {
388 case 'nusoap' : return $this->client->response; break;
389 case 'pearsoap' : return $this->client->__getlastresponse(); break;
390 case 'phpsoap' : return $this->client->__getLastResponse(); break;
391 }
392
393 return false;
394 }
395
396 /**
397 * Enter description here...
398 *
399 * @return unknown
400 */
401 function getFunctions() {
402 switch ($this->options['implementation']) {
403 case 'nusoap' : return array_keys($this->client->operations); break;
404 case 'pearsoap' : return false; break;
405 case 'phpsoap' : return $this->client->__getFunctions(); break;
406 }
407
408 return false;
409 }
410 }
411
412 ?>