<?php
$favIcon = new Favicon($urlSite); //$urlSite est l'url de la page dont vous voulez le favicon
$urlFav = $favIcon->getFavicon();
?>
Par contre, c'est un peu le bordel pour récupérer un favicon. Entre les différents attributs "type" ou "rel" ainsi que les différentes valeurs possible "icon", "favicon" et plein d'autre de la balise link. Il y a aussi le cas par défaut du favicon.ico. Et après, c'est pas fini! Certains sont en liens relatifs, d'autres en absolus. Après, il y a les liens cassés qui pointent sur une belle page 404. Tout ça est géré. Si une page n'a pas de favicon et qu'il n'y a pas de favicon.ico, j'analyse la page de la racine du site. En fait, j'ai fait ça pour Aeres, certaine page étant le flux RSS directement, je me suis dit que ça serait bien de récupérer le favicon du site.
<?php
/**
* Cette classe me permet de récupérer facilement le favicon d'un site
*
* L'utilisation de cette classe est ultra basique :
* $favIcon = new Favicon($urlSite);
* $urlFav = $favIcon->getFavicon();
*
* Copyright 2012-2013 Superbaillot
* This file is part of Superbaillot's Project.
*
* Superbaillot's Project is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Superbaillot's Project 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.
*
*/function sky_curl_get_file_contents( $URL ){
$c = curl_init();
curl_setopt( $c, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $c, CURLOPT_URL, $URL );
$contents = curl_exec( $c );
curl_close( $c );
if( $contents ) :
return $contents;
else:
return false;
endif;
}
class Favicon
{
private $urlSite="";
public function getUrlSite(){return $this->urlSite;}
public function setUrlSite($urlSite){ $this->urlSite = trim($urlSite);}
public function __construct($url)
{
$this->setUrlSite($url);
}
/**
* fonction qui va récupérer le favicon d'un site s'il existe.
* @return String : url du favicon
*/
public function getFavicon()
{
$urlFav = "";
$urlFavSecour = "";
$nomFichier = "";
$trouver = false;
$url = $this->getUrlSite();
$info = parse_url($url);
$pro = $info['scheme'] . "://";
$urlRacine = $info['host'];
$url = $urlRacine . (isset($info['path']) ? $info['path'] : "");
$contenuLigne = "";
//on va essayer de récuperer le favicon de la page
if ($fichier = sky_curl_get_file_contents($this->getUrlSite()))
{
//je sais, c'est moche, mais je ne suis pas un pro des regex, alors je fais ça en plusieurs fois
//si je m'améliore, je pourrais essayer de faire ça en une regex
$recherche = "#rel=[\",'].*icon[\",'].+href=[\",'](.+)[\",']#i";
$recherche2 = "#type=[\",'].*icon[\",'].+href=[\",'](.+)[\",']#i";
$recherche3 = "#href=[\",'](.+)[\",'].+rel=[\",'].*icon[\",']#i";
$recherche4 = "#href=[\",'](.+)[\",'].+type=[\",'].*icon[\",']#i";
$finHead = false;
$lignes = explode("\n", $fichier);
// while( $ligne = @fgets($fichier))
foreach ($lignes as $ligne)
{
//il m'est arrivé de voir la balise <link> sur 2 lignes, donc je concatène au cas ou. Quand je trouverais une correspondance, je réinitialise la variable dans le cas où ne autre balise ait l'attribut "href"
$contenuLigne .= trim($ligne);
//je m'arrete si on est plus dans le head
if(strpos(strtolower($contenuLigne), "</head") === 0 || $finHead)
{
break;
}
//il m'est arrivé de voir plusieurs balises sur une ligne, on va donc analyser balise par balise
$listeBalise = explode(">", $contenuLigne);
foreach($listeBalise as $balise)
{
if(strpos(strtolower($balise), "</head") !== false)
{
$finHead = true;
break;
}
$contenuLigne = "$balise ";
//je teste les différents regex
$temp = preg_match_all($recherche, $balise, $data);
if($temp>0)
{
$urlFav = $data[1][count($data[0])-1];
$trouver = true;
break;
}
$temp = preg_match_all($recherche2, $balise, $data);
if($temp>0)
{
$urlFav = $data[1][count($data[0])-1];
$trouver = true;
break;
}
$temp = preg_match_all($recherche3, $balise, $data);
if($temp>0)
{
$urlFav = $data[1][count($data[0])-1];
$trouver = true;
break;
}
$temp = preg_match_all($recherche4, $balise, $data);
if($temp>0)
{
$urlFav = $data[1][count($data[0])-1];
$trouver = true;
break;
}
}
//si on a trouvé un favicon, on s'arrête
if($trouver)
{
break;
}
}
@fclose($fichier);
$urlFavSecour = "$pro" . "$urlRacine/favicon.ico";
//si je n'ai pas trouvé de favicon défini dans la page, on va chercher le favicon par défaut
if(!$trouver)
{
if (Favicon::imageExiste($urlFavSecour))
{
$urlFav = $urlFavSecour;
$trouver = true;
}
//si le favicon par défaut n'existe pas non plus, je vais chercher, si c'est pas encore le cas, le favicon défini à la racine du site
//c'est utile, par exemple, dans le cas de l'url d'un flux RSS qui n'aura pas de favicon, mais le site peut en avoir
elseif($pro . $urlRacine != trim($this->getUrlSite()) && $pro . $urlRacine . "/" != trim($this->getUrlSite()))
{
$favIcon = new Favicon($pro . $urlRacine);
$urlFav = $favIcon->getFavicon();
if($urlFav != "")
{
$trouver = true;
}
}
}
}
//si j'ai trouvé un favicon, je fais quelques vérifications
if($trouver)
{
//j'ai eu le cas où il y a d'autres attribus dans le String récupérés.
//on va donc les virer
$pos=strpos($urlFav, "'");
if($pos >0)
{
$urlFav = substr($urlFav, 0, $pos);
}
else
{
$pos=strpos($urlFav, "\"");
if($pos >0)
{
$urlFav = substr($urlFav, 0, $pos);
}
}
//j'ai eu le cas où il y avait des paramètres dans l'url, je me suis posé la question de savoir si je les garde ou non, j'ai décidé que non
$recherche = "#(.+)[?].*#i";
$temp = preg_match_all($recherche, $urlFav, $data);
if($temp>0)
{
$urlFav = $data[1][count($data[0])-1];
}
//si le chemin est relatif, je le transforme en absolu
if(strpos($urlFav, "http") === false)
{
//dans certains cas, l'url est absolue, mais sans le http.
//on va donc tester si c'est le cas
$urlFavTemp = Favicon::nettoieURL("http://" . $urlFav);
if (Favicon::imageExiste($urlFavTemp))
{
$urlFav = $urlFavTemp;
}
//si elle n'existe pas, c'est que c'est un chemin relatif. On le transforme donc en absolu
else
{
$urlFav = $pro."$url/$urlFav";
}
}
//j'enlève tous les doubles /
$urlFav = Favicon::nettoieURL($urlFav);
$trouver = false;
//on vérifie que le fichier icone existe bien et est accessible (j'ai eu le cas d'erreur 503)
if (!Favicon::imageExiste($urlFav))
{
//si l'image n'existe pas, et que l'on a pas testé le fichier favicon.ico par défaut, on le teste
if($urlFav != $urlFavSecour && Favicon::imageExiste($urlFavSecour))
{
$urlFav = $urlFavSecour;
$trouver = true;
}
else
{
$urlFav = "";
}
}
else
{
$trouver = true;
}
//si on n'a pas de favicon, on renvoie une chaine vide
if(!$trouver)
{
$urlFav = "";
}
}
else
{
$urlFav = "";
}
return $urlFav;
}
/**
* fonction qui enlève les doubles slash dans une url
* @param $url String : url à nettoyer
* @return url nettoyé
*/
public static function nettoieURL($url)
{
//j'enlève tous les doubles
$url = preg_replace("#[/]+#", "/", $url);
//je rajoute le double / apres le http:
$url = preg_replace("#:/#", "://", $url);
return $url;
}
/**
* fonction qui vérifie si l'image existe.
* Gros bordel cette fonction : fopen peut renvoyer une page html si l'image n'est pas disponible. Dans ce cas, je teste si on a une balise <body> dans le fichier reçu.
* Il n'est pas impossible de trouver cette suite de caractère dans une image, mais trés peu problable, donc je m'en satisfais
* J'ai encore pas réglé le cas ou l'image est corrompu…
* @param $url String : url de l'image
* @return boolean
*/
public static function imageExiste($url)
{
$extension = strtolower(pathinfo($url, PATHINFO_EXTENSION));
$valide = false;
//si c'est un type d'image que gère php, j'essaie de l'ouvrir.
//si on y arrive, c'est bien une image
switch($extension)
{
case "jpg" :
case "jpeg" :
$valide = @ImageCreateFromJpeg($url);
break;
case "png" :
$valide = @ImageCreateFromPng($url);
break;
case "gif" :
$valide = @ImageCreateFromGif($url);
break;
//si ce n'est pas un format connu, (un fichier ico par exemple),
//je fais des tests un peu foireu, mais qui marchent dans la plupart des cas.
default:
if($fichier = @fopen($url, "rb"))
{
//dans certain cas, j'ai eu un fichier vide, donc fopen marche et je ne trouve pas de balise, mais ce n'est pas une image pour autant
$vide = true;
//dans certains cas, on a une page html d'erreur et donc fopen marche
//je cherche donc une balise qui est sensé être dans une page html : <body> (j'ai pas mis <html> car bizarement, je suis déjà tombé sur un cas où elle n'était pas là...)
while ($temp = @fgets($fichier))
{
$nb = preg_match("#<body#i", trim($temp), $data);
if($nb>0)
{
return false;
}
//on sauve le fait que le fichier n'est pas vide
if(trim($temp) != "")
{
$vide = false;
}
}
@fclose($fichier);
//si le fichier est vide, cela signifie que ce n'est pas une image
if($vide)
{
return false;
}
//ça a bien l'air d'être une icone valide
return true;
}
}
if($valide)
{
return true;
}
return false;
}
}
?>
CLE=Votre texte. ou CLE=le texte d'un autre vaut %arg%.Le texte peut contenir un ou plusieurs arguments. Ce sont des élements que vous passez en paramètres et qui vont s'incorporer dans le texte final. Pour ce faire, il faut utiliser un symbole spécial. J'ai choisi %arg%, mais si ça ne vous plait pas, vous pouvez le changer facilement, il est aussi défini en début de classe ($ARG).
<?php
$lang = new Langue($rep, $fichier);
?>
Ensuite, pour afficher le texte, il suffit d'appeler la clé correspondante avec d'éventuels paramètres :
<?php
$lang->get('CLE');
pseudo = 'bob';
$texte = $lang->get('CLE_DE_MON_TEXTE', $pseudo);
$pseudo = 'bob';
$age = '900 ans';
$texte = $lang->get('CLE_DE_MON_TEXTE', $pseudo, $age);
?>
<?php
/**
* Cette classe me permet de gérer un fichier de langue.
*
* Apres avoir chargé un fichier, l'utilisation est basique.
* Pour appeler un texte, il faut connaitre la clé corresondante et l'appel se fait grace à la méthode get().
* Cette méthode renvoie TOUJOURS un string, si la clé n'a pas été trouvé, elle affiche un String par défaut.
*
* Ex :
* $lang = new Langue($rep, $fichier);
* ...
* $texte = $lang->get('CLE_DE_MON_TEXTE');
*
*
* Si vous avez besoin de remplacer un mot dans une phrase, vous pouvez utiliser le symbole défini par $ARG.
* Il sera alors remplacé par le deuxième paramètre de la fonction get()
*
* Ex :
* $lang = new Langue($rep, $fichier);
* ...
* $pseudo = "bob";
* ...
* $texte = $lang->get('CLE_DE_MON_TEXTE', $pseudo);
*
*
* Si vous avez besoin de remplacer plusieurs mots dans une phrase, vous pouvez utiliser plusieur fois le symbole défini par $ARG.
* Utilisez autant de paramètres que de mots à remplacer. Ces mots seront alors remplacés dans l'ordre.
*
* Ex :
* $lang = new Langue($rep, $fichier);
* ...
* $pseudo = "bob";
* $age = "900 ans";
* ...
* $texte = $lang->get('CLE_DE_MON_TEXTE', $pseudo, $age);
*
*
*
* Copyright 2012-2013 Superbaillot
* This file is part of Aeres.
*
* Aeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Aeres 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.
*
*/
class Langue {
public static $EXTENTION_LANGUE = "lang";
private static $ARG = "%arg%"; //définition des paramètres dans le fichier .lang
private static $ARG_REMPLACEMENT = " "; //définition du paramètre de remplacement.
//si dans la valeur du paramètre de remplacement, il y a $ARG, on va le remplacer pour ne pas avoir de boucle infinie.
private $repertoire = ""; //répertoire qui contient les fichiers de langue
private $nom = ""; //nom du langage (le nom du fichier sans l'extention)
private $liste = array(); //tableau qui associe une clé à un texte traduit
public function getNom(){return $this->nom;}
public function setNom($nom)
{
//si le nom est modifié, il faut recharger la liste
if($nom != $this->nom)
{
$this->nom = $nom;
$this->charger();
}
}
public function getListe(){return $this->liste;}
public function setListe($liste){$this->liste = $liste;}
public function getRepertoire(){return $this->repertoire;}
public function setRepertoire($repertoire)
{
if($repertoire == "")
{
$repertoire = ".";
}
$this->repertoire = $repertoire;
}
/**
* lors de la construction de l'objet, on charge le fichier (le chargement se fait dans setNom())
* @param $repertoire String : chemin du répertoire contenant les fichiers lang
* @param $fichier String : nom du fichier sans l'extension (pas le chemin complet)
*/
public function __construct($repertoire, $fichier)
{
$this->setRepertoire($repertoire);
$this->setNom($fichier);
}
/**
* méthode qui charge le tableau de langue avec le fichier
*/
private function charger()
{
$liste = array();
$pathFichier = $this->getRepertoire() . $this->getNom() . "." . Langue::$EXTENTION_LANGUE;
verifChemin($pathFichier);
//si le fichier existe, je le charge, sinon, je ne charge rien et Chewbacca fera le reste.
if(file_exists($pathFichier))
{
$file = fopen($pathFichier, 'r');
while($ligne = fgets($file))
{
$info = explode("=",$ligne,2);
$liste[$info[0]] = $info[1];
}
fclose($file);
}
$this->setListe($liste);
}
/**
* fonction qui renvoie la traduction pour une clé donnée
* @param $cle String
* @param $param... le nombre de parametres varie en fonction du nombre de terme à remplacer
* @return String : traduction
*/
public function get()
{
$nbArg = func_num_args();
$cle = func_get_arg(0); //le premier paramètre est toujours la clé, les suivants seront les mots à remplacer
$cptArg = 1; //va servir à chercher le paramètre suivant
$motRemplace = "";
//si la clé se trouve dans le tableau, on va chercher sa valeur
if(array_key_exists($cle, $this->getListe()))
{
$retour = $this->liste[$cle];
//tant qu'on trouve un "paramètre", on le remplace et on recommence avec le mot suivant
while (($pos = strpos($retour, Langue::$ARG)) !== false)
{
//on met à jour le mot de remplacement
if($nbArg > $cptArg)
{
$motRemplace = func_get_arg($cptArg);
$cptArg++;
}
//si $ARG se trouve dans $motRemplace, on a une boucle infinie
$motRemplace = str_replace(Langue::$ARG, Langue::$ARG_REMPLACEMENT, $motRemplace);
$retour = substr_replace($retour, "$motRemplace", $pos, strlen(Langue::$ARG));
}
return trim($retour, "\t\n\r");
}
else
{
//si la clé n'existe pas, c'est Chewbacca qui le traduit
//bon, j'affiche quand même la clé qui pose problème
return $cle . " : " . $this->tradChewbacca();
}
}
/**
* traduction de Chewbacca
* @return String Wookie
*/
private function tradChewbacca()
{
$trad = "";
$rand = rand(1, 10);
for($i = 0; $i < $rand; $i++)
{
$trad .= "R";
}
$rand = rand(1, 10);
for($i = 0; $i < $rand; $i++)
{
$trad .= "r";
}
$rand = rand(1, 10);
for($i = 0; $i < $rand; $i++)
{
$trad .= "R";
}
$rand = rand(1, 10);
for($i = 0; $i < $rand; $i++)
{
$trad .= "!";
}
return $trad;
}
}
?>
Je ne vous demande pas grand chose, mais je me réserve le droit de supprimer une partie ou l'intégralité des messages qui ne respectes pas ces règles.
Je me réserve le droit de supprimer une partie ou l'intégralité des messages pour d'autres raisons que je préciserais le cas échéant.
Ces règles sont donc susceptibles d'évoluer, n'hésitez pas à revenir y jeter un oeil plus tard.