Skip to content

Commit

Permalink
Merge pull request #9 from chubbyphp/middleware
Browse files Browse the repository at this point in the history
Middleware
  • Loading branch information
dominikzogg authored Feb 4, 2024
2 parents f1b5caf + 624d253 commit dd66c07
Show file tree
Hide file tree
Showing 24 changed files with 915 additions and 18 deletions.
86 changes: 77 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ A simple negotiation library.
## Requirements

* php: ^8.1
* chubbyphp/chubbyphp-http-exception: ^1.1
* psr/http-message: ^1.1|^2.0
* psr/http-server-middleware: ^1.0

## Suggest

Expand All @@ -39,7 +41,7 @@ A simple negotiation library.
Through [Composer](http://getcomposer.org) as [chubbyphp/chubbyphp-negotiation][1].

```sh
composer require chubbyphp/chubbyphp-negotiation "^2.0"
composer require chubbyphp/chubbyphp-negotiation "^2.1"
```

## Usage
Expand All @@ -60,6 +62,20 @@ $value->getValue(); // de
$value->getAttributes(); // ['q' => '1.0']
```

### AcceptLanguageMiddleware

```php
<?php

use Chubbyphp\Negotiation\Middleware\AcceptLanguageMiddleware;

$request = ...;
$request->withHeader('Accept-Language', 'de,en-US;q=0.7,en;q=0.3');

$middleware = new AcceptLanguageMiddleware($acceptLanguageNegotiator);
$response = $negotiator->process($request, $handler);
```

### AcceptNegotiator

```php
Expand All @@ -76,6 +92,20 @@ $value->getValue(); // application/xml
$value->getAttributes(); // ['q' => '0.9']
```

### AcceptMiddleware

```php
<?php

use Chubbyphp\Negotiation\Middleware\AcceptMiddleware;

$request = ...;
$request->withHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q =0.8');

$middleware = new AcceptMiddleware($acceptNegotiator);
$response = $negotiator->process($request, $handler);
```

### ContentTypeNegotiator

```php
Expand All @@ -92,6 +122,20 @@ $value->getValue(); // application/xml
$value->getAttributes(); // ['charset' => 'UTF-8']
```

### ContentTypeMiddleware

```php
<?php

use Chubbyphp\Negotiation\Middleware\ContentTypeMiddleware;

$request = ...;
$request->withHeader('Content-Type', 'application/xml; charset=UTF-8');

$middleware = new ContentTypeMiddleware($contentTypeNegotiator);
$response = $negotiator->process($request, $handler);
```

### NegotiationServiceFactory

```php
Expand All @@ -109,11 +153,20 @@ $request = ...;
$container->get('negotiator.acceptNegotiator')
->negotiate($request);

$container->get('negotiator.acceptNegotiator')
$container->get('negotiator.acceptMiddleware')
->process($request, $handler);

$container->get('negotiator.acceptLanguageNegotiator')
->negotiate($request);

$container->get('negotiator.acceptLanguageMiddleware')
->process($request, $handler);

$container->get('negotiator.contentTypeNegotiator')
->negotiate($request);

$container->get('negotiator.contentTypeMiddleware')
->process($request, $handler);
```

### NegotiationServiceProvider
Expand All @@ -133,25 +186,40 @@ $request = ...;
$container['negotiator.acceptNegotiator']
->negotiate($request);

$container['negotiator.acceptNegotiator']
$container['negotiator.acceptMiddleware']
->process($request, $handler);

$container['negotiator.acceptLanguageNegotiator']
->negotiate($request);

$container['negotiator.acceptLanguageMiddleware']
->process($request, $handler);

$container['negotiator.contentTypeNegotiator']
->negotiate($request);

$container['negotiator.contentTypeMiddleware']
->process($request, $handler);
```

### ServiceFactory

* [AcceptLanguageNegotiatorFactory][2]
* [AcceptNegotiatorFactory][3]
* [ContentTypeNegotiatorFactory][4]
* [AcceptLanguageMiddlewareFactory][2]
* [AcceptLanguageNegotiatorFactory][3]
* [AcceptMiddlewareFactory][4]
* [AcceptNegotiatorFactory][5]
* [ContentTypeMiddlewareFactory][6]
* [ContentTypeNegotiatorFactory][7]

## Copyright

2024 Dominik Zogg

[1]: https://packagist.org/packages/chubbyphp/chubbyphp-negotiation

[2]: doc/ServiceFactory/AcceptLanguageNegotiatorFactory.md
[3]: doc/ServiceFactory/AcceptNegotiatorFactory.md
[4]: doc/ServiceFactory/ContentTypeNegotiatorFactory.md
[2]: doc/ServiceFactory/AcceptLanguageMiddlewareFactory.md
[3]: doc/ServiceFactory/AcceptLanguageNegotiatorFactory.md
[4]: doc/ServiceFactory/AcceptMiddlewareFactory.md
[5]: doc/ServiceFactory/AcceptNegotiatorFactory.md
[6]: doc/ServiceFactory/ContentTypeMiddlewareFactory.md
[7]: doc/ServiceFactory/ContentTypeNegotiatorFactory.md
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
],
"require": {
"php": "^8.1",
"psr/http-message": "^1.1|^2.0"
"chubbyphp/chubbyphp-http-exception": "^1.1",
"psr/http-message": "^1.1|^2.0",
"psr/http-server-middleware": "^1.0"
},
"require-dev": {
"chubbyphp/chubbyphp-container": "^2.2",
Expand Down Expand Up @@ -47,7 +49,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "2.1-dev"
}
},
"scripts": {
Expand Down
39 changes: 39 additions & 0 deletions doc/ServiceFactory/AcceptLanguageMiddlewareFactory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# AcceptLanguageMiddlewareFactory

## without name (default)

```php
<?php

use Chubbyphp\Negotiation\AcceptLanguageMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\AcceptLanguageMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(AcceptLanguageNegotiator::class)

$factory = new AcceptLanguageMiddlewareFactory();

$acceptLanguageMiddleware = $factory($container);
```

## with name `default`

```php
<?php

use Chubbyphp\Negotiation\AcceptLanguageMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\AcceptLanguageMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(AcceptLanguageNegotiator::class.'default')

$factory = [AcceptLanguageMiddlewareFactory::class, 'default'];

$acceptLanguageMiddleware = $factory($container);
```
2 changes: 0 additions & 2 deletions doc/ServiceFactory/AcceptLanguageNegotiatorFactory.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(AcceptLanguageNegotiatorInterface::class.'supportedLocales[]')
// ['de-CH', 'en-US']

$factory = new AcceptLanguageNegotiatorFactory();

Expand All @@ -33,7 +32,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(AcceptLanguageNegotiatorInterface::class.'supportedLocales[]default')
// ['de-CH', 'en-US']

$factory = [AcceptLanguageNegotiatorFactory::class, 'default'];

Expand Down
39 changes: 39 additions & 0 deletions doc/ServiceFactory/AcceptMiddlewareFactory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# AcceptMiddlewareFactory

## without name (default)

```php
<?php

use Chubbyphp\Negotiation\AcceptMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\AcceptMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(AcceptNegotiator::class)

$factory = new AcceptMiddlewareFactory();

$acceptMiddleware = $factory($container);
```

## with name `default`

```php
<?php

use Chubbyphp\Negotiation\AcceptMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\AcceptMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(AcceptNegotiator::class.'default')

$factory = [AcceptMiddlewareFactory::class, 'default'];

$acceptMiddleware = $factory($container);
```
2 changes: 0 additions & 2 deletions doc/ServiceFactory/AcceptNegotiatorFactory.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(AcceptNegotiatorInterface::class.'supportedMediaTypes[]')
// ['application/json', 'application/xml']

$factory = new AcceptNegotiatorFactory();

Expand All @@ -33,7 +32,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(AcceptNegotiatorInterface::class.'supportedMediaTypes[]default')
// ['application/json', 'application/xml']

$factory = [AcceptNegotiatorFactory::class, 'default'];

Expand Down
39 changes: 39 additions & 0 deletions doc/ServiceFactory/ContentTypeMiddlewareFactory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ContentTypeMiddlewareFactory

## without name (default)

```php
<?php

use Chubbyphp\Negotiation\ContentTypeMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\ContentTypeMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(ContentTypeNegotiator::class)

$factory = new ContentTypeMiddlewareFactory();

$contentTypeMiddleware = $factory($container);
```

## with name `default`

```php
<?php

use Chubbyphp\Negotiation\ContentTypeMiddleware;
use Chubbyphp\Negotiation\ServiceFactory\ContentTypeMiddlewareFactory;
use Psr\Container\ContainerInterface;

/** @var ContainerInterface $container */
$container = ...;

// $container->get(ContentTypeNegotiator::class.'default')

$factory = [ContentTypeMiddlewareFactory::class, 'default'];

$contentTypeMiddleware = $factory($container);
```
2 changes: 0 additions & 2 deletions doc/ServiceFactory/ContentTypeNegotiatorFactory.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(ContentTypeNegotiatorInterface::class.'supportedMediaTypes[]')
// ['application/json', 'application/xml']

$factory = new ContentTypeNegotiatorFactory();

Expand All @@ -33,7 +32,6 @@ use Psr\Container\ContainerInterface;
$container = ...;

// $container->get(ContentTypeNegotiatorInterface::class.'supportedMediaTypes[]default')
// ['application/json', 'application/xml']

$factory = [ContentTypeNegotiatorFactory::class, 'default'];

Expand Down
55 changes: 55 additions & 0 deletions src/Middleware/AcceptLanguageMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Chubbyphp\Negotiation\Middleware;

use Chubbyphp\HttpException\HttpException;
use Chubbyphp\Negotiation\AcceptLanguageNegotiatorInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class AcceptLanguageMiddleware implements MiddlewareInterface
{
public function __construct(
private AcceptLanguageNegotiatorInterface $acceptLanguageNegotiator,
) {}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (null === $acceptLanguage = $this->acceptLanguageNegotiator->negotiate($request)) {
throw HttpException::createNotAcceptable(
$this->aggregateData(
'acceptLanguage',
$request->getHeaderLine('Accept-Language'),
$this->acceptLanguageNegotiator->getSupportedLocales()
)
);
}

$request = $request->withAttribute('acceptLanguage', $acceptLanguage->getValue());

return $handler->handle($request);
}

/**
* @param array<string> $supportedValues
*
* @return array<string, array<string>|string>
*/
private function aggregateData(string $header, string $value, array $supportedValues): array
{
return [
'detail' => sprintf(
'%s %s, supportedValues: "%s"',
'' !== $value ? 'Not supported' : 'Missing',
$header,
implode('", ', $supportedValues)
),
'value' => $value,
'supportedValues' => $supportedValues,
];
}
}
Loading

0 comments on commit dd66c07

Please sign in to comment.