[ Index ]
 

Code source de SPIP 1.9.2c

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/ecrire/inc/ -> invalideur.php (source)

   1  <?php
   2  
   3  /***************************************************************************\
   4   *  SPIP, Systeme de publication pour l'internet                           *
   5   *                                                                         *
   6   *  Copyright (c) 2001-2007                                                *
   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  if (!defined("_ECRIRE_INC_VERSION")) return;
  15  
  16  include_spip('base/serial');
  17  
  18  // http://doc.spip.org/@supprime_invalideurs
  19  function supprime_invalideurs() {
  20      spip_query("DELETE FROM spip_caches");
  21  }
  22  
  23  //
  24  // Calcul des pages : noter dans la base les liens d'invalidation
  25  //
  26  // http://doc.spip.org/@maj_invalideurs
  27  function maj_invalideurs ($fichier, &$page) {
  28      // ne pas noter les POST et les delais=0
  29      if ($fichier == '') return;
  30  
  31      // Supprimer les anciens invalideurs
  32      $f = str_replace('.gz', '', $fichier);
  33      spip_query("DELETE FROM spip_caches WHERE fichier='$f' OR fichier='$f.gz'");
  34  
  35      // Creer un invalideur 't' nous informant de la date d'expiration
  36      // et de la taille du fichier cache
  37      # Note : on ajoute 3600s pour eviter toute concurrence
  38      # entre un invalideur et un appel public de page
  39      $bedtime = time() + $page['entetes']['X-Spip-Cache'] + 3600;
  40      $taille = @filesize(_DIR_CACHE . $fichier);
  41      spip_query("INSERT IGNORE INTO spip_caches (fichier,id,type,taille) VALUES (" . _q($fichier) . ",'$bedtime','t','$taille')");
  42  
  43      // invalidations
  44      insere_invalideur($page['invalideurs'], $fichier);
  45  }
  46  
  47  // pour les forums l'invalideur est : 'id_forum/a23'
  48  // pour les petitions et autres, l'invalideur est par exemple :
  49  // 'varia/pet60'
  50  // http://doc.spip.org/@insere_invalideur
  51  function insere_invalideur($inval, $fichier) {
  52      if ($inval)
  53      foreach ($inval as $type => $a) {
  54          if (is_array($a)) {
  55              $values = array();
  56              foreach($a as $k => $v)
  57                  $values[] = "('$fichier', '$type/$k')";
  58              spip_query("INSERT IGNORE INTO spip_caches (fichier, id) VALUES " . join(", ", $values));
  59          }
  60      }
  61  }
  62  
  63  
  64  //
  65  // Invalider les caches lies a telle condition
  66  // on en profite pour noter la date de mise a jour dans les metas
  67  //
  68  // http://doc.spip.org/@suivre_invalideur
  69  function suivre_invalideur($cond, $modif=true) {
  70      include_spip('inc/meta');
  71      if ($modif) {
  72          ecrire_meta('derniere_modif', time());
  73          ecrire_metas();
  74      }
  75      $result = spip_query("SELECT DISTINCT fichier FROM spip_caches WHERE $cond");
  76      $tous = array();
  77      while ($row = spip_fetch_array($result))
  78          $tous[] = $row['fichier'];
  79  
  80      spip_log("suivre $cond dans " . count($tous) . " caches");
  81      applique_invalideur($tous);
  82  }
  83  
  84  
  85  //
  86  // Supprimer les vieux caches
  87  //
  88  // http://doc.spip.org/@retire_vieux_caches
  89  function retire_vieux_caches() {
  90      $condition = "type='t' AND id<".time();
  91      suivre_invalideur($condition);
  92  }
  93  
  94  
  95  //
  96  // Marquer les fichiers caches invalides comme etant a supprimer
  97  //
  98  // http://doc.spip.org/@applique_invalideur
  99  function applique_invalideur($depart) {
 100  
 101      if ($depart) {
 102          $tous = "'".join("', '", $depart)."'";
 103          spip_log("applique $tous");
 104  
 105          include_spip('base/abstract_sql'); # pour calcul_mysql_in
 106          spip_query("UPDATE spip_caches SET type='x' WHERE " . calcul_mysql_in('fichier', $tous));
 107  
 108          // Demander a inc-public de retirer les caches
 109          // invalides ;
 110          // - le signal (meta='invalider') indique
 111          // qu'il faut faire attention ;
 112          // - le signal (meta='invalider_caches') indique qu'on
 113          // peut effacer 100 caches invalides
 114          // (Signaux differents pour eviter de la concurrence entre
 115          // les processus d'invalidation)
 116          ecrire_meta('invalider', 'oui'); // se verifier soi-meme
 117          ecrire_meta('invalider_caches', 'oui'); // supprimer les autres
 118          ecrire_metas();
 119      }
 120  }
 121  
 122  
 123  // Utilisee pour vider le cache depuis l'espace prive
 124  // (ou juste les squelettes si un changement de config le necessite)
 125  // http://doc.spip.org/@purger_repertoire
 126  function purger_repertoire($dir) {
 127      $handle = @opendir($dir);
 128      if (!$handle) return;
 129  
 130      while (($fichier = @readdir($handle)) !== false) {
 131          // Eviter ".", "..", ".htaccess", etc.
 132          if ($fichier[0] == '.') continue;
 133          $chemin = "$dir/$fichier";
 134          if (is_file($chemin))
 135              @unlink($chemin);
 136          else if (is_dir($chemin))
 137              if ($fichier != 'CVS')
 138                  purger_repertoire($chemin);
 139      }
 140      closedir($handle);
 141  }
 142  
 143  // http://doc.spip.org/@cron_invalideur
 144  function cron_invalideur($t) {
 145      //
 146      // menage des vieux fichiers du cache
 147      // marques par l'invalideur 't' = date de fin de fichier
 148      //
 149  
 150      retire_vieux_caches();
 151  
 152      // En cas de quota sur le CACHE/, nettoyer les fichiers les plus vieux
 153  
 154      // A revoir: il semble y avoir une desynchro ici.
 155      $t = spip_fetch_array(spip_query("SELECT SUM(taille) AS n FROM spip_caches WHERE type IN ('t', 'x')"));
 156      $total_cache = $t['n'];
 157      spip_log("Taille du CACHE: $total_cache octets");
 158  
 159      global $quota_cache;
 160      $total_cache -= $quota_cache*1024*1024;
 161      if ($quota_cache > 0 AND $total_cache > 0) {
 162          $taille_supprimee = 0;
 163          $q = spip_query("SELECT id, taille FROM spip_caches WHERE type IN ('t', 'x') ORDER BY id");
 164          while ($r = spip_fetch_array($q)
 165          AND ($total_cache > $taille_supprimee)) {
 166              $date_limite = $r['id'];
 167              $taille_supprimee += $r['taille'];
 168          }
 169          spip_log ("Quota cache: efface $taille_supprimee octets");
 170          suivre_invalideur("id <= $date_limite AND type in ('t', 'x')", false);
 171      }
 172      return 1;
 173  }
 174  
 175  //
 176  // Destruction des fichiers caches invalides
 177  //
 178  
 179  // Securite : est sur que c'est un cache
 180  // http://doc.spip.org/@retire_cache
 181  function retire_cache($cache) {
 182  
 183      if (preg_match(
 184      "|^([0-9a-f]/)?([0-9]+/)?[^.][\-_\%0-9a-z]+\.[0-9a-f]+(\.gz)?$|i",
 185      $cache)) {
 186          // supprimer le fichier (de facon propre)
 187          supprimer_fichier(_DIR_CACHE . $cache);
 188      } else
 189          spip_log("Impossible de retirer $cache");
 190  }
 191  
 192  // Supprimer les caches marques "x"
 193  // http://doc.spip.org/@retire_caches
 194  function retire_caches($chemin = '') {
 195      include_spip('base/abstract_sql');
 196      include_spip('inc/meta');
 197      lire_metas();
 198      // recuperer la liste des caches voues a la suppression
 199      $suppr = array();
 200  
 201      // En priorite le cache qu'on appelle maintenant
 202      if ($chemin) {
 203          $f = spip_abstract_fetsel(array("fichier"),
 204              array("spip_caches"),
 205              array("fichier = " . _q($chemin) . " ",
 206                  "type='x'"),
 207              "",
 208              array(),
 209              1);
 210          if ($f['fichier']) $suppr[$f['fichier']] = true;
 211      }
 212  
 213      // Et puis une centaine d'autres
 214      $compte = 0;
 215      if (isset($GLOBALS['meta']['invalider_caches'])) {
 216          $compte = 1;
 217          effacer_meta('invalider_caches'); # concurrence
 218          ecrire_metas();
 219  
 220          $q = spip_abstract_select(array("fichier"),
 221                  array("spip_caches"),
 222                  array("type='x'"),
 223                  "",
 224                  array(),
 225                  100);
 226          while ($r = spip_abstract_fetch($q)) {
 227              $compte ++;    # compte le nombre de resultats vus (y compris doublons)
 228              $suppr[$r['fichier']] = true;
 229          }
 230      }
 231  
 232      if ($n = count($suppr)) {
 233          spip_log ("Retire $n caches");
 234          foreach ($suppr as $cache => $ignore)
 235              retire_cache($cache);
 236          spip_query("DELETE FROM spip_caches WHERE " . calcul_mysql_in('fichier', "'".join("','",array_keys($suppr))."'") );
 237      }
 238  
 239      // Si on a regarde (compte > 0), signaler s'il reste des caches invalides
 240      if ($compte > 0) {
 241          if ($compte > 100) # s'il y en a 101 c'est qu'on n'a pas fini
 242              ecrire_meta('invalider_caches', 'oui');
 243          else
 244              effacer_meta('invalider');
 245          ecrire_metas();
 246      }
 247  }
 248  
 249  
 250  // Pour que le compilo ajoute un invalideur a la balise #PARAMETRES_FORUM
 251  // Noter l'invalideur de la page contenant ces parametres,
 252  // en cas de premier post sur le forum
 253  // http://doc.spip.org/@code_invalideur_forums
 254  function code_invalideur_forums($p, $code) {
 255      $type = 'id_forum';
 256      $valeur = "\n\t\tcalcul_index_forum("
 257          // Retournera 4 [$SP] mais force la demande du champ SQL
 258          . champ_sql('id_article', $p) . ','
 259          . champ_sql('id_breve', $p) .  ','
 260          . champ_sql('id_rubrique', $p) .','
 261          . champ_sql('id_syndic', $p) .  ")\n\t";
 262  
 263      return '
 264      // invalideur '.$type.'
 265      (!($Cache[\''.$type.'\']['.$valeur."]=1) ? '':\n\t" . $code .")\n";
 266  }
 267  
 268  
 269  // Fonction permettant au compilo de calculer les invalideurs d'une page
 270  // http://doc.spip.org/@calcul_invalideurs
 271  function calcul_invalideurs($corps, $primary, &$boucles, $id_boucle) {
 272      if ($primary == 'id_forum'
 273      OR in_array($primary, explode(',', $GLOBALS['invalider_caches']))) {
 274          $corps .= "\n\t\t\$Cache['$primary'][intval(" .
 275            (($primary != 'id_forum')  ? 
 276             index_pile($id_boucle, $primary, $boucles) :
 277             ("calcul_index_forum(" . 
 278          // Retournera 4 [$SP] mais force la demande du champ a MySQL
 279              index_pile($id_boucle, 'id_article', $boucles) . ',' .
 280              index_pile($id_boucle, 'id_breve', $boucles) .  ',' .
 281              index_pile($id_boucle, 'id_rubrique', $boucles) .',' .
 282              index_pile($id_boucle, 'id_syndic', $boucles) .
 283              ")")) .
 284            ")] = 1; // invalideurs\n";
 285      }
 286      return $corps;
 287  }
 288  
 289  ?>


Généré le : Wed Nov 21 10:20:27 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics