source: spip-zone/_plugins_/gravatar/gravatar_fonctions.php @ 113876

Last change on this file since 113876 was 113876, checked in by cedric@…, 19 months ago

on peut forcer le refresh d'un gravatar d'un auteur depuis sa page dans ecrire/ avec un ?var_mode=recalcul

  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1<?php
2/**
3 *
4 * Gravatar : Globally Recognized AVATAR
5 *
6 * @package     plugins
7 * @subpackage  gravatar
8 *
9 * @author      Fil, Cedric, Thomas Beaumanoir
10 * @license     GNU/GPL
11 *
12 * @version     $Id: gravatar_fonctions.php 113876 2019-02-12 16:54:29Z cedric@yterium.com $
13 **/
14
15if (!defined("_ECRIRE_INC_VERSION")) return;
16
17// taille max des gravatars à récupérer sur le site
18if (!defined('_TAILLE_MAX_GRAVATAR')) define('_TAILLE_MAX_GRAVATAR',80);
19
20// le host vers gravatar
21if (!defined('_GRAVATAR_HOST')) define('_GRAVATAR_HOST','http://www.gravatar.com');
22
23// les caches
24if (!defined('_GRAVATAR_CACHE_DELAY_REFRESH')) define('_GRAVATAR_CACHE_DELAY_REFRESH',3600*24); // 24h pour checker un existant
25if (!defined('_GRAVATAR_CACHE_DELAY_CHECK_NEW')) define('_GRAVATAR_CACHE_DELAY_CHECK_NEW',3600*8); // 8h pour re-checker un user sans gravatar
26if (!defined('_GRAVATAR_CACHE_DELAY_LOCK')) define('_GRAVATAR_CACHE_DELAY_LOCK',3600*23); // 24h si gravatar nous a locke
27
28/**
29 * notre fonction de recherche de logo
30 *
31 * @deprecated obsolete, on la garde pour ne pas planter les squelettes non recalcules
32 * @param  string $email  Le mail qui sert a recuperer l'image sur gravatar.com
33 * @return Array          Le logo de l'utilisateur
34 */
35function calcule_logo_ou_gravatar($email) {
36        $a = func_get_args();
37        $email = array_shift($a);
38
39        // la fonction normale
40        $c = call_user_func_array('calcule_logo',$a);
41
42        // si elle repond pas, on va chercher le gravatar
43        if (!$c[0])
44                $c[0] = gravatar($email);
45
46        return $c;
47}
48
49/**
50 * Construit la balise HTML <img> affichant le gravatar
51 *
52 * @param  string $img    Chemin de l'image
53 * @param  string $alt    Texte alternatif
54 * @param  string $class  Classe facultativ
55 * @return string         Le code HTML
56 */
57function gravatar_balise_img($img,$alt="",$class=""){
58        $taille = taille_image($img);
59        list($hauteur,$largeur) = $taille;
60        if (!$hauteur OR !$largeur)
61                return "";
62        return
63        "<img src='$img' width='$largeur' height='$hauteur'"
64          ." alt='".attribut_html($alt)."'"
65          .($class?" class='".attribut_html($class)."'":'')
66          .' />';
67}
68
69
70/**
71 * pour 2.1 on se contente de produire une balise IMG
72 *
73 * @param  string $email        le mail qui sert a recuperer l'image sur gravatar.com
74 * @param  string $logo_auteur  Le logo de l'auteur s'il existe
75 * @param  bool $force          forcer le refresh du gravatar
76 * @return string               La balise IMG
77 */
78function gravatar_img($email, $logo_auteur='', $force = false) {
79        include_spip('inc/config');
80        $config = function_exists('lire_config')?lire_config('gravatar'):unserialize($GLOBALS['meta']['gravatar']);
81        $default = '404'; // par defaut rien si ni logo ni gravatar (consigne a passer a gravatar)
82        $image_default = ''; // image
83
84        if ($config
85          AND strlen($image_default=$config['image_defaut'])
86                AND strpos($image_default,".")===FALSE){
87                $default = $image_default; // c'est une consigne pour l'api gravatar
88                $image_default = ($default=='404')?'':'images/gravatar.png'; // si pas d'email, fournir quand meme une image
89        }
90
91        // retrouver l'image du mieux qu'on peut :
92        // logo_auteur si il existe
93        // ou gravatar si on a un email et si on trouve le gravatar
94        if (!$img = $logo_auteur){
95                if (!$g = gravatar($email,$default,$force)) // chercher le gravatar etendu pour cet email
96                        $img = '';
97                else
98                        $img = gravatar_balise_img($g, "", "spip_logo spip_logos photo avatar");
99        }
100        else {
101                // changer la class du logo auteur
102                $img = inserer_attribut($img, 'class', 'spip_logo spip_logos photo avatar');
103        }
104
105        // si pas de config, retourner ce qu'on a
106        if (!$config)
107                return $img;
108       
109        // ensuite le mettre en forme si les options ont ete activees
110        if (!$img
111                AND $image_default
112                AND $img = find_in_path($image_default))
113                $img = gravatar_balise_img($img, "", "spip_logo spip_logos photo avatar");
114
115        if (!$img)
116                return '';
117
118        // mises en formes optionnelles du gravatar
119        if ($config AND $t=$config['taille']){
120                $img = filtrer('image_passe_partout',$img,$t);
121                $img = filtrer('image_recadre',$img,$t,$t,'center');
122                $img = filtrer('image_graver',$img);
123        }
124
125        return $img;
126}
127
128/**
129 * Verifie (une fois) qu'un index index.php existe dans $tmp
130 *
131 * @staticvar boolean $done  True si la verif a deja ete faite
132 * @param     string  $tmp   Le repertoire dans lequel on posera le gravatar
133 * @return    null
134 */
135function gravatar_verifier_index($tmp) {
136        static $done = false;
137        if ($done) return;
138        $done = true;
139        if (!file_exists($tmp.'index.php'))
140                ecrire_fichier ($tmp.'index.php', '<?php
141        foreach(glob(\'./*.jpg\') as $i)
142                echo "<img src=\'$i\' />\n";
143?>'
144                );
145}
146
147/**
148 * Recupere l'image sur www.gravatar.com et la met en cache
149 *
150 * @staticvar int         $nb       le nombre max d'anciens
151 * @staticvar int         $max      le nombre max de nouveaux
152 * @param     string      $email    le mail qui va servir pour calculer le gravatar
153 * @param     int|string  $default  gravatar par defaut : 404 ou identicon/monsterid/wavatar
154 * @param     bool        $force    forcer le refresh synchrone
155 * @return    null|string           le chemin du fichier gravatar, s'il existe
156 */
157function gravatar($email, $default='404', $force=false) {
158        static $nb=5; // ne pas en charger plus de 5 anciens par tour
159        static $max=10; // et en tout etat de cause pas plus de 10 nouveaux
160
161        // eviter une requete quand l'email est invalide
162        if (!$email=trim($email)
163                OR !strlen($email)
164                OR !email_valide($email))
165                return '';
166
167        $tmp = sous_repertoire(_DIR_VAR, 'cache-gravatar');
168        $lock_file = $tmp."gravatar.lock";
169
170
171        $md5_email = md5(strtolower($email));
172        // privacy : http://archive.hack.lu/2013/dbongard_hacklu_2013.pdf
173        // eviter de rendre les emails retrouvables par simple reverse sur le md5 de gravatar
174        if (!isset($GLOBALS['meta']['gravatar_salt'])){
175                include_spip('inc/acces');
176                include_spip('auth/sha256.inc');
177                ecrire_meta('gravatar_salt', _nano_sha256($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SERVER_SIGNATURE"] . creer_uniqid()), 'non');
178        }
179        if (function_exists("sha1"))
180                $gravatar_id = sha1(strtolower($email).$GLOBALS['meta']['gravatar_salt']);
181        else
182                $gravatar_id = md5(strtolower($email).$GLOBALS['meta']['gravatar_salt']);
183
184        $gravatar_default = '';
185        if (in_array($default,array('404','mm','identicon','monsterid','wavatar','retro'))){
186                $gravatar_default = $default;
187                $default = '';
188        }
189        elseif(strpos($default,".")!==false AND file_exists($default)){
190                $gravatar_default = '404';
191        }
192        else{
193                $default = '';
194        }
195
196        $gravatar_id .= ($gravatar_default=='404'?"":"-$gravatar_default");
197        $gravatar_cache = $tmp.$gravatar_id.'.jpg';
198        $gravatar_vide = $tmp.$gravatar_id.'.vide';
199
200        $gravatar = "";
201        // On verifie si le gravatar existe en controlant la taille du fichier
202        if (@filesize($gravatar_cache)) {
203                $gravatar = $gravatar_cache;
204        }
205        // sinon si default est un chemin d'image, le prendre en fallback
206        elseif($default){
207                $gravatar = $default;
208        }
209
210
211        // si on est locke, on utilise ce qu'on a
212        if (file_exists($lock_file)
213                AND $_SERVER['REQUEST_TIME']-filemtime($lock_file)<_GRAVATAR_CACHE_DELAY_LOCK){
214                return $gravatar;
215        }
216
217        // si on a un cache valide, on l'utilise
218        if ($gravatar==$gravatar_cache and !$force){
219                $duree = $_SERVER['REQUEST_TIME']-filemtime($gravatar_cache);
220                if ($duree<_GRAVATAR_CACHE_DELAY_REFRESH OR $nb--<=0){
221                        return $gravatar;
222                }
223                spip_log("Actualiser gravatar existant $email anciennete $duree s (cache maxi " . _GRAVATAR_CACHE_DELAY_REFRESH . "s)", "gravatar");
224                @touch($gravatar_cache); // un touch pour eviter une autre mise a jour concurrente
225        }
226        // si c'est un email sans gravatar connu (deja verifie), on ne reverifie pas que passe un delai suffisant
227        else {
228                // si un fichier vides.txt existe encore, le transformer en touch unitaires
229                lire_fichier($tmp . 'vides.txt', $vides);
230                if ($vides AND $vides = @unserialize($vides)){
231                        foreach($vides as $id=>$t){
232                                @touch($tmp.$id.".vide",$t);
233                        }
234                        @unlink($tmp . 'vides.txt');
235                }
236
237                if (file_exists($gravatar_vide)){
238                        $duree_vide = $_SERVER['REQUEST_TIME']-filemtime($gravatar_vide);
239                        if ($duree_vide<_GRAVATAR_CACHE_DELAY_CHECK_NEW OR $nb--<=0){
240                                return $gravatar;
241                        }
242                        // un actualise un gravatar vide que si c'est celui du visiteur identifie
243                        if ($force
244                          OR (isset($GLOBALS['visiteur_session']['email']) AND $GLOBALS['visiteur_session']['email']===$email)
245                          OR (isset($GLOBALS['visiteur_session']['session_email']) AND $GLOBALS['visiteur_session']['session_email']===$email) ){
246                                spip_log("Actualiser gravatar vide $email $duree_vide s (cache maxi " . _GRAVATAR_CACHE_DELAY_CHECK_NEW . "s)", "gravatar");
247                                @touch($gravatar_vide); // un touch pour eviter une autre mise a jour concurrente
248                        }
249                        else {
250                                return $gravatar;
251                        }
252                }
253                else {
254                        spip_log("Recherche nouveau gravatar $email", "gravatar");
255                }
256        }
257
258        // pas trop de requetes sur un seul tour
259        if ($max--<=0){
260                return $gravatar;
261        }
262
263        include_spip("inc/distant");
264        spip_timer('gravatar');
265        $url_gravatar = _GRAVATAR_HOST
266                . '/avatar/'
267                . $md5_email
268                . ".jpg"
269                . ($gravatar_default ? "?d=$gravatar_default" : "")
270                . "&s=" . _TAILLE_MAX_GRAVATAR;
271
272        // recuperation OK ?
273        $GLOBALS['inc_distant_allow_fopen'] = false; // pas de fallback sur fopen si on est bloque par gravatar.com
274        $gravatar_bin = recuperer_page($url_gravatar);
275        unset($GLOBALS['inc_distant_allow_fopen']);
276        $dt = spip_timer('gravatar', true);
277        if ($gravatar_bin){
278                spip_log('recuperer gravatar OK pour ' . $email,"gravatar");
279                ecrire_fichier($gravatar_cache, $gravatar_bin);
280                // si c'est un png, le convertir en jpg
281                $a = @getimagesize($gravatar_cache);
282                // png ?
283                if ($a[2]==3) {
284                        // pour eviter un warning sous windows si le fichier existe deja
285                        if (file_exists($gravatar_cache . '.png')){
286                                @unlink($gravatar_cache . '.png');
287                        }
288                        rename($gravatar_cache, $gravatar_cache . '.png');
289                        include_spip('inc/filtres_images');
290                        include_spip('inc/filtres_images_mini');
291                        $img = imagecreatefrompng($gravatar_cache . '.png');
292                        // Compatibilite avec la 2.1
293                        if (function_exists('_image_imagejpg')){
294                                _image_imagejpg($img, $gravatar_cache);
295                        }
296                        else {
297                                image_imagejpg($img, $gravatar_cache);
298                        }
299                }
300                else {
301                        if (file_exists($gravatar_cache . '.png')){
302                                @unlink($gravatar_cache . '.png');
303                        }
304                }
305                if (file_exists($gravatar_vide)){
306                        @unlink($gravatar_vide);
307                }
308
309                if ($gravatar!==$gravatar_cache){
310                        gravatar_verifier_index($tmp);
311                        $gravatar = $gravatar_cache;
312                }
313        }
314        else {
315                // si ca a ete trop long, ne pas ressayer (IP serveur ban par gravatar ?)
316                if ($dt>10000){
317                        $nb = 0;
318                        @touch($lock_file);
319                        spip_log("gravatar.com trop long a repondre pour $email ($dt), on lock $lock_file", "gravatar");
320                }
321                else {
322                        spip_log('gravatar vide pour ' . $email,"gravatar");
323                }
324                // si on a pas eu de reponse mais qu'un cache existe le prolonger pour eviter de rechecker tout le temps
325                if ($gravatar===$gravatar_cache){
326                        @touch($gravatar_cache);
327                }
328                else {
329                        @touch($gravatar_vide);
330                }
331        }
332
333        return $gravatar;
334}
Note: See TracBrowser for help on using the repository browser.