Subversion Repositories Sites.tela-botanica.org

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 david 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
				$p = strpos($page,"\n\n");
250
				$s = strpos($page,"\n");
251
				if ($p AND $s) {
252
					if ($p>$s)
253
						$headers = substr($page,$s+1,$p-$s);
254
					$sujet_nouveautes = substr($page,0,$s);
255
					$mail_nouveautes = trim(substr($page,$p+2));
256
				}
257
	}
258
 
259
	if (strlen($mail_nouveautes) > 10)
260
		envoyer_mail($adresse_neuf, $sujet_nouveautes, $mail_nouveautes, '', $headers);
261
	else
262
		spip_log("mail nouveautes : rien de neuf depuis $jours_neuf jours");
263
	return 1;
264
}
265
 
266
function cron_invalideur($t) {
267
	//
268
	// menage des vieux fichiers du cache
269
	// marques par l'invalideur 't' = date de fin de fichier
270
	//
271
 
272
	retire_vieux_caches();
273
 
274
	// En cas de quota sur le CACHE/, nettoyer les fichiers les plus vieux
275
 
276
	// A revoir: il semble y avoir une désynchro ici.
277
 
278
		list ($total_cache) = spip_fetch_array(spip_query("SELECT SUM(taille)
279
		FROM spip_caches WHERE type IN ('t', 'x')"));
280
		spip_log("Taille du CACHE: $total_cache octets");
281
 
282
		global $quota_cache;
283
		$total_cache -= $quota_cache*1024*1024;
284
		if ($quota_cache > 0 AND $total_cache > 0) {
285
			$q = spip_query("SELECT id, taille FROM spip_caches
286
			WHERE type IN ('t', 'x') ORDER BY id");
287
			while ($r = spip_fetch_array($q)
288
			AND ($total_cache > $taille_supprimee)) {
289
				$date_limite = $r['id'];
290
				$taille_supprimee += $r['taille'];
291
			}
292
			spip_log ("Quota cache: efface $taille_supprimee octets");
293
			include_ecrire('inc_invalideur.php3');
294
			suivre_invalideur("id <= $date_limite AND type in ('t', 'x')");
295
		}
296
	return 1;
297
}
298
 
299
?>