diff --git a/README.md b/README.md index ef25050..795c3f9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,37 @@ # PHP IBM Watson API Bridge +[![Build Status](https://travis-ci.org/findbrok/php-watson-api-bridge.svg?branch=master)](https://travis-ci.org/findbrok/php-watson-api-bridge) + A simple PHP wrapper for IBM Watson API + +### Installation + +``` +composer require findbrok/php-watson-api-bridge +``` + +### Usage + +Before using the package checkout [Watson API Explorer](https://watson-api-explorer.mybluemix.net/), +to get a sense of what you can and cannot do with Watson + +```php +require 'vendor/autoload.php' + +use FindBrok\WatsonBridge\Bridge; + +//Create a new bridge Object +$bridge = new Bridge('username', 'password', 'baseUrl'); + +//Simple get request +$queryParams = ['foo' => 'bar']; +$response = $bridge->get('uri', $queryParams); + +//Simple post request +$dataToPost = ['foo' => 'bar']; +$response = $bridge->post('uri', $dataToPost, 'json'); +``` + +The Package uses [Guzzle](http://docs.guzzlephp.org/en/latest/testing.html) to perform requests, +all your responses will be instances of ```GuzzleHttp\Psr7\Response``` + diff --git a/composer.json b/composer.json index 2c355a5..9d98427 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ ], "require": { "php": ">=5.5.0", - "guzzlehttp/guzzle": "~5.3|~6.0|~6.2" + "guzzlehttp/guzzle": "~5.3|~6.0|~6.2", + "illuminate/support": "~5.0|~5.1|~5.2" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/src/Bridge.php b/src/Bridge.php index b03ac32..56d8099 100644 --- a/src/Bridge.php +++ b/src/Bridge.php @@ -2,8 +2,9 @@ namespace FindBrok\WatsonBridge; +use FindBrok\WatsonBridge\Exceptions\WatsonBridgeException; use GuzzleHttp\Client; -use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Exception\ClientException; /** * Class Bridge @@ -41,11 +42,14 @@ class Bridge protected $client; /** - * The request object + * Default headers * - * @var \GuzzleHttp\Psr7\Request + * @var array */ - protected $request; + protected $headers = [ + 'Accept' => 'application/json', + 'X-Watson-Learning-Opt-Out' => false + ]; /** * Create a new instance of bridge @@ -72,9 +76,35 @@ public function __construct($username = null, $password = null, $endpoint = null public function getAuth() { //Return access authorization - return [ - 'auth' => [$this->username, $this->password] - ]; + return [$this->username, $this->password]; + } + + /** + * Appends headers to the request + * + * @param array $headers + * @return self + */ + public function appendHeaders($headers = []) + { + //We have some headers to append + if (! empty($headers)) { + //Append headers + $this->headers = collect($this->headers)->merge($headers)->all(); + } + //Return calling object + return $this; + } + + /** + * Return the headers used for making request + * + * @return array + */ + public function getHeaders() + { + //Return headers + return $this->headers; } /** @@ -100,4 +130,150 @@ public function getClient() //Return client return $this->client; } + + /** + * Clean options by removing empty items + * + * @param array $options + * @return array + */ + public function cleanOptions($options = []) + { + //If item is null or empty we will remove them + return collect($options)->reject(function ($item) { + return (empty($item) || is_null($item)); + })->all(); + } + + /** + * Failed Request to Watson + * + * @param \GuzzleHttp\Psr7\Response $response + * @throws WatsonBridgeException + */ + public function failedRequest($response) + { + //Decode Response + $decodedResponse = json_decode($response->getBody()->getContents(), true); + //Get error message + $errorMessage = (isset($decodedResponse['error_message']) && ! is_null($decodedResponse['error_message'])) ? + $decodedResponse['error_message'] : + $response->getReasonPhrase(); + //ClientException + throw new WatsonBridgeException($errorMessage, $response->getStatusCode()); + } + + /** + * Make a Request to Watson + * + * @param string $method + * @param string $uri + * @param array $options + * @return \GuzzleHttp\Psr7\Response + */ + public function request($method = 'GET', $uri = '', $options = []) + { + try { + //Make the request + return $this->getClient()->request($method, $uri, $options); + } catch (ClientException $e) { + //Call Failed Request + $this->failedRequest($e->getResponse()); + } + } + + /** + * Send a Request to Watson + * + * @param string $method + * @param string $uri + * @param mixed $data + * @param string $type + * @return \GuzzleHttp\Psr7\Response + */ + private function send($method = 'POST', $uri, $data, $type = 'json') + { + //Make a Post Request + $response = $this->request($method, $uri, $this->cleanOptions([ + 'headers' => $this->getHeaders(), + 'auth' => $this->getAuth(), + $type => $data + ])); + //Request Failed + if ($response->getStatusCode() != 200) { + //Throw Watson Bridge Exception + $this->failedRequest($response); + } + //We return response + return $response; + } + + /** + * Make a GET Request to Watson + * + * @param string $uri + * @param array $query + * @return \GuzzleHttp\Psr7\Response + */ + public function get($uri = '', $query = []) + { + //Make a Post and return response + return $this->send('GET', $uri, $query, 'query'); + } + + /** + * Make a POST Request to Watson + * + * @param string $uri + * @param mixed $data + * @param string $type + * @return \GuzzleHttp\Psr7\Response + */ + public function post($uri = '', $data, $type = 'json') + { + //Make a Post and return response + return $this->send('POST', $uri, $data, $type); + } + + /** + * Make a PUT Request to Watson + * + * @param string $uri + * @param $data + * @param string $type + * @return \GuzzleHttp\Psr7\Response + */ + public function put($uri = '', $data, $type = 'json') + { + //Make a Put and return response + return $this->send('PUT', $uri, $data, $type); + } + + /** + * Make a PATCH Request to Watson + * + * @param string $uri + * @param $data + * @param string $type + * @return \GuzzleHttp\Psr7\Response + */ + public function patch($uri = '', $data, $type = 'json') + { + //Make a Patch and return response + return $this->send('PATCH', $uri, $data, $type); + } + + /** + * Make a DELETE Request to Watson + * + * @param string $uri + * @param $data + * @param string $type + * @return \GuzzleHttp\Psr7\Response + */ + public function delete($uri = '', $data, $type = 'json') + { + //Make a Delete and return response + return $this->send('DELETE', $uri, $data, $type); + } } diff --git a/src/Exceptions/WatsonBridgeException.php b/src/Exceptions/WatsonBridgeException.php new file mode 100644 index 0000000..90e6339 --- /dev/null +++ b/src/Exceptions/WatsonBridgeException.php @@ -0,0 +1,36 @@ +message); + //Call parent exception + parent::__construct($message, $code, $previous); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index b4054fc..bf83f70 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,9 +1,74 @@ bridge = $this->getMockBuilder('FindBrok\WatsonBridge\Bridge') + ->disableOriginalConstructor() + ->setMethods(['getClient']) + ->getMock(); + } + + /** + * Test a Successful Get request + */ + public function testGetRequestResponseOk() + { + // Create a mock and queue one response + $mock = new MockHandler([ + new Response(200, ['X-Foo' => 'Bar']), + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + + $this->bridge->method('getClient')->willReturn($client); + + $this->assertEquals(200, $this->bridge->get('version/watson-api-method', ['foo' => 'bar'])->getStatusCode()); + } + + /** + * Test a Get request which fails + * + * @expectedException \FindBrok\WatsonBridge\Exceptions\WatsonBridgeException + */ + public function testGetRequestWithException() + { + // Create a mock and queue one response + $mock = new MockHandler([ + new ClientException( + 'Watson Error', + new Request('GET', 'version/watson-api-method'), + new Response(400, ['X-Foo' => 'Bar'], collect(['error_code' => 400, 'error_message' => 'Watson Error'])->toJson()) + ) + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + + $this->bridge->method('getClient')->willReturn($client); + + $this->bridge->get('version/watson-api-method', ['foo' => 'bar']); + $this->setExpectedException('\FindBrok\WatsonBridge\Exceptions\WatsonBridgeException'); + } }