diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..27645834 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.0.13-dev diff --git a/composer.json b/composer.json index 623ad5c2..6e268f92 100644 --- a/composer.json +++ b/composer.json @@ -48,6 +48,9 @@ "@cs", "@stan" ], + "release": [ + "release VERSION" + ], "coveralls": "php ./vendor/bin/php-coveralls -v" } } diff --git a/src/Connector/Client.php b/src/Connector/Client.php index 25860e60..bf795d4f 100644 --- a/src/Connector/Client.php +++ b/src/Connector/Client.php @@ -40,7 +40,7 @@ public function __construct(ConnectorInterface $connector) } /** - * Client factory method for instantiating . + * Client factory method for instantiating. * * @param ConnectorInterface $connector * @@ -56,20 +56,64 @@ public static function factory(ConnectorInterface $connector) } /** - * @inheritdoc + * Returns the current version of the library. + * + * @return string + * @throws \Exception */ - public function request(string $verb, string $path, array $options = []) + public function getVersion() { - // @TODO follow this up by removing $options from the parameters able - // to be passed into this function and instead solely relying on the - // addOption() method as this can then be tested. + if ($file = @file_get_contents(dirname(dirname(__DIR__)) . '/VERSION')) { + return trim($file); + } else { + throw new \Exception('No VERSION file'); + } + } + + /** + * Allows the library to modify the request prior to making the call to the API. + */ + public function modifyOptions($options = []): array + { + // Add the user agent header here so it can't be removed by other libraries. + $this->addOption('headers', [ + 'User-Agent' => sprintf( + "%s/%s (https://github.com/typhonius/acquia-php-sdk-v2)", + 'acquia-php-sdk-v2', + $this->getVersion() + ) + ]); + + // Combine options set globally e.g. headers with options set by individual API calls e.g. form_params. $options = $this->options + $options; - $options['query'] = $this->query; + // This library can be standalone or as a dependency. Dependent libraries may also set their own user agent + // which will make $options['headers']['User-Agent'] an array. + // We need to reverse the array of User-Agent headers to order this library's header first in log files. + // As Guzzle joins arrays with a comma, we must implode with a space here to pass Guzzle a string. + if (is_array($options['headers']['User-Agent'])) { + $options['headers']['User-Agent'] = implode(' ', array_reverse($options['headers']['User-Agent'])); + } + + $options['query'] = $this->query; if (!empty($options['query']['filter']) && is_array($options['query']['filter'])) { // Default to an AND filter. $options['query']['filter'] = implode(',', $options['query']['filter']); } + + return $options; + } + + /** + * @inheritdoc + */ + public function request(string $verb, string $path, array $options = []) + { + // @TODO follow this up by removing $options from the parameters able + // to be passed into this function and instead solely relying on the + // addOption() method as this can then be tested. + $options = $this->modifyOptions($options); + $response = $this->makeRequest($verb, $path, $options); return $this->processResponse($response); @@ -78,7 +122,7 @@ public function request(string $verb, string $path, array $options = []) /** * @inheritdoc */ - public function makeRequest(string $verb, string $path, array $options = []) + public function makeRequest(string $verb, string $path, array $options = []): ResponseInterface { try { $response = $this->connector->sendRequest($verb, $path, $options); @@ -116,7 +160,7 @@ public function processResponse(ResponseInterface $response) /** * @inheritdoc */ - public function getQuery() + public function getQuery(): array { return $this->query; } @@ -124,7 +168,7 @@ public function getQuery() /** * @inheritdoc */ - public function clearQuery() + public function clearQuery(): void { $this->query = []; } @@ -132,7 +176,7 @@ public function clearQuery() /** * @inheritdoc */ - public function addQuery($name, $value) + public function addQuery($name, $value): void { $this->query = array_merge_recursive($this->query, [$name => $value]); } @@ -140,7 +184,7 @@ public function addQuery($name, $value) /** * @inheritdoc */ - public function getOptions() + public function getOptions(): array { return $this->options; } @@ -148,7 +192,7 @@ public function getOptions() /** * @inheritdoc */ - public function clearOptions() + public function clearOptions(): void { $this->options = []; } @@ -156,7 +200,7 @@ public function clearOptions() /** * @inheritdoc */ - public function addOption($name, $value) + public function addOption($name, $value): void { $this->options = array_merge_recursive($this->options, [$name => $value]); } diff --git a/tests/Endpoints/ClientTest.php b/tests/Endpoints/ClientTest.php index 062a2a4d..15148d20 100644 --- a/tests/Endpoints/ClientTest.php +++ b/tests/Endpoints/ClientTest.php @@ -75,4 +75,70 @@ public function testOptions() $client->clearOptions(); $this->assertTrue(empty($client->getOptions())); } + + public function testModifyOptions() + { + $client = $this->getMockClient(); + + // Set a number of options and queries as a dependent library would. + $client->addOption('headers', ['User-Agent' => 'AcquiaCli/4.20']); + $client->addQuery('filter', 'name=@*2014*'); + $client->addQuery('filter', 'type=@*true*'); + $client->addQuery('limit', '1'); + + // Set options as an endpoint call would. + $options = [ + 'form_params' => [ + 'source' => 'source', + 'message' => 'message', + ], + ]; + + // Modify the request to ensure that all of the above get merged correctly. + $actualOptions = $client->modifyOptions($options); + + $version = $client->getVersion(); + $expectedOptions = [ + 'headers' => [ + 'User-Agent' => sprintf('acquia-php-sdk-v2/%s (https://github.com/typhonius/acquia-php-sdk-v2) AcquiaCli/4.20', $version) + ], + 'form_params' => [ + 'source' => 'source', + 'message' => 'message' + ], + 'query' => [ + 'filter' => 'name=@*2014*,type=@*true*', + 'limit' => '1' + ] + ]; + + $this->assertEquals($expectedOptions, $actualOptions); + } + + public function testVersion() + { + $versionFile = sprintf('%s/VERSION', dirname(dirname(__DIR__))); + $version = trim(file_get_contents($versionFile)); + + $client = $this->getMockClient(); + $actualValue = $client->getVersion(); + + $this->assertEquals($version, $actualValue); + } + + public function testMissingVersion() + { + $versionFile = sprintf('%s/VERSION', dirname(dirname(__DIR__))); + $versionFileBak = sprintf('%s.bak', $versionFile); + rename($versionFile, $versionFileBak); + + try { + $client = $this->getMockClient(); + $version = $client->getVersion(); + } catch (\Exception $e) { + $this->assertEquals('Exception', get_class($e)); + $this->assertEquals('No VERSION file', $e->getMessage()); + } + rename($versionFileBak, $versionFile); + } }