SproutCMS

This is the code documentation for the SproutCMS project

source of /modules/HarborAndSprout/Helpers/GoogleDriveApi.php

  1. <?php
  2. namespace SproutModules\Karmabunny\HarborAndSprout\Helpers;
  3.  
  4. use Exception;
  5. use Kohana;
  6. use Sprout\Helpers\HttpReq;
  7. use Sprout\Helpers\Sprout;
  8. use Sprout\Helpers\Url;
  9.  
  10.  
  11. class GoogleDriveApi
  12. {
  13. public static $domain = 'https://www.googleapis.com/drive/v3';
  14.  
  15.  
  16. /**
  17.   * Loads Oauth2 config
  18.   *
  19.   * @return array
  20.   */
  21. public static function getConfig()
  22. {
  23. $config = json_decode(file_get_contents(DOCROOT . 'config/google_credentials.json'), true);
  24. return $config['web'];
  25. }
  26.  
  27.  
  28. /**
  29.   * Request an Oauth2 code
  30.   *
  31.   * @return void Redirects
  32.   */
  33. public static function requestOauthCode()
  34. {
  35. $config = self::getConfig();
  36.  
  37. $params = array(
  38. 'response_type' => 'code',
  39. 'client_id' => $config['client_id'],
  40. 'redirect_uri' => Sprout::absRoot() . 'google-drive/auth-action',
  41. 'scope' => 'https://www.googleapis.com/auth/drive',
  42. 'access_type' => 'offline',
  43. 'approval_prompt' => 'force',
  44. );
  45.  
  46. Url::redirect(sprintf('%s?%s', $config['auth_uri'], http_build_query($params)));
  47. }
  48.  
  49.  
  50. /**
  51.   * Save Oauth token
  52.   *
  53.   * @param string $code oAuth2 code
  54.   * @return array
  55.   */
  56. public static function saveOauthToken($code)
  57. {
  58. $config = self::getConfig();
  59. $errors = [];
  60.  
  61. $params = array(
  62. 'code' => $code,
  63. 'client_id' => $config['client_id'],
  64. 'client_secret' => $config['client_secret'],
  65. 'redirect_uri' => Sprout::absRoot() . 'google-drive/auth-action',
  66. 'grant_type' => 'authorization_code',
  67. );
  68.  
  69. $resp = json_decode(HttpReq::post($config['token_uri'], $params), true);
  70.  
  71. if (!empty($resp['error_description'])) throw new Exception($resp['error_description']);
  72.  
  73. if (empty($resp['access_token'])) $errors[] = 'Did not receive "access_token" field';
  74. if (empty($resp['refresh_token'])) $errors[] = 'Did not receive "refresh_token" field';
  75.  
  76. if (count($errors) > 0) throw new Exception(sprintf('%s -- repsonse: %s', implode('; ', $errors), print_r($resp, true)));
  77.  
  78. $token_info = array(
  79. 'access_token' => $resp['access_token'],
  80. 'refresh_token' => $resp['refresh_token'],
  81. 'expires' => time() + $resp['expires_in'],
  82. );
  83.  
  84. file_put_contents(DOCROOT . 'config/google_drive_token.json', json_encode($token_info));
  85.  
  86. return $token_info;
  87. }
  88.  
  89.  
  90. /**
  91.   *
  92.   * @param mixed $token
  93.   * @return void
  94.   */
  95. public static function refreshOauthToken($token)
  96. {
  97. if (empty($token)) throw new Exception('Need to refresh access token but "refresh_token" field empty');
  98.  
  99. $config = self::getConfig();
  100.  
  101. $params = array(
  102. 'refresh_token' => $token,
  103. 'client_id' => $config['client_id'],
  104. 'client_secret' => $config['client_secret'],
  105. 'grant_type' => 'refresh_token',
  106. );
  107.  
  108. $resp = json_decode(HttpReq::post($config['token_uri'], $params), true);
  109.  
  110. if (empty($resp['access_token'])) throw new Exception('Failed to get new access_token from refresh_token');
  111.  
  112. $token_info = array(
  113. 'access_token' => $resp['access_token'],
  114. 'refresh_token' => $token,
  115. 'expires' => time() + $resp['expires_in'],
  116. );
  117.  
  118. file_put_contents(DOCROOT . 'config/google_drive_token.json', json_encode($token_info));
  119.  
  120. return $token_info;
  121. }
  122.  
  123.  
  124. /**
  125.   * Load Oauth2 token. May cause a token refresh
  126.   *
  127.   * @return mixed
  128.   * @throws Exception
  129.   */
  130. public static function getToken()
  131. {
  132. $token_info = @file_get_contents(DOCROOT . 'config/google_drive_token.json');
  133. if (empty($token_info)) return null;
  134.  
  135. $token_info = json_decode($token_info, true);
  136.  
  137. if ($token_info['expires'] <= time()) $token_info = self::refreshOauthToken($token_info['refresh_token']);
  138.  
  139. return $token_info['access_token'];
  140. }
  141.  
  142.  
  143. /**
  144.   * Performs an API request
  145.   *
  146.   * @param string $method GET|POST
  147.   * @param string $url API endpoint URL. @see https://developers.google.com/drive/v3/reference/
  148.   * @param array $data Message body. Will be json encoded
  149.   * @param bool $headers False by default
  150.   * @return array Response from Google
  151.   */
  152. public static function apiRequest($method, $url, $data = null, $headers = false)
  153. {
  154. $token = self::getToken();
  155.  
  156. if (!in_array($method, ['GET','POST'])) throw new Exception("Either GET or POST as method");
  157.  
  158. if (empty($token)) throw new Exception("API access token missing from cache, please rerun the 'Connect to Google Drive' tool");
  159.  
  160. $opts = [
  161. 'method' => $method,
  162. 'headers' => [
  163. 'Authorization' => "Bearer {$token}",
  164. ]
  165. ];
  166.  
  167. if (!empty($headers)) $opts['getheaders'] = true;
  168.  
  169. // Data as request body as JSON
  170. if (is_array($data) and $method == 'POST')
  171. {
  172. $data = json_encode($data);
  173. $opts['headers']['Content-type'] = 'application/json';
  174. }
  175. // Data as request URL params
  176. else if (is_array($data) and $method == 'GET')
  177. {
  178. $url .= '?' . http_build_query($data);
  179. }
  180.  
  181. $resp = json_decode(HttpReq::req($url, $opts, $method == 'POST' ? $data : null), true);
  182.  
  183. $resp['headers'] = HttpReq::getLastreqHeaders();
  184. $resp['status'] = HttpReq::getLastreqStatus();
  185. $resp['info'] = HttpReq::getLastreqInfo();
  186. $resp['url'] = $url;
  187.  
  188. return $resp;
  189. }
  190. }
  191.  
  192.  
  193.