/lib/Github/HttpClient/Curl.php

https://github.com/hit-moodle/moodle-assignment-type_github · PHP · 130 lines · 98 code · 15 blank · 17 comment · 10 complexity · 7d6dcd13e1b9879be486bf1cb19aaa97 MD5 · raw file

  1. <?php
  2. /**
  3. * Performs requests on GitHub API. API documentation should be self-explanatory.
  4. *
  5. * @author Thibault Duplessis <thibault.duplessis at gmail dot com>
  6. * @license MIT License
  7. */
  8. class Github_HttpClient_Curl extends Github_HttpClient
  9. {
  10. /**
  11. * Send a request to the server, receive a response
  12. *
  13. * @param string $url Request url
  14. * @param array $parameters Parameters
  15. * @param string $httpMethod HTTP method to use
  16. * @param array $options Request options
  17. *
  18. * @return string HTTP response
  19. */
  20. public function doRequest($url, array $parameters = array(), $httpMethod = 'GET', array $options = array())
  21. {
  22. $curlOptions = array();
  23. if ($options['login'] || $options['auth_method'] == Github_Client::OAUTH_ACCESS_TOKEN) {
  24. switch ($options['auth_method']) {
  25. case Github_Client::AUTH_HTTP_PASSWORD:
  26. $curlOptions += array(
  27. CURLOPT_USERPWD => $options['login'].':'.$options['secret'],
  28. );
  29. break;
  30. case Github_Client::AUTH_HTTP_TOKEN:
  31. $curlOptions += array(
  32. CURLOPT_USERPWD => $options['login'].'/token:'.$options['secret'],
  33. );
  34. break;
  35. case Github_Client::OAUTH_ACCESS_TOKEN:
  36. $curlOptions += array(
  37. CURLOPT_HTTPHEADER => array('Authorization: token '.$options['secret']),
  38. );
  39. break;
  40. case Github_Client::AUTH_URL_TOKEN:
  41. default:
  42. $parameters = array_merge(array(
  43. 'login' => $options['login'],
  44. 'token' => $options['secret']
  45. ), $parameters);
  46. break;
  47. }
  48. }
  49. if (!empty($parameters)) {
  50. $queryString = utf8_encode(http_build_query($parameters, '', '&'));
  51. if ('GET' === $httpMethod) {
  52. $url .= '?'.$queryString;
  53. } else {
  54. $curlOptions += array(
  55. CURLOPT_POSTFIELDS => json_encode($parameters),
  56. );
  57. }
  58. }
  59. $curlValue = true;
  60. switch($httpMethod) {
  61. case 'GET':
  62. $curlMethod = CURLOPT_HTTPGET;
  63. break;
  64. case 'POST':
  65. $curlMethod = CURLOPT_POST;
  66. break;
  67. case 'HEAD':
  68. $curlMethod = CURLOPT_CUSTOMREQUEST;
  69. $curlValue = "HEAD";
  70. break;
  71. case 'PUT':
  72. $curlMethod = CURLOPT_CUSTOMREQUEST;
  73. $curlValue = "PUT";
  74. break;
  75. case 'DELETE':
  76. $curlMethod = CURLOPT_CUSTOMREQUEST;
  77. $curlValue = "DELETE";
  78. break;
  79. case 'PATCH':
  80. // since PATCH is new the end points accept as POST
  81. $curlMethod = CURLOPT_POST;
  82. break;
  83. default:
  84. throw new Github_HttpClient_Exception('Method currently not supported');
  85. }
  86. $curlOptions += array(
  87. CURLOPT_URL => $url,
  88. CURLOPT_PORT => $options['http_port'],
  89. CURLOPT_USERAGENT => $options['user_agent'],
  90. CURLOPT_FOLLOWLOCATION => true,
  91. CURLOPT_RETURNTRANSFER => true,
  92. CURLOPT_TIMEOUT => $options['timeout'],
  93. $curlMethod => $curlValue
  94. );
  95. $response = $this->doCurlCall($curlOptions);
  96. if (!in_array($response['headers']['http_code'], array(0, 200, 201, 204))) {
  97. throw new Github_HttpClient_Exception(null, (int) $response['headers']['http_code']);
  98. }
  99. if ($response['errorNumber'] != '') {
  100. throw new Github_HttpClient_Exception('error '.$response['errorNumber']);
  101. }
  102. return $response['response'];
  103. }
  104. protected function doCurlCall(array $curlOptions)
  105. {
  106. $curl = curl_init();
  107. curl_setopt_array($curl, $curlOptions);
  108. $response = curl_exec($curl);
  109. $headers = curl_getinfo($curl);
  110. $errorNumber = curl_errno($curl);
  111. $errorMessage = curl_error($curl);
  112. curl_close($curl);
  113. return compact('response', 'headers', 'errorNumber', 'errorMessage');
  114. }
  115. }