Skip to content

Commit 5fbb8c5

Browse files
committed
Replace cURL with the Cake Http client and fix tests with Cake Client response mocks
1 parent af50085 commit 5fbb8c5

4 files changed

Lines changed: 125 additions & 146 deletions

File tree

phpstan-baseline.neon

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,30 +72,12 @@ parameters:
7272
count: 1
7373
path: src/Controller/Component/GithubApiComponent.php
7474

75-
-
76-
message: '#^Parameter \#1 \$json of function json_decode expects string, string\|true given\.$#'
77-
identifier: argument.type
78-
count: 1
79-
path: src/Controller/Component/GithubApiComponent.php
80-
8175
-
8276
message: '#^Parameter \#2 \$data of method App\\Controller\\Component\\GithubApiComponent\:\:apiRequest\(\) expects array\|string, string\|false given\.$#'
8377
identifier: argument.type
8478
count: 2
8579
path: src/Controller/Component/GithubApiComponent.php
8680

87-
-
88-
message: '#^Parameter \#3 \$value of function curl_setopt expects bool, int given\.$#'
89-
identifier: argument.type
90-
count: 2
91-
path: src/Controller/Component/GithubApiComponent.php
92-
93-
-
94-
message: '#^Parameter \#3 \$value of function curl_setopt expects non\-empty\-string\|null, string given\.$#'
95-
identifier: argument.type
96-
count: 1
97-
path: src/Controller/Component/GithubApiComponent.php
98-
9981
-
10082
message: '#^Method App\\Controller\\Component\\MailerComponent\:\:sendReportMail\(\) has parameter \$viewVars with no value type specified in iterable type array\.$#'
10183
identifier: missingType.iterableValue

src/Controller/Component/GithubApiComponent.php

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,18 @@
2020

2121
use Cake\Controller\Component;
2222
use Cake\Core\Configure;
23+
use Cake\Http\Client;
24+
use Cake\Http\Client\Request as ClientRequest;
25+
use Cake\Http\Client\Response as ClientResponse;
2326
use Cake\Log\Log;
2427
use Cake\Routing\Router;
2528

2629
use 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;
3231
use function http_build_query;
33-
use function json_decode;
3432
use function json_encode;
3533
use 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
);

src/Controller/GithubController.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function create_issue($reportId): ?Response
107107
$this->request->getSession()->read('access_token')
108108
);
109109

110-
if ($this->handleGithubResponse($status, 1, $reportId, $issueDetails['number'])) {
110+
if ($this->handleGithubResponse($status, 1, $reportId, $issueDetails['number'] ?? null)) {
111111
// Update report status
112112
$report->status = $this->getReportStatusFromIssueState($issueDetails['state']);
113113
$reportsTable->save($report);
@@ -325,18 +325,18 @@ protected function getReportDescriptionText(int $reportId, array $report): strin
325325
/**
326326
* Github Response Handler.
327327
*
328-
* @param int $response the status returned by Github API
329-
* @param int $type type of response. 1 for create_issue, 2 for link_issue, 3 for unlink_issue,
330-
* 1 for create_issue,
331-
* 2 for link_issue,
332-
* 3 for unlink_issue,
333-
* 4 for get_issue
334-
* @param int $report_id report id
335-
* @param int $ticket_id ticket id, required for link ticket only
328+
* @param int $response the status returned by Github API
329+
* @param int $type type of response. 1 for create_issue, 2 for link_issue, 3 for unlink_issue,
330+
* 1 for create_issue,
331+
* 2 for link_issue,
332+
* 3 for unlink_issue,
333+
* 4 for get_issue
334+
* @param int $report_id report id
335+
* @param int|null $ticket_id ticket id, required for link ticket only
336336
*
337337
* @return bool value. True on success. False on any type of failure.
338338
*/
339-
protected function handleGithubResponse(int $response, int $type, int $report_id, int $ticket_id = 1): bool
339+
protected function handleGithubResponse(int $response, int $type, int $report_id, int|null $ticket_id = null): bool
340340
{
341341
if (! in_array($type, [1, 2, 3, 4])) {
342342
throw new InvalidArgumentException('Invalid Argument ' . $type . '.');

0 commit comments

Comments
 (0)