7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
16 * @package Zend_XmlRpc
18 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
24 * For handling the HTTP connection to the XML-RPC service
25 * @see Zend_Http_Client
27 require_once 'Zend/Http/Client.php';
30 * Enables object chaining for calling namespaced XML-RPC methods.
31 * @see Zend_XmlRpc_Client_ServerProxy
33 require_once 'Zend/XmlRpc/Client/ServerProxy.php';
36 * Introspects remote servers using the XML-RPC de facto system.* methods
37 * @see Zend_XmlRpc_Client_ServerIntrospection
39 require_once 'Zend/XmlRpc/Client/ServerIntrospection.php';
42 * Represent a native XML-RPC value, used both in sending parameters
43 * to methods and as the parameters retrieve from method calls
44 * @see Zend_XmlRpc_Value
46 require_once 'Zend/XmlRpc/Value.php';
50 * @see Zend_XmlRpc_Request
52 require_once 'Zend/XmlRpc/Request.php';
56 * @see Zend_XmlRpc_Response
58 require_once 'Zend/XmlRpc/Response.php';
62 * @see Zend_XmlRpc_Fault
64 require_once 'Zend/XmlRpc/Fault.php';
68 * An XML-RPC client implementation
71 * @package Zend_XmlRpc
73 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
74 * @license http://framework.zend.com/license/new-bsd New BSD License
76 class Zend_XmlRpc_Client
79 * Full address of the XML-RPC service
81 * @example http://time.xmlrpc.com/RPC2
83 protected $_serverAddress;
86 * HTTP Client to use for requests
87 * @var Zend_Http_Client
89 protected $_httpClient = null;
92 * Introspection object
93 * @var Zend_Http_Client_Introspector
95 protected $_introspector = null;
98 * Request of the last method call
99 * @var Zend_XmlRpc_Request
101 protected $_lastRequest = null;
104 * Response received from the last method call
105 * @var Zend_XmlRpc_Response
107 protected $_lastResponse = null;
110 * Proxy object for more convenient method calls
111 * @var array of Zend_XmlRpc_Client_ServerProxy
113 protected $_proxyCache = array();
116 * Flag for skipping system lookup
119 protected $_skipSystemLookup = false;
122 * Create a new XML-RPC client to a remote server
124 * @param string $server Full address of the XML-RPC service
125 * (e.g. http://time.xmlrpc.com/RPC2)
126 * @param Zend_Http_Client $httpClient HTTP Client to use for requests
129 public function __construct($server, Zend_Http_Client
$httpClient = null)
131 if ($httpClient === null) {
132 $this->_httpClient
= new Zend_Http_Client();
134 $this->_httpClient
= $httpClient;
137 $this->_introspector
= new Zend_XmlRpc_Client_ServerIntrospection($this);
138 $this->_serverAddress
= $server;
143 * Sets the HTTP client object to use for connecting the XML-RPC server.
145 * @param Zend_Http_Client $httpClient
146 * @return Zend_Http_Client
148 public function setHttpClient(Zend_Http_Client
$httpClient)
150 return $this->_httpClient
= $httpClient;
155 * Gets the HTTP client object.
157 * @return Zend_Http_Client
159 public function getHttpClient()
161 return $this->_httpClient
;
166 * Sets the object used to introspect remote servers
168 * @param Zend_XmlRpc_Client_ServerIntrospection
169 * @return Zend_XmlRpc_Client_ServerIntrospection
171 public function setIntrospector(Zend_XmlRpc_Client_ServerIntrospection
$introspector)
173 return $this->_introspector
= $introspector;
178 * Gets the introspection object.
180 * @return Zend_XmlRpc_Client_ServerIntrospection
182 public function getIntrospector()
184 return $this->_introspector
;
189 * The request of the last method call
191 * @return Zend_XmlRpc_Request
193 public function getLastRequest()
195 return $this->_lastRequest
;
200 * The response received from the last method call
202 * @return Zend_XmlRpc_Response
204 public function getLastResponse()
206 return $this->_lastResponse
;
211 * Returns a proxy object for more convenient method calls
213 * @param $namespace Namespace to proxy or empty string for none
214 * @return Zend_XmlRpc_Client_ServerProxy
216 public function getProxy($namespace = '')
218 if (empty($this->_proxyCache
[$namespace])) {
219 $proxy = new Zend_XmlRpc_Client_ServerProxy($this, $namespace);
220 $this->_proxyCache
[$namespace] = $proxy;
222 return $this->_proxyCache
[$namespace];
226 * Set skip system lookup flag
229 * @return Zend_XmlRpc_Client
231 public function setSkipSystemLookup($flag = true)
233 $this->_skipSystemLookup
= (bool) $flag;
238 * Skip system lookup when determining if parameter should be array or struct?
242 public function skipSystemLookup()
244 return $this->_skipSystemLookup
;
248 * Perform an XML-RPC request and return a response.
250 * @param Zend_XmlRpc_Request $request
251 * @param null|Zend_XmlRpc_Response $response
253 * @throws Zend_XmlRpc_Client_HttpException
255 public function doRequest($request, $response = null)
257 $this->_lastRequest
= $request;
259 iconv_set_encoding('input_encoding', 'UTF-8');
260 iconv_set_encoding('output_encoding', 'UTF-8');
261 iconv_set_encoding('internal_encoding', 'UTF-8');
263 $http = $this->getHttpClient();
264 if($http->getUri() === null) {
265 $http->setUri($this->_serverAddress
);
268 $http->setHeaders(array(
269 'Content-Type: text/xml; charset=utf-8',
270 'User-Agent: Zend_XmlRpc_Client',
274 $xml = $this->_lastRequest
->__toString();
275 $http->setRawData($xml);
276 $httpResponse = $http->request(Zend_Http_Client
::POST
);
278 if (! $httpResponse->isSuccessful()) {
280 * Exception thrown when an HTTP error occurs
281 * @see Zend_XmlRpc_Client_HttpException
283 require_once 'Zend/XmlRpc/Client/HttpException.php';
284 throw new Zend_XmlRpc_Client_HttpException(
285 $httpResponse->getMessage(),
286 $httpResponse->getStatus());
289 if ($response === null) {
290 $response = new Zend_XmlRpc_Response();
292 $this->_lastResponse
= $response;
293 $this->_lastResponse
->loadXml($httpResponse->getBody());
297 * Send an XML-RPC request to the service (for a specific method)
299 * @param string $method Name of the method we want to call
300 * @param array $params Array of parameters for the method
302 * @throws Zend_XmlRpc_Client_FaultException
304 public function call($method, $params=array())
306 if (!$this->skipSystemLookup() && ('system.' != substr($method, 0, 7))) {
307 // Ensure empty array/struct params are cast correctly
308 // If system.* methods are not available, bypass. (ZF-2978)
311 $signatures = $this->getIntrospector()->getMethodSignature($method);
312 } catch (Zend_XmlRpc_Exception
$e) {
316 foreach ($params as $key => $param) {
317 if (is_array($param) && empty($param)) {
319 foreach ($signatures as $signature) {
320 if (!is_array($signature)) {
323 if (array_key_exists($key +
1, $signature)) {
324 $type = $signature[$key +
1];
325 $type = (in_array($type, array('array', 'struct'))) ?
$type : 'array';
329 $params[$key] = array(
338 $request = new Zend_XmlRpc_Request($method, $params);
340 $this->doRequest($request);
342 if ($this->_lastResponse
->isFault()) {
343 $fault = $this->_lastResponse
->getFault();
345 * Exception thrown when an XML-RPC fault is returned
346 * @see Zend_XmlRpc_Client_FaultException
348 require_once 'Zend/XmlRpc/Client/FaultException.php';
349 throw new Zend_XmlRpc_Client_FaultException($fault->getMessage(),
353 return $this->_lastResponse
->getReturnValue();