Le menu
À retenir
Outils
- Convertisseur de code source en HTML
- Générateur de lien en (x)HTML
- Traduction Français-Esperanto online
Vie pratique
Portfolio
Présidentielles
Culture
- Respect des droits d'auteurs et droits voisins — Refus des Mesures Techniques de Protection (MTP)
- Licence globale : finalement je suis contre...
- Lettre à la SACEM : Réaction par rapport au projet de loi DADVSI
- Reprenons en main la culture !
- Gestion Numérique des droits (DRM) : une question de confiance
- Gestion Numérique des droits (DRM) : une question de confiance (2)
Archives
- Septembre 2008
- Aout 2008
- Juillet 2008
- Juin 2008
- Mai 2008
- Avril 2008
- Mars 2008
- Février 2008
- Janvier 2008
- Décembre 2007
- Novembre 2007
- Octobre 2007
- Septembre 2007
- Aout 2007
- Juillet 2007
- Juin 2007
- Mai 2007
- Avril 2007
- Mars 2007
- Février 2007
- Janvier 2007
- Décembre 2006
- Novembre 2006
- Octobre 2006
- Septembre 2006
- Aout 2006
- Juillet 2006
- Juin 2006
- Mai 2006
- Avril 2006
- Mars 2006
- Février 2006
- Janvier 2006
- Décembre 2005
- Novembre 2005
- Octobre 2005
- Septembre 2005
- Aout 2005
- Juillet 2005
- Juin 2005
- Mai 2005
- Avril 2005
- Mars 2005
- Février 2005
- Janvier 2005
- Décembre 2004
- Novembre 2004
- Octobre 2004
Spornikethon
- Mes créations vous plaisent ?
- Vous voulez me soutenir financièrement ?
- Cliquez sur un des boutons ci-dessous selon le montant du dons.
- Merci !
Rouleaux de blogs
Mes préférés
Les amis
- Les bla-blas de Chibi
- Lysel
- Orpheelin
- Nae-chan in Psycholand
- Circée
- Faery Book
- Les bijoux de Hime-Decco
Divers
Mes liens
- Non à la brevetabilité des logiciels en Europe
- Promotion d'artistes proposant de la musique légale et gratuite à télécharger
- Associations pour le Maintien d’une Agriculture Paysanne
- La Bible
- Wikipédia
- Le Trésor de la Langue Française Informatisé
- Liste prête à l'emploi pour Adblock
- Partitions pour guitare classique
- Forum francophone pour les collectionneurs et créateurs de poupées
- Association sportive et culturelle du 13ème arrondissement
Bombardement Google
UserAgentCapabilities : faciliter la négociation du contenu
Le 15 Février 2005 à 16:33
Objectifs
Afin de renvoyer au client le contenu le plus adapté, on va examiner ses capacités. Deux objectifs pour cette première version :
- Examen des langues acceptées, afin de servir si possible dans la langue du client.
- Examen des contenus acceptés, ce qui peut permettre, par exemple, de renvoyer un contenu en XHTML ou en WML.
Code source
<?php /* (c)2004 David Sporn This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2.1 as published by the Free Software Foundation. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ class UserAgentCapabilities { var myLanguages ; var myAccepts ; function UserAgentCapabilities() { //Init languages capabilities $this->myLanguages = array() ; if (@$_SERVER["HTTP_ACCEPT_LANGUAGE"]) { $langs_list = explode(',',@$_SERVER["HTTP_ACCEPT_LANGUAGE"]) ;// each language is separated by a "," foreach($langs_list as $lang_item) { $lang_parts = explode(';',$lang_item) ; //the pattern is "lang[;q=quality]" if (!preg_match('/^[a-z]{1,8}(?:[-][a-z]{1,8}){0,8}$/i', $lang_parts[0])) //skip invalid language names or too long names { continue ; } $quality_value = (float)1.0 ; //Default value if (1 < $lang_parts.length) { if (preg_match('/q=(0(?:.d{1,3})?)|(1(?:.[0]{1,3})?)/', $lang_parts[1],$values_array)) { $quality_value = (float)$values_array[1] ; } } if ($this->myLanguages[$quality_value]) { $this->myLanguages[$quality_value] += ','.$lang_parts[0] ; } else { $this->myLanguages[$quality_value] = $lang_parts[0] ; } } krsort($this->myLanguages) ; } //Init accept-content capabilities /* source : http://www.ietf.org/rfc/rfc1700.txt Recognized Content Types and Subtypes (exhaustive) -------------------------------------------------- Type Subtype Description Reference ---- ------- ----------- --------- text plain [RFC1521,NSB] xml [?] html [?] application octet-stream [RFC1521,NSB] xml [?] xhtml+xml [?] image jpeg [RFC1521,NSB] gif [RFC1521,NSB] png [?] Generic types (text/*, application/* and image/* are also recognized) Not recognised Content Types and Subtypes (non exhaustive) -------------------------------------------------- Type Subtype Description Reference ---- ------- ----------- --------- text richtext [RFC1521,NSB] tab-separated-values [Paul Lindner] multipart mixed [RFC1521,NSB] alternative [RFC1521,NSB] digest [RFC1521,NSB] parallel [RFC1521,NSB] appledouble [MacMime,Patrik Faltstrom] header-set [Dave Crocker] message rfc822 [RFC1521,NSB] partial [RFC1521,NSB] external-body [RFC1521,NSB] news [RFC 1036, Henry Spencer] image ief Image Exchange Format [RFC1314] tiff Tag Image File Format [MTR] application postscript [RFC1521,NSB] oda [RFC1521,NSB] atomicmail [atomicmail,NSB] andrew-inset [andrew-inset,NSB] slate [slate,terry crowley] wita [Wang Info Transfer,Larry Campbell] dec-dx [Digital Doc Trans, Larry Campbell] dca-rft [IBM Doc Content Arch, Larry Campbell] activemessage [Ehud Shapiro] rtf [Paul Lindner] applefile [MacMime,Patrik Faltstrom] mac-binhex40 [MacMime,Patrik Faltstrom] news-message-id [RFC1036, Henry Spencer] news-transmission [RFC1036, Henry Spencer] wordperfect5.1 [Paul Lindner] pdf [Paul Lindner] zip [Paul Lindner] macwriteii [Paul Lindner] msword [Paul Lindner] remote-printing [RFC1486,MTR] audio basic [RFC1521,NSB] video mpeg [RFC1521,NSB] quicktime [Paul Lindner] */ $this->myAccepts = array() ; if (@$_SERVER["HTTP_ACCEPT"]) { $pattern_any_type = '(\*/\*)' ; $pattern_text_type = '(text/(\*)|(html)|(xml)|(plain))' ; $pattern_image_type = '(image)/(\*)|(jpg)|(gif)|(jpeg)|(png)' ; $pattern_application_type = '(application)/(\*)|(octet-stream)|(xml)|(xhtml+xml)' ; $accepts_list = explode(',',@$_SERVER["HTTP_ACCEPT"]) ;// each content-type is separated by a "," foreach($accepts_list as $accept_item) { $accept_parts = explode(';',$accept_item) ; //the pattern is "lang[;q=quality]" if (!preg_match('/^'.$pattern_any_type.'|'.$pattern_text_type.'|' .$pattern_image_type.'|'.$pattern_application_type.'$/i' ,$accept_parts[0])) //keep recognized type names only { continue ; } $quality_value = (float)1.0 ; //Default value if (1 < $accept_parts.length) { if (preg_match('/q=(0(?:.d{1,3})?)|(1(?:.[0]{1,3})?)/', $accept_parts[1],$values_array)) { $quality_value = (float)$values_array[1] ; } } if ($this->myAccepts[$quality_value]) { $this->myAccepts[$quality_value] += ','.$accept_parts[0] ; } else { $this->myAccepts[$quality_value] = $accept_parts[0] ; } } krsort($this->myAccepts) ; } } /**Get a comma separated list of languages. * The returned list contains all the preferred languages of the user agent * (with a quality value of 1). */ function getPreferredLanguages() { if ($this->myLanguages.length) { reset($this->myLanguages) ; return current($this->myLanguages) } else { return '' ; } } /**Get the best match among a list of specified language. * The best match means that it has the best quality value here. * If there are more that one answer, the first language in the * provided list is returned. * @param languages a list of language, the most preferred first. * @return the language code that has the best match. Empty if the language does not exists. */ function getBestLanguage($languages) { $retour_language = '' ; $score_language = -1 ; if ($languages.length && $this->myLanguages.length) { //Looks for an exact match first foreach($languages as $candidate_language) { $language_index = 0 ; foreach($this->myLanguages.length as $languages_list) { if (0 <= $score_language && $language_index >= $score_language) { break ; //Not a better match } $languages_match = explode(',',$languages_list) ; foreach($languages_match as $languages_item) { if ($candidate_language == $languages_item) { $score_language = $language_index ; $retour_language = $candidate_language ; break 2; //WARNING//==> foreach($this->myLanguages.length as $languages_list) } } $language_index++ ; } } if (0 <= $score_language) { return $retour_language ; //Exact match } //Looks for an close match //for instance, 'fr-FR' is a close match for 'fr' foreach($languages as $candidate_language) { $language_index = 0 ; foreach($this->myLanguages.length as $languages_list) { if (0 <= $score_language && $language_index >= $score_language) { break ; //Not a better match } $languages_match = explode(',',$languages_list) ; foreach($languages_match as $languages_item) { if (stripos($candidate_language == $languages_item) == 0) //starts with $candidate_language { $score_language = $language_index ; $retour_language = $candidate_language ; break 2; //WARNING//==> foreach($this->myLanguages.length as $languages_list) } } $language_index++ ; } } if (0 <= $score_language) { return $retour_language ; //Exact match } } return '' ; } /**Get a comma separated list of languages. * The returned list contains all the preferred languages of the user agent * (with a quality value of 1). */ function getPreferredContentType() { if ($this->myAccepts.length) { reset($this->myAccepts) ; return current($this->myAccepts) } else { return '' ; } } /**Get the best match among a list of specified content type. * The best match means that it has the best quality value here. * If there are more that one answer, the first content type in the * provided list is returned. * @param contentTypes a list of content types, the most preferred first. * @return the content type code that has the best match. Empty if the content type does not exists. */ function getBestContentType($contentTypes) { $retour_content_type = '' ; $score_content_type = -1 ; if ($contentTypes.length && $this->myAccepts.length) { //Looks for an exact match first foreach($contentTypes as $candidate_content_type) { $content_type_index = 0 ; foreach($this->myAccepts.length as $content_types_list) { if (0 <= $score_content_type && $content_type_index >= $score_content_type) { break ; //Not a better match } $content_types_match = explode(',',$content_types_list) ; foreach($content_types_match as $content_types_item) { if ($candidate_content_type == $content_types_item) { $score_content_type = $content_type_index ; $retour_content_type = $candidate_content_type ; break 2; //WARNING//==> foreach($this->myAccepts.length as $content_types_list) } } $content_type_index++ ; } } if (0 <= $score_content_type) { return $retour_content_type ; //Exact match } } return '' ; } } ?>