[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * Author: Neuman Vong [email protected] 5 * License: http://creativecommons.org/licenses/MIT/ MIT 6 * Link: https://twilio-php.readthedocs.org/en/latest/ 7 */ 8 9 function Services_Twilio_autoload($className) { 10 if (substr($className, 0, 15) != 'Services_Twilio') { 11 return false; 12 } 13 $file = str_replace('_', '/', $className); 14 $file = str_replace('Services/', '', $file); 15 return include dirname(__FILE__) . "/$file.php"; 16 } 17 18 spl_autoload_register('Services_Twilio_autoload'); 19 20 /** 21 * Create a client to talk to the Twilio API. 22 * 23 * 24 * :param string $sid: Your Account SID 25 * :param string $token: Your Auth Token from `your dashboard 26 * <https://www.twilio.com/user/account>`_ 27 * :param string $version: API version to use 28 * :param $_http: A HTTP client for making requests. 29 * :type $_http: :php:class:`Services_Twilio_TinyHttp` 30 * :param int $retryAttempts: 31 * Number of times to retry failed requests. Currently only idempotent 32 * requests (GET's and DELETE's) are retried. 33 * 34 * Here's an example: 35 * 36 * .. code-block:: php 37 * 38 * require('Services/Twilio.php'); 39 * $client = new Services_Twilio('AC123', '456bef', null, null, 3); 40 * // Take some action with the client, etc. 41 */ 42 class Services_Twilio extends Services_Twilio_Resource 43 { 44 const USER_AGENT = 'twilio-php/3.12.4'; 45 46 protected $http; 47 protected $retryAttempts; 48 protected $last_response; 49 protected $version; 50 protected $versions = array('2008-08-01', '2010-04-01'); 51 52 public function __construct( 53 $sid, 54 $token, 55 $version = null, 56 Services_Twilio_TinyHttp $_http = null, 57 $retryAttempts = 1 58 ) { 59 $this->version = in_array($version, $this->versions) ? 60 $version : end($this->versions); 61 62 if (null === $_http) { 63 if (!in_array('openssl', get_loaded_extensions())) { 64 throw new Services_Twilio_HttpException("The OpenSSL extension is required but not currently enabled. For more information, see http://php.net/manual/en/book.openssl.php"); 65 } 66 if (in_array('curl', get_loaded_extensions())) { 67 $_http = new Services_Twilio_TinyHttp( 68 "https://api.twilio.com", 69 array( 70 "curlopts" => array( 71 CURLOPT_USERAGENT => self::qualifiedUserAgent(phpversion()), 72 CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'), 73 CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', 74 ), 75 ) 76 ); 77 } else { 78 $_http = new Services_Twilio_HttpStream( 79 "https://api.twilio.com", 80 array( 81 "http_options" => array( 82 "http" => array( 83 "user_agent" => self::qualifiedUserAgent(phpversion()), 84 "header" => "Accept-Charset: utf-8\r\n", 85 ), 86 "ssl" => array( 87 'verify_peer' => true, 88 'cafile' => dirname(__FILE__) . '/cacert.pem', 89 'verify_depth' => 5, 90 ), 91 ), 92 ) 93 ); 94 } 95 } 96 $_http->authenticate($sid, $token); 97 $this->http = $_http; 98 $this->accounts = new Services_Twilio_Rest_Accounts($this, "/{$this->version}/Accounts"); 99 $this->account = $this->accounts->get($sid); 100 $this->retryAttempts = $retryAttempts; 101 } 102 103 /** 104 * Fully qualified user agent with the current PHP Version. 105 * 106 * :return: the user agent 107 * :rtype: string 108 */ 109 public static function qualifiedUserAgent($php_version) { 110 return self::USER_AGENT . " (php $php_version)"; 111 } 112 113 /** 114 * Get the api version used by the rest client 115 * 116 * :return: the API version in use 117 * :returntype: string 118 */ 119 public function getVersion() { 120 return $this->version; 121 } 122 123 /** 124 * Get the retry attempt limit used by the rest client 125 * 126 * :return: the number of retry attempts 127 * :rtype: int 128 */ 129 public function getRetryAttempts() { 130 return $this->retryAttempts; 131 } 132 133 /** 134 * Construct a URI based on initial path, query params, and paging 135 * information 136 * 137 * We want to use the query params, unless we have a next_page_uri from the 138 * API. 139 * 140 * :param string $path: The request path (may contain query params if it's 141 * a next_page_uri) 142 * :param array $params: Query parameters to use with the request 143 * :param boolean $full_uri: Whether the $path contains the full uri 144 * 145 * :return: the URI that should be requested by the library 146 * :returntype: string 147 */ 148 public static function getRequestUri($path, $params, $full_uri = false) { 149 $json_path = $full_uri ? $path : "$path.json"; 150 if (!$full_uri && !empty($params)) { 151 $query_path = $json_path . '?' . http_build_query($params, '', '&'); 152 } else { 153 $query_path = $json_path; 154 } 155 return $query_path; 156 } 157 158 /** 159 * Helper method for implementing request retry logic 160 * 161 * :param array $callable: The function that makes an HTTP request 162 * :param string $uri: The URI to request 163 * :param int $retriesLeft: Number of times to retry 164 * 165 * :return: The object representation of the resource 166 * :rtype: object 167 */ 168 protected function _makeIdempotentRequest($callable, $uri, $retriesLeft) { 169 $response = call_user_func_array($callable, array($uri)); 170 list($status, $headers, $body) = $response; 171 if ($status >= 500 && $retriesLeft > 0) { 172 return $this->_makeIdempotentRequest($callable, $uri, $retriesLeft - 1); 173 } else { 174 return $this->_processResponse($response); 175 } 176 } 177 178 /** 179 * GET the resource at the specified path. 180 * 181 * :param string $path: Path to the resource 182 * :param array $params: Query string parameters 183 * :param boolean $full_uri: Whether the full URI has been passed as an 184 * argument 185 * 186 * :return: The object representation of the resource 187 * :rtype: object 188 */ 189 public function retrieveData($path, $params = array(), 190 $full_uri = false 191 ) { 192 $uri = self::getRequestUri($path, $params, $full_uri); 193 return $this->_makeIdempotentRequest(array($this->http, 'get'), 194 $uri, $this->retryAttempts); 195 } 196 197 /** 198 * DELETE the resource at the specified path. 199 * 200 * :param string $path: Path to the resource 201 * :param array $params: Query string parameters 202 * 203 * :return: The object representation of the resource 204 * :rtype: object 205 */ 206 public function deleteData($path, $params = array()) 207 { 208 $uri = self::getRequestUri($path, $params); 209 return $this->_makeIdempotentRequest(array($this->http, 'delete'), 210 $uri, $this->retryAttempts); 211 } 212 213 /** 214 * POST to the resource at the specified path. 215 * 216 * :param string $path: Path to the resource 217 * :param array $params: Query string parameters 218 * 219 * :return: The object representation of the resource 220 * :rtype: object 221 */ 222 public function createData($path, $params = array()) 223 { 224 $path = "$path.json"; 225 $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); 226 $response = $this->http->post( 227 $path, $headers, self::buildQuery($params, '') 228 ); 229 return $this->_processResponse($response); 230 } 231 232 /** 233 * Build a query string from query data 234 * 235 * :param array $queryData: An associative array of keys and values. The 236 * values can be a simple type or a list, in which case the list is 237 * converted to multiple query parameters with the same key. 238 * :param string $numericPrefix: 239 * :param string $queryStringStyle: Determine how to build the url 240 * - strict: Build a standards compliant query string without braces (can be hacked by using braces in key) 241 * - php: Build a PHP compatible query string with nested array syntax 242 * :return: The encoded query string 243 * :rtype: string 244 */ 245 public static function buildQuery($queryData, $numericPrefix = '') { 246 $query = ''; 247 // Loop through all of the $query_data 248 foreach ($queryData as $key => $value) { 249 // If the key is an int, add the numeric_prefix to the beginning 250 if (is_int($key)) { 251 $key = $numericPrefix . $key; 252 } 253 254 // If the value is an array, we will end up recursing 255 if (is_array($value)) { 256 // Loop through the values 257 foreach ($value as $value2) { 258 // Add an arg_separator if needed 259 if ($query !== '') { 260 $query .= '&'; 261 } 262 // Recurse 263 $query .= self::buildQuery(array($key => $value2), $numericPrefix); 264 } 265 } else { 266 // Add an arg_separator if needed 267 if ($query !== '') { 268 $query .= '&'; 269 } 270 // Add the key and the urlencoded value (as a string) 271 $query .= $key . '=' . urlencode((string)$value); 272 } 273 } 274 return $query; 275 } 276 277 /** 278 * Convert the JSON encoded resource into a PHP object. 279 * 280 * :param array $response: 3-tuple containing status, headers, and body 281 * 282 * :return: PHP object decoded from JSON 283 * :rtype: object 284 * :throws: A :php:class:`Services_Twilio_RestException` if the Response is 285 * in the 300-500 range of status codes. 286 */ 287 private function _processResponse($response) 288 { 289 list($status, $headers, $body) = $response; 290 if ($status === 204) { 291 return true; 292 } 293 $decoded = json_decode($body); 294 if ($decoded === null) { 295 throw new Services_Twilio_RestException( 296 $status, 297 'Could not decode response body as JSON. ' . 298 'This likely indicates a 500 server error' 299 ); 300 } 301 if (200 <= $status && $status < 300) { 302 $this->last_response = $decoded; 303 return $decoded; 304 } 305 throw new Services_Twilio_RestException( 306 $status, 307 isset($decoded->message) ? $decoded->message : '', 308 isset($decoded->code) ? $decoded->code : null, 309 isset($decoded->more_info) ? $decoded->more_info : null 310 ); 311 } 312 } 313
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |