diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3a06f..808a237 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,16 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 1.2.1 - TBD +## 1.2.1 - 2018-02-05 ### Added -- Nothing. +- [#19](https://github.com/zfcampus/zf-versioning/pull/19) adds the ability to + override the `default_version` setting to specify default versions by route + name. As such, the `default_version` value may be one of the following: + + - An integer value, indicating the default version for all APIs. + - An associative array of route name keys pointing to their specific default version. ### Deprecated @@ -18,7 +23,9 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#19](https://github.com/zfcampus/zf-versioning/pull/19) fixes a problem with + how the `PrototypeRouteListener` handles the `default_version` setting; the + value was overriding route-specific defaults. ## 1.2.0 - 2016-07-13 diff --git a/README.md b/README.md index effad1b..8a0b3f5 100644 --- a/README.md +++ b/README.md @@ -97,11 +97,29 @@ would look like: The `default_version` key provides the default version number to use in case a version is not provided by the client. `1` is the default for `default_version`. +The setting accepts one of the two following possible values: + +- A PHP `integer` indicating the default version number for *all* routes. +- An associative array, where the keys are route names, and the values the default version to use with the associated route. + Full Example: ```php +// Set v2 as default version for all routes 'zf-versioning' => [ - 'default_version' => 1, + 'default_version' => 2, +], +``` + +or + +```php +// Set default version to v2 and v3 for the users and status routes respectively +'zf-versioning' => [ + 'default_version' => [ + 'myapi.rest.users' => 2, + 'myapi.rpc.status' => 3, + ], ], ``` diff --git a/src/PrototypeRouteListener.php b/src/PrototypeRouteListener.php index a7d1d98..8aa5c21 100644 --- a/src/PrototypeRouteListener.php +++ b/src/PrototypeRouteListener.php @@ -83,7 +83,9 @@ public function onMergeConfig(ModuleEvent $e) } // Override default version of 1 with user-specified config value, if available. - if (isset($config['zf-versioning']['default_version'])) { + if (isset($config['zf-versioning']['default_version']) + && is_scalar($config['zf-versioning']['default_version']) + ) { $this->versionRouteOptions['defaults']['version'] = $config['zf-versioning']['default_version']; } @@ -117,9 +119,14 @@ public function onMergeConfig(ModuleEvent $e) . $config['router']['routes'][$routeName]['options']['route']; } + $routeVersion = $this->versionRouteOptions; + if (isset($config['zf-versioning']['default_version'][$routeName])) { + $routeVersion['defaults']['version'] = $config['zf-versioning']['default_version'][$routeName]; + } + $config['router']['routes'][$routeName]['options'] = ArrayUtils::merge( $config['router']['routes'][$routeName]['options'], - $this->versionRouteOptions + $routeVersion ); } diff --git a/test/PrototypeRouteListenerTest.php b/test/PrototypeRouteListenerTest.php index d99b7f3..95c4a7f 100644 --- a/test/PrototypeRouteListenerTest.php +++ b/test/PrototypeRouteListenerTest.php @@ -15,37 +15,39 @@ class PrototypeRouteListenerTest extends TestCase { public function setUp() { - $this->config = ['router' => [ - 'routes' => [ - 'status' => [ - 'type' => 'Segment', - 'options' => [ - 'route' => '/status[/:id]', - 'defaults' => [ - 'controller' => 'StatusController', + $this->config = [ + 'router' => [ + 'routes' => [ + 'status' => [ + 'type' => 'Segment', + 'options' => [ + 'route' => '/status[/:id]', + 'defaults' => [ + 'controller' => 'StatusController', + ], ], ], - ], - 'user' => [ - 'type' => 'Segment', - 'options' => [ - 'route' => '/user[/:id]', - 'defaults' => [ - 'controller' => 'UserController', + 'user' => [ + 'type' => 'Segment', + 'options' => [ + 'route' => '/user[/:id]', + 'defaults' => [ + 'controller' => 'UserController', + ], ], ], - ], - 'group' => [ - 'type' => 'Segment', - 'options' => [ - 'route' => '/group[/v:version][/:id]', - 'defaults' => [ - 'controller' => 'GroupController', + 'group' => [ + 'type' => 'Segment', + 'options' => [ + 'route' => '/group[/v:version][/:id]', + 'defaults' => [ + 'controller' => 'GroupController', + ], ], ], ], ], - ]]; + ]; $this->configListener = new ConfigListener(); $this->configListener->setMergedConfig($this->config); $this->event = new ModuleEvent(); @@ -136,4 +138,99 @@ public function testPrototypeAddedToRoutesProvidedToListener(array $routes, $api $this->assertEquals($apiVersion, $options['defaults']['version']); } } + + public function defaultVersionValues() + { + return [ + 'v1' => [1], + 'v2' => [2], + 'empty' => [null], + ]; + } + + /** + * @dataProvider defaultVersionValues + */ + public function testPrototypeAddedToRoutesWithDefaultVersion($apiVersion = null) + { + $routes = array_keys($this->config['router']['routes']); + $this->config['zf-versioning'] = [ + 'default_version' => $apiVersion, + 'uri' => $routes + ]; + + $this->configListener->setMergedConfig($this->config); + $listener = new PrototypeRouteListener(); + $listener->onMergeConfig($this->event); + + $config = $this->configListener->getMergedConfig(false); + $this->assertArrayHasKey('router', $config, var_export($config, 1)); + $routerConfig = $config['router']; + + $routesConfig = $routerConfig['routes']; + + foreach ($routes as $routeName) { + $this->assertArrayHasKey($routeName, $routesConfig); + $routeConfig = $routesConfig[$routeName]; + $this->assertArrayHasKey('options', $routeConfig); + $options = $routeConfig['options']; + + $this->assertArrayHasKey('constraints', $options); + $this->assertArrayHasKey('version', $options['constraints']); + $this->assertEquals('\d+', $options['constraints']['version']); + + $this->assertArrayHasKey('defaults', $options); + $this->assertArrayHasKey('version', $options['defaults']); + + $apiVersion = isset($apiVersion) ? $apiVersion : 1; + $this->assertEquals($apiVersion, $options['defaults']['version']); + } + } + + public function specificDefaultVersionForWhichToVerifyPrototype() + { + return [ + 'status' => [['status' => 2]], + 'user' => [['user' => 4]], + 'all-except-group' => [['status' => 2, 'user' => 3]], + ]; + } + + /** + * @dataProvider specificDefaultVersionForWhichToVerifyPrototype + */ + public function testPrototypeAddedToRoutesWithSpecificDefaultVersion(array $defaultVersions) + { + $routes = array_keys($this->config['router']['routes']); + $this->config['zf-versioning'] = [ + 'default_version' => $defaultVersions, + 'uri' => $routes + ]; + + $this->configListener->setMergedConfig($this->config); + $listener = new PrototypeRouteListener(); + $listener->onMergeConfig($this->event); + + $config = $this->configListener->getMergedConfig(false); + $this->assertArrayHasKey('router', $config, var_export($config, 1)); + $routerConfig = $config['router']; + + $routesConfig = $routerConfig['routes']; + + foreach ($routes as $routeName) { + $this->assertArrayHasKey($routeName, $routesConfig); + $routeConfig = $routesConfig[$routeName]; + $this->assertArrayHasKey('options', $routeConfig); + $options = $routeConfig['options']; + + $this->assertArrayHasKey('constraints', $options); + $this->assertArrayHasKey('version', $options['constraints']); + $this->assertEquals('\d+', $options['constraints']['version']); + + $this->assertArrayHasKey('defaults', $options); + $this->assertArrayHasKey('version', $options['defaults']); + $apiVersion = isset($defaultVersions[$routeName]) ? $defaultVersions[$routeName] : 1; + $this->assertEquals($apiVersion, $options['defaults']['version']); + } + } }