Changeset View
Changeset View
Standalone View
Standalone View
externals/twilio-php/Services/Twilio.php
- This file was added.
| Property | Old Value | New Value |
|---|---|---|
| File Mode | null | 100755 |
| <?php | |||||
| /* | |||||
| * Author: Neuman Vong neuman@twilio.com | |||||
| * License: http://creativecommons.org/licenses/MIT/ MIT | |||||
| * Link: https://twilio-php.readthedocs.org/en/latest/ | |||||
| */ | |||||
| function Services_Twilio_autoload($className) { | |||||
| if (substr($className, 0, 15) != 'Services_Twilio') { | |||||
| return false; | |||||
| } | |||||
| $file = str_replace('_', '/', $className); | |||||
| $file = str_replace('Services/', '', $file); | |||||
| return include dirname(__FILE__) . "/$file.php"; | |||||
| } | |||||
| spl_autoload_register('Services_Twilio_autoload'); | |||||
| /** | |||||
| * Create a client to talk to the Twilio API. | |||||
| * | |||||
| * | |||||
| * :param string $sid: Your Account SID | |||||
| * :param string $token: Your Auth Token from `your dashboard | |||||
| * <https://www.twilio.com/user/account>`_ | |||||
| * :param string $version: API version to use | |||||
| * :param $_http: A HTTP client for making requests. | |||||
| * :type $_http: :php:class:`Services_Twilio_TinyHttp` | |||||
| * :param int $retryAttempts: | |||||
| * Number of times to retry failed requests. Currently only idempotent | |||||
| * requests (GET's and DELETE's) are retried. | |||||
| * | |||||
| * Here's an example: | |||||
| * | |||||
| * .. code-block:: php | |||||
| * | |||||
| * require('Services/Twilio.php'); | |||||
| * $client = new Services_Twilio('AC123', '456bef', null, null, 3); | |||||
| * // Take some action with the client, etc. | |||||
| */ | |||||
| class Services_Twilio extends Services_Twilio_Resource | |||||
| { | |||||
| const USER_AGENT = 'twilio-php/3.12.4'; | |||||
| protected $http; | |||||
| protected $retryAttempts; | |||||
| protected $last_response; | |||||
| protected $version; | |||||
| protected $versions = array('2008-08-01', '2010-04-01'); | |||||
| public function __construct( | |||||
| $sid, | |||||
| $token, | |||||
| $version = null, | |||||
| Services_Twilio_TinyHttp $_http = null, | |||||
| $retryAttempts = 1 | |||||
| ) { | |||||
| $this->version = in_array($version, $this->versions) ? | |||||
| $version : end($this->versions); | |||||
| if (null === $_http) { | |||||
| if (!in_array('openssl', get_loaded_extensions())) { | |||||
| 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"); | |||||
| } | |||||
| if (in_array('curl', get_loaded_extensions())) { | |||||
| $_http = new Services_Twilio_TinyHttp( | |||||
| "https://api.twilio.com", | |||||
| array( | |||||
| "curlopts" => array( | |||||
| CURLOPT_USERAGENT => self::qualifiedUserAgent(phpversion()), | |||||
| CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'), | |||||
| CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', | |||||
| ), | |||||
| ) | |||||
| ); | |||||
| } else { | |||||
| $_http = new Services_Twilio_HttpStream( | |||||
| "https://api.twilio.com", | |||||
| array( | |||||
| "http_options" => array( | |||||
| "http" => array( | |||||
| "user_agent" => self::qualifiedUserAgent(phpversion()), | |||||
| "header" => "Accept-Charset: utf-8\r\n", | |||||
| ), | |||||
| "ssl" => array( | |||||
| 'verify_peer' => true, | |||||
| 'cafile' => dirname(__FILE__) . '/cacert.pem', | |||||
| 'verify_depth' => 5, | |||||
| ), | |||||
| ), | |||||
| ) | |||||
| ); | |||||
| } | |||||
| } | |||||
| $_http->authenticate($sid, $token); | |||||
| $this->http = $_http; | |||||
| $this->accounts = new Services_Twilio_Rest_Accounts($this, "/{$this->version}/Accounts"); | |||||
| $this->account = $this->accounts->get($sid); | |||||
| $this->retryAttempts = $retryAttempts; | |||||
| } | |||||
| /** | |||||
| * Fully qualified user agent with the current PHP Version. | |||||
| * | |||||
| * :return: the user agent | |||||
| * :rtype: string | |||||
| */ | |||||
| public static function qualifiedUserAgent($php_version) { | |||||
| return self::USER_AGENT . " (php $php_version)"; | |||||
| } | |||||
| /** | |||||
| * Get the api version used by the rest client | |||||
| * | |||||
| * :return: the API version in use | |||||
| * :returntype: string | |||||
| */ | |||||
| public function getVersion() { | |||||
| return $this->version; | |||||
| } | |||||
| /** | |||||
| * Get the retry attempt limit used by the rest client | |||||
| * | |||||
| * :return: the number of retry attempts | |||||
| * :rtype: int | |||||
| */ | |||||
| public function getRetryAttempts() { | |||||
| return $this->retryAttempts; | |||||
| } | |||||
| /** | |||||
| * Construct a URI based on initial path, query params, and paging | |||||
| * information | |||||
| * | |||||
| * We want to use the query params, unless we have a next_page_uri from the | |||||
| * API. | |||||
| * | |||||
| * :param string $path: The request path (may contain query params if it's | |||||
| * a next_page_uri) | |||||
| * :param array $params: Query parameters to use with the request | |||||
| * :param boolean $full_uri: Whether the $path contains the full uri | |||||
| * | |||||
| * :return: the URI that should be requested by the library | |||||
| * :returntype: string | |||||
| */ | |||||
| public static function getRequestUri($path, $params, $full_uri = false) { | |||||
| $json_path = $full_uri ? $path : "$path.json"; | |||||
| if (!$full_uri && !empty($params)) { | |||||
| $query_path = $json_path . '?' . http_build_query($params, '', '&'); | |||||
| } else { | |||||
| $query_path = $json_path; | |||||
| } | |||||
| return $query_path; | |||||
| } | |||||
| /** | |||||
| * Helper method for implementing request retry logic | |||||
| * | |||||
| * :param array $callable: The function that makes an HTTP request | |||||
| * :param string $uri: The URI to request | |||||
| * :param int $retriesLeft: Number of times to retry | |||||
| * | |||||
| * :return: The object representation of the resource | |||||
| * :rtype: object | |||||
| */ | |||||
| protected function _makeIdempotentRequest($callable, $uri, $retriesLeft) { | |||||
| $response = call_user_func_array($callable, array($uri)); | |||||
| list($status, $headers, $body) = $response; | |||||
| if ($status >= 500 && $retriesLeft > 0) { | |||||
| return $this->_makeIdempotentRequest($callable, $uri, $retriesLeft - 1); | |||||
| } else { | |||||
| return $this->_processResponse($response); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * GET the resource at the specified path. | |||||
| * | |||||
| * :param string $path: Path to the resource | |||||
| * :param array $params: Query string parameters | |||||
| * :param boolean $full_uri: Whether the full URI has been passed as an | |||||
| * argument | |||||
| * | |||||
| * :return: The object representation of the resource | |||||
| * :rtype: object | |||||
| */ | |||||
| public function retrieveData($path, $params = array(), | |||||
| $full_uri = false | |||||
| ) { | |||||
| $uri = self::getRequestUri($path, $params, $full_uri); | |||||
| return $this->_makeIdempotentRequest(array($this->http, 'get'), | |||||
| $uri, $this->retryAttempts); | |||||
| } | |||||
| /** | |||||
| * DELETE the resource at the specified path. | |||||
| * | |||||
| * :param string $path: Path to the resource | |||||
| * :param array $params: Query string parameters | |||||
| * | |||||
| * :return: The object representation of the resource | |||||
| * :rtype: object | |||||
| */ | |||||
| public function deleteData($path, $params = array()) | |||||
| { | |||||
| $uri = self::getRequestUri($path, $params); | |||||
| return $this->_makeIdempotentRequest(array($this->http, 'delete'), | |||||
| $uri, $this->retryAttempts); | |||||
| } | |||||
| /** | |||||
| * POST to the resource at the specified path. | |||||
| * | |||||
| * :param string $path: Path to the resource | |||||
| * :param array $params: Query string parameters | |||||
| * | |||||
| * :return: The object representation of the resource | |||||
| * :rtype: object | |||||
| */ | |||||
| public function createData($path, $params = array()) | |||||
| { | |||||
| $path = "$path.json"; | |||||
| $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); | |||||
| $response = $this->http->post( | |||||
| $path, $headers, self::buildQuery($params, '') | |||||
| ); | |||||
| return $this->_processResponse($response); | |||||
| } | |||||
| /** | |||||
| * Build a query string from query data | |||||
| * | |||||
| * :param array $queryData: An associative array of keys and values. The | |||||
| * values can be a simple type or a list, in which case the list is | |||||
| * converted to multiple query parameters with the same key. | |||||
| * :param string $numericPrefix: | |||||
| * :param string $queryStringStyle: Determine how to build the url | |||||
| * - strict: Build a standards compliant query string without braces (can be hacked by using braces in key) | |||||
| * - php: Build a PHP compatible query string with nested array syntax | |||||
| * :return: The encoded query string | |||||
| * :rtype: string | |||||
| */ | |||||
| public static function buildQuery($queryData, $numericPrefix = '') { | |||||
| $query = ''; | |||||
| // Loop through all of the $query_data | |||||
| foreach ($queryData as $key => $value) { | |||||
| // If the key is an int, add the numeric_prefix to the beginning | |||||
| if (is_int($key)) { | |||||
| $key = $numericPrefix . $key; | |||||
| } | |||||
| // If the value is an array, we will end up recursing | |||||
| if (is_array($value)) { | |||||
| // Loop through the values | |||||
| foreach ($value as $value2) { | |||||
| // Add an arg_separator if needed | |||||
| if ($query !== '') { | |||||
| $query .= '&'; | |||||
| } | |||||
| // Recurse | |||||
| $query .= self::buildQuery(array($key => $value2), $numericPrefix); | |||||
| } | |||||
| } else { | |||||
| // Add an arg_separator if needed | |||||
| if ($query !== '') { | |||||
| $query .= '&'; | |||||
| } | |||||
| // Add the key and the urlencoded value (as a string) | |||||
| $query .= $key . '=' . urlencode((string)$value); | |||||
| } | |||||
| } | |||||
| return $query; | |||||
| } | |||||
| /** | |||||
| * Convert the JSON encoded resource into a PHP object. | |||||
| * | |||||
| * :param array $response: 3-tuple containing status, headers, and body | |||||
| * | |||||
| * :return: PHP object decoded from JSON | |||||
| * :rtype: object | |||||
| * :throws: A :php:class:`Services_Twilio_RestException` if the Response is | |||||
| * in the 300-500 range of status codes. | |||||
| */ | |||||
| private function _processResponse($response) | |||||
| { | |||||
| list($status, $headers, $body) = $response; | |||||
| if ($status === 204) { | |||||
| return true; | |||||
| } | |||||
| $decoded = json_decode($body); | |||||
| if ($decoded === null) { | |||||
| throw new Services_Twilio_RestException( | |||||
| $status, | |||||
| 'Could not decode response body as JSON. ' . | |||||
| 'This likely indicates a 500 server error' | |||||
| ); | |||||
| } | |||||
| if (200 <= $status && $status < 300) { | |||||
| $this->last_response = $decoded; | |||||
| return $decoded; | |||||
| } | |||||
| throw new Services_Twilio_RestException( | |||||
| $status, | |||||
| isset($decoded->message) ? $decoded->message : '', | |||||
| isset($decoded->code) ? $decoded->code : null, | |||||
| isset($decoded->more_info) ? $decoded->more_info : null | |||||
| ); | |||||
| } | |||||
| } | |||||