diff --git a/extension.neon b/extension.neon index 4e03e28..63a4891 100644 --- a/extension.neon +++ b/extension.neon @@ -150,3 +150,6 @@ services: - %todo_by.ticket.jira.server% - %todo_by.ticket.jira.credentials% - %todo_by.ticket.jira.credentialsFilePath% + + - + class: staabm\PHPStanTodoBy\utils\HttpClient diff --git a/src/TodoByPackageVersionRule.php b/src/TodoByPackageVersionRule.php index c9f0a30..597a46c 100644 --- a/src/TodoByPackageVersionRule.php +++ b/src/TodoByPackageVersionRule.php @@ -107,7 +107,7 @@ public function processNode(Node $node, Scope $scope): array $satisfiesOrError = $this->satisfiesInstalledPackage($package, $version, $comment, $match[0][1]); } - if ($satisfiesOrError instanceof \PHPStan\Rules\RuleError) { + if ($satisfiesOrError instanceof RuleError) { $errors[] = $satisfiesOrError; continue; } diff --git a/src/utils/HttpClient.php b/src/utils/HttpClient.php new file mode 100644 index 0000000..c30b901 --- /dev/null +++ b/src/utils/HttpClient.php @@ -0,0 +1,39 @@ + $headers + * @return array{int, string} + */ + public function get(string $url, array $headers): array + { + $curl = curl_init($url); + if (!$curl) { + throw new RuntimeException('Could not initialize cURL connection'); + } + + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + + if ([] !== $headers) { + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + } + + $response = curl_exec($curl); + + if (!is_string($response)) { + throw new RuntimeException("Could not fetch url $url"); + } + + $responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); + + return [$responseCode, $response]; + } +} diff --git a/src/utils/ticket/GitHubTicketStatusFetcher.php b/src/utils/ticket/GitHubTicketStatusFetcher.php index 178b1fc..c9f4352 100644 --- a/src/utils/ticket/GitHubTicketStatusFetcher.php +++ b/src/utils/ticket/GitHubTicketStatusFetcher.php @@ -4,6 +4,7 @@ use RuntimeException; use staabm\PHPStanTodoBy\utils\CredentialsHelper; +use staabm\PHPStanTodoBy\utils\HttpClient; use function array_key_exists; use function is_array; @@ -27,13 +28,16 @@ final class GitHubTicketStatusFetcher implements TicketStatusFetcher */ private array $cache; - public function __construct(string $defaultOwner, string $defaultRepo, ?string $credentials, ?string $credentialsFilePath) + private HttpClient $httpClient; + + public function __construct(string $defaultOwner, string $defaultRepo, ?string $credentials, ?string $credentialsFilePath, HttpClient $httpClient) { $this->defaultOwner = $defaultOwner; $this->defaultRepo = $defaultRepo; $this->accessToken = CredentialsHelper::getCredentials($credentials, $credentialsFilePath); $this->cache = []; + $this->httpClient = $httpClient; } public function fetchTicketStatus(string $ticketKey): ?string @@ -51,11 +55,6 @@ public function fetchTicketStatus(string $ticketKey): ?string } $url = "https://api.github.com/repos/$owner/$repo/issues/$number"; - $curl = curl_init($url); - if (!$curl) { - throw new RuntimeException('Could not initialize cURL connection'); - } - $apiVersion = self::API_VERSION; $headers = [ @@ -68,22 +67,16 @@ public function fetchTicketStatus(string $ticketKey): ?string $headers[] = "Authorization: Bearer $this->accessToken"; } - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + [$responseCode, $response] = $this->httpClient->get($url, $headers); - $response = curl_exec($curl); - - if (404 === $responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE)) { + if (404 === $responseCode) { return null; } - if (!is_string($response) || 200 !== $responseCode) { + if (200 !== $responseCode) { throw new RuntimeException("Could not fetch ticket's status from GitHub with $url"); } - curl_close($curl); - $data = json_decode($response, true); if (!is_array($data) || !array_key_exists('state', $data) || !is_string($data['state'])) { diff --git a/src/utils/ticket/JiraTicketStatusFetcher.php b/src/utils/ticket/JiraTicketStatusFetcher.php index b1e9851..3cdd5e0 100644 --- a/src/utils/ticket/JiraTicketStatusFetcher.php +++ b/src/utils/ticket/JiraTicketStatusFetcher.php @@ -4,6 +4,7 @@ use RuntimeException; use staabm\PHPStanTodoBy\utils\CredentialsHelper; +use staabm\PHPStanTodoBy\utils\HttpClient; use function array_key_exists; use function is_array; @@ -21,7 +22,9 @@ final class JiraTicketStatusFetcher implements TicketStatusFetcher */ private array $cache; - public function __construct(string $host, ?string $credentials, ?string $credentialsFilePath) + private HttpClient $httpClient; + + public function __construct(string $host, ?string $credentials, ?string $credentialsFilePath, HttpClient $httpClient) { $credentials = CredentialsHelper::getCredentials($credentials, $credentialsFilePath); @@ -29,6 +32,7 @@ public function __construct(string $host, ?string $credentials, ?string $credent $this->authorizationHeader = $credentials ? self::createAuthorizationHeader($credentials) : null; $this->cache = []; + $this->httpClient = $httpClient; } public function fetchTicketStatus(string $ticketKey): ?string @@ -40,32 +44,23 @@ public function fetchTicketStatus(string $ticketKey): ?string $apiVersion = self::API_VERSION; $url = "{$this->host}/rest/api/$apiVersion/issue/$ticketKey?expand=status"; - $curl = curl_init($url); - if (!$curl) { - throw new RuntimeException('Could not initialize cURL connection'); - } - - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - + $headers = []; if (null !== $this->authorizationHeader) { - curl_setopt($curl, CURLOPT_HTTPHEADER, [ + $headers = [ "Authorization: $this->authorizationHeader", - ]); + ]; } - $response = curl_exec($curl); + [$responseCode, $response] = $this->httpClient->get($url, $headers); - if (404 === $responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE)) { + if (404 === $responseCode) { return null; } - if (!is_string($response) || 200 !== $responseCode) { + if (200 !== $responseCode) { throw new RuntimeException("Could not fetch ticket's status from Jira with url $url"); } - curl_close($curl); - $data = self::decodeAndValidateResponse($response); return $this->cache[$ticketKey] = $data['fields']['status']['name'];