|
1 <?php |
|
2 |
|
3 /** |
|
4 * IXR_IntrospectionServer |
|
5 * |
|
6 * @package IXR |
|
7 * @since 1.5.0 |
|
8 */ |
|
9 class IXR_IntrospectionServer extends IXR_Server |
|
10 { |
|
11 var $signatures; |
|
12 var $help; |
|
13 |
|
14 /** |
|
15 * PHP5 constructor. |
|
16 */ |
|
17 function __construct() |
|
18 { |
|
19 $this->setCallbacks(); |
|
20 $this->setCapabilities(); |
|
21 $this->capabilities['introspection'] = array( |
|
22 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', |
|
23 'specVersion' => 1 |
|
24 ); |
|
25 $this->addCallback( |
|
26 'system.methodSignature', |
|
27 'this:methodSignature', |
|
28 array('array', 'string'), |
|
29 'Returns an array describing the return type and required parameters of a method' |
|
30 ); |
|
31 $this->addCallback( |
|
32 'system.getCapabilities', |
|
33 'this:getCapabilities', |
|
34 array('struct'), |
|
35 'Returns a struct describing the XML-RPC specifications supported by this server' |
|
36 ); |
|
37 $this->addCallback( |
|
38 'system.listMethods', |
|
39 'this:listMethods', |
|
40 array('array'), |
|
41 'Returns an array of available methods on this server' |
|
42 ); |
|
43 $this->addCallback( |
|
44 'system.methodHelp', |
|
45 'this:methodHelp', |
|
46 array('string', 'string'), |
|
47 'Returns a documentation string for the specified method' |
|
48 ); |
|
49 } |
|
50 |
|
51 /** |
|
52 * PHP4 constructor. |
|
53 */ |
|
54 public function IXR_IntrospectionServer() { |
|
55 self::__construct(); |
|
56 } |
|
57 |
|
58 function addCallback($method, $callback, $args, $help) |
|
59 { |
|
60 $this->callbacks[$method] = $callback; |
|
61 $this->signatures[$method] = $args; |
|
62 $this->help[$method] = $help; |
|
63 } |
|
64 |
|
65 function call($methodname, $args) |
|
66 { |
|
67 // Make sure it's in an array |
|
68 if ($args && !is_array($args)) { |
|
69 $args = array($args); |
|
70 } |
|
71 |
|
72 // Over-rides default call method, adds signature check |
|
73 if (!$this->hasMethod($methodname)) { |
|
74 return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.'); |
|
75 } |
|
76 $method = $this->callbacks[$methodname]; |
|
77 $signature = $this->signatures[$methodname]; |
|
78 $returnType = array_shift($signature); |
|
79 |
|
80 // Check the number of arguments |
|
81 if (count($args) != count($signature)) { |
|
82 return new IXR_Error(-32602, 'server error. wrong number of method parameters'); |
|
83 } |
|
84 |
|
85 // Check the argument types |
|
86 $ok = true; |
|
87 $argsbackup = $args; |
|
88 for ($i = 0, $j = count($args); $i < $j; $i++) { |
|
89 $arg = array_shift($args); |
|
90 $type = array_shift($signature); |
|
91 switch ($type) { |
|
92 case 'int': |
|
93 case 'i4': |
|
94 if (is_array($arg) || !is_int($arg)) { |
|
95 $ok = false; |
|
96 } |
|
97 break; |
|
98 case 'base64': |
|
99 case 'string': |
|
100 if (!is_string($arg)) { |
|
101 $ok = false; |
|
102 } |
|
103 break; |
|
104 case 'boolean': |
|
105 if ($arg !== false && $arg !== true) { |
|
106 $ok = false; |
|
107 } |
|
108 break; |
|
109 case 'float': |
|
110 case 'double': |
|
111 if (!is_float($arg)) { |
|
112 $ok = false; |
|
113 } |
|
114 break; |
|
115 case 'date': |
|
116 case 'dateTime.iso8601': |
|
117 if (!is_a($arg, 'IXR_Date')) { |
|
118 $ok = false; |
|
119 } |
|
120 break; |
|
121 } |
|
122 if (!$ok) { |
|
123 return new IXR_Error(-32602, 'server error. invalid method parameters'); |
|
124 } |
|
125 } |
|
126 // It passed the test - run the "real" method call |
|
127 return parent::call($methodname, $argsbackup); |
|
128 } |
|
129 |
|
130 function methodSignature($method) |
|
131 { |
|
132 if (!$this->hasMethod($method)) { |
|
133 return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); |
|
134 } |
|
135 // We should be returning an array of types |
|
136 $types = $this->signatures[$method]; |
|
137 $return = array(); |
|
138 foreach ($types as $type) { |
|
139 switch ($type) { |
|
140 case 'string': |
|
141 $return[] = 'string'; |
|
142 break; |
|
143 case 'int': |
|
144 case 'i4': |
|
145 $return[] = 42; |
|
146 break; |
|
147 case 'double': |
|
148 $return[] = 3.1415; |
|
149 break; |
|
150 case 'dateTime.iso8601': |
|
151 $return[] = new IXR_Date(time()); |
|
152 break; |
|
153 case 'boolean': |
|
154 $return[] = true; |
|
155 break; |
|
156 case 'base64': |
|
157 $return[] = new IXR_Base64('base64'); |
|
158 break; |
|
159 case 'array': |
|
160 $return[] = array('array'); |
|
161 break; |
|
162 case 'struct': |
|
163 $return[] = array('struct' => 'struct'); |
|
164 break; |
|
165 } |
|
166 } |
|
167 return $return; |
|
168 } |
|
169 |
|
170 function methodHelp($method) |
|
171 { |
|
172 return $this->help[$method]; |
|
173 } |
|
174 } |