first commit
This commit is contained in:
165
libraries/vendor/willdurand/negotiation/src/Negotiation/AbstractNegotiator.php
vendored
Normal file
165
libraries/vendor/willdurand/negotiation/src/Negotiation/AbstractNegotiator.php
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
<?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, $strict = false)
|
||||
{
|
||||
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) {
|
||||
if ($strict) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
$acceptedPriorities = array();
|
||||
foreach ($priorities as $p) {
|
||||
$acceptedPriorities[] = $this->acceptFactory($p);
|
||||
}
|
||||
$matches = $this->findMatches($acceptedHeaders, $acceptedPriorities);
|
||||
$specificMatches = array_reduce($matches, 'Negotiation\AcceptMatch::reduce', []);
|
||||
|
||||
usort($specificMatches, 'Negotiation\AcceptMatch::compare');
|
||||
|
||||
$match = array_shift($specificMatches);
|
||||
|
||||
return null === $match ? null : $acceptedPriorities[$match->index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $header A string containing an `Accept|Accept-*` header.
|
||||
*
|
||||
* @return AcceptHeader[] An ordered list of accept header elements
|
||||
*/
|
||||
public function getOrderedElements($header)
|
||||
{
|
||||
if (!$header) {
|
||||
throw new InvalidArgument('The header string should not be empty.');
|
||||
}
|
||||
|
||||
$elements = array();
|
||||
$orderKeys = array();
|
||||
foreach ($this->parseHeader($header) as $key => $h) {
|
||||
try {
|
||||
$element = $this->acceptFactory($h);
|
||||
$elements[] = $element;
|
||||
$orderKeys[] = [$element->getQuality(), $key, $element->getValue()];
|
||||
} catch (Exception\Exception $e) {
|
||||
// silently skip in case of invalid headers coming in from a client
|
||||
}
|
||||
}
|
||||
|
||||
// sort based on quality and then original order. This is necessary as
|
||||
// to ensure that the first in the list for two items with the same
|
||||
// quality stays in that order in both PHP5 and PHP7.
|
||||
uasort($orderKeys, function ($a, $b) {
|
||||
$qA = $a[0];
|
||||
$qB = $b[0];
|
||||
|
||||
if ($qA == $qB) {
|
||||
return $a[1] <=> $b[1];
|
||||
}
|
||||
|
||||
return ($qA > $qB) ? -1 : 1;
|
||||
});
|
||||
|
||||
$orderedElements = [];
|
||||
foreach ($orderKeys as $key) {
|
||||
$orderedElements[] = $elements[$key[1]];
|
||||
}
|
||||
|
||||
return $orderedElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 AcceptMatch|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 AcceptMatch($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 AcceptMatch[] 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;
|
||||
}
|
||||
}
|
||||
46
libraries/vendor/willdurand/negotiation/src/Negotiation/Accept.php
vendored
Normal file
46
libraries/vendor/willdurand/negotiation/src/Negotiation/Accept.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptCharset.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptCharset.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
final class AcceptCharset extends BaseAccept implements AcceptHeader
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptEncoding.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptEncoding.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
final class AcceptEncoding extends BaseAccept implements AcceptHeader
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptHeader.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptHeader.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
interface AcceptHeader
|
||||
{
|
||||
}
|
||||
49
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptLanguage.php
vendored
Normal file
49
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptLanguage.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
62
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptMatch.php
vendored
Normal file
62
libraries/vendor/willdurand/negotiation/src/Negotiation/AcceptMatch.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
final class AcceptMatch
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $quality;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $score;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $index;
|
||||
|
||||
public function __construct($quality, $score, $index)
|
||||
{
|
||||
$this->quality = $quality;
|
||||
$this->score = $score;
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AcceptMatch $a
|
||||
* @param AcceptMatch $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function compare(AcceptMatch $a, AcceptMatch $b)
|
||||
{
|
||||
if ($a->quality !== $b->quality) {
|
||||
return $a->quality > $b->quality ? -1 : 1;
|
||||
}
|
||||
|
||||
if ($a->index !== $b->index) {
|
||||
return $a->index > $b->index ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $carry reduced array
|
||||
* @param AcceptMatch $match match to be reduced
|
||||
*
|
||||
* @return AcceptMatch[]
|
||||
*/
|
||||
public static function reduce(array $carry, AcceptMatch $match)
|
||||
{
|
||||
if (!isset($carry[$match->index]) || $carry[$match->index]->score < $match->score) {
|
||||
$carry[$match->index] = $match;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}
|
||||
}
|
||||
158
libraries/vendor/willdurand/negotiation/src/Negotiation/BaseAccept.php
vendored
Normal file
158
libraries/vendor/willdurand/negotiation/src/Negotiation/BaseAccept.php
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
abstract class BaseAccept
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $quality = 1.0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $normalized;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct($value)
|
||||
{
|
||||
list($type, $parameters) = $this->parseParameters($value);
|
||||
|
||||
if (isset($parameters['q'])) {
|
||||
$this->quality = (float) $parameters['q'];
|
||||
unset($parameters['q']);
|
||||
}
|
||||
|
||||
$type = trim(strtolower($type));
|
||||
|
||||
$this->value = $value;
|
||||
$this->normalized = $type . ($parameters ? "; " . $this->buildParametersString($parameters) : '');
|
||||
$this->type = $type;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedValue()
|
||||
{
|
||||
return $this->normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getQuality()
|
||||
{
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getParameter($key, $default = null)
|
||||
{
|
||||
return isset($this->parameters[$key]) ? $this->parameters[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasParameter($key)
|
||||
{
|
||||
return isset($this->parameters[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string|null $acceptPart
|
||||
* @return array
|
||||
*/
|
||||
private function parseParameters($acceptPart)
|
||||
{
|
||||
if ($acceptPart === null) {
|
||||
return ['', []];
|
||||
}
|
||||
|
||||
$parts = explode(';', $acceptPart);
|
||||
$type = array_shift($parts);
|
||||
|
||||
$parameters = [];
|
||||
foreach ($parts as $part) {
|
||||
$part = explode('=', $part);
|
||||
|
||||
if (2 !== count($part)) {
|
||||
continue; // TODO: throw exception here?
|
||||
}
|
||||
|
||||
$key = strtolower(trim($part[0])); // TODO: technically not allowed space around "=". throw exception?
|
||||
$parameters[$key] = trim($part[1], ' "');
|
||||
}
|
||||
|
||||
return [ $type, $parameters ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildParametersString($parameters)
|
||||
{
|
||||
$parts = [];
|
||||
|
||||
ksort($parameters);
|
||||
foreach ($parameters as $key => $val) {
|
||||
$parts[] = sprintf('%s=%s', $key, $val);
|
||||
}
|
||||
|
||||
return implode('; ', $parts);
|
||||
}
|
||||
}
|
||||
14
libraries/vendor/willdurand/negotiation/src/Negotiation/CharsetNegotiator.php
vendored
Normal file
14
libraries/vendor/willdurand/negotiation/src/Negotiation/CharsetNegotiator.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
class CharsetNegotiator extends AbstractNegotiator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function acceptFactory($accept)
|
||||
{
|
||||
return new AcceptCharset($accept);
|
||||
}
|
||||
}
|
||||
14
libraries/vendor/willdurand/negotiation/src/Negotiation/EncodingNegotiator.php
vendored
Normal file
14
libraries/vendor/willdurand/negotiation/src/Negotiation/EncodingNegotiator.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
class EncodingNegotiator extends AbstractNegotiator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function acceptFactory($accept)
|
||||
{
|
||||
return new AcceptEncoding($accept);
|
||||
}
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/Exception.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/Exception.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation\Exception;
|
||||
|
||||
interface Exception
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidArgument.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidArgument.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation\Exception;
|
||||
|
||||
class InvalidArgument extends \InvalidArgumentException implements Exception
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidHeader.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidHeader.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation\Exception;
|
||||
|
||||
class InvalidHeader extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidLanguage.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidLanguage.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation\Exception;
|
||||
|
||||
class InvalidLanguage extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidMediaType.php
vendored
Normal file
7
libraries/vendor/willdurand/negotiation/src/Negotiation/Exception/InvalidMediaType.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation\Exception;
|
||||
|
||||
class InvalidMediaType extends \RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
41
libraries/vendor/willdurand/negotiation/src/Negotiation/LanguageNegotiator.php
vendored
Normal file
41
libraries/vendor/willdurand/negotiation/src/Negotiation/LanguageNegotiator.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
class LanguageNegotiator extends AbstractNegotiator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function acceptFactory($accept)
|
||||
{
|
||||
return new AcceptLanguage($accept);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function match(AcceptHeader $acceptLanguage, AcceptHeader $priority, $index)
|
||||
{
|
||||
if (!$acceptLanguage instanceof AcceptLanguage || !$priority instanceof AcceptLanguage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ab = $acceptLanguage->getBasePart();
|
||||
$pb = $priority->getBasePart();
|
||||
|
||||
$as = $acceptLanguage->getSubPart();
|
||||
$ps = $priority->getSubPart();
|
||||
|
||||
$baseEqual = !strcasecmp((string)$ab, (string)$pb);
|
||||
$subEqual = !strcasecmp((string)$as, (string)$ps);
|
||||
|
||||
if (($ab == '*' || $baseEqual) && ($as === null || $subEqual || null === $ps)) {
|
||||
$score = 10 * $baseEqual + $subEqual;
|
||||
|
||||
return new AcceptMatch($acceptLanguage->getQuality() * $priority->getQuality(), $score, $index);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
89
libraries/vendor/willdurand/negotiation/src/Negotiation/Negotiator.php
vendored
Normal file
89
libraries/vendor/willdurand/negotiation/src/Negotiation/Negotiator.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Negotiation;
|
||||
|
||||
class Negotiator extends AbstractNegotiator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function acceptFactory($accept)
|
||||
{
|
||||
return new Accept($accept);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function match(AcceptHeader $accept, AcceptHeader $priority, $index)
|
||||
{
|
||||
if (!$accept instanceof Accept || !$priority instanceof Accept) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$acceptBase = $accept->getBasePart();
|
||||
$priorityBase = $priority->getBasePart();
|
||||
|
||||
$acceptSub = $accept->getSubPart();
|
||||
$prioritySub = $priority->getSubPart();
|
||||
|
||||
$intersection = array_intersect_assoc($accept->getParameters(), $priority->getParameters());
|
||||
|
||||
$baseEqual = !strcasecmp($acceptBase, $priorityBase);
|
||||
$subEqual = !strcasecmp($acceptSub, $prioritySub);
|
||||
|
||||
if (($acceptBase === '*' || $baseEqual)
|
||||
&& ($acceptSub === '*' || $subEqual)
|
||||
&& count($intersection) === count($accept->getParameters())
|
||||
) {
|
||||
$score = 100 * $baseEqual + 10 * $subEqual + count($intersection);
|
||||
|
||||
return new AcceptMatch($accept->getQuality() * $priority->getQuality(), $score, $index);
|
||||
}
|
||||
|
||||
if (!strstr($acceptSub, '+') || !strstr($prioritySub, '+')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Handle "+" segment wildcards
|
||||
list($acceptSub, $acceptPlus) = $this->splitSubPart($acceptSub);
|
||||
list($prioritySub, $priorityPlus) = $this->splitSubPart($prioritySub);
|
||||
|
||||
// If no wildcards in either the subtype or + segment, do nothing.
|
||||
if (!($acceptBase === '*' || $baseEqual)
|
||||
|| !($acceptSub === '*' || $prioritySub === '*' || $acceptPlus === '*' || $priorityPlus === '*')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$subEqual = !strcasecmp($acceptSub, $prioritySub);
|
||||
$plusEqual = !strcasecmp($acceptPlus, $priorityPlus);
|
||||
|
||||
if (($acceptSub === '*' || $prioritySub === '*' || $subEqual)
|
||||
&& ($acceptPlus === '*' || $priorityPlus === '*' || $plusEqual)
|
||||
&& count($intersection) === count($accept->getParameters())
|
||||
) {
|
||||
$score = 100 * $baseEqual + 10 * $subEqual + $plusEqual + count($intersection);
|
||||
|
||||
return new AcceptMatch($accept->getQuality() * $priority->getQuality(), $score, $index);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a subpart into the subpart and "plus" part.
|
||||
*
|
||||
* For media-types of the form "application/vnd.example+json", matching
|
||||
* should allow wildcards for either the portion before the "+" or
|
||||
* after. This method splits the subpart to allow such matching.
|
||||
*/
|
||||
protected function splitSubPart($subPart)
|
||||
{
|
||||
if (!strstr($subPart, '+')) {
|
||||
return [$subPart, ''];
|
||||
}
|
||||
|
||||
return explode('+', $subPart, 2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user