]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - Zend/Oauth/Client.php
Release 6.5.0
[Github/sugarcrm.git] / Zend / Oauth / Client.php
1 <?php
2 /**
3  * Zend Framework
4  *
5  * LICENSE
6  *
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.
14  *
15  * @category   Zend
16  * @package    Zend_Oauth
17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
19
20  */
21
22 /** Zend_Oauth */
23 require_once 'Zend/Oauth.php';
24
25 /** Zend_Http_Client */
26 require_once 'Zend/Http/Client.php';
27
28 /** Zend_Oauth_Http_Utility */
29 require_once 'Zend/Oauth/Http/Utility.php';
30
31 /** Zend_Oauth_Config */
32 require_once 'Zend/Oauth/Config.php';
33
34 /**
35  * @category   Zend
36  * @package    Zend_Oauth
37  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
38  * @license    http://framework.zend.com/license/new-bsd     New BSD License
39  */
40 class Zend_Oauth_Client extends Zend_Http_Client
41 {
42     /**
43      * Flag to indicate that the client has detected the server as supporting
44      * OAuth 1.0a
45      */
46     public static $supportsRevisionA = false;
47
48     /**
49      * Holds the current OAuth Configuration set encapsulated in an instance
50      * of Zend_Oauth_Config; it's not a Zend_Config instance since that level
51      * of abstraction is unnecessary and doesn't let me escape the accessors
52      * and mutators anyway!
53      *
54      * @var Zend_Oauth_Config
55      */
56     protected $_config = null;
57
58     /**
59      * True if this request is being made with data supplied by
60      * a stream object instead of a raw encoded string.
61      *
62      * @var bool
63      */
64     protected $_streamingRequest = null;
65
66     /**
67      * Constructor; creates a new HTTP Client instance which itself is
68      * just a typical Zend_Http_Client subclass with some OAuth icing to
69      * assist in automating OAuth parameter generation, addition and
70      * cryptographioc signing of requests.
71      *
72      * @param  array $oauthOptions
73      * @param  string $uri
74      * @param  array|Zend_Config $config
75      * @return void
76      */
77     public function __construct($oauthOptions, $uri = null, $config = null)
78     {
79         parent::__construct($uri, $config);
80         $this->_config = new Zend_Oauth_Config;
81         if ($oauthOptions !== null) {
82             if ($oauthOptions instanceof Zend_Config) {
83                 $oauthOptions = $oauthOptions->toArray();
84             }
85             $this->_config->setOptions($oauthOptions);
86         }
87     }
88
89     /**
90      * Return the current connection adapter
91      *
92      * @return Zend_Http_Client_Adapter_Interface|string $adapter
93      */
94     public function getAdapter()
95     {
96         return $this->adapter;
97     }
98
99    /**
100      * Load the connection adapter
101      *
102      * @param Zend_Http_Client_Adapter_Interface $adapter
103      * @return void
104      */
105     public function setAdapter($adapter)
106     {
107         if ($adapter == null) {
108             $this->adapter = $adapter;
109         } else {
110               parent::setAdapter($adapter);
111         }
112     }
113
114     /**
115      * Set the streamingRequest variable which controls whether we are
116      * sending the raw (already encoded) POST data from a stream source.
117      *
118      * @param boolean $value The value to set.
119      * @return void
120      */
121     public function setStreamingRequest($value)
122     {
123         $this->_streamingRequest = $value;
124     }
125
126     /**
127      * Check whether the client is set to perform streaming requests.
128      *
129      * @return boolean True if yes, false otherwise.
130      */
131     public function getStreamingRequest()
132     {
133         if ($this->_streamingRequest) {
134             return true;
135         } else {
136             return false;
137         }
138     }
139
140     /**
141      * Prepare the request body (for POST and PUT requests)
142      *
143      * @return string
144      * @throws Zend_Http_Client_Exception
145      */
146     protected function _prepareBody()
147     {
148         if($this->_streamingRequest) {
149             $this->setHeaders(self::CONTENT_LENGTH,
150                 $this->raw_post_data->getTotalSize());
151             return $this->raw_post_data;
152         }
153         else {
154             return parent::_prepareBody();
155         }
156     }
157
158     /**
159      * Clear all custom parameters we set.
160      *
161      * @return Zend_Http_Client
162      */
163     public function resetParameters($clearAll = false)
164     {
165         $this->_streamingRequest = false;
166         return parent::resetParameters($clearAll);
167     }
168
169     /**
170      * Set the raw (already encoded) POST data from a stream source.
171      *
172      * This is used to support POSTing from open file handles without
173      * caching the entire body into memory. It is a wrapper around
174      * Zend_Http_Client::setRawData().
175      *
176      * @param string $data The request data
177      * @param string $enctype The encoding type
178      * @return Zend_Http_Client
179      */
180     public function setRawDataStream($data, $enctype = null)
181     {
182         $this->_streamingRequest = true;
183         return $this->setRawData($data, $enctype);
184     }
185
186     /**
187      * Same as Zend_Http_Client::setMethod() except it also creates an
188      * Oauth specific reference to the method type.
189      * Might be defunct and removed in a later iteration.
190      *
191      * @param  string $method
192      * @return Zend_Http_Client
193      */
194     public function setMethod($method = self::GET)
195     {
196         if ($method == self::GET) {
197             $this->setRequestMethod(self::GET);
198         } elseif($method == self::POST) {
199             $this->setRequestMethod(self::POST);
200         } elseif($method == self::PUT) {
201             $this->setRequestMethod(self::PUT);
202         }  elseif($method == self::DELETE) {
203             $this->setRequestMethod(self::DELETE);
204         }   elseif($method == self::HEAD) {
205             $this->setRequestMethod(self::HEAD);
206         }
207         return parent::setMethod($method);
208     }
209
210     /**
211      * Same as Zend_Http_Client::request() except just before the request is
212      * executed, we automatically append any necessary OAuth parameters and
213      * sign the request using the relevant signature method.
214      *
215      * @param  string $method
216      * @return Zend_Http_Response
217      */
218     public function request($method = null)
219     {
220         if ($method !== null) {
221             $this->setMethod($method);
222         }
223         $this->prepareOauth();
224         return parent::request();
225     }
226
227     /**
228      * Performs OAuth preparation on the request before sending.
229      *
230      * This primarily means taking a request, correctly encoding and signing
231      * all parameters, and applying the correct OAuth scheme to the method
232      * being used.
233      *
234      * @return void
235      * @throws Zend_Oauth_Exception If POSTBODY scheme requested, but GET request method used; or if invalid request scheme provided
236      */
237     public function prepareOauth()
238     {
239         $requestScheme = $this->getRequestScheme();
240         $requestMethod = $this->getRequestMethod();
241         $query = null;
242         if ($requestScheme == Zend_Oauth::REQUEST_SCHEME_HEADER) {
243             $oauthHeaderValue = $this->getToken()->toHeader(
244                 $this->getUri(true),
245                 $this->_config,
246                 $this->_getSignableParametersAsQueryString()
247             );
248             $this->setHeaders('Authorization', $oauthHeaderValue);
249         } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_POSTBODY) {
250             if ($requestMethod == self::GET) {
251                 require_once 'Zend/Oauth/Exception.php';
252                 throw new Zend_Oauth_Exception(
253                     'The client is configured to'
254                     . ' pass OAuth parameters through a POST body but request method'
255                     . ' is set to GET'
256                 );
257             }
258             $raw = $this->getToken()->toQueryString(
259                 $this->getUri(true),
260                 $this->_config,
261                 $this->_getSignableParametersAsQueryString()
262             );
263             $this->setRawData($raw);
264             $this->paramsPost = array();
265         } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_QUERYSTRING) {
266             $params = array();
267             $query = $this->getUri()->getQuery();
268             if ($query) {
269                 $queryParts = explode('&', $this->getUri()->getQuery());
270                 foreach ($queryParts as $queryPart) {
271                     $kvTuple = explode('=', $queryPart);
272                     $params[$kvTuple[0]] =
273                         (array_key_exists(1, $kvTuple) ? $kvTuple[1] : NULL);
274                 }
275             }
276             if (!empty($this->paramsPost)) {
277                 $params = array_merge($params, $this->paramsPost);
278                 $query  = $this->getToken()->toQueryString(
279                     $this->getUri(true), $this->_config, $params
280                 );
281             }
282             $query = $this->getToken()->toQueryString(
283                 $this->getUri(true), $this->_config, $params
284             );
285             $this->getUri()->setQuery($query);
286             $this->paramsGet = array();
287         } else {
288             require_once 'Zend/Oauth/Exception.php';
289             throw new Zend_Oauth_Exception('Invalid request scheme: ' . $requestScheme);
290         }
291     }
292
293     /**
294      * Collect all signable parameters into a single array across query string
295      * and POST body. These are returned as a properly formatted single
296      * query string.
297      *
298      * @return string
299      */
300     protected function _getSignableParametersAsQueryString()
301     {
302         $params = array();
303             if (!empty($this->paramsGet)) {
304                 $params = array_merge($params, $this->paramsGet);
305                 $query  = $this->getToken()->toQueryString(
306                     $this->getUri(true), $this->_config, $params
307                 );
308             }
309             if (!empty($this->paramsPost)) {
310                 $params = array_merge($params, $this->paramsPost);
311                 $query  = $this->getToken()->toQueryString(
312                     $this->getUri(true), $this->_config, $params
313                 );
314             }
315             return $params;
316     }
317
318     /**
319      * Simple Proxy to the current Zend_Oauth_Config method. It's that instance
320      * which holds all configuration methods and values this object also presents
321      * as it's API.
322      *
323      * @param  string $method
324      * @param  array $args
325      * @return mixed
326      * @throws Zend_Oauth_Exception if method does not exist in config object
327      */
328     public function __call($method, array $args)
329     {
330         if (!method_exists($this->_config, $method)) {
331             require_once 'Zend/Oauth/Exception.php';
332             throw new Zend_Oauth_Exception('Method does not exist: ' . $method);
333         }
334         return call_user_func_array(array($this->_config,$method), $args);
335     }
336 }