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;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |