-
Notifications
You must be signed in to change notification settings - Fork 26
/
ripcord.php
356 lines (332 loc) · 11.5 KB
/
ripcord.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
<?php
/**
* Ripcord is an easy to use XML-RPC library for PHP.
* @package Ripcord
* @author Auke van Slooten <[email protected]>
* @copyright Copyright (C) 2010, Muze <www.muze.nl>
* @license http://opensource.org/licenses/gpl-3.0.html GNU Public License
* @version Ripcord 0.9 - PHP 5
*/
/**
* The ripcord class contains a number of useful static methods. This makes it a bit easier to create a server or client, convert types
* and check for errors.
* @package Ripcord
*/
class ripcord
{
/**
* This method checks whether the given argument is an XML-RPC fault.
* @param mixed $fault
* @return bool
*/
public static function isFault($fault)
{
if ( isset($fault) && is_array($fault) ) {
return xmlrpc_is_fault($fault);
} else {
return false;
}
}
/**
* This method generates an XML-RPC fault with the given code and message.
* @param int $code
* @param string $message
* @return array
*/
public static function fault($code, $message)
{
return array('faultCode' => $code, 'faultString' => $message);
}
/**
* This method returns a new Ripcord server, which by default implements XML-RPC, Simple RPC and SOAP 1.1.
* The server will publish any methods passed through the $services argument. It can be configured through
* the $options argument.
* @param mixed $services Optional. Either an object or an array of objects. If the array has non-numeric keys, the key will be used as a namespace for the methods in the object.
* @param array $options Optional. An array of options to set for the Ripcord server.
* @see Ripcord_Server
*/
public static function server($services = null, $options = null, $documentor = null)
{
self::load('Ripcord_Server');
if ( !isset($documentor) )
{
$doc = array('name', 'css', 'wsdl', 'wsdl2');
$docOptions = array();
foreach ( $doc as $key )
{
if ( isset($options[$key]) )
{
$docOptions[$key] = $options[$key];
unset( $options[$key] );
}
}
$docOptions['version'] = $options['version'];
$documentor = self::documentor( $docOptions );
}
return new Ripcord_Server($services, $options, $documentor);
}
/**
* This method returns a new Ripcord client. By default this will be an XML-RPC client, but you can change this
* through the $options argument.
* @param string $url The url of the RPC server to connect with
* @param array $options Optional. An array of options to set for the Ripcord client.
* @see Ripcord_Client
*/
public static function client($url, $options = null, $transport = null )
{
self::load('Ripcord_Client');
if ( !isset($transport) )
{
$transport = new Ripcord_Transport_Stream();
}
return new Ripcord_Client($url, $options, $transport);
}
/**
* This method returns a new Ripcord documentor object.
* @param array $options Optional. An array of options to set for the Ripcord documentor.
* @param object docCommentParser Optional. An object that parses a docComment block. Must
* implement the Ripcord_Documentor_CommentParser interface.
* @see Ripcord_Client
*/
public static function documentor( $options = null, $docCommentParser = null )
{
self::load('Ripcord_Documentor');
if (!$docCommentParser) {
$docCommentParser = new Ripcord_Documentor_Parser_phpdoc();
}
return new Ripcord_Documentor( $options, $docCommentParser );
}
/**
* This method returns an XML-RPC datetime object from a given unix timestamp.
* @param int $timestamp
* @return object
*/
public static function datetime($timestamp)
{
$datetime = date("Ymd\TH:i:s", $timestamp);
xmlrpc_set_type($datetime, 'datetime');
return $datetime;
}
/**
* This method returns a unix timestamp from a given XML-RPC datetime object.
* It will throw a 'Variable is not of type datetime' Ripcord_Exception (code -6)
* if the given argument is not of the correct type.
* @param object $datetime
* @return int
*/
public static function timestamp($datetime)
{
if (xmlrpc_get_type($datetime)=='datetime')
{
return $datetime->timestamp;
} else {
throw Ripcord_Exception('Variable is not of type datetime', -6);
}
}
/**
* This method returns an XML-RPC base64 object from a given binary string.
* @param string $binary
* @return object
*/
public static function base64($binary)
{
xmlrpc_set_type($binary, 'base64');
return $binary;
}
/**
* This method returns a (binary) string from a given XML-RPC base64 object.
* It will throw a 'Variable is not of type base64' Ripcord_Exception (code -7)
* if the given argument is not of the correct type.
* @param object $base64
* @return string
*/
public static function binary($base64)
{
if (xmlrpc_get_type($base64)=='base64')
{
return $base64->scalar;
} else {
throw Ripcord_Exception('Variable is not of type base64', -7);
}
}
/**
* This method returns the type of the given parameter. This can be any of the XML-RPC data types, e.g.
* 'struct', 'int', 'string', 'base64', 'boolean', 'double', 'array' or 'datetime'.
* @param mixed $param
* @return string
*/
public static function getType($param)
{
return xmlrpc_get_type($param);
}
/**
* This method returns a new Ripcord client, configured to access a SOAP 1.1 server.
* @param string $url
* @param array $options Optional.
* @see Ripcord_Client
*/
public static function soapClient($url, $options = null, $transport = null)
{
$options['version'] = 'soap 1.1';
return self::client($url, $options, $transport);
}
/**
* This method returns a new Ripcord client, configured to access an XML-RPC server.
* @param string $url
* @param array $options Optional.
* @return object
* @see Ripcord_Client
*/
public static function xmlrpcClient($url, $options = null, $transport = null)
{
$options['version'] = 'xmlrpc';
return self::client($url, $options, $transport);
}
/**
* This method returns a new Ripcord client, configured to access a Simple RPC server.
* @param string $url
* @param array $options Optional.
* @return object
* @see Ripcord_Client
*/
public static function simpleClient($url, $options = null, $transport = null)
{
$options['version'] = 'simple';
return self::client($url, $options, $transport);
}
/**
* This method includes a ripcord class, using require_once. Used for autoloading ripcord classes.
* @param string $class The name of the class to load.
* @return boolean
*/
public static function load($class)
{
if (substr($class, 0, 8)=='Ripcord_')
{
$root = dirname(__FILE__).'/ripcord_';
$class = substr($class, 8);
$file = str_replace('.', '', $class);
$file = str_replace('_', '/', $file);
$file = strtolower($file);
while ($file && $file!='.')
{
if ( file_exists($root.$file.'.php') )
{
require_once($root.$file.'.php');
return true;
} else {
$file = dirname($file);
}
}
}
return false;
}
/**
* This method creates a new Ripcord_Client_Call object, which encodes the information needed for
* a method call to an rpc server. This is mostly used for the system.multiCall method.
* @param string $method The name of the method call to encode
* @param mixed $args,... The remainder of the arguments are encoded as parameters to the call
* @return object
*/
public static function encodeCall()
{
self::load('Ripcord_Client');
$params = func_get_args();
$method = array_shift($params);
return new Ripcord_Client_Call( $method, $params );
}
/*
* This method binds the first parameter to the output of a Ripcord client call. If
* the second argument is a Ripcord_Client_Call object, it binds the parameter to it,
* if not it simply assigns the second parameter to the first parameter.
* This means that doing:
* > ripcord::bind( $result, $client->someMethod() )
* will always result in $result eventually containing the return value of $client->someMethod().
* Whether multiCall mode has been enabled or not.
*/
public function bind(&$bound, $call)
{
if ( is_a( $call, 'Ripcord_Client_Call' ) )
{
$call->bound =& $bound;
} else {
$bound = $call;
}
return null;
}
/**
* Method {method} not found. - Thrown by the ripcord server when a requested method isn't found.
*/
const methodNotFound = -1;
/**
* Argument {index} is not a valid Ripcord call - Thrown by the client when passing incorrect arguments to system.multiCall.
*/
const notRipcordCall = -2;
/**
* Cannot recurse system.multiCall - Thrown by the ripcord server when system.multicall is called within itself.
*/
const cannotRecurse = -3;
/**
* Could not access {url} - Thrown by the transport object when unable to access the given url.
*/
const cannotAccessURL = -4;
/**
* PHP XMLRPC library is not installed - Thrown by the ripcord server and client when the xmlrpc library is not installed.
*/
const xmlrpcNotInstalled = -5;
/**
* Variable is not of type datetime - Thrown by the ripcord timestamp method.
*/
const notDatetime = -6;
/**
* Variable is not of type base64 - Thrown by the ripcord binary method.
*/
const notBase64 = -7;
/**
* Variable is not a classname or an object - Thrown by the ripcord server.
*/
const unknownServiceType = -8;
}
/**
* This interface is implemented by all exceptions thrown by Ripcord.
* @package Ripcord
*/
interface Ripcord_Exception {}
/**
* This class is used whenever an when a method passed to the server is invalid.
* - ripcord::methodNotFound (-1) Method {method} not found. - Thrown by the ripcord server when a requested method isn't found.
* @package Ripcord
*/
class Ripcord_BadMethodCallException extends BadMethodCallException implements Ripcord_Exception { }
/**
* This class is used whenever prerequisite requirements are not met.
* - ripcord::xmlrpcNotInstalled (-5) PHP XMLRPC library is not installed - Thrown by the ripcord server and client when the xmlrpc library is not installed.
* @package Ripcord
*/
class Ripcord_ConfigurationException extends Exception implements Ripcord_Exception { }
/**
* This class is used whenever an argument passed to a Ripcord method is invalid for any reason. Possible exceptions thrown are:
* - ripcord::notRipcordCall (-2) Argument {index} is not a valid Ripcord call - Thrown by the client when passing incorrect arguments to system.multiCall.
* - ripcord::cannotRecurse (-3) Cannot recurse system.multiCall - Thrown by the ripcord server when system.multicall is called within itself.
* - ripcord::notDateTime (-6) Variable is not of type datetime - Thrown by the ripcord timestamp method.
* - ripcord::notBase64 (-7) Variable is not of type base64 - Thrown by the ripcord binary method.
* - ripcord::unknownServiceType (-8) Variable is not a classname or an object - Thrown by the ripcord server.
* @package Ripcord
*/
class Ripcord_InvalidArgumentException extends InvalidArgumentException implements Ripcord_Exception { }
/**
* This class is used whenever something goes wrong in sending / receiving data. Possible exceptions thrown are:
* - ripcord::cannotAccessURL (-4) Could not access {url} - Thrown by the transport object when unable to access the given url.
* @package Ripcord
*/
class Ripcord_TransportException extends RuntimeException implements Ripcord_Exception { }
/**
* This class is used for exceptions generated from xmlrpc faults returned by the server. The code and message correspond
* to the code and message from the xmlrpc fault.
* @package Ripcord
*/
class Ripcord_RemoteException extends Exception implements Ripcord_Exception { }
if (function_exists('spl_autoload_register')) {
spl_autoload_register('ripcord::load');
}
?>