File indexing completed on 2024-05-12 06:02:55

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Rest
0017  * @subpackage Client
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 
0024 /** Zend_Service_Abstract */
0025 // require_once 'Zend/Service/Abstract.php';
0026 
0027 /** Zend_Rest_Client_Result */
0028 // require_once 'Zend/Rest/Client/Result.php';
0029 
0030 /** Zend_Uri */
0031 // require_once 'Zend/Uri.php';
0032 
0033 /**
0034  * @category   Zend
0035  * @package    Zend_Rest
0036  * @subpackage Client
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 class Zend_Rest_Client extends Zend_Service_Abstract
0041 {
0042     /**
0043      * Data for the query
0044      * @var array
0045      */
0046     protected $_data = array();
0047 
0048      /**
0049      * Zend_Uri of this web service
0050      * @var Zend_Uri_Http
0051      */
0052     protected $_uri = null;
0053     
0054     /**
0055      * Flag indicating the Zend_Http_Client is fresh and needs no reset.
0056      * Must be set explicitly if you want to keep preset parameters.
0057      * @var bool true if you do not want a reset. Default false.
0058      */
0059     protected $_noReset = false;
0060 
0061     /**
0062      * Constructor
0063      *
0064      * @param string|Zend_Uri_Http $uri URI for the web service
0065      * @return void
0066      */
0067     public function __construct($uri = null)
0068     {
0069         if (!empty($uri)) {
0070             $this->setUri($uri);
0071         }
0072     }
0073 
0074     /**
0075      * Set the URI to use in the request
0076      *
0077      * @param string|Zend_Uri_Http $uri URI for the web service
0078      * @return Zend_Rest_Client
0079      */
0080     public function setUri($uri)
0081     {
0082         if ($uri instanceof Zend_Uri_Http) {
0083             $this->_uri = $uri;
0084         } else {
0085             $this->_uri = Zend_Uri::factory($uri);
0086         }
0087 
0088         return $this;
0089     }
0090 
0091     /**
0092      * Retrieve the current request URI object
0093      *
0094      * @return Zend_Uri_Http
0095      */
0096     public function getUri()
0097     {
0098         return $this->_uri;
0099     }
0100 
0101     /**
0102      * Call a remote REST web service URI and return the Zend_Http_Response object
0103      *
0104      * @param  string $path            The path to append to the URI
0105      * @throws Zend_Rest_Client_Exception
0106      * @return void
0107      */
0108     private function _prepareRest($path)
0109     {
0110         // Get the URI object and configure it
0111         if (!$this->_uri instanceof Zend_Uri_Http) {
0112             // require_once 'Zend/Rest/Client/Exception.php';
0113             throw new Zend_Rest_Client_Exception('URI object must be set before performing call');
0114         }
0115 
0116         $uri = $this->_uri->getUri();
0117 
0118         if ($path[0] != '/' && $uri[strlen($uri)-1] != '/') {
0119             $path = '/' . $path;
0120         }
0121 
0122         $this->_uri->setPath($path);
0123 
0124         /**
0125          * Get the HTTP client and configure it for the endpoint URI.  Do this each time
0126          * because the Zend_Http_Client instance is shared among all Zend_Service_Abstract subclasses.
0127          */
0128         if ($this->_noReset) {
0129             // if $_noReset we do not want to reset on this request, 
0130             // but we do on any subsequent request
0131             $this->_noReset = false;
0132         } else {
0133             self::getHttpClient()->resetParameters();
0134         }
0135         
0136         self::getHttpClient()->setUri($this->_uri);
0137     }
0138     
0139     /**
0140      * Tells Zend_Rest_Client not to reset all parameters on it's 
0141      * Zend_Http_Client. If you want no reset, this must be called explicitly
0142      * before every request for which you do not want to reset the parameters.
0143      * Parameters will accumulate between requests, but as soon as you do not
0144      * call this function prior to any request, all preset parameters will be reset
0145      * as by default.
0146      * @param boolean $bool
0147      */
0148     public function setNoReset($bool = true)
0149     {
0150         $this->_noReset = $bool;
0151     }
0152 
0153     /**
0154      * Performs an HTTP GET request to the $path.
0155      *
0156      * @param string $path
0157      * @param array  $query Array of GET parameters
0158      * @throws Zend_Http_Client_Exception
0159      * @return Zend_Http_Response
0160      */
0161     public function restGet($path, array $query = null)
0162     {
0163         $this->_prepareRest($path);
0164         $client = self::getHttpClient();
0165         $client->setParameterGet($query);
0166         return $client->request('GET');
0167     }
0168 
0169     /**
0170      * Perform a POST or PUT
0171      *
0172      * Performs a POST or PUT request. Any data provided is set in the HTTP
0173      * client. String data is pushed in as raw POST data; array or object data
0174      * is pushed in as POST parameters.
0175      *
0176      * @param mixed $method
0177      * @param mixed $data
0178      * @return Zend_Http_Response
0179      */
0180     protected function _performPost($method, $data = null)
0181     {
0182         $client = self::getHttpClient();
0183         if (is_string($data)) {
0184             $client->setRawData($data);
0185         } elseif (is_array($data) || is_object($data)) {
0186             $client->setParameterPost((array) $data);
0187         }
0188         return $client->request($method);
0189     }
0190 
0191     /**
0192      * Performs an HTTP POST request to $path.
0193      *
0194      * @param string $path
0195      * @param mixed $data Raw data to send
0196      * @throws Zend_Http_Client_Exception
0197      * @return Zend_Http_Response
0198      */
0199     public function restPost($path, $data = null)
0200     {
0201         $this->_prepareRest($path);
0202         return $this->_performPost('POST', $data);
0203     }
0204 
0205     /**
0206      * Performs an HTTP PUT request to $path.
0207      *
0208      * @param string $path
0209      * @param mixed $data Raw data to send in request
0210      * @throws Zend_Http_Client_Exception
0211      * @return Zend_Http_Response
0212      */
0213     public function restPut($path, $data = null)
0214     {
0215         $this->_prepareRest($path);
0216         return $this->_performPost('PUT', $data);
0217     }
0218 
0219     /**
0220      * Performs an HTTP DELETE request to $path.
0221      *
0222      * @param string $path
0223      * @throws Zend_Http_Client_Exception
0224      * @return Zend_Http_Response
0225      */
0226     public function restDelete($path, $data = null)
0227     {
0228         $this->_prepareRest($path);
0229         return $this->_performPost('DELETE', $data);
0230     }
0231 
0232     /**
0233      * Method call overload
0234      *
0235      * Allows calling REST actions as object methods; however, you must
0236      * follow-up by chaining the request with a request to an HTTP request
0237      * method (post, get, delete, put):
0238      * <code>
0239      * $response = $rest->sayHello('Foo', 'Manchu')->get();
0240      * </code>
0241      *
0242      * Or use them together, but in sequential calls:
0243      * <code>
0244      * $rest->sayHello('Foo', 'Manchu');
0245      * $response = $rest->get();
0246      * </code>
0247      *
0248      * @param string $method Method name
0249      * @param array $args Method args
0250      * @return Zend_Rest_Client_Result|Zend_Rest_Client Zend_Rest_Client if using
0251      * a remote method, Zend_Rest_Client_Result if using an HTTP request method
0252      */
0253     public function __call($method, $args)
0254     {
0255         $methods = array('post', 'get', 'delete', 'put');
0256 
0257         if (in_array(strtolower($method), $methods)) {
0258             if (!isset($args[0])) {
0259                 $args[0] = $this->_uri->getPath();
0260             }
0261             $this->_data['rest'] = 1;
0262             $data = array_slice($args, 1) + $this->_data;
0263             $response = $this->{'rest' . $method}($args[0], $data);
0264             $this->_data = array();//Initializes for next Rest method.
0265             return new Zend_Rest_Client_Result($response->getBody());
0266         } else {
0267             // More than one arg means it's definitely a Zend_Rest_Server
0268             if (sizeof($args) == 1) {
0269                 // Uses first called function name as method name
0270                 if (!isset($this->_data['method'])) {
0271                     $this->_data['method'] = $method;
0272                     $this->_data['arg1']  = $args[0];
0273                 }
0274                 $this->_data[$method]  = $args[0];
0275             } else {
0276                 $this->_data['method'] = $method;
0277                 if (sizeof($args) > 0) {
0278                     foreach ($args as $key => $arg) {
0279                         $key = 'arg' . $key;
0280                         $this->_data[$key] = $arg;
0281                     }
0282                 }
0283             }
0284             return $this;
0285         }
0286     }
0287 }