forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			117 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			117 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|   | <?php | ||
|  | /** | ||
|  |  * Note : Code is released under the GNU LGPL | ||
|  |  * | ||
|  |  * Please do not change the header of this file | ||
|  |  * | ||
|  |  * This library is free software; you can redistribute it and/or modify it under the terms of the GNU | ||
|  |  * Lesser General Public License as published by the Free Software Foundation; either version 2 of | ||
|  |  * the License, or (at your option) any later version. | ||
|  |  * | ||
|  |  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | ||
|  |  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
|  |  * | ||
|  |  * See the GNU Lesser General Public License for more details. | ||
|  |  */ | ||
|  | 
 | ||
|  | /** | ||
|  |  * The AcceptHeader page will parse and sort the different | ||
|  |  * allowed types for the content negociations | ||
|  |  * | ||
|  |  * @author Pierrick Charron <pierrick@webstart.fr> | ||
|  |  */ | ||
|  | class AcceptHeader extends \ArrayObject | ||
|  | { | ||
|  |     /** | ||
|  |      * Constructor | ||
|  |      * | ||
|  |      * @param string $header Value of the Accept header | ||
|  |      * @return void | ||
|  |      */ | ||
|  |     public function __construct($header) | ||
|  |     { | ||
|  |         $acceptedTypes = $this->_parse($header); | ||
|  |         usort($acceptedTypes, [$this, '_compare']); | ||
|  |         parent::__construct($acceptedTypes); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Parse the accept header and return an array containing | ||
|  |      * all the informations about the Accepted types | ||
|  |      * | ||
|  |      * @param string $data Value of the Accept header | ||
|  |      * @return array | ||
|  |      */ | ||
|  |     private function _parse($data) | ||
|  |     { | ||
|  |         $array = []; | ||
|  |         $items = explode(',', $data); | ||
|  |         foreach ($items as $item) { | ||
|  |             $elems = explode(';', $item); | ||
|  | 
 | ||
|  |             $acceptElement = []; | ||
|  |             $mime = current($elems); | ||
|  |             list($type, $subtype) = explode('/', $mime); | ||
|  |             $acceptElement['type'] = trim($type); | ||
|  |             $acceptElement['subtype'] = trim($subtype); | ||
|  |             $acceptElement['raw'] = $mime; | ||
|  | 
 | ||
|  |             $acceptElement['params'] = []; | ||
|  |             while (next($elems)) { | ||
|  |                 list($name, $value) = explode('=', current($elems)); | ||
|  |                 $acceptElement['params'][trim($name)] = trim($value); | ||
|  |             } | ||
|  | 
 | ||
|  |             $array[] = $acceptElement; | ||
|  |         } | ||
|  |         return $array; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Compare two Accepted types with their parameters to know | ||
|  |      * if one media type should be used instead of an other | ||
|  |      * | ||
|  |      * @param array $a The first media type and its parameters | ||
|  |      * @param array $b The second media type and its parameters | ||
|  |      * @return int | ||
|  |      */ | ||
|  |     private function _compare($a, $b) | ||
|  |     { | ||
|  |         $a_q = isset($a['params']['q']) ? floatval($a['params']['q']) : 1.0; | ||
|  |         $b_q = isset($b['params']['q']) ? floatval($b['params']['q']) : 1.0; | ||
|  |         if ($a_q === $b_q) { | ||
|  |             $a_count = count($a['params']); | ||
|  |             $b_count = count($b['params']); | ||
|  |             if ($a_count === $b_count) { | ||
|  |                 if ($r = $this->_compareSubType($a['subtype'], $b['subtype'])) { | ||
|  |                     return $r; | ||
|  |                 } else { | ||
|  |                     return $this->_compareSubType($a['type'], $b['type']); | ||
|  |                 } | ||
|  |             } else { | ||
|  |                 return $a_count < $b_count; | ||
|  |             } | ||
|  |         } else { | ||
|  |             return $a_q < $b_q; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Compare two subtypes | ||
|  |      * | ||
|  |      * @param string $a First subtype to compare | ||
|  |      * @param string $b Second subtype to compare | ||
|  |      * @return int | ||
|  |      */ | ||
|  |     private function _compareSubType($a, $b) | ||
|  |     { | ||
|  |         if ($a === '*' && $b !== '*') { | ||
|  |             return 1; | ||
|  |         } elseif ($b === '*' && $a !== '*') { | ||
|  |             return -1; | ||
|  |         } else { | ||
|  |             return 0; | ||
|  |         } | ||
|  |     } | ||
|  | } |