[ Index ] |
|
Code source de SPIP 1.8.3 |
1 <?php 2 3 /***************************************************************************\ 4 * SPIP, Systeme de publication pour l'internet * 5 * * 6 * Copyright (c) 2001-2005 * 7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * 8 * * 9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * 10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * 11 \***************************************************************************/ 12 13 14 // Ce fichier ne sera execute qu'une fois 15 if (defined("_ECRIRE_INC_CRON")) return; 16 define("_ECRIRE_INC_CRON", "1"); 17 18 // -------------------------- 19 // Gestion des taches de fond 20 // -------------------------- 21 22 // Deux difficultes: 23 // - la plupat des hebergeurs ne fournissent pas le Cron d'Unix 24 // - les scripts usuels standard sont limites a 30 secondes 25 26 // Solution: 27 // les scripts usuels les plus brefs, en plus de livrer la page demandee, 28 // s'achevent par un appel a la fonction spip_cron. 29 // Celle-ci prend dans la liste des taches a effectuer la plus prioritaire. 30 // Une seule tache est executee pour eviter la guillotine des 30 secondes. 31 // Une fonction executant une tache doit retourner un nombre: 32 // - nul, si la tache n'a pas a etre effecutee 33 // - positif, si la tache a ete effectuee 34 // - negatif, si la tache doit etre poursuivie ou recommencee 35 // Elle recoit en argument la date de la derniere execution de la tache. 36 37 // On peut appeler spip_cron avec d'autres taches (pour etendre Spip) 38 // specifiee par des fonctions respectant le protocole ci-dessus 39 // On peut modifier la frequence de chaque tache et leur ordre d'analyse 40 // en modifiant les variables ci-dessous. 41 42 //---------- 43 44 // Cette fonction execute la premiere tache d'intervalle de temps expire, 45 // sous reserve que le serveur MySQL soit actif. 46 // La date de la derniere intervention est donnee par un fichier homonyme, 47 // de suffixe ".lock", modifie a chaque intervention et des le debut 48 // de celle-ci afin qu'un processus concurrent ne la demarre pas aussi. 49 // Les taches les plus longues sont tronconnees, ce qui impose d'antidater 50 // le fichier de verrouillage (avec la valeur absolue du code de retour). 51 // La fonction executant la tache est un homonyme de prefixe "cron_" 52 // Le fichier homonyme de prefixe "inc_" et de suffixe _EXTENSION_PHP 53 // est automatiquement charge et est supposee la definir si ce n'est fait ici. 54 55 function spip_cron($taches=array()) { 56 57 global $frequence_taches; 58 $t = time(); 59 60 if (@file_exists(_FILE_MYSQL_OUT) 61 AND ($t - @filemtime(_FILE_MYSQL_OUT) < 300)) 62 return; 63 64 include(_FILE_CONNECT); 65 if (!$GLOBALS['db_ok']) { 66 spip_log('pas de connexion DB pour taches de fond (cron)'); 67 return; 68 } 69 70 if (!$taches) 71 $taches = taches_generales(); 72 73 include_ecrire ("inc_meta.php3"); 74 75 foreach ($taches as $tache) { 76 $lock = _DIR_SESSIONS . $tache . '.lock'; 77 clearstatcache(); 78 $last = @filemtime($lock); 79 80 // On opere un double lock : un dans _DIR_SESSIONS, pour les hits 81 // (en parallele sur le meme site) ; et un autre dans la base de 82 // donnees, de maniere a eviter toute concurrence entre deux SPIP 83 // differents partageant la meme base (replication de serveurs Web) 84 if (spip_touch($lock, $frequence_taches[$tache]) 85 AND spip_get_lock('cron'.$tache)) { 86 spip_timer('tache'); 87 include_ecrire('inc_' . $tache . _EXTENSION_PHP); 88 $fonction = 'cron_' . $tache; 89 $code_de_retour = $fonction($last); 90 if ($code_de_retour) { 91 $msg = "cron: $tache"; 92 if ($code_de_retour < 0) { 93 # modifier la date du fichier 94 @touch($lock, (0 - $code_de_retour)); 95 spip_log($msg . " (en cours, " . spip_timer('tache') .")"); 96 } 97 else 98 spip_log($msg . " (" . spip_timer('tache') . ")"); 99 break; 100 } 101 spip_release_lock('cron'.$tache); 102 } 103 } 104 } 105 106 // Construction de la liste ordonnee des taches. 107 // Certaines ne sont pas activables de l'espace prive. A revoir. 108 109 function taches_generales() { 110 $taches_generales = array(); 111 112 // MAJ des rubriques publiques (cas de la publication post-datee) 113 $taches_generales[] = 'rubriques'; 114 115 // Optimisation de la base 116 $taches_generales[] = 'optimiser'; 117 118 // cache 119 if (_DIR_RESTREINT) 120 $taches_generales[]= 'invalideur'; 121 122 // nouveautes 123 if (lire_meta('adresse_neuf') AND lire_meta('jours_neuf') 124 AND (lire_meta('quoi_de_neuf') == 'oui') AND _DIR_RESTREINT) 125 $taches_generales[]= 'mail'; 126 127 // Stat. Attention: la popularite DOIT preceder les visites 128 if (lire_meta("activer_statistiques") == "oui") { 129 $taches_generales[]= 'statistiques'; 130 $taches_generales[]= 'popularites'; 131 $taches_generales[]= 'visites'; 132 } 133 134 // syndication 135 if (lire_meta("activer_syndic") == "oui") 136 $taches_generales[]= 'sites'; 137 138 // indexation 139 if (lire_meta("activer_moteur") == "oui") 140 $taches_generales[]= 'index'; 141 142 return $taches_generales; 143 } 144 145 // Definit le temps minimal, en secondes, entre deux memes taches 146 // NE PAS METTRE UNE VALEUR INFERIEURE A 30 (cf ci-dessus) 147 // ca entrainerait plusieurs execution en parallele de la meme tache 148 // Ces valeurs sont destinees a devenir des "metas" accessibles dans 149 // le panneau de configuration, comme l'est deja la premiere 150 151 global $frequence_taches; 152 $frequence_taches = array( 153 'mail' => 3600 * 24 * lire_meta('jours_neuf'), 154 'visites' => 3600 * 24, 155 'statistiques' => 3600, 156 'invalideur' => 3600, 157 'rubriques' => 3600, 158 'popularites' => 1800, 159 'sites' => 90, 160 'index' => 60, 161 'optimiser' => 3600 * 48 162 ); 163 164 // Fonctions effectivement appelees. 165 // Elles sont destinees a migrer dans leur fichier homonyme. 166 167 function cron_rubriques($t) { 168 calculer_rubriques(); 169 return 1; 170 } 171 172 function cron_optimiser($t) { 173 optimiser_base (); 174 return 1; 175 } 176 177 function cron_index($t) { 178 return count(effectuer_une_indexation()); 179 } 180 181 function cron_sites($t) { 182 $r = executer_une_syndication(); 183 if ((lire_meta('activer_moteur') == 'oui') && 184 (lire_meta("visiter_sites") == 'oui')) { 185 include_ecrire ("inc_index.php3"); 186 $r2 = executer_une_indexation_syndic(); 187 $r = $r && $r2; 188 } 189 return $r; 190 } 191 192 // calcule les stats en plusieurs etapes par tranche de 100 193 194 function cron_statistiques($t) { 195 196 $ref = calculer_n_referers(100); 197 if ($ref == 100) return (0 - $t); 198 // Supprimer les referers trop vieux 199 supprimer_referers(); 200 supprimer_referers("article"); 201 return 1; 202 } 203 204 function cron_popularites($t) { 205 // Si c'est le premier appel (fichier .lock absent), ne pas calculer 206 if ($t == 0) return 0; 207 calculer_popularites($t); 208 return 1; 209 } 210 211 function cron_visites($t) { 212 // Si le fichier .lock est absent, ne pas calculer (mais reparer la date 213 // du .lock de maniere a commencer a 00:00:01 demain). 214 if ($t) calculer_visites(); 215 216 // il vaut mieux le lancer peu apres minuit, 217 // donc on pretend avoir ete execute precisement "ce matin a 00:00:01" 218 // pour etre appele demain a la meme heure 219 return 0 - (strtotime(date("d F Y", time()))+60); 220 } 221 222 function cron_mail($t) { 223 $adresse_neuf = lire_meta('adresse_neuf'); 224 $jours_neuf = lire_meta('jours_neuf'); 225 // $t = 0 si le fichier de lock a ete detruit 226 if (!$t) $t = time() - (3600 * 24 * $jours_neuf); 227 228 include_local("inc-calcul.php3"); 229 $page= cherche_page('', 230 array('date' => date('Y-m-d H:i:s', $t), 231 'jours_neuf' => $jours_neuf), 232 'nouveautes', 233 '', 234 lire_meta('langue_site')); 235 $page = $page['texte']; 236 if (substr($page,0,5) == '<'.'?php') { 237 # ancienne version: squelette en PHP avec affection des 2 variables ci-dessous 238 # 1 passe de + à la sortie 239 $mail_nouveautes = ''; 240 $sujet_nouveautes = ''; 241 $headers = ''; 242 eval ('?' . '>' . $page); 243 } else { 244 # nouvelle version en une seule passe avec un squelette textuel: 245 # 1ere ligne = sujet 246 # lignes suivantes jusqu'a la premiere blanche: headers SMTP 247 248 $page = stripslashes(trim($page)); 249 $page = preg_replace(",\r\n?,", "\n", $page); 250 $p = strpos($page,"\n\n"); 251 $s = strpos($page,"\n"); 252 if ($p AND $s) { 253 if ($p>$s) 254 $headers = substr($page,$s+1,$p-$s); 255 $sujet_nouveautes = substr($page,0,$s); 256 $mail_nouveautes = trim(substr($page,$p+2)); 257 } 258 } 259 260 if (strlen($mail_nouveautes) > 10) 261 envoyer_mail($adresse_neuf, $sujet_nouveautes, $mail_nouveautes, '', $headers); 262 else 263 spip_log("mail nouveautes : rien de neuf depuis $jours_neuf jours"); 264 return 1; 265 } 266 267 function cron_invalideur($t) { 268 // 269 // menage des vieux fichiers du cache 270 // marques par l'invalideur 't' = date de fin de fichier 271 // 272 273 retire_vieux_caches(); 274 275 // En cas de quota sur le CACHE/, nettoyer les fichiers les plus vieux 276 277 // A revoir: il semble y avoir une désynchro ici. 278 279 list ($total_cache) = spip_fetch_array(spip_query("SELECT SUM(taille) 280 FROM spip_caches WHERE type IN ('t', 'x')")); 281 spip_log("Taille du CACHE: $total_cache octets"); 282 283 global $quota_cache; 284 $total_cache -= $quota_cache*1024*1024; 285 if ($quota_cache > 0 AND $total_cache > 0) { 286 $q = spip_query("SELECT id, taille FROM spip_caches 287 WHERE type IN ('t', 'x') ORDER BY id"); 288 while ($r = spip_fetch_array($q) 289 AND ($total_cache > $taille_supprimee)) { 290 $date_limite = $r['id']; 291 $taille_supprimee += $r['taille']; 292 } 293 spip_log ("Quota cache: efface $taille_supprimee octets"); 294 include_ecrire ('inc_invalideur.php3'); 295 suivre_invalideur("id <= $date_limite AND type in ('t', 'x')"); 296 } 297 return 1; 298 } 299 300 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Feb 22 22:27:47 2007 | par Balluche grâce à PHPXref 0.7 |