2020
2121use Cake \Controller \Component ;
2222use Cake \Core \Configure ;
23+ use Cake \Http \Client ;
24+ use Cake \Http \Client \Request as ClientRequest ;
25+ use Cake \Http \Client \Response as ClientResponse ;
2326use Cake \Log \Log ;
2427use Cake \Routing \Router ;
2528
2629use function array_merge ;
27- use function curl_error ;
28- use function curl_exec ;
29- use function curl_getinfo ;
30- use function curl_init ;
31- use function curl_setopt ;
30+ use function assert ;
3231use function http_build_query ;
33- use function json_decode ;
3432use function json_encode ;
3533use function strtoupper ;
3634
37- use const CURL_HTTP_VERSION_1_1 ;
38- use const CURLINFO_HTTP_CODE ;
39- use const CURLOPT_CUSTOMREQUEST ;
40- use const CURLOPT_FOLLOWLOCATION ;
41- use const CURLOPT_HTTP_VERSION ;
42- use const CURLOPT_HTTPHEADER ;
43- use const CURLOPT_POSTFIELDS ;
44- use const CURLOPT_RETURNTRANSFER ;
45- use const CURLOPT_USERAGENT ;
46-
4735/**
4836 * Github api component handling comunication with github.
4937 */
@@ -53,28 +41,29 @@ class GithubApiComponent extends Component
5341 * perform an api request given a path, the data to send, the method and whether
5442 * or not to return a status.
5543 *
44+ * @see GithubApiComponent::sendRequest()
45+ *
5646 * @param string $path the api path to preform the request to
5747 * @param array|string $data the data to send in the request. This works with both GET
5848 * and Post requests
5949 * @param string $method the method type of the request
6050 * @param bool $returnStatus whether to return the status code with the
6151 * request
6252 * @param string $access_token the github access token
53+ * @phpstan-param ClientRequest::METHOD_* $method
6354 *
6455 * @return array the returned response decoded and optionally the status code,
6556 * see GithubApiComponent::sendRequest()
66- *
67- * @see GithubApiComponent::sendRequest()
6857 */
6958 public function apiRequest (
70- string $ path = '' ,
71- $ data = [] ,
72- string $ method = ' GET ' ,
59+ string $ path ,
60+ array | string $ data ,
61+ string $ method ,
7362 bool $ returnStatus = false ,
7463 string $ access_token = ''
7564 ): array {
7665 $ path = 'https://api.github.com/ ' . $ path ;
77- if (strtoupper ($ method ) === ' GET ' ) {
66+ if (strtoupper ($ method ) === ClientRequest:: METHOD_GET ) {
7867 $ path .= '? ' . http_build_query ($ data );
7968 $ data = [];
8069 }
@@ -96,7 +85,7 @@ public function getAccessToken(?string $code): ?string
9685 Configure::read ('GithubConfig ' , []),
9786 ['code ' => $ code ]
9887 );
99- $ decodedResponse = $ this ->sendRequest ($ url , http_build_query ($ data ), ' POST ' );
88+ $ decodedResponse = $ this ->sendRequest ($ url , http_build_query ($ data ), ClientRequest:: METHOD_POST );
10089
10190 return $ decodedResponse ['access_token ' ] ?? null ;
10291 }
@@ -111,63 +100,60 @@ public function getAccessToken(?string $code): ?string
111100 */
112101 public function getUserInfo (string $ accessToken ): array
113102 {
114- return $ this ->apiRequest ('user ' , [], ' GET ' , true , $ accessToken );
103+ return $ this ->apiRequest ('user ' , [], ClientRequest:: METHOD_GET , true , $ accessToken );
115104 }
116105
117106 /**
118107 * perform an http request using curl given a url, the post data to send, the
119108 * request method and whether or not to return a status.
120109 *
121- * @param string $url the url to preform the request to
122- * @param array|string $data the post data to send in the request. This only works with POST requests. GET requests need the data appended in the url.
123- * with POST requests. GET requests need the data appended
124- * in the url.
125- * @param string $method the method type of the request
126- * @param bool $returnCode whether to return the status code with the
127- * request
128- * @param string $access_token the github access token
110+ * @param string $url the url to preform the request to
111+ * @param array|string $data the post data to send in the request. This only works with POST requests. GET requests need the data appended in the url.
112+ * with POST requests. GET requests need the data appended
113+ * in the url.
114+ * @param string $method the method type of the request
115+ * @param bool $returnCode whether to return the status code with the
116+ * request
117+ * @param string $accessToken the github access token
118+ * @phpstan-param ClientRequest::METHOD_* $method
129119 *
130120 * @return array the returned response decoded and optionally the status code,
131121 * eg: array($decodedResponse, $statusCode) or just $decodedResponse
132122 */
133123 public function sendRequest (
134124 string $ url ,
135- $ data ,
125+ array | string $ data ,
136126 string $ method ,
137127 bool $ returnCode = false ,
138- string $ access_token = ''
128+ string $ accessToken = ''
139129 ): array {
140130 Log::debug ('Request-url: ' . $ url );
141- $ curlHandle = curl_init ($ url );
142- if ($ curlHandle === false ) {
143- Log::error ('Curl init error for: ' . $ url );
144-
145- return ['' , 0 ];
146- }
147131
148- curl_setopt ($ curlHandle , CURLOPT_CUSTOMREQUEST , $ method );
149- $ header = ['Accept: application/json ' ];
150- if ($ access_token !== '' ) {
151- $ header [] = 'Authorization: token ' . $ access_token ;
132+ $ headers = [
133+ 'Accept ' => 'application/json ' ,
134+ 'User-Agent ' => 'phpMyAdmin - Error Reporting Server ' ,
135+ ];
136+ if ($ accessToken !== '' ) {
137+ $ headers ['Authorization ' ] = 'token ' . $ accessToken ;
152138 }
153139
154- curl_setopt ($ curlHandle , CURLOPT_HTTPHEADER , $ header );
155- curl_setopt ($ curlHandle , CURLOPT_USERAGENT , 'phpMyAdmin - Error Reporting Server ' );
156- curl_setopt ($ curlHandle , CURLOPT_POSTFIELDS , $ data );
157- curl_setopt ($ curlHandle , CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
158- curl_setopt ($ curlHandle , CURLOPT_FOLLOWLOCATION , 1 );// Issues moved to another repo have redirects
159- curl_setopt ($ curlHandle , CURLOPT_RETURNTRANSFER , 1 );
160- $ response = curl_exec ($ curlHandle );
161- if ($ response === false ) {
162- Log::error ('Curl error: " ' . curl_error ($ curlHandle ) . '" for: ' . $ url );
140+ $ request = new ClientRequest (
141+ url: $ url ,
142+ method: $ method ,
143+ headers: $ headers ,
144+ data: $ data ,
145+ );
146+ $ http = new Client ([
147+ 'redirect ' => 5 ,// Max redirects to follow
148+ ]);
149+ $ response = $ http ->sendRequest ($ request );
163150
164- return [ '' , 0 ] ;
165- }
151+ $ status = $ response -> getStatusCode () ;
152+ assert ( $ response instanceof ClientResponse);
166153
167- $ status = curl_getinfo ($ curlHandle , CURLINFO_HTTP_CODE );
168154 Log::debug ('Response-code: ' . $ status . ' for: ' . $ url );
169155
170- $ decodedResponse = json_decode ( $ response, true );
156+ $ decodedResponse = $ response-> getJson ( );
171157 if ($ returnCode ) {
172158 return [
173159 $ decodedResponse ,
@@ -218,7 +204,7 @@ public function canCommitTo(string $username, string $repoPath, string $access_t
218204 [, $ status ] = $ this ->apiRequest (
219205 'repos/ ' . $ repoPath . '/collaborators/ ' . $ username ,
220206 [],
221- ' GET ' ,
207+ ClientRequest:: METHOD_GET ,
222208 true ,
223209 $ access_token
224210 );
@@ -242,7 +228,7 @@ public function createIssue(string $repoPath, array $data, string $access_token)
242228 return $ this ->apiRequest (
243229 'repos/ ' . $ repoPath . '/issues ' ,
244230 json_encode ($ data ),
245- ' POST ' ,
231+ ClientRequest:: METHOD_POST ,
246232 true ,
247233 $ access_token
248234 );
@@ -262,7 +248,7 @@ public function createComment(string $repoPath, array $data, int $issueNumber, s
262248 return $ this ->apiRequest (
263249 'repos/ ' . $ repoPath . '/issues/ ' . $ issueNumber . '/comments ' ,
264250 json_encode ($ data ),
265- ' POST ' ,
251+ ClientRequest:: METHOD_POST ,
266252 true ,
267253 $ access_token
268254 );
@@ -282,7 +268,7 @@ public function getIssue(string $repoPath, array $data, int $issueNumber, string
282268 return $ this ->apiRequest (
283269 'repos/ ' . $ repoPath . '/issues/ ' . $ issueNumber ,
284270 $ data ,
285- ' GET ' ,
271+ ClientRequest:: METHOD_GET ,
286272 true ,
287273 $ access_token
288274 );
0 commit comments