]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - extlib/AcceptHeader.php
[ROUTES] Allow accept-header specification during router creation
[quix0rs-gnu-social.git] / extlib / AcceptHeader.php
1 <?php
2 /**
3  * Note : Code is released under the GNU LGPL
4  *
5  * Please do not change the header of this file
6  *
7  * This library is free software; you can redistribute it and/or modify it under the terms of the GNU
8  * Lesser General Public License as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * See the GNU Lesser General Public License for more details.
15  */
16
17 /**
18  * The AcceptHeader page will parse and sort the different
19  * allowed types for the content negociations
20  *
21  * @author Pierrick Charron <pierrick@webstart.fr>
22  */
23 class AcceptHeader extends \ArrayObject
24 {
25     /**
26      * Constructor
27      *
28      * @param string $header Value of the Accept header
29      * @return void
30      */
31     public function __construct($header)
32     {
33         $acceptedTypes = $this->_parse($header);
34         usort($acceptedTypes, [$this, '_compare']);
35         parent::__construct($acceptedTypes);
36     }
37
38     /**
39      * Parse the accept header and return an array containing
40      * all the informations about the Accepted types
41      *
42      * @param string $data Value of the Accept header
43      * @return array
44      */
45     private function _parse($data)
46     {
47         $array = [];
48         $items = explode(',', $data);
49         foreach ($items as $item) {
50             $elems = explode(';', $item);
51
52             $acceptElement = [];
53             $mime = current($elems);
54             list($type, $subtype) = explode('/', $mime);
55             $acceptElement['type'] = trim($type);
56             $acceptElement['subtype'] = trim($subtype);
57             $acceptElement['raw'] = $mime;
58
59             $acceptElement['params'] = [];
60             while (next($elems)) {
61                 list($name, $value) = explode('=', current($elems));
62                 $acceptElement['params'][trim($name)] = trim($value);
63             }
64
65             $array[] = $acceptElement;
66         }
67         return $array;
68     }
69
70     /**
71      * Compare two Accepted types with their parameters to know
72      * if one media type should be used instead of an other
73      *
74      * @param array $a The first media type and its parameters
75      * @param array $b The second media type and its parameters
76      * @return int
77      */
78     private function _compare($a, $b)
79     {
80         $a_q = isset($a['params']['q']) ? floatval($a['params']['q']) : 1.0;
81         $b_q = isset($b['params']['q']) ? floatval($b['params']['q']) : 1.0;
82         if ($a_q === $b_q) {
83             $a_count = count($a['params']);
84             $b_count = count($b['params']);
85             if ($a_count === $b_count) {
86                 if ($r = $this->_compareSubType($a['subtype'], $b['subtype'])) {
87                     return $r;
88                 } else {
89                     return $this->_compareSubType($a['type'], $b['type']);
90                 }
91             } else {
92                 return $a_count < $b_count;
93             }
94         } else {
95             return $a_q < $b_q;
96         }
97     }
98
99     /**
100      * Compare two subtypes
101      *
102      * @param string $a First subtype to compare
103      * @param string $b Second subtype to compare
104      * @return int
105      */
106     private function _compareSubType($a, $b)
107     {
108         if ($a === '*' && $b !== '*') {
109             return 1;
110         } elseif ($b === '*' && $a !== '*') {
111             return -1;
112         } else {
113             return 0;
114         }
115     }
116 }