From df20f6c37254a1e25ec621f86163010175369adc Mon Sep 17 00:00:00 2001 From: Dominique Fournier Date: Fri, 6 Dec 2019 14:57:38 +0000 Subject: [PATCH] Update http bestChoice to support the priority Add unittests git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@5802 bf3deb0d-5f1a-0410-827f-c0cc1f45334c --- Tests/httpTest.php | 55 ++++++++++++++++++++++++++++++++++++++++++++++ http.php | 38 +++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 Tests/httpTest.php diff --git a/Tests/httpTest.php b/Tests/httpTest.php new file mode 100644 index 0000000..eac2617 --- /dev/null +++ b/Tests/httpTest.php @@ -0,0 +1,55 @@ + + */ + +/** Test the http.php file */ +class httpTest extends PHPUnit_Framework_TestCase +{ + /** bestChoice : exact existing entry + */ + public function testBestChoice1 () + { + $http = new http (); + $res = $http->bestChoice ( + "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + array ("application/xml"), "text/html"); + $this->assertSame ($res, "application/xml"); + } + + /** bestChoice : Generic catch. + * Use default value + */ + public function testBestChoice2 () + { + $http = new http (); + $res = $http->bestChoice ( + "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + array ("text/plain"), "text/html"); + $this->assertSame ($res, "text/html"); + } + + /** bestChoice : no solution : use the default value + */ + public function testBestChoice3 () + { + $http = new http (); + $res = $http->bestChoice ( + "text/html,application/xhtml+xml,application/xml;q=0.9", + array ("text/plain"), "text/html"); + $this->assertSame ($res, "text/html"); + } + + /** bestChoice : invalid entry (end with comma). Continue without error and + * skip the bad choices + */ + public function testBestChoice4 () + { + $http = new http (); + $res = $http->bestChoice ( + "text/html,application/xhtml+xml,application/xml;q=0.9,", + array ("text/plain"), "text/html"); + $this->assertSame ($res, "text/html"); + } +} diff --git a/http.php b/http.php index dea7f3e..b1b5253 100644 --- a/http.php +++ b/http.php @@ -17,9 +17,11 @@ class http * If available is empty, then return the best priority defined by user, * and throw an exception if nothing is provided for by the user. * If nothing match, return $default + * Defined in https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html * @param string $uservar The parameter provided by the user * @param array|null $available The list of available choices in the soft * @param string|null $default The choice if nothing match + * @return string The prefered choice */ function bestChoice ($uservar, $available=array(), $default=FALSE) // {{{ @@ -32,20 +34,40 @@ class http throw new \Exception ("No user choice provided to bestChoice", 500); return $default; } - // Remove weights (provided by the order of the user) - // TODO : Reorganise the order if the weights are not in the right order - foreach ($userchoices as $key=>$val) + + // If the priority is not set, must be used in priority + // If the priority is set, use it if it is valid + $choicesPrio = array (); + foreach ($userchoices as $choice) { - $vals = @explode (";q", $val); - $userchoices[$key] = $vals[0]; + @list ($choice, $prio) = explode (";q=", $choice); + if (trim ($choice) === "") + continue; + if ($prio === null) + $prio = 1.0; + else + { + $nums = explode (".", $prio); + if (count ($nums) > 2) + $prio = 0.0; + elseif ($nums[0] !== "0") + $prio = 0.0; + elseif ($nums[0] < 0 || $nums[0] > 9) + $prio = 0.0; + } + $choicesPrio[$choice] = $prio; } + // Sort by priority + arsort ($choicesPrio, SORT_NATURAL); if (count ($available) === 0) return $userchoices[0]; // Look at the best existing solution - foreach ($userchoices as $choice) + foreach ($choicesPrio as $choice => $priority) { + if ($choice === "*/*") + return $default; foreach ($available as $avail) { if (strtolower ($avail) === strtolower ($choice)) @@ -54,10 +76,6 @@ class http $availTmp = str_replace ("_", "-", $avail); if (strtolower ($availTmp) === strtolower ($choice)) return $avail; - // Case text/xml, application/csv (just compare xml or csv) - $mimes = explode ("/", $choice); - if (isset ($mimes[1]) && strtolower ($availTmp) === $mimes[1]) - return $avail; } }