import v1.0.0-RC4 | 2009-05-20
This commit is contained in:
252
libs/Zend/Rest/Client.php
Normal file
252
libs/Zend/Rest/Client.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
|
||||
/** Zend_Service_Abstract */
|
||||
require_once 'Zend/Service/Abstract.php';
|
||||
|
||||
/** Zend_Rest_Client_Result */
|
||||
require_once 'Zend/Rest/Client/Result.php';
|
||||
|
||||
/** Zend_Uri */
|
||||
require_once 'Zend/Uri.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Client extends Zend_Service_Abstract
|
||||
{
|
||||
/**
|
||||
* Data for the query
|
||||
* @var array
|
||||
*/
|
||||
protected $_data = array();
|
||||
|
||||
/**
|
||||
* Zend_Uri of this web service
|
||||
* @var Zend_Uri_Http
|
||||
*/
|
||||
protected $_uri = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string|Zend_Uri_Http $uri URI for the web service
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($uri = null)
|
||||
{
|
||||
if (!empty($uri)) {
|
||||
$this->setUri($uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URI to use in the request
|
||||
*
|
||||
* @param string|Zend_Uri_Http $uri URI for the web service
|
||||
* @return Zend_Rest_Client
|
||||
*/
|
||||
public function setUri($uri)
|
||||
{
|
||||
if ($uri instanceof Zend_Uri_Http) {
|
||||
$this->_uri = $uri;
|
||||
} else {
|
||||
$this->_uri = Zend_Uri::factory($uri);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current request URI object
|
||||
*
|
||||
* @return Zend_Uri_Http
|
||||
*/
|
||||
public function getUri()
|
||||
{
|
||||
return $this->_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a remote REST web service URI and return the Zend_Http_Response object
|
||||
*
|
||||
* @param string $path The path to append to the URI
|
||||
* @throws Zend_Rest_Client_Exception
|
||||
* @return void
|
||||
*/
|
||||
final private function _prepareRest($path)
|
||||
{
|
||||
// Get the URI object and configure it
|
||||
if (!$this->_uri instanceof Zend_Uri_Http) {
|
||||
require_once 'Zend/Rest/Client/Exception.php';
|
||||
throw new Zend_Rest_Client_Exception('URI object must be set before performing call');
|
||||
}
|
||||
|
||||
$uri = $this->_uri->getUri();
|
||||
|
||||
if ($path[0] != '/' && $uri[strlen($uri)-1] != '/') {
|
||||
$path = '/' . $path;
|
||||
}
|
||||
|
||||
$this->_uri->setPath($path);
|
||||
|
||||
/**
|
||||
* Get the HTTP client and configure it for the endpoint URI. Do this each time
|
||||
* because the Zend_Http_Client instance is shared among all Zend_Service_Abstract subclasses.
|
||||
*/
|
||||
self::getHttpClient()->resetParameters()->setUri($this->_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an HTTP GET request to the $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $query Array of GET parameters
|
||||
* @return Zend_Http_Response
|
||||
*/
|
||||
final public function restGet($path, array $query = null)
|
||||
{
|
||||
$this->_prepareRest($path);
|
||||
$client = self::getHttpClient();
|
||||
$client->setParameterGet($query);
|
||||
return $client->request('GET');
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a POST or PUT
|
||||
*
|
||||
* Performs a POST or PUT request. Any data provided is set in the HTTP
|
||||
* client. String data is pushed in as raw POST data; array or object data
|
||||
* is pushed in as POST parameters.
|
||||
*
|
||||
* @param mixed $method
|
||||
* @param mixed $data
|
||||
* @return Zend_Http_Response
|
||||
*/
|
||||
protected function _performPost($method, $data = null)
|
||||
{
|
||||
$client = self::getHttpClient();
|
||||
if (is_string($data)) {
|
||||
$client->setRawData($data);
|
||||
} elseif (is_array($data) || is_object($data)) {
|
||||
$client->setParameterPost((array) $data);
|
||||
}
|
||||
return $client->request($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an HTTP POST request to $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $data Raw data to send
|
||||
* @return Zend_Http_Response
|
||||
*/
|
||||
final public function restPost($path, $data = null)
|
||||
{
|
||||
$this->_prepareRest($path);
|
||||
return $this->_performPost('POST', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an HTTP PUT request to $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $data Raw data to send in request
|
||||
* @return Zend_Http_Response
|
||||
*/
|
||||
final public function restPut($path, $data = null)
|
||||
{
|
||||
$this->_prepareRest($path);
|
||||
return $this->_performPost('PUT', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an HTTP DELETE request to $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @return Zend_Http_Response
|
||||
*/
|
||||
final public function restDelete($path)
|
||||
{
|
||||
$this->_prepareRest($path);
|
||||
return self::getHttpClient()->request('DELETE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method call overload
|
||||
*
|
||||
* Allows calling REST actions as object methods; however, you must
|
||||
* follow-up by chaining the request with a request to an HTTP request
|
||||
* method (post, get, delete, put):
|
||||
* <code>
|
||||
* $response = $rest->sayHello('Foo', 'Manchu')->get();
|
||||
* </code>
|
||||
*
|
||||
* Or use them together, but in sequential calls:
|
||||
* <code>
|
||||
* $rest->sayHello('Foo', 'Manchu');
|
||||
* $response = $rest->get();
|
||||
* </code>
|
||||
*
|
||||
* @param string $method Method name
|
||||
* @param array $args Method args
|
||||
* @return Zend_Rest_Client_Result|Zend_Rest_Client Zend_Rest_Client if using
|
||||
* a remote method, Zend_Rest_Client_Result if using an HTTP request method
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$methods = array('post', 'get', 'delete', 'put');
|
||||
|
||||
if (in_array(strtolower($method), $methods)) {
|
||||
if (!isset($args[0])) {
|
||||
$args[0] = $this->_uri->getPath();
|
||||
}
|
||||
$this->_data['rest'] = 1;
|
||||
$data = array_slice($args, 1) + $this->_data;
|
||||
$response = $this->{'rest' . $method}($args[0], $data);
|
||||
return new Zend_Rest_Client_Result($response->getBody());
|
||||
} else {
|
||||
// More than one arg means it's definitely a Zend_Rest_Server
|
||||
if (sizeof($args) == 1) {
|
||||
// Uses first called function name as method name
|
||||
if (!isset($this->_data['method'])) {
|
||||
$this->_data['method'] = $method;
|
||||
$this->_data['arg1'] = $args[0];
|
||||
}
|
||||
$this->_data[$method] = $args[0];
|
||||
} else {
|
||||
$this->_data['method'] = $method;
|
||||
if (sizeof($args) > 0) {
|
||||
foreach ($args as $key => $arg) {
|
||||
$key = 'arg' . $key;
|
||||
$this->_data[$key] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
39
libs/Zend/Rest/Client/Exception.php
Normal file
39
libs/Zend/Rest/Client/Exception.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Zend_Rest_Exception
|
||||
*/
|
||||
require_once 'Zend/Rest/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* Zend_Rest_Server_Exception
|
||||
*
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Client_Exception extends Zend_Rest_Exception
|
||||
{
|
||||
}
|
||||
|
224
libs/Zend/Rest/Client/Result.php
Normal file
224
libs/Zend/Rest/Client/Result.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Client_Result implements IteratorAggregate {
|
||||
/**
|
||||
* @var SimpleXMLElement
|
||||
*/
|
||||
protected $_sxml;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $data XML Result
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
set_error_handler(array($this, 'handleXmlErrors'));
|
||||
$this->_sxml = simplexml_load_string($data);
|
||||
if($this->_sxml === false) {
|
||||
$this->handleXmlErrors(0, "An error occured while parsing the REST response with simplexml.");
|
||||
} else {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary error handler for parsing REST responses.
|
||||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param string $errfile
|
||||
* @param string $errline
|
||||
* @param array $errcontext
|
||||
* @throws Zend_Result_Client_Result_Exception
|
||||
*/
|
||||
public function handleXmlErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null)
|
||||
{
|
||||
restore_error_handler();
|
||||
require_once "Zend/Rest/Client/Result/Exception.php";
|
||||
throw new Zend_Rest_Client_Result_Exception("REST Response Error: ".$errstr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a SimpleXMLElement to its appropriate PHP value
|
||||
*
|
||||
* @param SimpleXMLElement $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function toValue(SimpleXMLElement $value)
|
||||
{
|
||||
$node = dom_import_simplexml($value);
|
||||
return $node->nodeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Property Overload
|
||||
*
|
||||
* @param string $name
|
||||
* @return null|SimpleXMLElement|array Null if not found, SimpleXMLElement if only one value found, array of Zend_Rest_Client_Result objects otherwise
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->_sxml->{$name})) {
|
||||
return $this->_sxml->{$name};
|
||||
}
|
||||
|
||||
$result = $this->_sxml->xpath("//$name");
|
||||
$count = count($result);
|
||||
|
||||
if ($count == 0) {
|
||||
return null;
|
||||
} elseif ($count == 1) {
|
||||
return $result[0];
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast properties to PHP values
|
||||
*
|
||||
* For arrays, loops through each element and casts to a value as well.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (null !== ($value = $this->__get($method))) {
|
||||
if (!is_array($value)) {
|
||||
return $this->toValue($value);
|
||||
} else {
|
||||
$return = array();
|
||||
foreach ($value as $element) {
|
||||
$return[] = $this->toValue($element);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Isset Overload
|
||||
*
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
if (isset($this->_sxml->{$name})) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$result = $this->_sxml->xpath("//$name");
|
||||
|
||||
if (sizeof($result) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement IteratorAggregate::getIterator()
|
||||
*
|
||||
* @return SimpleXMLIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->_sxml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Request Status
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
$status = $this->_sxml->xpath('//status/text()');
|
||||
|
||||
$status = strtolower($status[0]);
|
||||
|
||||
if (ctype_alpha($status) && $status == 'success') {
|
||||
return true;
|
||||
} elseif (ctype_alpha($status) && $status != 'success') {
|
||||
return false;
|
||||
} else {
|
||||
return (bool) $status;
|
||||
}
|
||||
}
|
||||
|
||||
public function isError()
|
||||
{
|
||||
$status = $this->getStatus();
|
||||
if ($status) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function isSuccess()
|
||||
{
|
||||
$status = $this->getStatus();
|
||||
if ($status) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toString overload
|
||||
*
|
||||
* Be sure to only call this when the result is a single value!
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (!$this->getStatus()) {
|
||||
$message = $this->_sxml->xpath('//message');
|
||||
return (string) $message[0];
|
||||
} else {
|
||||
$result = $this->_sxml->xpath('//response');
|
||||
if (sizeof($result) > 1) {
|
||||
return (string) "An error occured.";
|
||||
} else {
|
||||
return (string) $result[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
libs/Zend/Rest/Client/Result/Exception.php
Normal file
27
libs/Zend/Rest/Client/Result/Exception.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Client
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Zend_Rest_Client_Exception
|
||||
*/
|
||||
require_once "Zend/Rest/Client/Exception.php";
|
||||
|
||||
class Zend_Rest_Client_Result_Exception extends Zend_Rest_Client_Exception{}
|
36
libs/Zend/Rest/Exception.php
Normal file
36
libs/Zend/Rest/Exception.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Zend_Exception
|
||||
*/
|
||||
require_once 'Zend/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Exception extends Zend_Exception
|
||||
{}
|
||||
|
610
libs/Zend/Rest/Server.php
Normal file
610
libs/Zend/Rest/Server.php
Normal file
@ -0,0 +1,610 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Server
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Zend_Server_Interface
|
||||
*/
|
||||
require_once 'Zend/Server/Interface.php';
|
||||
|
||||
/**
|
||||
* Zend_Server_Reflection
|
||||
*/
|
||||
require_once 'Zend/Server/Reflection.php';
|
||||
|
||||
/**
|
||||
* Zend_Rest_Server_Exception
|
||||
*/
|
||||
require_once 'Zend/Rest/Server/Exception.php';
|
||||
|
||||
/**
|
||||
* Zend_Server_Abstract
|
||||
*/
|
||||
require_once 'Zend/Server/Abstract.php';
|
||||
|
||||
/**
|
||||
* @category Zend
|
||||
* @package Zend_Rest
|
||||
* @subpackage Server
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Server implements Zend_Server_Interface
|
||||
{
|
||||
/**
|
||||
* Class Constructor Args
|
||||
* @var array
|
||||
*/
|
||||
protected $_args = array();
|
||||
|
||||
/**
|
||||
* @var string Encoding
|
||||
*/
|
||||
protected $_encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* @var array An array of Zend_Server_Reflect_Method
|
||||
*/
|
||||
protected $_functions = array();
|
||||
|
||||
/**
|
||||
* @var array Array of headers to send
|
||||
*/
|
||||
protected $_headers = array();
|
||||
|
||||
/**
|
||||
* @var array PHP's Magic Methods, these are ignored
|
||||
*/
|
||||
protected static $magicMethods = array(
|
||||
'__construct',
|
||||
'__destruct',
|
||||
'__get',
|
||||
'__set',
|
||||
'__call',
|
||||
'__sleep',
|
||||
'__wakeup',
|
||||
'__isset',
|
||||
'__unset',
|
||||
'__tostring',
|
||||
'__clone',
|
||||
'__set_state',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string Current Method
|
||||
*/
|
||||
protected $_method;
|
||||
|
||||
/**
|
||||
* @var Zend_Server_Reflection
|
||||
*/
|
||||
protected $_reflection = null;
|
||||
|
||||
/**
|
||||
* Whether or not {@link handle()} should send output or return the response.
|
||||
* @var boolean Defaults to false
|
||||
*/
|
||||
protected $_returnResponse = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
set_exception_handler(array($this, "fault"));
|
||||
$this->_reflection = new Zend_Server_Reflection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set XML encoding
|
||||
*
|
||||
* @param string $encoding
|
||||
* @return Zend_Rest_Server
|
||||
*/
|
||||
public function setEncoding($encoding)
|
||||
{
|
||||
$this->_encoding = (string) $encoding;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML encoding
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEncoding()
|
||||
{
|
||||
return $this->_encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowercase a string
|
||||
*
|
||||
* Lowercase's a string by reference
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $key
|
||||
* @return string Lower cased string
|
||||
*/
|
||||
public static function lowerCase(&$value, &$key)
|
||||
{
|
||||
return $value = strtolower($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not to return a response
|
||||
*
|
||||
* If called without arguments, returns the value of the flag. If called
|
||||
* with an argument, sets the flag.
|
||||
*
|
||||
* When 'return response' is true, {@link handle()} will not send output,
|
||||
* but will instead return the response from the dispatched function/method.
|
||||
*
|
||||
* @param boolean $flag
|
||||
* @return boolean|Zend_Rest_Server Returns Zend_Rest_Server when used to set the flag; returns boolean flag value otherwise.
|
||||
*/
|
||||
public function returnResponse($flag = null)
|
||||
{
|
||||
if (null == $flag) {
|
||||
return $this->_returnResponse;
|
||||
}
|
||||
|
||||
$this->_returnResponse = ($flag) ? true : false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::handle()
|
||||
*
|
||||
* @param array $request
|
||||
* @throws Zend_Rest_Server_Exception
|
||||
* @return string|void
|
||||
*/
|
||||
public function handle($request = false)
|
||||
{
|
||||
$this->_headers = array('Content-Type: text/xml');
|
||||
if (!$request) {
|
||||
$request = $_REQUEST;
|
||||
}
|
||||
if (isset($request['method'])) {
|
||||
$this->_method = $request['method'];
|
||||
if (isset($this->_functions[$this->_method])) {
|
||||
if ($this->_functions[$this->_method] instanceof Zend_Server_Reflection_Function || $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method && $this->_functions[$this->_method]->isPublic()) {
|
||||
$request_keys = array_keys($request);
|
||||
array_walk($request_keys, array(__CLASS__, "lowerCase"));
|
||||
$request = array_combine($request_keys, $request);
|
||||
|
||||
$func_args = $this->_functions[$this->_method]->getParameters();
|
||||
|
||||
$calling_args = array();
|
||||
foreach ($func_args as $arg) {
|
||||
if (isset($request[strtolower($arg->getName())])) {
|
||||
$calling_args[] = $request[strtolower($arg->getName())];
|
||||
} elseif ($arg->isOptional()) {
|
||||
$calling_args[] = $arg->getDefaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($request as $key => $value) {
|
||||
if (substr($key, 0, 3) == 'arg') {
|
||||
$key = str_replace('arg', '', $key);
|
||||
$calling_args[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort arguments by key -- @see ZF-2279
|
||||
ksort($calling_args);
|
||||
|
||||
$result = false;
|
||||
if (count($calling_args) < count($func_args)) {
|
||||
$result = $this->fault(new Zend_Rest_Server_Exception('Invalid Method Call to ' . $this->_method . '. Requires ' . count($func_args) . ', ' . count($calling_args) . ' given.'), 400);
|
||||
}
|
||||
|
||||
if (!$result && $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method) {
|
||||
// Get class
|
||||
$class = $this->_functions[$this->_method]->getDeclaringClass()->getName();
|
||||
|
||||
if ($this->_functions[$this->_method]->isStatic()) {
|
||||
// for some reason, invokeArgs() does not work the same as
|
||||
// invoke(), and expects the first argument to be an object.
|
||||
// So, using a callback if the method is static.
|
||||
$result = $this->_callStaticMethod($class, $calling_args);
|
||||
} else {
|
||||
// Object method
|
||||
$result = $this->_callObjectMethod($class, $calling_args);
|
||||
}
|
||||
} elseif (!$result) {
|
||||
try {
|
||||
$result = call_user_func_array($this->_functions[$this->_method]->getName(), $calling_args); //$this->_functions[$this->_method]->invokeArgs($calling_args);
|
||||
} catch (Exception $e) {
|
||||
$result = $this->fault($e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
require_once "Zend/Rest/Server/Exception.php";
|
||||
$result = $this->fault(
|
||||
new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
|
||||
404
|
||||
);
|
||||
}
|
||||
} else {
|
||||
require_once "Zend/Rest/Server/Exception.php";
|
||||
$result = $this->fault(
|
||||
new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
|
||||
404
|
||||
);
|
||||
}
|
||||
} else {
|
||||
require_once "Zend/Rest/Server/Exception.php";
|
||||
$result = $this->fault(
|
||||
new Zend_Rest_Server_Exception("No Method Specified."),
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
if ($result instanceof SimpleXMLElement) {
|
||||
$response = $result->asXML();
|
||||
} elseif ($result instanceof DOMDocument) {
|
||||
$response = $result->saveXML();
|
||||
} elseif ($result instanceof DOMNode) {
|
||||
$response = $result->ownerDocument->saveXML($result);
|
||||
} elseif (is_array($result) || is_object($result)) {
|
||||
$response = $this->_handleStruct($result);
|
||||
} else {
|
||||
$response = $this->_handleScalar($result);
|
||||
}
|
||||
|
||||
if (!$this->returnResponse()) {
|
||||
if (!headers_sent()) {
|
||||
foreach ($this->_headers as $header) {
|
||||
header($header);
|
||||
}
|
||||
}
|
||||
|
||||
echo $response;
|
||||
return;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::setClass()
|
||||
*
|
||||
* @param string $classname Class name
|
||||
* @param string $namespace Class namespace (unused)
|
||||
* @param array $argv An array of Constructor Arguments
|
||||
*/
|
||||
public function setClass($classname, $namespace = '', $argv = array())
|
||||
{
|
||||
$this->_args = $argv;
|
||||
foreach ($this->_reflection->reflectClass($classname, $argv)->getMethods() as $method) {
|
||||
$this->_functions[$method->getName()] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an array or object result
|
||||
*
|
||||
* @param array|object $struct Result Value
|
||||
* @return string XML Response
|
||||
*/
|
||||
protected function _handleStruct($struct)
|
||||
{
|
||||
$function = $this->_functions[$this->_method];
|
||||
if ($function instanceof Zend_Server_Reflection_Method) {
|
||||
$class = $function->getDeclaringClass()->getName();
|
||||
} else {
|
||||
$class = false;
|
||||
}
|
||||
|
||||
$method = $function->getName();
|
||||
|
||||
$dom = new DOMDocument('1.0', $this->getEncoding());
|
||||
if ($class) {
|
||||
$root = $dom->createElement($class);
|
||||
$method = $dom->createElement($method);
|
||||
$root->appendChild($method);
|
||||
} else {
|
||||
$root = $dom->createElement($method);
|
||||
$method = $root;
|
||||
}
|
||||
$root->setAttribute('generator', 'zend');
|
||||
$root->setAttribute('version', '1.0');
|
||||
$dom->appendChild($root);
|
||||
|
||||
$this->_structValue($struct, $dom, $method);
|
||||
|
||||
$struct = (array) $struct;
|
||||
if (!isset($struct['status'])) {
|
||||
$status = $dom->createElement('status', 'success');
|
||||
$method->appendChild($status);
|
||||
}
|
||||
|
||||
return $dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively iterate through a struct
|
||||
*
|
||||
* Recursively iterates through an associative array or object's properties
|
||||
* to build XML response.
|
||||
*
|
||||
* @param mixed $struct
|
||||
* @param DOMDocument $dom
|
||||
* @param DOMElement $parent
|
||||
* @return void
|
||||
*/
|
||||
protected function _structValue($struct, DOMDocument $dom, DOMElement $parent)
|
||||
{
|
||||
$struct = (array) $struct;
|
||||
|
||||
foreach ($struct as $key => $value) {
|
||||
if ($value === false) {
|
||||
$value = 0;
|
||||
} elseif ($value === true) {
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
if (ctype_digit((string) $key)) {
|
||||
$key = 'key_' . $key;
|
||||
}
|
||||
|
||||
if (is_array($value) || is_object($value)) {
|
||||
$element = $dom->createElement($key);
|
||||
$this->_structValue($value, $dom, $element);
|
||||
} else {
|
||||
$element = $dom->createElement($key);
|
||||
$element->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
|
||||
$parent->appendChild($element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a single value
|
||||
*
|
||||
* @param string|int|boolean $value Result value
|
||||
* @return string XML Response
|
||||
*/
|
||||
protected function _handleScalar($value)
|
||||
{
|
||||
$function = $this->_functions[$this->_method];
|
||||
if ($function instanceof Zend_Server_Reflection_Method) {
|
||||
$class = $function->getDeclaringClass()->getName();
|
||||
} else {
|
||||
$class = false;
|
||||
}
|
||||
|
||||
$method = $function->getName();
|
||||
|
||||
$dom = new DOMDocument('1.0', $this->getEncoding());
|
||||
if ($class) {
|
||||
$xml = $dom->createElement($class);
|
||||
$methodNode = $dom->createElement($method);
|
||||
$xml->appendChild($methodNode);
|
||||
} else {
|
||||
$xml = $dom->createElement($method);
|
||||
$methodNode = $xml;
|
||||
}
|
||||
$xml->setAttribute('generator', 'zend');
|
||||
$xml->setAttribute('version', '1.0');
|
||||
$dom->appendChild($xml);
|
||||
|
||||
if ($value === false) {
|
||||
$value = 0;
|
||||
} elseif ($value === true) {
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
if (isset($value)) {
|
||||
$element = $dom->createElement('response');
|
||||
$element->appendChild($dom->createTextNode($value));
|
||||
$methodNode->appendChild($element);
|
||||
} else {
|
||||
$methodNode->appendChild($dom->createElement('response'));
|
||||
}
|
||||
|
||||
$methodNode->appendChild($dom->createElement('status', 'success'));
|
||||
|
||||
return $dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::fault()
|
||||
*
|
||||
* Creates XML error response, returning DOMDocument with response.
|
||||
*
|
||||
* @param string|Exception $fault Message
|
||||
* @param int $code Error Code
|
||||
* @return DOMDocument
|
||||
*/
|
||||
public function fault($exception = null, $code = null)
|
||||
{
|
||||
if (isset($this->_functions[$this->_method])) {
|
||||
$function = $this->_functions[$this->_method];
|
||||
} elseif (isset($this->_method)) {
|
||||
$function = $this->_method;
|
||||
} else {
|
||||
$function = 'rest';
|
||||
}
|
||||
|
||||
if ($function instanceof Zend_Server_Reflection_Method) {
|
||||
$class = $function->getDeclaringClass()->getName();
|
||||
} else {
|
||||
$class = false;
|
||||
}
|
||||
|
||||
if ($function instanceof Zend_Server_Reflection_Function_Abstract) {
|
||||
$method = $function->getName();
|
||||
} else {
|
||||
$method = $function;
|
||||
}
|
||||
|
||||
$dom = new DOMDocument('1.0', $this->getEncoding());
|
||||
if ($class) {
|
||||
$xml = $dom->createElement($class);
|
||||
$xmlMethod = $dom->createElement($method);
|
||||
$xml->appendChild($xmlMethod);
|
||||
} else {
|
||||
$xml = $dom->createElement($method);
|
||||
$xmlMethod = $xml;
|
||||
}
|
||||
$xml->setAttribute('generator', 'zend');
|
||||
$xml->setAttribute('version', '1.0');
|
||||
$dom->appendChild($xml);
|
||||
|
||||
$xmlResponse = $dom->createElement('response');
|
||||
$xmlMethod->appendChild($xmlResponse);
|
||||
|
||||
if ($exception instanceof Exception) {
|
||||
$element = $dom->createElement('message');
|
||||
$element->appendChild($dom->createTextNode($exception->getMessage()));
|
||||
$xmlResponse->appendChild($element);
|
||||
$code = $exception->getCode();
|
||||
} elseif (!is_null($exception) || 'rest' == $function) {
|
||||
$xmlResponse->appendChild($dom->createElement('message', 'An unknown error occured. Please try again.'));
|
||||
} else {
|
||||
$xmlResponse->appendChild($dom->createElement('message', 'Call to ' . $method . ' failed.'));
|
||||
}
|
||||
|
||||
$xmlMethod->appendChild($xmlResponse);
|
||||
$xmlMethod->appendChild($dom->createElement('status', 'failed'));
|
||||
|
||||
// Headers to send
|
||||
if (is_null($code) || (404 != $code))
|
||||
{
|
||||
$this->_headers[] = 'HTTP/1.0 400 Bad Request';
|
||||
} else {
|
||||
$this->_headers[] = 'HTTP/1.0 404 File Not Found';
|
||||
}
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve any HTTP extra headers set by the server
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::addFunction()
|
||||
*
|
||||
* @param string $function Function Name
|
||||
* @param string $namespace Function namespace (unused)
|
||||
*/
|
||||
public function addFunction($function, $namespace = '')
|
||||
{
|
||||
if (!is_array($function)) {
|
||||
$function = (array) $function;
|
||||
}
|
||||
|
||||
foreach ($function as $func) {
|
||||
if (is_callable($func) && !in_array($func, self::$magicMethods)) {
|
||||
$this->_functions[$func] = $this->_reflection->reflectFunction($func);
|
||||
} else {
|
||||
throw new Zend_Rest_Server_Exception("Invalid Method Added to Service.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::getFunctions()
|
||||
*
|
||||
* @return array An array of Zend_Server_Reflection_Method's
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return $this->_functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::loadFunctions()
|
||||
*
|
||||
* @todo Implement
|
||||
* @param array $functions
|
||||
*/
|
||||
public function loadFunctions($functions)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement Zend_Server_Interface::setPersistence()
|
||||
*
|
||||
* @todo Implement
|
||||
* @param int $mode
|
||||
*/
|
||||
public function setPersistence($mode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a static class method and return the result
|
||||
*
|
||||
* @param string $class
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _callStaticMethod($class, array $args)
|
||||
{
|
||||
try {
|
||||
$result = call_user_func_array(array($class, $this->_functions[$this->_method]->getName()), $args);
|
||||
} catch (Exception $e) {
|
||||
$result = $this->fault($e);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call an instance method of an object
|
||||
*
|
||||
* @param string $class
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
* @throws Zend_Rest_Server_Exception For invalid class name
|
||||
*/
|
||||
protected function _callObjectMethod($class, array $args)
|
||||
{
|
||||
try {
|
||||
if ($this->_functions[$this->_method]->getDeclaringClass()->getConstructor()) {
|
||||
$object = $this->_functions[$this->_method]->getDeclaringClass()->newInstanceArgs($this->_args);
|
||||
} else {
|
||||
$object = $this->_functions[$this->_method]->getDeclaringClass()->newInstance();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
throw new Zend_Rest_Server_Exception('Error instantiating class ' . $class . ' to invoke method ' . $this->_functions[$this->_method]->getName(), 500);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->_functions[$this->_method]->invokeArgs($object, $args);
|
||||
} catch (Exception $e) {
|
||||
$result = $this->fault($e);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
39
libs/Zend/Rest/Server/Exception.php
Normal file
39
libs/Zend/Rest/Server/Exception.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Zend Framework
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://framework.zend.com/license/new-bsd
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@zend.com so we can send you a copy immediately.
|
||||
*
|
||||
* @package Zend_Rest
|
||||
* @subpackage Server
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Zend_Rest_Exception
|
||||
*/
|
||||
require_once 'Zend/Rest/Exception.php';
|
||||
|
||||
|
||||
/**
|
||||
* Zend_Rest_Server_Exception
|
||||
*
|
||||
* @package Zend_Rest
|
||||
* @subpackage Server
|
||||
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
class Zend_Rest_Server_Exception extends Zend_Rest_Exception
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user