This repository has been archived by the owner on Jan 8, 2020. It is now read-only.
/
ServerIntrospection.php
153 lines (131 loc) · 4.26 KB
/
ServerIntrospection.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
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_XmlRpc
*/
namespace Zend\XmlRpc\Client;
use Zend\XmlRpc\Client as XMLRPCClient;
/**
* Wraps the XML-RPC system.* introspection methods
*
* @category Zend
* @package Zend_XmlRpc
* @subpackage Client
*/
class ServerIntrospection
{
/**
* @var \Zend\XmlRpc\Client\ServerProxy
*/
private $system = null;
/**
* @param \Zend\XmlRpc\Client $client
*/
public function __construct(XMLRPCClient $client)
{
$this->system = $client->getProxy('system');
}
/**
* Returns the signature for each method on the server,
* autodetecting whether system.multicall() is supported and
* using it if so.
*
* @return array
*/
public function getSignatureForEachMethod()
{
$methods = $this->listMethods();
try {
$signatures = $this->getSignatureForEachMethodByMulticall($methods);
} catch (Exception\FaultException $e) {
// degrade to looping
}
if (empty($signatures)) {
$signatures = $this->getSignatureForEachMethodByLooping($methods);
}
return $signatures;
}
/**
* Attempt to get the method signatures in one request via system.multicall().
* This is a boxcar feature of XML-RPC and is found on fewer servers. However,
* can significantly improve performance if present.
*
* @param array $methods
* @throws Exception\IntrospectException
* @return array array(array(return, param, param, param...))
*/
public function getSignatureForEachMethodByMulticall($methods = null)
{
if ($methods === null) {
$methods = $this->listMethods();
}
$multicallParams = array();
foreach ($methods as $method) {
$multicallParams[] = array('methodName' => 'system.methodSignature',
'params' => array($method));
}
$serverSignatures = $this->system->multicall($multicallParams);
if (! is_array($serverSignatures)) {
$type = gettype($serverSignatures);
$error = "Multicall return is malformed. Expected array, got $type";
throw new Exception\IntrospectException($error);
}
if (count($serverSignatures) != count($methods)) {
$error = 'Bad number of signatures received from multicall';
throw new Exception\IntrospectException($error);
}
// Create a new signatures array with the methods name as keys and the signature as value
$signatures = array();
foreach ($serverSignatures as $i => $signature) {
$signatures[$methods[$i]] = $signature;
}
return $signatures;
}
/**
* Get the method signatures for every method by
* successively calling system.methodSignature
*
* @param array $methods
* @return array
*/
public function getSignatureForEachMethodByLooping($methods = null)
{
if ($methods === null) {
$methods = $this->listMethods();
}
$signatures = array();
foreach ($methods as $method) {
$signatures[$method] = $this->getMethodSignature($method);
}
return $signatures;
}
/**
* Call system.methodSignature() for the given method
*
* @param array $method
* @throws Exception\IntrospectException
* @return array array(array(return, param, param, param...))
*/
public function getMethodSignature($method)
{
$signature = $this->system->methodSignature($method);
if (!is_array($signature)) {
$error = 'Invalid signature for method "' . $method . '"';
throw new Exception\IntrospectException($error);
}
return $signature;
}
/**
* Call system.listMethods()
*
* @return array array(method, method, method...)
*/
public function listMethods()
{
return $this->system->listMethods();
}
}