Skip to content
Snippets Groups Projects
Commit 1fda22c9 authored by David Maus's avatar David Maus
Browse files

Verwende willdurand/negotiation

parent 8b2841a4
No related branches found
No related tags found
No related merge requests found
Showing
with 670 additions and 2 deletions
[submodule "vendor\\pica2mods"]
path = vendor\\pica2mods
url = https://github.com/dmj/pica2mods.git
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7b4e0ab48493485011f66d6e7fc1e6b2", "content-hash": "d60aaa0891d9bd50b170b054a1e81a63",
"packages": [ "packages": [
{ {
"name": "hab/picareader", "name": "hab/picareader",
...@@ -333,6 +333,58 @@ ...@@ -333,6 +333,58 @@
"shim" "shim"
], ],
"time": "2018-01-30T19:27:44+00:00" "time": "2018-01-30T19:27:44+00:00"
},
{
"name": "willdurand/negotiation",
"version": "v2.3.1",
"source": {
"type": "git",
"url": "https://github.com/willdurand/Negotiation.git",
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-4": {
"Negotiation\\": "src/Negotiation"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "William Durand",
"email": "will+git@drnd.me"
}
],
"description": "Content Negotiation tools for PHP provided as a standalone library.",
"homepage": "http://williamdurand.fr/Negotiation/",
"keywords": [
"accept",
"content",
"format",
"header",
"negotiation"
],
"time": "2017-05-14T17:21:12+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
......
...@@ -9,4 +9,5 @@ return array( ...@@ -9,4 +9,5 @@ return array(
'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'), 'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Negotiation\\' => array($vendorDir . '/willdurand/negotiation/src/Negotiation'),
); );
...@@ -19,6 +19,10 @@ class ComposerStaticInit78daec5e1761b48dba06a78068db3ccf ...@@ -19,6 +19,10 @@ class ComposerStaticInit78daec5e1761b48dba06a78068db3ccf
'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Component\\HttpFoundation\\' => 33, 'Symfony\\Component\\HttpFoundation\\' => 33,
), ),
'N' =>
array (
'Negotiation\\' => 12,
),
); );
public static $prefixDirsPsr4 = array ( public static $prefixDirsPsr4 = array (
...@@ -34,6 +38,10 @@ class ComposerStaticInit78daec5e1761b48dba06a78068db3ccf ...@@ -34,6 +38,10 @@ class ComposerStaticInit78daec5e1761b48dba06a78068db3ccf
array ( array (
0 => __DIR__ . '/..' . '/symfony/http-foundation', 0 => __DIR__ . '/..' . '/symfony/http-foundation',
), ),
'Negotiation\\' =>
array (
0 => __DIR__ . '/..' . '/willdurand/negotiation/src/Negotiation',
),
); );
public static $prefixesPsr0 = array ( public static $prefixesPsr0 = array (
......
...@@ -340,5 +340,59 @@ ...@@ -340,5 +340,59 @@
"portable", "portable",
"shim" "shim"
] ]
},
{
"name": "willdurand/negotiation",
"version": "v2.3.1",
"version_normalized": "2.3.1.0",
"source": {
"type": "git",
"url": "https://github.com/willdurand/Negotiation.git",
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.5"
},
"time": "2017-05-14T17:21:12+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Negotiation\\": "src/Negotiation"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "William Durand",
"email": "will+git@drnd.me"
}
],
"description": "Content Negotiation tools for PHP provided as a standalone library.",
"homepage": "http://williamdurand.fr/Negotiation/",
"keywords": [
"accept",
"content",
"format",
"header",
"negotiation"
]
} }
] ]
/vendor/
composer.lock
sudo: false
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script:
- composer self-update
- composer install --prefer-dist --no-interaction
script: phpunit --coverage-text
Contributing
============
First of all, **thank you** for contributing, **you are awesome**!
Here are a few rules to follow in order to ease code reviews, and discussions before
maintainers accept and merge your work.
You MUST follow the [PSR-1](http://www.php-fig.org/psr/1/) and
[PSR-2](http://www.php-fig.org/psr/2/). If you don't know about any of them, you
should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer
tool](http://cs.sensiolabs.org/).
You MUST run the test suite.
You MUST write (or update) unit tests.
You SHOULD write documentation.
Please, write [commit messages that make
sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing)
before submitting your Pull Request.
One may ask you to [squash your
commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)
too. This is used to "clean" your Pull Request before merging it (we don't want
commits such as `fix tests`, `fix 2`, `fix 3`, etc.).
Also, while creating your Pull Request on GitHub, you MUST write a description
which gives the context and/or explains why you are creating it.
Thank you!
Copyright (c) William Durand <will+git@drnd.me>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Negotiation
===========
[![Build
Status](https://travis-ci.org/willdurand/Negotiation.png?branch=master)](http://travis-ci.org/willdurand/Negotiation)
[![Build
status](https://ci.appveyor.com/api/projects/status/6tbe8j3gofdlfm4v?svg=true)](https://ci.appveyor.com/project/willdurand/negotiation)
[![Total
Downloads](https://poser.pugx.org/willdurand/Negotiation/downloads.png)](https://packagist.org/packages/willdurand/Negotiation)
[![Latest Stable
Version](https://poser.pugx.org/willdurand/Negotiation/v/stable.png)](https://packagist.org/packages/willdurand/Negotiation)
![PHP 7 ready](https://img.shields.io/badge/PHP%207-ready-green.svg)
**Negotiation** is a standalone library without any dependencies that allows you
to implement [content
negotiation](https://tools.ietf.org/html/rfc7231#section-5.3) in your
application, whatever framework you use. This library is based on [RFC
7231](https://tools.ietf.org/html/rfc7231). Negotiation is easy to use, and
extensively unit tested!
> **Important:** You are browsing the documentation of Negotiation **2.x**.
Documentation for version **1.x** is available here: [Negotiation 1.x
documentation](https://github.com/willdurand/Negotiation/blob/1.x/README.md#usage).
You might also be interested in this: [**What's new in Negotiation 2?**](https://github.com/willdurand/Negotiation/releases/tag/v2.0.0-alpha1)
Installation
------------
The recommended way to install Negotiation is through
[Composer](http://getcomposer.org/):
```bash
$ composer require willdurand/negotiation
```
Usage Examples
--------------
### Media Type Negotiation
``` php
$negotiator = new \Negotiation\Negotiator();
$acceptHeader = 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8';
$priorities = array('text/html; charset=UTF-8', 'application/json', 'application/xml;q=0.5');
$mediaType = $negotiator->getBest($acceptHeader, $priorities);
$value = $mediaType->getValue();
// $value == 'text/html; charset=UTF-8'
```
The `Negotiator` returns an instance of `Accept`, or `null` if negotiating the
best media type has failed.
### Language Negotiation
``` php
<?php
$negotiator = new \Negotiation\LanguageNegotiator();
$acceptLangageHeader = 'en; q=0.1, fr; q=0.4, fu; q=0.9, de; q=0.2';
$priorities = array('de', 'fu', 'en');
$bestLanguage = $negotiator->getBest($acceptLangageHeader, $priorities);
$type = $bestLanguage->getType();
// $type == 'fu';
$quality = $bestLanguage->getQuality();
// $quality == 0.9
```
The `LanguageNegotiator` returns an instance of `AcceptLanguage`.
### Encoding Negotiation
``` php
<?php
$negotiator = new \Negotiation\EncodingNegotiator();
$encoding = $negotiator->getBest($acceptHeader, $priorities);
```
The `EncodingNegotiator` returns an instance of `AcceptEncoding`.
### Charset Negotiation
``` php
<?php
$negotiator = new \Negotiation\CharsetNegotiator();
$acceptCharsetHeader = 'ISO-8859-1, UTF-8; q=0.9';
$priorities = array('iso-8859-1;q=0.3', 'utf-8;q=0.9', 'utf-16;q=1.0');
$bestCharset = $negotiator->getBest($acceptCharsetHeader, $priorities);
$type = $bestCharset->getType();
// $type == 'utf-8';
$quality = $bestCharset->getQuality();
// $quality == 0.81
```
The `CharsetNegotiator` returns an instance of `AcceptCharset`.
### `Accept*` Classes
`Accept` and `Accept*` classes share common methods such as:
* `getValue()` returns the accept value (e.g. `text/html; z=y; a=b; c=d`)
* `getNormalizedValue()` returns the value with parameters sorted (e.g.
`text/html; a=b; c=d; z=y`)
* `getQuality()` returns the quality if available (`q` parameter)
* `getType()` returns the accept type (e.g. `text/html`)
* `getParameters()` returns the set of parameters (excluding the `q` parameter
if provided)
* `getParameter()` allows to retrieve a given parameter by its name. Fallback to
a `$default` (nullable) value otherwise.
* `hasParameter()` indicates whether a parameter exists.
Unit Tests
----------
Setup the test suite using Composer:
$ composer install --dev
Run it using PHPUnit:
$ phpunit
Contributing
------------
See [CONTRIBUTING](CONTRIBUTING.md) file.
Credits
-------
* Some parts of this library are inspired by:
* [Symfony](http://github.com/symfony/symfony) framework;
* [FOSRest](http://github.com/FriendsOfSymfony/FOSRest);
* [PEAR HTTP2](https://github.com/pear/HTTP2).
* William Durand <will+git@drnd.me>
* [@neural-wetware](https://github.com/neural-wetware)
License
-------
Negotiation is released under the MIT License. See the bundled LICENSE file for
details.
build: false
shallow_clone: true
platform: x86
clone_folder: c:\projects\willdurand\negotiation
cache:
- '%LOCALAPPDATA%\Composer\files'
init:
- SET PATH=C:\Program Files\OpenSSL;c:\tools\php;c:\tools\php71;%PATH%
install:
- ps: Set-Service wuauserv -StartupType Manual
- cinst -y OpenSSL.Light
- cinst -y php
- cd c:\tools\php71
- copy php.ini-production php.ini /Y
- echo date.timezone="UTC" >> php.ini
- echo extension_dir=ext >> php.ini
- echo extension=php_openssl.dll >> php.ini
- echo extension=php_mbstring.dll >> php.ini
- echo extension=php_fileinfo.dll >> php.ini
- echo memory_limit=1G >> php.ini
- cd c:\projects\willdurand\negotiation
- php -r "readfile('http://getcomposer.org/installer');" | php
- php composer.phar update --no-interaction --no-progress
test_script:
- cd c:\projects\willdurand\negotiation
- vendor\bin\phpunit.bat --verbose
{
"name": "willdurand/negotiation",
"description": "Content Negotiation tools for PHP provided as a standalone library.",
"keywords": [ "content", "negotiation", "format", "accept", "header" ],
"license": "MIT",
"homepage": "http://williamdurand.fr/Negotiation/",
"authors": [
{
"name": "William Durand",
"email": "will+git@drnd.me"
}
],
"require": {
"php": ">=5.4.0"
},
"autoload": {
"psr-4": { "Negotiation\\": "src/Negotiation" }
},
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"require-dev": {
"phpunit/phpunit": "~4.5"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
>
<testsuites>
<testsuite name="Negotiation Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./src/Negotiation/</directory>
</whitelist>
</filter>
</phpunit>
<?php
namespace Negotiation;
use Negotiation\Exception\InvalidArgument;
use Negotiation\Exception\InvalidHeader;
abstract class AbstractNegotiator
{
/**
* @param string $header A string containing an `Accept|Accept-*` header.
* @param array $priorities A set of server priorities.
*
* @return AcceptHeader|null best matching type
*/
public function getBest($header, array $priorities)
{
if (empty($priorities)) {
throw new InvalidArgument('A set of server priorities should be given.');
}
if (!$header) {
throw new InvalidArgument('The header string should not be empty.');
}
// Once upon a time, two `array_map` calls were sitting there, but for
// some reasons, they triggered `E_WARNING` time to time (because of
// PHP bug [55416](https://bugs.php.net/bug.php?id=55416). Now, they
// are gone.
// See: https://github.com/willdurand/Negotiation/issues/81
$acceptedHeaders = array();
foreach ($this->parseHeader($header) as $h) {
try {
$acceptedHeaders[] = $this->acceptFactory($h);
} catch (Exception\Exception $e) {
// silently skip in case of invalid headers coming in from a client
}
}
$acceptedPriorities = array();
foreach ($priorities as $p) {
$acceptedPriorities[] = $this->acceptFactory($p);
}
$matches = $this->findMatches($acceptedHeaders, $acceptedPriorities);
$specificMatches = array_reduce($matches, 'Negotiation\Match::reduce', []);
usort($specificMatches, 'Negotiation\Match::compare');
$match = array_shift($specificMatches);
return null === $match ? null : $acceptedPriorities[$match->index];
}
/**
* @param string $header accept header part or server priority
*
* @return AcceptHeader Parsed header object
*/
abstract protected function acceptFactory($header);
/**
* @param AcceptHeader $header
* @param AcceptHeader $priority
* @param integer $index
*
* @return Match|null Headers matched
*/
protected function match(AcceptHeader $header, AcceptHeader $priority, $index)
{
$ac = $header->getType();
$pc = $priority->getType();
$equal = !strcasecmp($ac, $pc);
if ($equal || $ac === '*') {
$score = 1 * $equal;
return new Match($header->getQuality() * $priority->getQuality(), $score, $index);
}
return null;
}
/**
* @param string $header A string that contains an `Accept*` header.
*
* @return AcceptHeader[]
*/
private function parseHeader($header)
{
$res = preg_match_all('/(?:[^,"]*+(?:"[^"]*+")?)+[^,"]*+/', $header, $matches);
if (!$res) {
throw new InvalidHeader(sprintf('Failed to parse accept header: "%s"', $header));
}
return array_values(array_filter(array_map('trim', $matches[0])));
}
/**
* @param AcceptHeader[] $headerParts
* @param Priority[] $priorities Configured priorities
*
* @return Match[] Headers matched
*/
private function findMatches(array $headerParts, array $priorities)
{
$matches = [];
foreach ($priorities as $index => $p) {
foreach ($headerParts as $h) {
if (null !== $match = $this->match($h, $p, $index)) {
$matches[] = $match;
}
}
}
return $matches;
}
}
<?php
namespace Negotiation;
use Negotiation\Exception\InvalidMediaType;
final class Accept extends BaseAccept implements AcceptHeader
{
private $basePart;
private $subPart;
public function __construct($value)
{
parent::__construct($value);
if ($this->type === '*') {
$this->type = '*/*';
}
$parts = explode('/', $this->type);
if (count($parts) !== 2 || !$parts[0] || !$parts[1]) {
throw new InvalidMediaType();
}
$this->basePart = $parts[0];
$this->subPart = $parts[1];
}
/**
* @return string
*/
public function getSubPart()
{
return $this->subPart;
}
/**
* @return string
*/
public function getBasePart()
{
return $this->basePart;
}
}
<?php
namespace Negotiation;
final class AcceptCharset extends BaseAccept implements AcceptHeader
{
}
<?php
namespace Negotiation;
final class AcceptEncoding extends BaseAccept implements AcceptHeader
{
}
<?php
namespace Negotiation;
interface AcceptHeader
{
}
<?php
namespace Negotiation;
use Negotiation\Exception\InvalidLanguage;
final class AcceptLanguage extends BaseAccept implements AcceptHeader
{
private $language;
private $script;
private $region;
public function __construct($value)
{
parent::__construct($value);
$parts = explode('-', $this->type);
if (2 === count($parts)) {
$this->language = $parts[0];
$this->region = $parts[1];
} elseif (1 === count($parts)) {
$this->language = $parts[0];
} elseif (3 === count($parts)) {
$this->language = $parts[0];
$this->script = $parts[1];
$this->region = $parts[2];
} else {
// TODO: this part is never reached...
throw new InvalidLanguage();
}
}
/**
* @return string
*/
public function getSubPart()
{
return $this->region;
}
/**
* @return string
*/
public function getBasePart()
{
return $this->language;
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment