コード例 #1
0
ファイル: Podio.php プロジェクト: xengine/podio-php
 public static function request($method, $url, $attributes = array(), $options = array())
 {
     if (!self::$ch) {
         throw new Exception('Client has not been setup with client id and client secret.');
     }
     // Reset attributes so we can reuse curl object
     curl_setopt(self::$ch, CURLOPT_POSTFIELDS, null);
     unset(self::$headers['Content-length']);
     $original_url = $url;
     $encoded_attributes = null;
     if (is_object($attributes) && substr(get_class($attributes), 0, 5) == 'Podio') {
         $attributes = $attributes->as_json(false);
     }
     if (!is_array($attributes) && !is_object($attributes)) {
         throw new PodioDataIntegrityError('Attributes must be an array');
     }
     switch ($method) {
         case self::GET:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::GET);
             self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             $separator = strpos($url, '?') ? '&' : '?';
             if ($attributes) {
                 $query = self::encode_attributes($attributes);
                 $url = $url . $separator . $query;
             }
             self::$headers['Content-length'] = "0";
             break;
         case self::DELETE:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::DELETE);
             self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             $separator = strpos($url, '?') ? '&' : '?';
             if ($attributes) {
                 $query = self::encode_attributes($attributes);
                 $url = $url . $separator . $query;
             }
             self::$headers['Content-length'] = "0";
             break;
         case self::POST:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::POST);
             if (!empty($options['upload'])) {
                 curl_setopt(self::$ch, CURLOPT_POST, TRUE);
                 curl_setopt(self::$ch, CURLOPT_SAFE_UPLOAD, FALSE);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $attributes);
                 self::$headers['Content-type'] = 'multipart/form-data';
             } elseif (empty($options['oauth_request'])) {
                 // application/json
                 $encoded_attributes = json_encode($attributes);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
                 self::$headers['Content-type'] = 'application/json';
             } else {
                 // x-www-form-urlencoded
                 $encoded_attributes = self::encode_attributes($attributes);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
                 self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             }
             break;
         case self::PUT:
             $encoded_attributes = json_encode($attributes);
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::PUT);
             curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
             self::$headers['Content-type'] = 'application/json';
             break;
     }
     // Add access token to request
     if (Cache::has('podio_oauth')) {
         $token = Cache::get('podio_oauth')->access_token;
         self::$headers['Authorization'] = "OAuth2 {$token}";
     } else {
         unset(self::$headers['Authorization']);
     }
     // File downloads can be of any type
     if (empty($options['file_download'])) {
         self::$headers['Accept'] = 'application/json';
     } else {
         self::$headers['Accept'] = '*/*';
     }
     curl_setopt(self::$ch, CURLOPT_HTTPHEADER, self::curl_headers());
     curl_setopt(self::$ch, CURLOPT_URL, empty($options['file_download']) ? self::$url . $url : $url);
     $response = new PodioResponse();
     if (isset($options['return_raw_as_resource_only']) && $options['return_raw_as_resource_only'] == true) {
         $result_handle = fopen('php://temp', 'w');
         curl_setopt(self::$ch, CURLOPT_FILE, $result_handle);
         curl_exec(self::$ch);
         if (isset(self::$stdout) && is_resource(self::$stdout)) {
             fclose(self::$stdout);
         }
         self::$stdout = fopen('php://stdout', 'w');
         curl_setopt(self::$ch, CURLOPT_FILE, self::$stdout);
         curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, true);
         $raw_headers_size = curl_getinfo(self::$ch, CURLINFO_HEADER_SIZE);
         fseek($result_handle, 0);
         $response->status = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
         $response->headers = self::parse_headers(fread($result_handle, $raw_headers_size));
         self::$last_response = $response;
         return $result_handle;
     }
     $raw_response = curl_exec(self::$ch);
     if ($raw_response === false) {
         throw new PodioConnectionError('Connection to Podio API failed: [' . curl_errno(self::$ch) . '] ' . curl_error(self::$ch), curl_errno(self::$ch));
     }
     $raw_headers_size = curl_getinfo(self::$ch, CURLINFO_HEADER_SIZE);
     $response->body = substr($raw_response, $raw_headers_size);
     $response->status = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
     $response->headers = self::parse_headers(substr($raw_response, 0, $raw_headers_size));
     self::$last_response = $response;
     if (!isset($options['oauth_request'])) {
         $curl_info = curl_getinfo(self::$ch, CURLINFO_HEADER_OUT);
         self::log_request($method, $url, $encoded_attributes, $response, $curl_info);
     }
     switch ($response->status) {
         case 200:
         case 201:
         case 204:
             return $response;
             break;
         case 400:
             // invalid_grant_error or bad_request_error
             $body = $response->json_body();
             if (strstr($body['error'], 'invalid_grant')) {
                 // Reset access token & refresh_token
                 self::clear_authentication();
                 throw new PodioInvalidGrantError($response->body, $response->status, $url);
                 break;
             } else {
                 throw new PodioBadRequestError($response->body, $response->status, $url);
             }
             break;
         case 401:
             $body = $response->json_body();
             if (strstr($body['error_description'], 'expired_token') || strstr($body['error'], 'invalid_token')) {
                 if (self::$oauth->refresh_token) {
                     // Access token is expired. Try to refresh it.
                     if (self::authenticate('refresh_token', array('refresh_token' => Cache::get('podio_oauth')->refresh_token))) {
                         // Try the original request again.
                         return self::request($method, $original_url, $attributes);
                     } else {
                         self::clear_authentication();
                         throw new PodioAuthorizationError($response->body, $response->status, $url);
                     }
                 } else {
                     // We have tried in vain to get a new access token. Log the user out.
                     self::clear_authentication();
                     throw new PodioAuthorizationError($response->body, $response->status, $url);
                 }
             } elseif (strstr($body['error'], 'invalid_request') || strstr($body['error'], 'unauthorized')) {
                 // Access token is invalid.
                 self::clear_authentication();
                 throw new PodioAuthorizationError($response->body, $response->status, $url);
             }
             break;
         case 403:
             throw new PodioForbiddenError($response->body, $response->status, $url);
             break;
         case 404:
             throw new PodioNotFoundError($response->body, $response->status, $url);
             break;
         case 409:
             throw new PodioConflictError($response->body, $response->status, $url);
             break;
         case 410:
             throw new PodioGoneError($response->body, $response->status, $url);
             break;
         case 420:
             throw new PodioRateLimitError($response->body, $response->status, $url);
             break;
         case 500:
             throw new PodioServerError($response->body, $response->status, $url);
             break;
         case 502:
         case 503:
         case 504:
             throw new PodioUnavailableError($response->body, $response->status, $url);
             break;
         default:
             throw new PodioError($response->body, $response->status, $url);
             break;
     }
     return false;
 }
コード例 #2
0
 public static function request($method, $url, $attributes = array(), $options = array())
 {
     if (!self::$ch) {
         throw new Exception('Client has not been setup with client id and client secret.');
     }
     // Reset attributes so we can reuse curl object
     curl_setopt(self::$ch, CURLOPT_POSTFIELDS, null);
     unset(self::$headers['Content-length']);
     $original_url = $url;
     $encoded_attributes = null;
     if (is_object($attributes) && substr(get_class($attributes), 0, 5) == 'Podio') {
         $attributes = $attributes->as_json(false);
     }
     if (!is_array($attributes) && !is_object($attributes)) {
         throw new PodioDataIntegrityError('Attributes must be an array');
     }
     switch ($method) {
         case self::GET:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::GET);
             self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             if ($attributes) {
                 $query = self::encode_attributes($attributes);
                 $url = $url . '?' . $query;
             }
             self::$headers['Content-length'] = "0";
             break;
         case self::DELETE:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::DELETE);
             self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             $query = self::encode_attributes($attributes);
             $url = $url . '?' . $query;
             self::$headers['Content-length'] = "0";
             break;
         case self::POST:
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::POST);
             if (!empty($options['upload'])) {
                 curl_setopt(self::$ch, CURLOPT_POST, TRUE);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $attributes);
                 self::$headers['Content-type'] = 'multipart/form-data';
             } elseif (empty($options['oauth_request'])) {
                 // application/json
                 $encoded_attributes = json_encode($attributes);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
                 self::$headers['Content-type'] = 'application/json';
             } else {
                 // x-www-form-urlencoded
                 $encoded_attributes = self::encode_attributes($attributes);
                 curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
                 self::$headers['Content-type'] = 'application/x-www-form-urlencoded';
             }
             break;
         case self::PUT:
             $encoded_attributes = json_encode($attributes);
             curl_setopt(self::$ch, CURLOPT_CUSTOMREQUEST, self::PUT);
             curl_setopt(self::$ch, CURLOPT_POSTFIELDS, $encoded_attributes);
             self::$headers['Content-type'] = 'application/json';
             break;
     }
     // Add access token to request
     if (isset(self::$oauth) && !empty(self::$oauth->access_token) && !(isset($options['oauth_request']) && $options['oauth_request'] == true)) {
         $token = self::$oauth->access_token;
         self::$headers['Authorization'] = "OAuth2 {$token}";
     } else {
         unset(self::$headers['Authorization']);
     }
     // File downloads can be of any type
     if (empty($options['file_download'])) {
         self::$headers['Accept'] = 'application/json';
     } else {
         self::$headers['Accept'] = '*/*';
     }
     curl_setopt(self::$ch, CURLOPT_HTTPHEADER, self::curl_headers());
     curl_setopt(self::$ch, CURLOPT_URL, empty($options['file_download']) ? self::$url . $url : $url);
     $response = new PodioResponse();
     $raw_response = curl_exec(self::$ch);
     $raw_headers_size = curl_getinfo(self::$ch, CURLINFO_HEADER_SIZE);
     $response->body = substr($raw_response, $raw_headers_size);
     $response->status = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
     $response->headers = self::parse_headers(substr($raw_response, 0, $raw_headers_size));
     self::$last_response = $response;
     if (self::$debug && !isset($options['oauth_request'])) {
         if (!self::$logger) {
             self::$logger = new PodioLogger();
         }
         $curl_info = curl_getinfo(self::$ch, CURLINFO_HEADER_OUT);
         self::$logger->log_request($method, $url, $encoded_attributes, $response, $curl_info);
         self::$logger->call_log[] = curl_getinfo(self::$ch, CURLINFO_TOTAL_TIME);
     }
     switch ($response->status) {
         case 200:
         case 201:
         case 204:
             return $response;
             break;
         case 400:
             // invalid_grant_error or bad_request_error
             $body = $response->json_body();
             if (strstr($body['error'], 'invalid_grant')) {
                 // Reset access token & refresh_token
                 self::$oauth = new PodioOAuth();
                 throw new PodioInvalidGrantError($response->body, $response->status, $url);
                 break;
             } else {
                 throw new PodioBadRequestError($response->body, $response->status, $url);
             }
             break;
         case 401:
             $body = $response->json_body();
             if (strstr($body['error_description'], 'expired_token') || strstr($body['error'], 'invalid_token')) {
                 if (self::$oauth->refresh_token) {
                     // Access token is expired. Try to refresh it.
                     if (self::authenticate('refresh_token', array('refresh_token' => self::$oauth->refresh_token))) {
                         // Try the original request again.
                         return self::request($method, $original_url, $attributes);
                     } else {
                         self::$oauth = new PodioOAuth();
                         throw new PodioAuthorizationError($response->body, $response->status, $url);
                     }
                 } else {
                     // We have tried in vain to get a new access token. Log the user out.
                     self::$oauth = new PodioOAuth();
                     throw new PodioAuthorizationError($response->body, $response->status, $url);
                 }
             } elseif (strstr($body['error'], 'invalid_request')) {
                 // Access token is invalid.
                 self::$oauth = new PodioOAuth();
                 throw new PodioAuthorizationError($response->body, $response->status, $url);
             }
             break;
         case 403:
             throw new PodioForbiddenError($response->body, $response->status, $url);
             break;
         case 404:
             throw new PodioNotFoundError($response->body, $response->status, $url);
             break;
         case 409:
             throw new PodioConflictError($response->body, $response->status, $url);
             break;
         case 410:
             throw new PodioGoneError($response->body, $response->status, $url);
             break;
         case 420:
             throw new PodioRateLimitError($response->body, $response->status, $url);
             break;
         case 500:
             throw new PodioServerError($response->body, $response->status, $url);
             break;
         case 502:
         case 503:
         case 504:
             throw new PodioUnavailableError($response->body, $response->status, $url);
             break;
         default:
             throw new PodioError($response->body, $response->status, $url);
             break;
     }
     return false;
 }