middlewares/negotiation

Middleware to implement content negotiation

v1.1.0 2018-08-04 10:41 UTC

README

Latest Version on Packagist Software License Build Status Quality Score Total Downloads SensioLabs Insight

Middleware using wildurand/Negotiation to implement content negotiation. Contains the following components:

Requirements

Installation

This package is installable and autoloadable via Composer as middlewares/negotiation.

composer require middlewares/negotiation

Example

$dispatcher = new Dispatcher([
    new Middlewares\ContentType(),
    new Middlewares\ContentLanguage(['en', 'gl', 'es']),
    new Middlewares\ContentEncoding(['gzip', 'deflate']),
]);

$response = $dispatcher->dispatch(new ServerRequest());

ContentType

To detect the preferred mime type using the Accept header and the path extension and edit the header with this value. A Content-Type header is also added to the response if it's missing.

__construct(array $formats = null)

Set the available formats to negotiate sorted by priority. By default uses these

useDefault($useDefault = true)

Whether use the default format (the first format provided) if the negotiation does not return a valid format. Set to false to disable the default format and return a 406 response. By default is true.

charsets(array $charsets)

Array with the available charsets, to negotiate with the Accept-Charset header. By default is ['UTF-8'].

noSniff($nosniff = true)

Adds the X-Content-Type-Options: nosniff header, to mitigating MIME confusión attacks.. true by default. To disable it: noSniff(false).

responseFactory(Psr\Http\Message\ResponseFactoryInterface $responseFactory)

A PSR-17 factory to create 406 responses.

$request = (new ServerRequest())
    ->withHeader('Accept', 'application/xml;charset=UTF-8,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8');

$dispatcher = new Dispatcher([
    new Middlewares\ContentType(),

    function ($request, $next) {
        $type = $request->getHeaderLine('Accept');
        $response = new Response();

        if ($type === 'text/html') {
            $response->getBody()->write('<p>Hello world</p>');
        } elseif ($type === 'application/json') {
            $response->getBody()->write(json_encode(['message' => 'Hello world']));
        }

        return $response;
    }
]);

$response = $dispatcher->dispatch($request);

echo $response->getHeaderLine('Content-Type'); //text/html; charset=UTF-8
echo $response->getBody(); //<p>Hello world</p>

ContentLanguage

To detect the preferred language using the Accept-Language header or the path prefix and edit the header with this value. A Content-Language header is also added to the response if it's missing.

__construct(array $languages)

Set the available languages to negotiate sorted by priority. The first value will be used as default if no other languages is choosen in the negotiation.

$request = (new ServerRequest())
    ->withHeader('Accept-Language', 'gl-es, es;q=0.8, en;q=0.7');

$dispatcher = new Dispatcher([
    new Middlewares\ContentLanguage(['es', 'en']),

    function ($request, $next) {
        $language = $request->getHeaderLine('Accept-Language');
        $response = new Response();

        if ($language === 'es') {
            $response->getBody()->write('Hola mundo');
        } else {
            $response->getBody()->write('Hello world');
        }

        return $response;
    }
]);

$response = $dispatcher->dispatch($request);

echo $response->getHeaderLine('Content-Language'); //es
echo $response->getBody(); //Hola mundo

usePath()

To use the base path to detect the language. This is useful if you have different paths for each language, for example /gl/foo and /en/foo.

Note: the language in the path has preference over the Accept-Language header.

$request = (new ServerRequest())->withUri(new Uri('/en/hello-world'));

$dispatcher = new Dispatcher([
    (new Middlewares\ContentLanguage(['es', 'en']))
        ->usePath(),

    function ($request, $next) {
        $language = $request->getHeaderLine('Accept-Language');
        $response = new Response();

        if ($language === 'es') {
            $response->getBody()->write('Hola mundo');
        } else {
            $response->getBody()->write('Hello world');
        }

        return $response;
    }
]);

$response = $dispatcher->dispatch($request);

echo $response->getHeaderLine('Content-Language'); //en
echo $response->getBody(); //Hello world

redirect()

Used to return a 302 response redirecting to a path containing the language. This only works if usePath is enabled, so for example, if the request uri is /welcome, returns a redirection to /en/welcome.

responseFactory(Psr\Http\Message\ResponseFactoryInterface $responseFactory)

A PSR-17 factory to create redirect responses.

ContentEncoding

To detect the preferred encoding type using the Accept-Encoding header and edit the header with this value.

__construct(array $encodings)

Set the available encodings to negotiate.

$request = (new ServerRequest())
    ->withHeader('Accept-Encoding', 'gzip,deflate');

$dispatcher = new Dispatcher([
    new Middlewares\ContentEncoding(['gzip']),

    function ($request, $next) {
        echo $request->getHeaderLine('Accept-Encoding'); //gzip
    }
]);

$response = $dispatcher->dispatch($request);

Please see CHANGELOG for more information about recent changes and CONTRIBUTING for contributing details.

The MIT License (MIT). Please see LICENSE for more information.