Skip to content
This repository has been archived by the owner on Jan 31, 2022. It is now read-only.

Commit

Permalink
Allow to pass options so that one can configure priorities
Browse files Browse the repository at this point in the history
Fix #1
  • Loading branch information
willdurand committed Oct 28, 2014
1 parent 5e35c15 commit d3e185e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 18 deletions.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,10 @@ Installation
The recommended way to install StackNegotiation is through
[Composer](http://getcomposer.org/):

``` json
{
"require": {
"willdurand/stack-negotiation": "@stable"
}
}
``` bash
$ composer require "willdurand/stack-negotiation"
```

**Protip:** you should browse the
[`willdurand/stack-negotiation`](https://packagist.org/packages/willdurand/stack-negotiation)
page to choose a stable version to use, avoid the `@stable` meta constraint.


Usage
-----
Expand Down Expand Up @@ -62,6 +54,16 @@ Body](http://silex.sensiolabs.org/doc/cookbook/json_request_body.html) and
[FOSRestBundle Body
Listener](https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/3-listener-support.md#body-listener).

### Options

You can pass an array of _options_ to the middleware:

```php
$app = new Negotiation($app, null, null, null, [
'language_priorities' => [ '... '],
'format_priorities' => [ '... '],
]);
```

Unit Tests
----------
Expand Down
29 changes: 23 additions & 6 deletions src/Negotiation/Stack/Negotiation.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,43 @@ class Negotiation implements HttpKernelInterface
*/
private $decoderProvider;

/**
* @var array
*/
private $defaultOptions = [
'format_priorities' => [],
'language_priorities' => [],
];

/**
* @var array
*/
private $options;

public function __construct(
HttpKernelInterface $app,
FormatNegotiatorInterface $formatNegotiator = null,
NegotiatorInterface $languageNegotiator = null,
DecoderProviderInterface $decoderProvider = null
NegotiatorInterface $languageNegotiator = null,
DecoderProviderInterface $decoderProvider = null,
array $options = []
) {
$this->app = $app;
$this->formatNegotiator = $formatNegotiator ?: new FormatNegotiator();
$this->formatNegotiator = $formatNegotiator ?: new FormatNegotiator();
$this->languageNegotiator = $languageNegotiator ?: new LanguageNegotiator();
$this->decoderProvider = $decoderProvider ?: new DecoderProvider([
$this->decoderProvider = $decoderProvider ?: new DecoderProvider([
'json' => new JsonEncoder(),
'xml' => new XmlEncoder(),
]);
$this->options = array_merge($this->defaultOptions, $options);
}

public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
// `Accept` header
if (null !== $accept = $request->headers->get('Accept')) {
$accept = $this->formatNegotiator->getBest($accept);
$priorities = $this->formatNegotiator->normalizePriorities($this->options['format_priorities']);
$accept = $this->formatNegotiator->getBest($accept, $priorities);

$request->attributes->set('_accept', $accept);

if (null !== $accept && !$accept->isMediaRange()) {
Expand All @@ -70,7 +87,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ

// `Accept-Language` header
if (null !== $accept = $request->headers->get('Accept-Language')) {
$accept = $this->languageNegotiator->getBest($accept);
$accept = $this->languageNegotiator->getBest($accept, $this->options['language_priorities']);
$request->attributes->set('_accept_language', $accept);

if (null !== $accept) {
Expand Down
41 changes: 39 additions & 2 deletions tests/Negotiation/Tests/Stack/NegotiationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ public function testAcceptHeader()
$this->assertEquals('json', $req->attributes->get('_format'));
}

public function testAcceptHeaderWithPriorities()
{
$app = $this->createStackedApp([], [ 'format_priorities' => [ 'json', 'xml' ] ]);
$req = $this->createRequest(null, [
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
]);

$app->handle($req);

$header = $req->attributes->get('_accept');
$this->assertInstanceOf('Negotiation\AcceptHeader', $header);
$this->assertEquals('application/xml', $header->getValue());
$this->assertEquals('application/xml', $req->attributes->get('_mime_type'));
$this->assertEquals('xml', $req->attributes->get('_format'));
}

public function testAcceptLanguageHeader()
{
$app = $this->createStackedApp();
Expand All @@ -41,6 +57,21 @@ public function testAcceptLanguageHeader()
$this->assertEquals('fu', $req->attributes->get('_language'));
}

public function testAcceptLanguageHeaderWithPriorities()
{
$app = $this->createStackedApp([], [ 'language_priorities' => [ 'fr' ] ]);
$req = $this->createRequest(null, [
'Accept-Language' => 'en, fr, de',
]);

$app->handle($req);

$header = $req->attributes->get('_accept_language');
$this->assertInstanceOf('Negotiation\AcceptHeader', $header);
$this->assertEquals('fr', $header->getValue());
$this->assertEquals('fr', $req->attributes->get('_language'));
}

/**
* @dataProvider dataProviderForTestDecodeBody
*/
Expand Down Expand Up @@ -69,9 +100,15 @@ public function dataProviderForTestDecodeBody()
];
}

private function createStackedApp(array $responseHeaders = [])
private function createStackedApp(array $responseHeaders = [], array $options = [])
{
return new Negotiation(new MockApp($responseHeaders));
return new Negotiation(
new MockApp($responseHeaders),
null,
null,
null,
$options
);
}

private function createRequest($content = null, array $requestHeaders = [])
Expand Down

0 comments on commit d3e185e

Please sign in to comment.