Your IP : 216.73.217.141


Current Path : /home/b/o/u/bourgleram/www/398a1/
Upload File :
Current File : /home/b/o/u/bourgleram/www/398a1/genie.tar

syndic.php000066600000024031152522472730006563 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined("_ECRIRE_INC_VERSION")) return;
include_spip('inc/syndic');

## valeurs modifiables dans mes_options
## attention il est tres mal vu de prendre une periode < 20 minutes
if (!defined('_PERIODE_SYNDICATION'))
	define('_PERIODE_SYNDICATION', 2*60);
if (!defined('_PERIODE_SYNDICATION_SUSPENDUE'))
	define('_PERIODE_SYNDICATION_SUSPENDUE', 24*60);


// http://code.spip.net/@genie_syndic_dist
function genie_syndic_dist($t) {
	return executer_une_syndication();
}

//
// Effectuer la syndication d'un unique site,
// retourne 0 si aucun a faire ou echec lors de la tentative
//

// http://code.spip.net/@executer_une_syndication
function executer_une_syndication() {

	// On va tenter un site 'sus' ou 'off' de plus de 24h, et le passer en 'off'
	// s'il echoue
	$where = sql_in("syndication", array('sus','off')) . "
	AND statut<>'refuse'
	AND NOT(" . sql_date_proche('date_syndic', (0 - _PERIODE_SYNDICATION_SUSPENDUE) , "MINUTE") . ')';
	$id_syndic = sql_getfetsel("id_syndic", "spip_syndic", $where, '', "date_syndic", "1");
	if ($id_syndic) {
		// inserer la tache dans la file, avec controle d'unicite
		job_queue_add('syndic_a_jour','syndic_a_jour',array($id_syndic),'genie/syndic',true);
	}

	// Et un site 'oui' de plus de 2 heures, qui passe en 'sus' s'il echoue
	$where = "syndication='oui'
	AND statut<>'refuse'
	AND NOT(" . sql_date_proche('date_syndic', (0 - _PERIODE_SYNDICATION) , "MINUTE") . ')';
	$id_syndic = sql_getfetsel("id_syndic", "spip_syndic", $where, '', "date_syndic", "1");

	if ($id_syndic) {
		// inserer la tache dans la file, avec controle d'unicite
		job_queue_add('syndic_a_jour','syndic_a_jour',array($id_syndic),'genie/syndic',true);
	}

	return 0;
}


/**
 * Mettre a jour le site
 * Attention, cette fonction ne doit pas etre appellee simultanement
 * sur un meme site: un verrouillage a du etre pose en amont.
 * => elle doit toujours etre appelee par job_queue_add
 *
 * http://code.spip.net/@syndic_a_jour
 *
 * @param int $now_id_syndic
 * @return bool|string
 */
function syndic_a_jour($now_id_syndic) {
	include_spip('inc/texte');
	$call = debug_backtrace();
	if ($call[1]['function']!=='queue_start_job')
		spip_log("syndic_a_jour doit etre appelee par JobQueue Cf. http://trac.rezo.net/trac/spip/changeset/10294",_LOG_ERREUR);

	$row = sql_fetsel("*", "spip_syndic", "id_syndic=".intval($now_id_syndic));

	if (!$row) return;

	$url_syndic = $row['url_syndic'];
	$url_site = $row['url_site'];

	if ($row['moderation'] == 'oui')
		$moderation = 'dispo';	// a valider
	else
		$moderation = 'publie';	// en ligne sans validation

	// determiner le statut a poser en cas d'echec : sus par defaut
	// off si le site est deja off, ou sus depuis trop longtemps
	$statut = 'sus';
	if (
		$row['statut']=='off'
	  OR ($row['statut']=='sus' AND time()-strtotime($row['date_syndic'])>_PERIODE_SYNDICATION_SUSPENDUE*60)
	  )
		$statut = 'off';

	sql_updateq('spip_syndic', array('syndication'=>$statut, 'date_syndic'=>date('Y-m-d H:i:s')), "id_syndic=".intval($now_id_syndic));

	// Aller chercher les donnees du RSS et les analyser
	include_spip('inc/distant');
	$rss = recuperer_page($url_syndic, true);
	if (!$rss)
		$articles = _T('sites:avis_echec_syndication_02');
	else
		$articles = analyser_backend($rss, $url_syndic);

	// Renvoyer l'erreur le cas echeant
	if (!is_array($articles)) return $articles;

	// Les enregistrer dans la base

	$faits = array();
	foreach ($articles as $data) {
		inserer_article_syndique ($data, $now_id_syndic, $moderation, $url_site, $url_syndic, $row['resume'], $row['documents'], $faits);
	}

	// moderation automatique des liens qui sont sortis du feed
	if (count($faits) > 0) {
		$faits = sql_in("id_syndic_article", $faits, 'NOT');
		if ($row['miroir'] == 'oui') {
			sql_update('spip_syndic_articles', array('statut'=>"'off'", 'maj'=>'maj'), "id_syndic=$now_id_syndic AND $faits");
		}
	// suppression apres 2 mois des liens qui sont sortis du feed
		if ($row['oubli'] == 'oui') {

		  sql_delete('spip_syndic_articles', "id_syndic=$now_id_syndic AND NOT(" . sql_date_proche('maj', -2, 'MONTH') . ') AND NOT(' . sql_date_proche('date', -2, 'MONTH') . ") AND $faits");
		}
	}

	// Noter que la syndication est OK
	sql_updateq("spip_syndic", array("syndication" => 'oui'), "id_syndic=".intval($now_id_syndic));

	return false; # c'est bon
}


//
// Insere un article syndique (renvoie true si l'article est nouveau)
// en  verifiant qu'on ne vient pas de l'ecrire avec
// un autre item du meme feed qui aurait le meme link
//
// http://code.spip.net/@inserer_article_syndique
function inserer_article_syndique ($data, $now_id_syndic, $statut, $url_site, $url_syndic, $resume, $documents, &$faits) {
	// Creer le lien s'il est nouveau - cle=(id_syndic,url)
	// On coupe a 255 caracteres pour eviter tout doublon
	// sur une URL de plus de 255 qui exloserait la base de donnees
	$le_lien = substr($data['url'], 0,255);

	// si true, un lien deja syndique arrivant par une autre source est ignore
	// par defaut [false], chaque source a sa liste de liens, eventuellement
	// les memes
	define('_SYNDICATION_URL_UNIQUE', false);

	// Si false, on ne met pas a jour un lien deja syndique avec ses nouvelles
	// donnees ; par defaut [true] : on met a jour si le contenu a change
	// Attention si on modifie a la main un article syndique, les modifs sont
	// ecrasees lors de la syndication suivante
	define('_SYNDICATION_CORRECTION', true);

	// Chercher les liens de meme cle
	// S'il y a plusieurs liens qui repondent, il faut choisir le plus proche
	// (ie meme titre et pas deja fait), le mettre a jour et ignorer les autres
	$n = 0;
	$s = sql_select("id_syndic_article,titre,id_syndic,statut", "spip_syndic_articles",
		"url=" . sql_quote($le_lien)
		. (_SYNDICATION_URL_UNIQUE
			? ''
			: " AND id_syndic=$now_id_syndic")
		." AND " . sql_in('id_syndic_article', $faits, 'NOT'), "", "maj DESC");
	while ($a = sql_fetch($s)) {
		$id =  $a['id_syndic_article'];
		$id_syndic = $a['id_syndic'];
		if ($a['titre'] == $data['titre']) {
			$id_syndic_article = $id;
			break;
		}
		$n++;
	}
	// S'il y en avait qu'un, le prendre quel que soit le titre
	if ($n == 1)
		$id_syndic_article = $id;
	// Si l'article n'existe pas, on le cree
	elseif (!isset($id_syndic_article)) {
		$champs = array(
			'id_syndic' => $now_id_syndic,
			'url' => $le_lien,
			'date' => date("Y-m-d H:i:s", $data['date'] ? $data['date'] : $data['lastbuilddate']),
			'statut'  => $statut
		);
		// Envoyer aux plugins
		$champs = pipeline('pre_insertion',
			array(
				'args' => array(
					'table' => 'spip_syndic_articles',
				),
				'data' => $champs
			)
		);
		$ajout = $id_syndic_article = sql_insertq('spip_syndic_articles', $champs);
		if (!$ajout) return;
		pipeline('post_insertion',
			array(
				'args' => array(
					'table' => 'spip_syndic_articles',
					'id_objet' => $id_syndic_article
				),
				'data' => $champs
			)
		);
	}
	$faits[] = $id_syndic_article;


	// Si le lien n'est pas nouveau, plusieurs options :
	if (!$ajout) {
		// 1. Lien existant : on corrige ou pas ?
		if (!_SYNDICATION_CORRECTION) {
			return;
		}
		// 2. Le lien existait deja, lie a un autre spip_syndic
		if (_SYNDICATION_URL_UNIQUE AND $id_syndic != $now_id_syndic)
			return;
	}

	// Descriptif, en mode resume ou mode 'full text'
	// on prend en priorite data['descriptif'] si on est en mode resume,
	// et data['content'] si on est en mode "full syndication"
	if ($resume != 'non') {
		// mode "resume"
		$desc = strlen($data['descriptif']) ?
			$data['descriptif'] : $data['content'];
		$desc = couper(trim_more(textebrut($desc)), 300);
	} else {
		// mode "full syndication"
		// choisir le contenu pertinent
		// & refaire les liens relatifs
		$desc = strlen($data['content']) ?
			$data['content'] : $data['descriptif'];
		$desc = liens_absolus($desc, $url_syndic);
	}

	// tags & enclosures (preparer spip_syndic_articles.tags)
	$tags = ($data['enclosures']?$data['enclosures']:'');
	# eviter les doublons (cle = url+titre) et passer d'un tableau a une chaine
	if ($data['tags']) {
		$vus = array();
		foreach ($data['tags'] as $tag) {
			$cle = supprimer_tags($tag).extraire_attribut($tag,'href');
			$vus[$cle] = $tag;
		}
		$tags .= ($tags ? ', ' : '') . join(', ', $vus);
	}

	// Mise a jour du contenu (titre,auteurs,description,date?,source...)
	$vals = array(
			'titre' => $data['titre'],
			'lesauteurs' => $data['lesauteurs'],
			'descriptif' => $desc,
			'lang'=> substr($data['lang'],0,10),
			'source' => substr($data['source'],0,255),
			'url_source' => substr($data['url_source'],0,255),
			'tags' => $tags);

	// Mettre a jour la date si lastbuilddate
	if ($data['lastbuilddate'])
		$vals['date']= date("Y-m-d H:i:s", $data['lastbuilddate']);

	include_spip('inc/modifier');
	objet_modifier_champs('syndic_article',$id_syndic_article,array('data'=>$vals,'action'=>'syndiquer'),$vals);

	// Point d'entree post_syndication
	pipeline('post_syndication',
		array(
			'args' => array(
				'table' => 'spip_syndic_articles',
				'id_objet' => $id_syndic_article,
				'url' => $le_lien,
				'id_syndic' => $now_id_syndic,
				'ajout' => $ajout,
			),
			'data' => $data
		)
	);

	return $ajout;
}

/**
 * Nettoyer les contenus de flux qui utilisent des espaces insecables en debut
 * pour faire un retrait.
 * Peut etre sous la forme de l'entite &nbsp; ou en utf8 \xc2\xa0
 *
 * @param  string $texte
 * @return string
 */
function trim_more($texte){
	$texte = trim($texte);
	// chr(194)chr(160)
	$texte = preg_replace(",^(\s|(&nbsp;)|(\xc2\xa0))+,ums","",$texte);
	return  $texte;
}
?>
visites.php000066600000020527152522474260006766 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/


if (!defined("_ECRIRE_INC_VERSION")) return;
if (!defined('_CRON_LOT_FICHIERS_VISITE')) define('_CRON_LOT_FICHIERS_VISITE', 100);

### Pour se debarrasser du md5, comment faire ? Un index sur 'referer' ?
### ou alors la meme notion, mais sans passer par des fonctions HEX ?

//
// prendre en compte un fichier de visite
//
// http://code.spip.net/@compte_fichier_visite
function compte_fichier_visite($fichier, &$visites, &$visites_a, &$referers, &$referers_a) {

	// Noter la visite du site (article 0)
	$visites ++;

	$content = array();
	if (lire_fichier($fichier, $content))
		$content = @unserialize($content);
	if (!is_array($content)) return;

	foreach ($content as $source => $num) {
		list($log_type, $log_id_num, $log_referer)
			= preg_split(",\t,", $source, 3);
		
		// Noter le referer
		if ($log_referer)
			$referers[$log_referer]++;

		// S'il s'agit d'un article, noter ses visites
		if ($log_type == 'article'
		AND $id_article = intval($log_id_num)) {
			$visites_a[$id_article] ++;
			if ($log_referer)
				$referers_a[$id_article][$log_referer]++;
		}
	}
}


// http://code.spip.net/@calculer_visites
function calculer_visites($t) {
	include_spip('base/abstract_sql');

	// Initialisations
	$visites = array(); # visites du site
	$visites_a = array(); # tableau des visites des articles
	$referers = array(); # referers du site
	$referers_a = array(); # tableau des referers des articles

	// charger un certain nombre de fichiers de visites,
	// et faire les calculs correspondants

	// Traiter jusqu'a 100 sessions datant d'au moins 30 minutes
	$sessions = preg_files(sous_repertoire(_DIR_TMP, 'visites'));

	$compteur = _CRON_LOT_FICHIERS_VISITE;
	$date_init = time()-30*60;
	foreach ($sessions as $item) {
		if (($d=@filemtime($item)) < $date_init) {
			if (!$d) $d = $date_init; // si le fs ne donne pas de date, on prend celle du traitement, mais tout cela risque d'etre bien douteux
			$d = date("Y-m-d",$d);
			spip_log("traite la session $item");
			compte_fichier_visite($item,
				$visites[$d], $visites_a[$d], $referers[$d], $referers_a[$d]);
			spip_unlink($item);
			if (--$compteur <= 0)
				break;
		}
		#else spip_log("$item pas vieux");
	}
	if (!count($visites))
		return;

	include_spip('genie/popularites');
	list($a,$b) = genie_popularite_constantes(24*3600);

	// Maintenant on dispose de plusieurs tableaux qu'il faut ventiler dans
	// les tables spip_visites, spip_visites_articles, spip_referers
	// et spip_referers_articles ; attention a affecter tout ca a la bonne
	// date (celle de la visite, pas celle du traitement)
	foreach(array_keys($visites) as $date)
		if ($visites[$date]) {

			// 1. les visites du site (facile)
			if (!sql_countsel('spip_visites', "date='$date'"))
				sql_insertq('spip_visites',
					array('date' => $date, 'visites' => $visites[$date]));
			else 
				sql_update('spip_visites', array('visites' => "visites+".intval($visites[$date])), "date='$date'");
		
			// 2. les visites des articles 
			if ($visites_a[$date]) {
				$ar = array();	# tableau num -> liste des articles ayant num visites
				foreach($visites_a[$date] as $id_article => $n) {
					if (!sql_countsel('spip_visites_articles',
						 "id_article=$id_article AND date='$date'")){
						sql_insertq('spip_visites_articles',
								array('id_article' => $id_article,
								      'visites' => 0,
								      'date' => $date));
					}
					$ar[$n][] = $id_article;
				}
				foreach ($ar as $n => $liste) {
					$tous = sql_in('id_article', $liste);
					sql_update('spip_visites_articles',
						array('visites' => "visites+$n"),
						   "date='$date' AND $tous");
		
					$ref = $noref = array();
					foreach($liste as $id) {
						if (isset($referers_a[$id]))
							$ref[]= $id ;
						else $noref[]=$id;
					}
					// il faudrait ponderer la popularite ajoutee ($n) par son anciennete eventuelle
					// sur le modele de ce que fait genie/popularites
					if (count($noref))
						sql_update('spip_articles',
							array('visites' => "visites+$n",
							 'popularite' => "popularite+".number_format(round($n*$b,2), 2, '.', ''),
							 'maj' => 'maj'),
							sql_in('id_article',$noref));
							   
					if (count($ref))
						sql_update('spip_articles',
							   array('visites' => "visites+".($n+1),
							 'popularite' => "popularite+".number_format(round($n*$b,2), 2, '.', ''),
							 'maj' => 'maj'),
							sql_in('id_article',$ref));
							   
					## Ajouter un JOIN sur le statut de l'article ?
				}
			}
			// 3. Les referers du site
			// insertion pour les nouveaux, au tableau des increments sinon
			if ($referers[$date]) {
				$ar = array();
				$trouver_table = charger_fonction('trouver_table', 'base');
				$desc = $trouver_table('referers');
				$n = preg_match('/(\d+)/',$desc['field']['referer'], $r);
				$n = $n ? $r[1] : 255;
				foreach ($referers[$date] as $referer => $num) {
					$referer_md5 = sql_hex(substr(md5($referer), 0, 15));
					$referer = substr($referer,0,$n);
					if (!sql_countsel('spip_referers', "referer_md5=$referer_md5"))
						sql_insertq('spip_referers',
							array('visites' => $num,
							      'visites_jour' => $num,
							      'visites_veille' => $num,
							      'date' => $date,
							      'referer' => $referer,
							      'referer_md5' => $referer_md5));
					else $ar[$num][] = $referer_md5;
				}
		
			// appliquer les increments sur les anciens
			// attention on appelle sql_in en mode texte et pas array
			// pour ne pas passer sql_quote() sur les '0x1234' de referer_md5, cf #849
				foreach ($ar as $num => $liste) {
					sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), sql_in('referer_md5',join(', ', $liste)));
				}
			}
			
			// 4. Les referers d'articles
			if ($referers_a[$date]) {
				$ar = array();
				$insert = array();
				// s'assurer d'un slot pour chacun
				foreach ($referers_a[$date] as $id_article => $referers)
					foreach ($referers as $referer => $num) {
						$referer_md5 = sql_hex(substr(md5($referer), 0, 15));
						$prim = "(id_article=$id_article AND referer_md5=$referer_md5)";
						if (!sql_countsel('spip_referers_articles', $prim))
							sql_insertq('spip_referers_articles',
							     array('visites' => $num,
								   'id_article' => $id_article,
								   'referer' => $referer,
								   'referer_md5' => $referer_md5));
						else $ar[$num][] = $prim;
					}
				// ajouter les visites
				foreach ($ar as $num => $liste) {
					sql_update('spip_referers_articles', array('visites' => "visites+$num"), join(" OR ", $liste));
					## Ajouter un JOIN sur le statut de l'article ?
				}
			}
		}

	// S'il reste des fichiers a manger, le signaler pour reexecution rapide
	if ($compteur==0) {
		spip_log("il reste des visites a traiter...");
		return -$t;
	}
}

/**
 * Nettoyer les IPs des flooders 24H apres leur dernier passage
 */
function visites_nettoyer_flood(){
	if (is_dir($dir=_DIR_TMP.'flood/')){
		include_spip('inc/invalideur');
		if (!defined('_IP_FLOOD_TTL')) define('_IP_FLOOD_TTL',24*3600); // 24H par defaut
		$options = array(
			'mtime' => $_SERVER['REQUEST_TIME'] - _IP_FLOOD_TTL,
		);
		purger_repertoire($dir,$options);
	}
}


/**
 * Cron de calcul de statistiques des visites
 * 
 * Calcule les stats en plusieurs étapes
 * @uses calculer_visites()
 * 
 * @param int $t
 *     Timestamp de la dernière exécution de cette tâche
 * @return int
 *     Positif si la tâche a été terminée, négatif pour réexécuter cette tâche
**/
function genie_visites_dist($t) {
	$encore = calculer_visites($t);

	// Si ce n'est pas fini on redonne la meme date au fichier .lock
	// pour etre prioritaire lors du cron suivant
	if ($encore)
		return (0 - $t);

	// nettoyer les IP des floodeurs quand on a fini de compter les stats
	visites_nettoyer_flood();

	return 1;
}
?>
popularites.php000066600000006643152522474260007652 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined("_ECRIRE_INC_VERSION")) return;

//
// Popularite, modele logarithmique
//
function genie_popularite_constantes($duree){
	// duree de demi-vie d'une visite dans le calcul de la popularite (en jours)
	$demivie = 0.5;
	// periode de reference en jours
	$periode = 1;
	// $a est le coefficient d'amortissement depuis la derniere mesure
	$a = pow(2, - $duree / ($demivie * 24 * 3600));
	// $b est la constante multiplicative permettant d'avoir
	// une visite par jour (periode de reference) = un point de popularite
	// (en regime stationnaire)
	// or, magie des maths, ca vaut log(2) * duree journee/demi-vie
	// si la demi-vie n'est pas trop proche de la seconde ;)
	$b = log(2) * $periode / $demivie;

	return array($a,$b);
}

// http://code.spip.net/@genie_popularites_dist
function genie_popularites_dist($t) {

	// Si c'est le premier appel, ne pas calculer
	$t = $GLOBALS['meta']['date_popularites'];
	ecrire_meta('date_popularites', time());

	if (!$t)
		return 1;

	$duree = time() - $t;
	list($a,$b) = genie_popularite_constantes($duree);

	// du passe, faisons table (SQL) rase
	sql_update('spip_articles', array('maj'=>'maj', 'popularite' => "popularite * $a"), 'popularite>1');

	// enregistrer les metas...
	$row = sql_fetsel('MAX(popularite) AS max, SUM(popularite) AS tot', "spip_articles");
	ecrire_meta("popularite_max", $row['max']);
	ecrire_meta("popularite_total", $row['tot']);


	// Une fois par jour purger les referers du jour ; qui deviennent
	// donc ceux de la veille ; au passage on stocke une date_statistiques
	// dans spip_meta - cela permet au code d'etre "reentrant", ie ce cron
	// peut etre appele par deux bases SPIP ne partageant pas le meme
	// _DIR_TMP, sans tout casser...

	$aujourdhui = date("Y-m-d");
	if (($d = $GLOBALS['meta']['date_statistiques']) != $aujourdhui) {
		spip_log("Popularite: purger referer depuis $d");
		ecrire_meta('date_statistiques', $aujourdhui);
		if (strncmp($GLOBALS['connexions'][0]['type'],'sqlite',6)==0)
			spip_query("UPDATE spip_referers SET visites_veille=visites_jour, visites_jour=0");
	  else
			// version 3 fois plus rapide, mais en 2 requetes
			#spip_query("ALTER TABLE spip_referers CHANGE visites_jour visites_veille INT( 10 ) UNSIGNED NOT NULL DEFAULT '0',CHANGE visites_veille visites_jour INT( 10 ) UNSIGNED NOT NULL DEFAULT '0'");
			#spip_query("UPDATE spip_referers SET visites_jour=0");
			// version 4 fois plus rapide que la premiere, en une seule requete
		  // ATTENTION : peut poser probleme cf https://core.spip.net/issues/2505
			sql_alter("TABLE spip_referers DROP visites_veille,
			CHANGE visites_jour visites_veille INT(10) UNSIGNED NOT NULL DEFAULT '0',
			ADD visites_jour INT(10) UNSIGNED NOT NULL DEFAULT '0'");
	}
 
	// et c'est fini pour cette fois-ci
	return 1;

}

?>mail.php000066600000003727152526156150006224 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) return;

/**
 * Envoi du Mail des nouveautes
 * base sur le squelette nouveautes.html
 *
 * La meta dernier_envoi_neuf permet de marquer la date du dernier envoi
 * et de determiner les nouveautes publiees depuis cette date
 *
 * http://doc.spip.org/@genie_mail_dist
 *
 * @param int $t
 * @return int
 */
function genie_mail_dist($t) {
	$adresse_neuf = $GLOBALS['meta']['adresse_neuf'];
	$jours_neuf = $GLOBALS['meta']['jours_neuf'];

	$now = time();
	if (!isset($GLOBALS['meta']['dernier_envoi_neuf']))
		ecrire_meta('dernier_envoi_neuf',date('Y-m-d H:i:s',$now - (3600 * 24 * $jours_neuf)));

	$page = recuperer_fond('nouveautes',array('date'=>$GLOBALS['meta']['dernier_envoi_neuf'],'jours_neuf'=>$jours_neuf),array('raw'=>true));

	if (strlen(trim($page['texte']))){
		// recuperer les entetes envoyes par #HTTP_HEADER
		$headers = "";
		if (isset($page['entetes']) AND count($page['entetes'])){
			foreach ($page['entetes'] as $k => $v)
				$headers .= (strlen($v)?"$k: $v":$k)."\n";
		}

		include_spip("inc/notifications");
		notifications_envoyer_mails($adresse_neuf,$page['texte'],"","",$headers);
		ecrire_meta('dernier_envoi_neuf',date('Y-m-d H:i:s',$now));
	}
	else
		spip_log("mail nouveautes : rien de neuf depuis $jours_neuf jours");

	return 1;
}

?>
optimiser.php000066600000011511152526156150007303 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) return;

include_spip('base/abstract_sql');

// http://doc.spip.org/@genie_optimiser_dist
function genie_optimiser_dist($t) {

	optimiser_base_une_table();
	optimiser_base();

	// la date souhaitee pour le tour suivant = apres-demain a 4h du mat ;
	// sachant qu'on a un delai de 48h, on renvoie aujourd'hui a 4h du mat
	// avec une periode de flou entre 2h et 6h pour ne pas saturer un hebergeur
	// qui aurait beaucoup de sites SPIP
	return -(mktime(2,0,0) + rand(0, 3600*4));
}

// heure de reference pour le garbage collector = 24h auparavant
// http://doc.spip.org/@optimiser_base
function optimiser_base($attente = 86400) {
	optimiser_base_disparus($attente);
}


// http://doc.spip.org/@optimiser_base_une_table
function optimiser_base_une_table() {

	$tables = array();
	$result = sql_showbase();

	// on n'optimise qu'une seule table a chaque fois,
	// pour ne pas vautrer le systeme
	// lire http://dev.mysql.com/doc/refman/5.0/fr/optimize-table.html
	while ($row = sql_fetch($result))
		$tables[] = array_shift($row);

	if ($tables) {
		$table_op = intval($GLOBALS['meta']['optimiser_table']+1) % sizeof($tables);
		ecrire_meta('optimiser_table', $table_op);
		$q = $tables[$table_op];
		spip_log("debut d'optimisation de la table $q");
		if (sql_optimize($q))
			spip_log("fin d'optimisation de la table $q");
		else spip_log("Pas d'optimiseur necessaire");
	}
}

// mysql < 4.0 refuse les requetes DELETE multi table 
// et elles ont une syntaxe differente entre 4.0 et 4.1
// On passe donc par un SELECT puis DELETE avec IN 

// Utilitaire exploitant le SELECT et appliquant DELETE
// L'index du SELECT doit s'appeler "id"

// http://doc.spip.org/@optimiser_sansref
function optimiser_sansref($table, $id, $sel, $and="")
{
	$in = array();
	while ($row = sql_fetch($sel)) $in[$row['id']]=true;
	sql_free($sel);

	if ($in) {
		sql_delete($table,  sql_in($id,array_keys($in)) . ($and?" AND $and":""));
		spip_log("Numeros des entrees $id supprimees dans la table $table: $in");
	}
	return count($in);
}

// Nomenclature des liens morts entre les tables,
// suite a la suppresion d'articles, d'auteurs etc
// Maintenant que MySQL 5 a des Cascades on pourrait faire autrement
// mais on garde la compatibilite avec les versions precedentes.

// http://doc.spip.org/@optimiser_base_disparus
function optimiser_base_disparus($attente = 86400) {

	# format = 20060610110141, si on veut forcer une optimisation tout de suite
	$mydate = sql_quote(date("Y-m-d H:i:s", time() - $attente));

	$n = 0;

	//
	// Rubriques 
	//

	# les articles qui sont dans une id_rubrique inexistante
	# attention on controle id_rubrique>0 pour ne pas tuer les articles
	# specialement affectes a une rubrique non-existante (plugin,
	# cf. http://trac.rezo.net/trac/spip/ticket/1549 )
	$res = sql_select("A.id_article AS id",
		        "spip_articles AS A
		        LEFT JOIN spip_rubriques AS R
		          ON A.id_rubrique=R.id_rubrique",
			 "A.id_rubrique > 0
			 AND R.id_rubrique IS NULL
		         AND A.maj < $mydate");

	$n+= optimiser_sansref('spip_articles', 'id_article', $res);

	// les articles a la poubelle
	sql_delete("spip_articles", "statut='poubelle' AND maj < $mydate");

	//
	// Auteurs
	//

	include_spip('action/editer_liens');
	// optimiser les liens de tous les auteurs vers des objets effaces
	// et depuis des auteurs effaces
	$n+= objet_optimiser_liens(array('auteur'=>'*'),'*');

	# effacer les auteurs poubelle qui ne sont lies a rien
	$res = sql_select("A.id_auteur AS id",
		      	"spip_auteurs AS A
		      	LEFT JOIN spip_auteurs_liens AS L
		          ON L.id_auteur=A.id_auteur",
			"L.id_auteur IS NULL
		       	AND A.statut='5poubelle' AND A.maj < $mydate");

	$n+= optimiser_sansref('spip_auteurs', 'id_auteur', $res);

	# supprimer les auteurs 'nouveau' qui n'ont jamais donne suite
	# au mail de confirmation (45 jours pour repondre, ca devrait suffire)
	sql_delete("spip_auteurs", "statut='nouveau' AND maj < ". sql_quote(date('Y-m-d', time()-45*24*3600)));


	$n = pipeline('optimiser_base_disparus', array(
			'args'=>array(
				'attente' => $attente,
				'date' => $mydate),
			'data'=>$n
	));
	
	if (!$n) spip_log("Optimisation des tables: aucun lien mort");
}
?>
maintenance.php000066600000004312152526156150007553 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) return;

// Diverses taches de maintenance
// http://doc.spip.org/@genie_maintenance_dist
function genie_maintenance_dist ($t) {

	// (re)mettre .htaccess avec deny from all
	// dans les deux repertoires dits inaccessibles par http
	include_spip('inc/acces');
	verifier_htaccess(_DIR_ETC);
	verifier_htaccess(_DIR_TMP);

	// Verifier qu'aucune table n'est crashee
	if (!_request('reinstall'))
		verifier_crash_tables();

	return 1;
}


// http://doc.spip.org/@verifier_crash_tables
function verifier_crash_tables() {
	if (spip_connect()) {
		include_spip('base/serial');
		include_spip('base/auxiliaires');
		$crash = array();
		foreach (array('tables_principales', 'tables_auxiliaires') as $com) {
			foreach ($GLOBALS[$com] as $table => $desc) {
				if (!sql_select('*', $table,'','','', 1)
				AND !defined('spip_interdire_cache')) # cas "LOST CONNECTION"
					$crash[] = $table;
			}
		}
		#$crash[] = 'test';
		if ($crash) {
			ecrire_meta('message_crash_tables', serialize($crash));
			spip_log('crash des tables', 'err');
			spip_log($crash, 'err');
		} else {
			effacer_meta('message_crash_tables');
		}

		return $crash;
	}

	return false;
}

// http://doc.spip.org/@message_crash_tables
function message_crash_tables() {
	if ($crash = verifier_crash_tables()) {
		return 
		'<strong>' . _T('texte_recuperer_base') . '</strong><br />'
		. ' <tt>'.join(', ', $crash).'</tt><br />'
		. generer_form_ecrire('base_repair',
			_T('texte_crash_base'), '',
			_T('bouton_tenter_recuperation'))
		;
	}
}

?>
mise_a_jour.php000066600000006363152526156150007575 0ustar00<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

if (!defined('_ECRIRE_INC_VERSION')) return;

/**
 * Verifier si une mise a jour est disponible
 *
 * @param int $t
 * @return int
 */
function genie_mise_a_jour_dist($t) {
	include_spip('inc/meta');
	$maj = info_maj ('spip', 'SPIP', $GLOBALS['spip_version_branche']);
	ecrire_meta('info_maj_spip',$maj?($GLOBALS['spip_version_branche']."|$maj"):"",'non');

	spip_log("Verification version SPIP : ".($maj?$maj:"version a jour"),"verifie_maj");
	return 1;
}


// Determiner si une nouvelle version de SPIP est disponible
// sans demander tout le temps au serveur de versions si leur liste a change'.

define('_VERSIONS_SERVEUR', 'http://files.spip.org/');
define('_VERSIONS_LISTE', 'archives.xml');

function info_maj ($dir, $file, $version){
	include_spip('inc/plugin');
	
	list($maj,$min,$rev) = preg_split('/\D+/', $version);

	$nom = _DIR_CACHE_XML . _VERSIONS_LISTE;
	$page = !file_exists($nom) ? '' : file_get_contents($nom);
	$page = info_maj_cache($nom, $dir, $page);

	// reperer toutes les versions de numero majeur superieur ou egal
	// (a revoir quand on arrivera a SPIP V10 ...)
	$p = substr("0123456789", intval($maj));
	$p = ',/' . $file . '\D+([' . $p . ']+)\D+(\d+)(\D+(\d+))?.*?[.]zip",i';
	preg_match_all($p, $page, $m,  PREG_SET_ORDER);
	$page = '';
	foreach ($m as $v) {
		list(, $maj2, $min2,, $rev2) = $v;
		$version_maj = $maj2 . '.' . $min2 . '.' . $rev2;
		if ((spip_version_compare($version, $version_maj, '<'))
		AND (spip_version_compare($page, $version_maj, '<')))
			$page = $version_maj;
	}

	if (!$page) return "";
	return "<a class='info_maj_spip' href='"._VERSIONS_SERVEUR."$dir' title='$page'>" .
		_T('nouvelle_version_spip',array('version'=>$page)) .
	    '</a>';
}

// Verifie que la liste $page des versions dans le fichier $nom est a jour
// Ce fichier rajoute dans ce fichier l'alea ephemere courant;
// on teste la nouveaute par If-Modified-Since,
// et seulement quand celui-ci a change' pour limiter les acces HTTP

function info_maj_cache($nom, $dir, $page='')
{
	$re = '<archives id="a' . $GLOBALS['meta']["alea_ephemere"] . '">';
	if (preg_match("/$re/", $page)) return $page;

	$url = _VERSIONS_SERVEUR . $dir . '/' . _VERSIONS_LISTE;
	$a = file_exists($nom) ? filemtime($nom) : '';
	include_spip('inc/distant');
	$res = recuperer_lapage($url, false, 'GET', _COPIE_LOCALE_MAX_SIZE, '',false, $a);
	// Si rien de neuf (ou inaccessible), garder l'ancienne
	if ($res) list(, $page) = $res;
	// Placer l'indicateur de fraicheur
	$page = preg_replace('/^<archives.*?>/', $re, $page);
	sous_repertoire(_DIR_CACHE_XML);
	ecrire_fichier($nom, $page);
	return $page;
}

?>
svp_actualiser_depots.php000066600000001507152526253100011667 0ustar00<?php

/**
 * Gestion du génie svp_actualiser_depots
 *
 * @plugin SVP pour SPIP
 * @license GPL
 * @package SPIP\SVP\Genie
 */

if (!defined("_ECRIRE_INC_VERSION")) return;

/**
 * Actualise tous les dépots
 *
 * @genie svp_actualiser_depots
 *
 * @param int $last
 *     Timestamp de la dernière exécution de cette tâche
 * @return int
 *     Positif : la tâche a été effectuée
 */
function genie_svp_actualiser_depots_dist ($last) {

	include_spip('inc/svp_depoter_distant');

	// On recupere en base de donnees tous les depots a mettre a jour
	if ($resultats = sql_allfetsel('id_depot', 'spip_depots')) {
		foreach ($resultats as $depot) {
			svp_actualiser_depot($depot['id_depot']);
			spip_log("ACTION ACTUALISER DEPOT (automatique) : id_depot = ". $depot['id_depot'], 'svp_actions.' . _LOG_INFO);
		}
	}

	return 1;
}

?>
svp_taches_generales_cron.php000066600000002366152526253100012476 0ustar00<?php

/**
 * Déclaration des tâches du génie
 *
 * @plugin SVP pour SPIP
 * @license GPL
 * @package SPIP\SVP\Genie
 */
if (!defined("_ECRIRE_INC_VERSION")) return;


if (!defined('_SVP_CRON_ACTUALISATION_DEPOTS')) {
	/**
	 * Mise à jour automatique des depots (CRON)
	 * true pour autoriser les actualisations automatique
	 * @var bool
	 */
	define('_SVP_CRON_ACTUALISATION_DEPOTS', true);
}

if (!defined('_SVP_PERIODE_ACTUALISATION_DEPOTS')) {
	/**
	 * Période d'actualisation en nombre d'heures (de 1 a 24)
	 * @var int
	 */
	define('_SVP_PERIODE_ACTUALISATION_DEPOTS', 6);
}


/**
 * Ajoute la tâche d'actualisation des dépots dans la liste des tâches périodiques
 *
 * @pipeline taches_generales_cron
 *
 * @param array $taches_generales
 *     Tableau des tâches et leur périodicité en seconde
 * @return array
 *     Tableau des tâches et leur périodicité en seconde
 */
function svp_taches_generales_cron($taches_generales) {

	// Ajout de la tache CRON de mise a jour reguliere de tous les depots de la base
	// Par defaut, toutes les 6h
	// Conditionnee a la variable de configuration
	if (_SVP_CRON_ACTUALISATION_DEPOTS)
		$taches_generales['svp_actualiser_depots'] = _SVP_PERIODE_ACTUALISATION_DEPOTS*3600;

	return $taches_generales;
}

?>
optimiser_revisions.php000066600000005625152527240220011406 0ustar00<?php
/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2016                                                *
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
 *                                                                         *
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
\***************************************************************************/

/**
 * @plugin Revisions pour SPIP
 * @license GPL
 * @package SPIP\Revisions\Genie
 */

if (!defined('_ECRIRE_INC_VERSION')) return;

include_spip('base/abstract_sql');

/**
 * Tâche Cron d'optimisation des révisions
 * 
 * @param int $last
 *     Timestamp de la dernière exécution de cette tâche
 * @return int
 *     Positif : la tâche a été effectuée
 */
function genie_optimiser_revisions_dist($last) {

	optimiser_base_revisions();
	optimiser_tables_revision();
	
	return 1;
}

/**
 * Supprimer les révisions des objets disparus 
 */
function optimiser_base_revisions(){
	/**
	 * On commence par récupérer la liste des types d'objet ayant au moins une révision
	 */ 
	$objets_revises = sql_select('objet','spip_versions','id_version=1','objet');
	
	/**
	 * Pour chaque objet, on va contruire un tableau des identifiants disparus
	 * On supprimera ensuite les occurences dans spip_versions et spip_versions_fragments
	 */
	while($objet = sql_fetch($objets_revises)){
		$in = array();
		$table = table_objet_sql($objet['objet']);
		$id_table_objet = id_table_objet($objet['objet']);
		$res = sql_select("A.id_objet AS id_objet, A.objet AS objet",
							"spip_versions AS A LEFT JOIN $table AS R
							ON R.$id_table_objet=A.id_objet AND A.objet=".sql_quote($objet['objet']),
							"R.$id_table_objet IS NULL AND A.objet=".sql_quote($objet['objet'])." AND A.id_objet > 0",
							"A.id_objet",
							"A.id_objet");
		while ($row = sql_fetch($res)) $in[$row['id_objet']]=true;
		sql_free($sel);
		
		/**
		 * Si on a un array
		 * On supprime toute occurence des objets disparus dans : 
		 * -* spip_versions
		 * -* spip_versions_fragments
		 */
		if ($in) {
			foreach(array('spip_versions','spip_versions_fragments') as $table){
				sql_delete($table,  sql_in('id_objet',array_keys($in)) . " AND objet=".sql_quote($objet['objet']));
			}
		}
	}
}

/**
 * Optimisation des tables spip_versions et spip_versions_fragments
 */
function optimiser_tables_revision(){
	foreach(array('spip_versions','spip_versions_fragments') as $table){
		spip_log("debut d'optimisation de la table $table");
		if (sql_optimize($table))
			spip_log("fin d'optimisation de la table $table");
		else
			spip_log("Pas d'optimiseur necessaire pour $table");
	}
}
?>