NegotiateMedia command can recognize types and subtypes now.

This commit is contained in:
Lonnie Ezell 2015-11-01 23:36:11 -06:00
parent 0e37359211
commit 2677d79871
2 changed files with 80 additions and 12 deletions

View File

@ -296,7 +296,7 @@ class Message
*/ */
public function negotiateMedia(array $supported): string public function negotiateMedia(array $supported): string
{ {
return $this->getBestMatch($supported, $this->header('accept')); return $this->getBestMatch($supported, $this->header('accept'), true);
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -385,12 +385,13 @@ class Message
* *
* Portions of this code base on Aura.Accept library. * Portions of this code base on Aura.Accept library.
* *
* @param array $supported App-supported values * @param array $supported App-supported values
* @param string $header header string * @param string $header header string
* @param bool $enforceTypes If TRUE, will compare media types and sub-types.
* *
* @return string Best match * @return string Best match
*/ */
protected function getBestMatch(array $supported, string $header=null): string protected function getBestMatch(array $supported, string $header=null, bool $enforceTypes=false): string
{ {
if (empty($supported)) if (empty($supported))
{ {
@ -428,14 +429,14 @@ class Message
// If an acceptable value is supported, return it // If an acceptable value is supported, return it
foreach ($supported as $available) foreach ($supported as $available)
{ {
if ($this->match($accept, $available)) if ($this->match($accept, $available, $enforceTypes))
{ {
return $available; return $available;
} }
} }
} }
// No matches? return the first supported type // No matches? Return the first supported element.
return $supported[0]; return $supported[0];
} }
@ -533,7 +534,7 @@ class Message
//-------------------------------------------------------------------- //--------------------------------------------------------------------
protected function match($acceptable, $supported) protected function match(array $acceptable, string $supported, bool $enforceTypes=false)
{ {
$supported = $this->parseHeader($supported); $supported = $this->parseHeader($supported);
if (is_array($supported) && count($supported) == 1) if (is_array($supported) && count($supported) == 1)
@ -547,15 +548,28 @@ class Message
return $this->matchParameters($acceptable, $supported); return $this->matchParameters($acceptable, $supported);
} }
// Do we need to compare types/sub-types? Only used
// by negotiateMedia().
if ($enforceTypes)
{
return $this->matchTypes($acceptable, $supported);
}
return false;
// var_dump($acceptable);
// die(var_dump($supported));
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
protected function matchParameters($acceptable, $supported) /**
* Checks two Accept values with matching 'values' to see if their
* 'params' are the same.
*
* @param array $acceptable
* @param array $supported
*
* @return bool
*/
protected function matchParameters(array $acceptable, array $supported): bool
{ {
if (count($acceptable['params']) != count($supported['params'])) if (count($acceptable['params']) != count($supported['params']))
{ {
@ -576,5 +590,37 @@ class Message
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/**
* Compares the types/subtypes of an acceptable Media type and
* the supported string.
*
* @param array $acceptable
* @param array $supported
*
* @return bool
*/
public function matchTypes(array $acceptable, array $supported): bool
{
list($aType, $aSubType) = explode('/', $acceptable['value']);
list($sType, $sSubType) = explode('/', $supported['value']);
// If the types don't match, we're done.
if ($aType != $sType)
{
return false;
}
// If there's an asterisk, we're cool
if ($aSubType == '*')
{
return true;
}
// Otherwise, subtypes must match also.
return $aSubType == $sSubType;
}
//--------------------------------------------------------------------
} }

View File

@ -158,7 +158,7 @@ class MessageTest extends PHPUnit_Framework_TestCase
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public function testNegotiateMediaDeterminesCorrectPrecedence() public function testParseHeaderDeterminesCorrectPrecedence()
{ {
$header =$this->message->parseHeader('text/*, text/plain, text/plain;format=flowed, */*'); $header =$this->message->parseHeader('text/*, text/plain, text/plain;format=flowed, */*');
@ -170,5 +170,27 @@ class MessageTest extends PHPUnit_Framework_TestCase
//-------------------------------------------------------------------- //--------------------------------------------------------------------
public function testNegotiateMediaReturnsSupportedMatchWhenAsterisksInAvailable()
{
$this->message->setHeader('Accept', 'image/*, text/*');
$this->assertEquals('text/plain', $this->message->negotiateMedia(['text/plain']));
}
//--------------------------------------------------------------------
/**
* @group single
*/
public function testNegotiateMediaRecognizesMediaTypes()
{
// Image has a higher specificity, but is the wrong type...
$this->message->setHeader('Accept', 'text/*, image/jpeg');
$this->assertEquals('text/plain', $this->message->negotiateMedia(['text/plain']));
}
//--------------------------------------------------------------------
} }