diff --git a/composer.json b/composer.json index 7012f3c4..2a4c507f 100644 --- a/composer.json +++ b/composer.json @@ -53,6 +53,7 @@ "robmorgan/phinx": "0.8.*", "sensiolabs/ansi-to-html": "1.1.*", "pda/pheanstalk": "3.1.*", + "guzzlehttp/guzzle": "6.2.*", "phpunit/phpunit": "5.7.*", "codeception/codeception": "2.3.*", diff --git a/composer.lock b/composer.lock index 9a62f591..7c57dbd9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "cc097eb87d629ed226ac663ef5d8d842", + "content-hash": "42e176c39d818de34429d349a616831e", "packages": [ { "name": "behat/gherkin", @@ -171,12 +171,12 @@ "version": "2.0.1.0", "source": { "type": "git", - "url": "https://github.com/driftyco/ionicons.git", + "url": "https://github.com/ionic-team/ionicons.git", "reference": "ecb4b806831005c25b97ed9089fbb1d7dcc0879c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/driftyco/ionicons/zipball/ecb4b806831005c25b97ed9089fbb1d7dcc0879c", + "url": "https://api.github.com/repos/ionic-team/ionicons/zipball/ecb4b806831005c25b97ed9089fbb1d7dcc0879c", "reference": "ecb4b806831005c25b97ed9089fbb1d7dcc0879c", "shasum": null }, @@ -187,7 +187,7 @@ "version": "2.2.7.0", "source": { "type": "git", - "url": "https://github.com/DmitryBaranovskiy/raphael.git", + "url": "git@github.com:DmitryBaranovskiy/raphael.git", "reference": "c02b9c125d036e42b9bb95d0e401bbf6a5153da5" }, "dist": { @@ -1931,12 +1931,12 @@ "version": "v0.8.1", "source": { "type": "git", - "url": "https://github.com/robmorgan/phinx.git", + "url": "https://github.com/cakephp/phinx.git", "reference": "7a19de5bebc59321edd9613bc2a667e7f96224ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/robmorgan/phinx/zipball/7a19de5bebc59321edd9613bc2a667e7f96224ec", + "url": "https://api.github.com/repos/cakephp/phinx/zipball/7a19de5bebc59321edd9613bc2a667e7f96224ec", "reference": "7a19de5bebc59321edd9613bc2a667e7f96224ec", "shasum": "" }, diff --git a/src/B8Framework/HttpClient.php b/src/B8Framework/HttpClient.php deleted file mode 100644 index 19decf68..00000000 --- a/src/B8Framework/HttpClient.php +++ /dev/null @@ -1,167 +0,0 @@ -get('b8.http.client', ['base_url' => '', 'params' => []]); - $this->_base = $settings['base_url']; - $this->_params = isset($settings['params']) && is_array($settings['params']) ? $settings['params'] : []; - $this->_headers = ['Content-Type: application/x-www-form-urlencoded']; - - if (!is_null($base)) { - $this->_base = $base; - } - } - - public function setHeaders(array $headers) - { - $this->_headers = $headers; - } - - public function request($method, $uri, $params = []) - { - // Clean incoming: - $method = strtoupper($method); - $getParams = $this->_params; - - if ($method == 'GET' || $method == 'DELETE') { - $getParams = array_merge($getParams, $params); - } else { - $bodyParams = is_array($params) ? http_build_query($params) : $params; - } - - $getParams = http_build_query($getParams); - - if (substr($uri, 0, 1) != '/' && !empty($this->_base)) { - $uri = '/' . $uri; - } - - // Build HTTP context array: - $context = []; - $context['http']['user_agent'] = 'b8/1.0'; - $context['http']['timeout'] = 30; - $context['http']['method'] = $method; - $context['http']['ignore_errors'] = true; - $context['http']['header'] = implode(PHP_EOL, $this->_headers); - - if (in_array($method, ['PUT', 'POST'])) { - $context['http']['content'] = $bodyParams; - } - - $uri .= '?' . $getParams; - - $context = stream_context_create($context); - $result = file_get_contents($this->_base . $uri, false, $context); - - $res = []; - $res['headers'] = $http_response_header; - $res['code'] = (int)preg_replace('/HTTP\/1\.[0-1] ([0-9]+)/', '$1', $res['headers'][0]); - $res['success'] = false; - $res['body'] = $this->decodeResponse($result); - - if ($res['code'] >= 200 && $res['code'] < 300) { - $res['success'] = true; - } - - // Handle JSON responses: - foreach ($res['headers'] as $header) { - if (stripos($header, 'Content-Type') !== false || stripos($header, 'b8-Type') !== false) { - if (stripos($header, 'application/json') !== false) { - $res['text_body'] = $res['body']; - $res['body'] = json_decode($res['body'], true); - } - } - } - - return $res; - } - - public function get($uri, $params = []) - { - return $this->request('GET', $uri, $params); - } - - public function put($uri, $params = []) - { - return $this->request('PUT', $uri, $params); - } - - public function post($uri, $params = []) - { - return $this->request('POST', $uri, $params); - } - - public function delete($uri, $params = []) - { - return $this->request('DELETE', $uri, $params); - } - - protected function decodeResponse($originalResponse) - { - $response = $originalResponse; - $body = ''; - - do { - $line = $this->readChunk($response); - - if ($line == PHP_EOL) { - continue; - } - - $length = hexdec(trim($line)); - - if (!is_int($length) || empty($response) || $line === false || $length < 1) { - break; - } - - do { - $data = $this->readChunk($response, $length); - - // remove the amount received from the total length on the next loop - // it'll attempt to read that much less data - $length -= strlen($data); - - // store in string for later use - $body .= $data; - - // zero or less or end of connection break - if ($length <= 0 || empty($response)) { - break; - } - } while (true); - } while (true); - - if (empty($body)) { - $body = $originalResponse; - } - - return $body; - } - - protected function readChunk(&$string, $len = 4096) - { - $rtn = ''; - for ($i = 0; $i <= $len; $i++) { - if (empty($string)) { - break; - } - - $char = $string[0]; - $string = substr($string, 1); - $rtn .= $char; - - if ($char == PHP_EOL) { - break; - } - } - - return $rtn; - } -} diff --git a/src/PHPCensor/Controller/WebhookController.php b/src/PHPCensor/Controller/WebhookController.php index 001af4cb..d2603a0b 100644 --- a/src/PHPCensor/Controller/WebhookController.php +++ b/src/PHPCensor/Controller/WebhookController.php @@ -5,6 +5,7 @@ namespace PHPCensor\Controller; use b8; use b8\Store; use Exception; +use GuzzleHttp\Client; use PHPCensor\Helper\Lang; use PHPCensor\Model\Build; use PHPCensor\Model\Project; @@ -13,7 +14,6 @@ use PHPCensor\Store\BuildStore; use PHPCensor\Store\ProjectStore; use b8\Controller; use b8\Config; -use b8\HttpClient; use b8\Exception\HttpException\NotFoundException; /** @@ -299,29 +299,34 @@ class WebhookController extends Controller $token = Config::getInstance()->get('php-censor.github.token'); if (!empty($token)) { - $headers[] = 'Authorization: token ' . $token; + $headers['Authorization'] = 'token ' . $token; } - $url = $payload['pull_request']['commits_url']; - $http = new HttpClient(); - $http->setHeaders($headers); + $url = $payload['pull_request']['commits_url']; //for large pull requests, allow grabbing more then the default number of commits $custom_per_page = Config::getInstance()->get('php-censor.github.per_page'); $params = []; if ($custom_per_page) { - $params["per_page"] = $custom_per_page; + $params['per_page'] = $custom_per_page; } - $response = $http->get($url, $params); + + $client = new Client(); + $response = $client->get($url, [ + 'headers' => $headers, + 'query' => $params, + ]); + $status = (integer)$response->getStatusCode(); // Check we got a success response: - if (!$response['success']) { + if ($status < 200 || $status >= 300) { throw new Exception('Could not get commits, failed API request.'); } $results = []; $status = 'failed'; - foreach ($response['body'] as $commit) { + $commits = json_decode($response->getBody(), true); + foreach ($commits as $commit) { // Skip all but the current HEAD commit ID: $id = $commit['sha']; if ($id != $payload['pull_request']['head']['sha']) { diff --git a/src/PHPCensor/Helper/Github.php b/src/PHPCensor/Helper/Github.php index 6ed33398..3e19b848 100644 --- a/src/PHPCensor/Helper/Github.php +++ b/src/PHPCensor/Helper/Github.php @@ -4,27 +4,13 @@ namespace PHPCensor\Helper; use b8\Cache; use b8\Config; -use b8\HttpClient; +use GuzzleHttp\Client; /** * The Github Helper class provides some Github API call functionality. */ class Github { - /** - * Make a request to the Github API. - * @param $url - * @param $params - * @return mixed - */ - public function makeRequest($url, $params) - { - $http = new HttpClient('https://api.github.com'); - $res = $http->get($url, $params); - - return $res['body']; - } - /** * Make all GitHub requests following the Link HTTP headers. * @@ -36,15 +22,23 @@ class Github */ public function makeRecursiveRequest($url, $params, $results = []) { - $http = new HttpClient('https://api.github.com'); - $res = $http->get($url, $params); - - foreach ($res['body'] as $item) { + $client = new Client(); + $response = $client->get(('https://api.github.com' . $url), [ + 'query' => $params, + ]); + + $body = json_decode($response->getBody(), true); + $headers = $response->getHeaders(); + + foreach ($body as $item) { $results[] = $item; } - foreach ($res['headers'] as $header) { - if (preg_match('/^Link: <([^>]+)>; rel="next"/', $header, $r)) { + foreach ($headers as $header_name => $header) { + if ( + 'Link' === $header_name && + preg_match('/^<([^>]+)>; rel="next"/', implode(', ', $header), $r) + ) { $host = parse_url($r[1]); parse_str($host['query'], $params); @@ -65,21 +59,28 @@ class Github $token = Config::getInstance()->get('php-censor.github.token'); if (!$token) { - return null; + return []; } $cache = Cache::getCache(Cache::TYPE_APC); - $rtn = $cache->get('php-censor-github-repos'); + $rtn = $cache->get('php-censor-github-repos'); if (!$rtn) { - $orgs = $this->makeRequest('/user/orgs', ['access_token' => $token]); + $client = new Client(); + $response = $client->get('https://api.github.com/user/orgs', [ + 'query' => [ + 'access_token' => $token + ], + ]); + + $orgs = json_decode($response->getBody(), true); $params = ['type' => 'all', 'access_token' => $token]; $repos = ['user' => []]; $repos['user'] = $this->makeRecursiveRequest('/user/repos', $params); foreach ($orgs as $org) { - $repos[$org['login']] = $this->makeRecursiveRequest('/orgs/'.$org['login'].'/repos', $params); + $repos[$org['login']] = $this->makeRecursiveRequest('/orgs/' . $org['login'] . '/repos', $params); } $rtn = []; @@ -122,13 +123,14 @@ class Github 'position' => $line, ]; - $http = new HttpClient('https://api.github.com'); - $http->setHeaders([ - 'Content-Type: application/x-www-form-urlencoded', - 'Authorization: Basic ' . base64_encode($token . ':x-oauth-basic'), + $client = new Client(); + $client->post(('https://api.github.com' . $url), [ + 'headers' => [ + 'Authorization' => 'Basic ' . base64_encode($token . ':x-oauth-basic'), + 'Content-Type' => 'application/x-www-form-urlencoded' + ], + 'json' => $params, ]); - - $http->post($url, json_encode($params)); } /** @@ -156,12 +158,13 @@ class Github 'position' => $line, ]; - $http = new HttpClient('https://api.github.com'); - $http->setHeaders([ - 'Content-Type: application/x-www-form-urlencoded', - 'Authorization: Basic ' . base64_encode($token . ':x-oauth-basic'), + $client = new Client(); + $client->post(('https://api.github.com' . $url), [ + 'headers' => [ + 'Authorization' => 'Basic ' . base64_encode($token . ':x-oauth-basic'), + 'Content-Type' => 'application/x-www-form-urlencoded' + ], + 'json' => $params, ]); - - $http->post($url, json_encode($params)); } } diff --git a/src/PHPCensor/Model/Build/GithubBuild.php b/src/PHPCensor/Model/Build/GithubBuild.php index ae020eba..c3fd11cf 100644 --- a/src/PHPCensor/Model/Build/GithubBuild.php +++ b/src/PHPCensor/Model/Build/GithubBuild.php @@ -2,11 +2,11 @@ namespace PHPCensor\Model\Build; +use GuzzleHttp\Client; use PHPCensor\Builder; use PHPCensor\Helper\Diff; use PHPCensor\Helper\Github; use b8\Config; -use b8\HttpClient; use PHPCensor\Model\BuildError; /** @@ -57,9 +57,6 @@ class GithubBuild extends RemoteGitBuild return; } - $url = 'https://api.github.com/repos/'.$project->getReference().'/statuses/'.$this->getCommitId(); - $http = new HttpClient(); - switch ($this->getStatus()) { case 0: case 1: @@ -82,20 +79,20 @@ class GithubBuild extends RemoteGitBuild $phpCensorUrl = Config::getInstance()->get('php-censor.url'); - $params = [ - 'state' => $status, - 'target_url' => $phpCensorUrl . '/build/view/' . $this->getId(), - 'description' => $description, - 'context' => 'PHP Censor', - ]; - - $headers = [ - 'Authorization: token ' . $token, - 'Content-Type: application/x-www-form-urlencoded' - ]; - - $http->setHeaders($headers); - $http->request('POST', $url, json_encode($params)); + $url = 'https://api.github.com/repos/' . $project->getReference() . '/statuses/' . $this->getCommitId(); + $client = new Client(); + $client->post($url, [ + 'headers' => [ + 'Authorization' => 'token ' . $token, + 'Content-Type' => 'application/x-www-form-urlencoded' + ], + 'json' => [ + 'state' => $status, + 'target_url' => $phpCensorUrl . '/build/view/' . $this->getId(), + 'description' => $description, + 'context' => 'PHP Censor', + ] + ]); } /** diff --git a/src/PHPCensor/Plugin/Deployer.php b/src/PHPCensor/Plugin/Deployer.php index e03c4ae4..c18fd735 100644 --- a/src/PHPCensor/Plugin/Deployer.php +++ b/src/PHPCensor/Plugin/Deployer.php @@ -2,7 +2,7 @@ namespace PHPCensor\Plugin; -use b8\HttpClient; +use GuzzleHttp\Client; use PHPCensor\Builder; use PHPCensor\Model\Build; use PHPCensor\Plugin; @@ -55,17 +55,27 @@ class Deployer extends Plugin return false; } - $http = new HttpClient(); - - $response = $http->post($this->webhookUrl, [ - 'reason' => $this->builder->interpolate($this->reason), - 'source' => 'PHP Censor', - 'url' => $this->builder->interpolate('%BUILD_URI%'), - 'branch' => $this->builder->interpolate('%BRANCH%'), - 'commit' => $this->builder->interpolate('%COMMIT%'), - 'update_only' => $this->updateOnly, - ]); - - return $response['success']; + $client = new Client(); + $response = $client->post( + $this->webhookUrl, + [ + 'form_params' => [ + 'reason' => $this->builder->interpolate($this->reason), + 'source' => 'PHP Censor', + 'url' => $this->builder->interpolate('%BUILD_URI%'), + 'branch' => $this->builder->interpolate('%BRANCH%'), + 'commit' => $this->builder->interpolate('%COMMIT%'), + 'update_only' => $this->updateOnly, + ] + ] + ); + + $status = (integer)$response->getStatusCode(); + + return ( + ($status >= 200 && $status < 300) + ? true + : false + ); } } diff --git a/tests/B8Framework/HttpClientTest.php b/tests/B8Framework/HttpClientTest.php deleted file mode 100755 index ec7d3c8a..00000000 --- a/tests/B8Framework/HttpClientTest.php +++ /dev/null @@ -1,64 +0,0 @@ -request('GET', 'https://www.google.com'); - - $this->assertContains('Google', $html['body']); - } - - public function testBaseUrl() - { - $http = new HttpClient('https://www.google.com'); - $html = $http->request('GET', '/'); - - $this->assertContains('Google', $html['body']); - } - - public function testGet() - { - $http = new HttpClient('https://www.google.com'); - $html = $http->get('overview', ['x' => 1]); - - $this->assertContains('Google', $html['body']); - } - - public function testGetJson() - { - $http = new HttpClient('http://echo.jsontest.com'); - $data = $http->get('/key/value'); - - $this->assertArrayHasKey('key', $data['body']); - } - - public function testPost() - { - $http = new HttpClient('http://echo.jsontest.com'); - $data = $http->post('/key/value', ['test' => 'x']); - - $this->assertTrue(is_array($data)); - } - - public function testPut() - { - $http = new HttpClient('http://echo.jsontest.com'); - $data = $http->put('/key/value', ['test' => 'x']); - - $this->assertTrue(is_array($data)); - } - - public function testDelete() - { - $http = new HttpClient('http://echo.jsontest.com'); - $data = $http->delete('/key/value', ['test' => 'x']); - - $this->assertTrue(is_array($data)); - } -} \ No newline at end of file