Example #1
0
/**
 * Optimiser les liens morts dans la base de donnees
 *
 * @param array $flux
 * @return array
 */
function organiseur_optimiser_base_disparus($flux)
{
    //
    // Messages prives
    //
    # supprimer les messages lies a un auteur disparu
    $res = sql_select("M.id_message AS id", "spip_messages AS M\n\t\t        LEFT JOIN spip_auteurs AS A\n\t\t          ON A.id_auteur=M.id_auteur", "A.id_auteur IS NULL");
    $flux['data'] += optimiser_sansref('spip_messages', 'id_message', $res);
    return $flux;
}
Example #2
0
function optimiser_base_disparus($attente = 86400) {

	# format = 20060610110141, si on veut forcer une optimisation tout de suite
	$mydate = date("YmdHis", 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("articles.id_article AS id",
		        "spip_articles AS articles
		        LEFT JOIN spip_rubriques AS rubriques
		          ON articles.id_rubrique=rubriques.id_rubrique",
			 "articles.id_rubrique > 0
			 AND rubriques.id_rubrique IS NULL
		         AND articles.maj < $mydate");

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

	# les breves qui sont dans une id_rubrique inexistante
	$res = sql_select("breves.id_breve AS id",
		        "spip_breves AS breves
		        LEFT JOIN spip_rubriques AS rubriques
		          ON breves.id_rubrique=rubriques.id_rubrique",
			"rubriques.id_rubrique IS NULL
		         AND breves.maj < $mydate");

	$n+= optimiser_sansref('spip_breves', 'id_breve', $res);

	# les forums lies a une id_rubrique inexistante
	$res = sql_select("forum.id_forum AS id",
			"spip_forum AS forum
		        LEFT JOIN spip_rubriques AS rubriques
		          ON forum.id_rubrique=rubriques.id_rubrique",
			"rubriques.id_rubrique IS NULL
		         AND forum.id_rubrique>0");

	$n+= optimiser_sansref('spip_forum', 'id_forum', $res);

	# les droits d'auteurs sur une id_rubrique inexistante
	# (plusieurs entrees seront eventuellement detruites pour chaque rub)
	$res = sql_select("auteurs_rubriques.id_rubrique AS id",
	 	        "spip_auteurs_rubriques AS auteurs_rubriques
		        LEFT JOIN spip_rubriques AS rubriques
		          ON auteurs_rubriques.id_rubrique=rubriques.id_rubrique",
			"rubriques.id_rubrique IS NULL");

	$n+= optimiser_sansref('spip_auteurs_rubriques', 'id_rubrique', $res);

	# les liens des mots affectes a une id_rubrique inexistante
	$res = sql_select("mots_rubriques.id_rubrique AS id",
		      "spip_mots_rubriques AS mots_rubriques
		        LEFT JOIN spip_rubriques AS rubriques
		          ON mots_rubriques.id_rubrique=rubriques.id_rubrique",
			"rubriques.id_rubrique IS NULL");

	$n+= optimiser_sansref('spip_mots_rubriques', 'id_rubrique', $res);

	//
	// Articles
	//

	sql_delete("spip_articles", "statut='poubelle' AND maj < $mydate");

	# les liens d'auteurs d'articles effaces
	$res = sql_select("auteurs_articles.id_article AS id",
		      "spip_auteurs_articles AS auteurs_articles
		        LEFT JOIN spip_articles AS articles
		          ON auteurs_articles.id_article=articles.id_article",
			"articles.id_article IS NULL");

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

	# les liens de mots affectes a des articles effaces
	$res = sql_select("mots_articles.id_article AS id",
		        "spip_mots_articles AS mots_articles
		        LEFT JOIN spip_articles AS articles
		          ON mots_articles.id_article=articles.id_article",
			"articles.id_article IS NULL");

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

	# les forums lies a des articles effaces
	$res = sql_select("forum.id_forum AS id",
		        "spip_forum AS forum
		        LEFT JOIN spip_articles AS articles
		          ON forum.id_article=articles.id_article",
			"articles.id_article IS NULL
		         AND forum.id_article>0");

	$n+= optimiser_sansref('spip_forum', 'id_forum', $res);

	//
	// Breves
	//

	sql_delete("spip_breves", "statut='refuse' AND maj < $mydate");


	# les liens de mots affectes a des breves effacees
	$res = sql_select("mots_breves.id_breve AS id",
		        "spip_mots_breves AS mots_breves
		        LEFT JOIN spip_breves AS breves
		          ON mots_breves.id_breve=breves.id_breve",
			"breves.id_breve IS NULL");

	$n+= optimiser_sansref('spip_mots_breves', 'id_breve', $res);

	# les forums lies a des breves effacees
	$res = sql_select("forum.id_forum AS id",
		        "spip_forum AS forum
		        LEFT JOIN spip_breves AS breves
		          ON forum.id_breve=breves.id_breve",
			"breves.id_breve IS NULL
		         AND forum.id_breve>0");

	$n+= optimiser_sansref('spip_forum', 'id_forum', $res);


	//
	// Sites
	//

	sql_delete("spip_syndic", "maj < $mydate AND statut = 'refuse'");


	# les articles syndiques appartenant a des sites effaces
	$res = sql_select("syndic_articles.id_syndic AS id",
		      "spip_syndic_articles AS syndic_articles
		        LEFT JOIN spip_syndic AS syndic
		          ON syndic_articles.id_syndic=syndic.id_syndic",
			"syndic.id_syndic IS NULL");

	$n+= optimiser_sansref('spip_syndic_articles', 'id_syndic', $res);

	# les liens de mots affectes a des sites effaces
	$res = sql_select("mots_syndic.id_syndic AS id",
		        "spip_mots_syndic AS mots_syndic
		        LEFT JOIN spip_syndic AS syndic
		          ON mots_syndic.id_syndic=syndic.id_syndic",
			"syndic.id_syndic IS NULL");

	$n+= optimiser_sansref('spip_mots_syndic', 'id_syndic', $res);

	# les forums lies a des sites effaces
	$res = sql_select("forum.id_forum AS id",
		        "spip_forum AS forum
		        LEFT JOIN spip_syndic AS syndic
		          ON forum.id_syndic=syndic.id_syndic",
			"syndic.id_syndic IS NULL
		         AND forum.id_syndic>0");

	$n+= optimiser_sansref('spip_forum', 'id_forum', $res);

	//
	// Auteurs
	//

	# les liens d'articles sur des auteurs effaces
	$res = sql_select("auteurs_articles.id_auteur AS id",
		      "spip_auteurs_articles AS auteurs_articles
		        LEFT JOIN spip_auteurs AS auteurs
		          ON auteurs_articles.id_auteur=auteurs.id_auteur",
			"auteurs.id_auteur IS NULL");

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

	# les liens de messages sur des auteurs effaces
	$res = sql_select("auteurs_messages.id_auteur AS id",
		      "spip_auteurs_messages AS auteurs_messages
		        LEFT JOIN spip_auteurs AS auteurs
		          ON auteurs_messages.id_auteur=auteurs.id_auteur",
			"auteurs.id_auteur IS NULL");

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

	# les liens de rubriques sur des auteurs effaces
	$res = sql_select("auteurs_rubriques.id_rubrique AS id",
		      "spip_auteurs_rubriques AS auteurs_rubriques
		        LEFT JOIN spip_rubriques AS rubriques
		          ON auteurs_rubriques.id_rubrique=rubriques.id_rubrique",
			"rubriques.id_rubrique IS NULL");

	$n+= optimiser_sansref('spip_auteurs_rubriques', 'id_rubrique', $res);

	# effacer les auteurs poubelle qui ne sont lies a aucun article
	$res = sql_select("auteurs.id_auteur AS id",
		      	"spip_auteurs AS auteurs
		      	LEFT JOIN spip_auteurs_articles AS auteurs_articles
		          ON auteurs_articles.id_auteur=auteurs.id_auteur",
			"auteurs_articles.id_auteur IS NULL
		       	AND auteurs.statut='5poubelle' AND auteurs.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)));


	//
	// Documents
	//
	
	# les liens des documents qui sont lies a un objet inexistant
	$r = sql_select("DISTINCT objet","spip_documents_liens");
	while ($t = sql_fetch($r)){
		$type = $t['objet'];
		$spip_table_objet = table_objet_sql($type);
		$id_table_objet = id_table_objet($type);
		$res = sql_select("L.id_document AS id,id_objet",
			      "spip_documents_liens AS L
			        LEFT JOIN $spip_table_objet AS O
			          ON O.$id_table_objet=L.id_objet AND L.objet=".sql_quote($type),
				"O.$id_table_objet IS NULL");
		// sur une cle primaire composee, pas d'autres solutions que de virer un a un
		while ($row = sql_fetch($res)){
			sql_delete("spip_documents_liens", array("id_document=".$row['id'],"id_objet=".$row['id_objet'],"objet=".sql_quote($type)));
			spip_log("Entree ".$row['id']."/".$row['id_objet']."/$type supprimee dans la table spip_documents_liens");
		}
	}
	
	// on ne nettoie volontairement pas automatiquement les documents orphelins
	
	//
	// Messages prives
	//

	# supprimer les messages lies a un auteur disparu
	$res = sql_select("messages.id_message AS id",
		      "spip_messages AS messages
		        LEFT JOIN spip_auteurs AS auteurs
		          ON auteurs.id_auteur=messages.id_auteur",
			"auteurs.id_auteur IS NULL");

	$n+= optimiser_sansref('spip_messages', 'id_message', $res);

	//
	// Mots-cles
	//

	$result = sql_delete("spip_mots", "titre='' AND maj < $mydate");


	# les liens mots-articles sur des mots effaces
	$res = sql_select("mots_articles.id_mot AS id",
		        "spip_mots_articles AS mots_articles
		        LEFT JOIN spip_mots AS mots
		          ON mots_articles.id_mot=mots.id_mot",
			"mots.id_mot IS NULL");

	$n+= optimiser_sansref('spip_mots_articles', 'id_mot', $res);

	# les liens mots-breves sur des mots effaces
	$res = sql_select("mots_breves.id_mot AS id",
		        "spip_mots_breves AS mots_breves
		        LEFT JOIN spip_mots AS mots
		          ON mots_breves.id_mot=mots.id_mot",
			"mots.id_mot IS NULL");

	$n+= optimiser_sansref('spip_mots_breves', 'id_mot', $res);

	# les liens mots-forum sur des mots effaces
	$res = sql_select("mots_forum.id_mot AS id",
		        "spip_mots_forum AS mots_forum
		        LEFT JOIN spip_mots AS mots
		          ON mots_forum.id_mot=mots.id_mot",
			"mots.id_mot IS NULL");

	$n+= optimiser_sansref('spip_mots_forum', 'id_mot', $res);

	# les liens mots-rubriques sur des mots effaces
	$res = sql_select("mots_rubriques.id_mot AS id",
		      "spip_mots_rubriques AS mots_rubriques
		        LEFT JOIN spip_mots AS mots
		          ON mots_rubriques.id_mot=mots.id_mot",
			"mots.id_mot IS NULL");

	$n+= optimiser_sansref('spip_mots_rubriques', 'id_mot', $res);

	# les liens mots-syndic sur des mots effaces
	$res = sql_select("mots_syndic.id_mot AS id",
		        "spip_mots_syndic AS mots_syndic
		        LEFT JOIN spip_mots AS mots
		          ON mots_syndic.id_mot=mots.id_mot",
			"mots.id_mot IS NULL");

	$n+= optimiser_sansref('spip_mots_syndic', 'id_mot', $res);


	//
	// Forums
	//

	sql_delete("spip_forum", "statut='redac' AND maj < $mydate");


	# les liens mots-forum sur des forums effaces
	$res = sql_select("mots_forum.id_forum AS id",
		        "spip_mots_forum AS mots_forum
		        LEFT JOIN spip_forum AS forum
		          ON mots_forum.id_forum=forum.id_forum",
			"forum.id_forum IS NULL");

	$n+= optimiser_sansref('spip_mots_forum', 'id_forum', $res);
	
	$n = pipeline('optimiser_base_disparus', array(
			'args'=>array(
				'attente' => $attente,
				'date' => $mydate),
			'data'=>$n
	));


	//
	// CNIL -- Informatique et libertes
	//
	// masquer le numero IP des vieux forums
	//
	## date de reference = 4 mois
	## definir a 0 pour desactiver
	define('_CNIL_PERIODE', 3600*24*31*4);

	if (_CNIL_PERIODE) {
		$critere_cnil = 'date_heure<"'.date('Y-m-d', time()-_CNIL_PERIODE).'"'
			. ' AND statut != "spam"'
			. ' AND (ip LIKE "%.%" OR ip LIKE "%:%")'; # ipv4 ou ipv6

		$c = sql_countsel('spip_forum', $critere_cnil);

		if ($c>0) {
			spip_log("CNIL: masquer IP de $c forums anciens");
			sql_update('spip_forum', array('ip' => 'MD5(ip)'), $critere_cnil);
		}
	}


	if (!$n) spip_log("Optimisation des tables: aucun lien mort");
}
Example #3
0
/**
 * Optimiser la base de donnee en supprimant les forums orphelins
 *
 * @param int $n
 * @return int
 */
function forum_optimiser_base_disparus($flux)
{
    $n =& $flux['data'];
    $mydate = $flux['args']['date'];
    # les forums lies a une id_objet inexistant
    $r = sql_select("DISTINCT objet", 'spip_forum');
    while ($t = sql_fetch($r)) {
        if ($type = $t['objet']) {
            $spip_table_objet = table_objet_sql($type);
            $id_table_objet = id_table_objet($type);
            # les forums lies a un objet inexistant
            $res = sql_select("forum.id_forum AS id", "spip_forum AS forum\n\t\t\t\t\t\t\t\tLEFT JOIN {$spip_table_objet} AS O\n\t\t\t\t\t\t\t\t\tON O.{$id_table_objet}=forum.id_objet", "forum.objet=" . sql_quote($type) . " AND O.{$id_table_objet} IS NULL AND forum.id_objet>0");
            $n += optimiser_sansref('spip_forum', 'id_forum', $res);
        }
    }
    //
    // Forums
    //
    sql_delete("spip_forum", "statut='redac' AND maj < {$mydate}");
    // nettoyer les documents des forums en spam&poubelle pour eviter de sortir des quota disques
    // bizarrement on ne nettoie jamais les messages eux meme ?
    include_spip('action/editer_liens');
    if (objet_associable('document')) {
        $res = sql_select('L.id_document,F.id_forum', "spip_documents_liens AS L JOIN spip_forum AS F ON (F.id_forum=L.id_objet AND L.objet='forum')", "F.statut IN ('off','spam')");
        while ($row = sql_fetch($res)) {
            include_spip('inc/autoriser');
            // si un seul lien (ce forum donc), on supprime le document
            // si un document est attache a plus d'un forum, c'est un cas bizarre ou gere a la main
            // on ne touche a rien !
            if (count(objet_trouver_liens(array('document' => $row['id_document']), '*')) == 1) {
                autoriser_exception('supprimer', 'document', $row['id_document']);
                if ($supprimer_document = charger_fonction('supprimer_document', 'action', true)) {
                    $supprimer_document($row['id_document']);
                }
            }
        }
    }
    //
    // CNIL -- Informatique et libertes
    //
    // masquer le numero IP des vieux forums
    //
    ## date de reference = 4 mois
    ## definir a 0 pour desactiver
    if (!defined('_CNIL_PERIODE')) {
        define('_CNIL_PERIODE', 3600 * 24 * 31 * 4);
    }
    if (_CNIL_PERIODE) {
        $critere_cnil = 'date_heure<"' . date('Y-m-d', time() - _CNIL_PERIODE) . '"' . ' AND statut != "spam"' . ' AND (ip LIKE "%.%" OR ip LIKE "%:%")';
        # ipv4 ou ipv6
        $c = sql_countsel('spip_forum', $critere_cnil);
        if ($c > 0) {
            spip_log("CNIL: masquer IP de {$c} forums anciens");
            sql_update('spip_forum', array('ip' => 'MD5(ip)'), $critere_cnil);
        }
    }
    return $flux;
}
Example #4
0
/**
 * Optimiser la base de donnee en supprimant les liens orphelins
 *
 * @param array $flux
 * @return array
 */
function sites_optimiser_base_disparus($flux)
{
    $n =& $flux['data'];
    $mydate = $flux['args']['date'];
    sql_delete("spip_syndic", "maj < {$mydate} AND statut = 'refuse'");
    # les articles syndiques appartenant a des sites effaces
    $res = sql_select("S.id_syndic AS id", "spip_syndic_articles AS S\n\t\t        LEFT JOIN spip_syndic AS syndic\n\t\t          ON S.id_syndic=syndic.id_syndic", "syndic.id_syndic IS NULL");
    $n += optimiser_sansref('spip_syndic_articles', 'id_syndic', $res);
    return $flux;
}
Example #5
0
/**
 * Suppression des liens morts entre tables
 *
 * Supprime des liens morts entre tables suite à la suppression d'articles,
 * d'auteurs, etc...
 *
 * @note
 *     Maintenant que MySQL 5 a des Cascades on pourrait faire autrement
 *     mais on garde la compatibilité avec les versions précédentes.
 *
 * @pipeline_appel optimiser_base_disparus
 * 
 * @param int $attente
 *     Attente entre 2 exécutions de la tache en secondes
 * @return void
**/
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\n\t\t        LEFT JOIN spip_rubriques AS R\n\t\t          ON A.id_rubrique=R.id_rubrique", "A.id_rubrique > 0\n\t\t\t AND R.id_rubrique IS NULL\n\t\t         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\n\t\t      \tLEFT JOIN spip_auteurs_liens AS L\n\t\t          ON L.id_auteur=A.id_auteur", "L.id_auteur IS NULL\n\t\t       \tAND 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)));
    /**
     * Permet aux plugins de compléter l'optimisation suite aux éléments disparus
     *
     * L'index 'data' est un entier indiquant le nombre d'optimisations
     * qui ont été réalisées (par exemple le nombre de suppressions faites)
     * et qui doit être incrémenté par les fonctions
     * utilisant ce pipeline si elles suppriment des éléments.
     * 
     * @pipeline_appel optimiser_base_disparus
     */
    $n = pipeline('optimiser_base_disparus', array('args' => array('attente' => $attente, 'date' => $mydate), 'data' => $n));
    if (!$n) {
        spip_log("Optimisation des tables: aucun lien mort");
    }
}
/**
 * Sous fonction optimisation
 * qui nettoie les liens morts (vers un objet inexistant)
 * pour un objet source dont la clé primaire
 * et la table de lien sont fournies
 *
 * $objets et de la forme
 * array($objet=>$id_objets,...)
 * un * pour $id,$objet,$id_objets permet de traiter par lot
 *
 * @internal
 * @param string $objet_source
 * @param string $primary
 * @param string $table_lien
 * @param int $id
 * @param array $objets
 * @return bool|int
 */
function lien_optimise($objet_source, $primary, $table_lien, $id, $objets)
{
    include_spip('genie/optimiser');
    $echec = false;
    $dels = 0;
    foreach ($objets as $objet => $id_objets) {
        $objet = $objet == '*' ? $objet : objet_type($objet);
        # securite
        if (!is_array($id_objets) or reset($id_objets) == "NOT") {
            $id_objets = array($id_objets);
        }
        foreach ($id_objets as $id_objet) {
            $where = lien_where($primary, $id, $objet, $id_objet);
            # les liens vers un objet inexistant
            $r = sql_select("DISTINCT objet", $table_lien, $where);
            while ($t = sql_fetch($r)) {
                $type = $t['objet'];
                $spip_table_objet = table_objet_sql($type);
                $id_table_objet = id_table_objet($type);
                $res = sql_select("L.{$primary} AS id,L.id_objet", "{$table_lien} AS L\n\t\t\t\t\t\t\t\t\tLEFT JOIN {$spip_table_objet} AS O\n\t\t\t\t\t\t\t\t\t\tON (O.{$id_table_objet}=L.id_objet AND L.objet=" . sql_quote($type) . ")", "L.objet=" . sql_quote($type) . " AND O.{$id_table_objet} IS NULL");
                // sur une cle primaire composee, pas d'autres solutions que de virer un a un
                while ($row = sql_fetch($res)) {
                    $e = sql_delete($table_lien, array("{$primary}=" . $row['id'], "id_objet=" . $row['id_objet'], "objet=" . sql_quote($type)));
                    if ($e != false) {
                        $dels += $e;
                        spip_log("Entree " . $row['id'] . "/" . $row['id_objet'] . "/{$type} supprimee dans la table {$table_lien}", _LOG_INFO_IMPORTANTE);
                    }
                }
            }
            # les liens depuis un objet inexistant
            $table_source = table_objet_sql($objet_source);
            // filtrer selon $id, $objet, $id_objet eventuellement fournis
            // (en general '*' pour chaque)
            $where = lien_where("L.{$primary}", $id, $objet, $id_objet);
            $where[] = "O.{$primary} IS NULL";
            $res = sql_select("L.{$primary} AS id", "{$table_lien} AS L LEFT JOIN {$table_source} AS O ON L.{$primary}=O.{$primary}", $where);
            $dels += optimiser_sansref($table_lien, $primary, $res);
        }
    }
    return $echec ? false : $dels;
}
/**
 * Optimiser la base de données en supprimant les liens de brèves orphelins
 *
 * @pipeline optimiser_base_disparus
 *
 * @param array $flux Données du pipeline
 * @return array       Données du pipeline
 */
function breves_optimiser_base_disparus($flux)
{
    $n =& $flux['data'];
    $mydate = $flux['args']['date'];
    # les breves qui sont dans une id_rubrique inexistante
    $res = sql_select("B.id_breve AS id", "spip_breves AS B\n\t\t        LEFT JOIN spip_rubriques AS R\n\t\t          ON B.id_rubrique=R.id_rubrique", "R.id_rubrique IS NULL\n\t\t         AND B.maj < " . sql_quote($mydate));
    $n += optimiser_sansref('spip_breves', 'id_breve', $res);
    //
    // Breves
    //
    sql_delete("spip_breves", "statut='refuse' AND maj < {$mydate}");
    return $flux;
}