Proposer une amélioration de commentaire

Le commentaire à poster est au format «docblock» (de phpDoc) qui peut être enrichi de tags spécifiques pour SPIP.
Fichier
ecrire/inc/rubriques.php
Fonction
propager_les_secteurs

    Nom ou pseudo de l'auteur de la proposition

Code original

/**
 * Recalcule les secteurs et les profondeurs des rubriques (et articles)
 *
 * Cherche les rubriques ayant des id_secteur ou profondeurs ne correspondant pas
 * avec leur parent, et les met à jour. De même avec les articles et leur id_secteur
 * On procede en iterant la profondeur de 1 en 1 pour ne pas risquer une boucle infinie sur reference circulaire
 *
 * @pipeline_appel trig_propager_les_secteurs
 *
 * @return void
 **/
function propager_les_secteurs() {
	// Profondeur 0
	// Toutes les rubriques racines sont de profondeur 0
	// et fixer les id_secteur des rubriques racines
	sql_update('spip_rubriques', array('id_secteur' => 'id_rubrique', 'profondeur' => 0), "id_parent=0");
	// Toute rubrique non racine est de profondeur >0
	sql_updateq('spip_rubriques', array('profondeur' => 1), "id_parent<>0 AND profondeur=0");
 
	// securite : pas plus d'iteration que de rubriques dans la base
	$maxiter = sql_countsel("spip_rubriques");
 
	// reparer les rubriques qui n'ont pas l'id_secteur de leur parent
	// on fait profondeur par profondeur
 
	$prof = 0;
	do {
		$continuer = false;
 
		// Par recursivite : si toutes les rubriques de profondeur $prof sont bonnes
		// on fixe le profondeur $prof+1
 
		// Toutes les rubriques dont le parent est de profondeur $prof ont une profondeur $prof+1
		// on teste A.profondeur > $prof+1 car :
		// - toutes les rubriques de profondeur 0 à $prof sont bonnes
		// - si A.profondeur = $prof+1 c'est bon
		// - cela nous protege de la boucle infinie en cas de reference circulaire dans les rubriques
		$maxiter2 = $maxiter;
		while ($maxiter2--
			and $rows = sql_allfetsel(
				"A.id_rubrique AS id, R.id_secteur AS id_secteur, R.profondeur+1 as profondeur",
				"spip_rubriques AS A JOIN spip_rubriques AS R ON A.id_parent = R.id_rubrique",
				"R.profondeur=" . intval($prof) . " AND (A.id_secteur <> R.id_secteur OR A.profondeur > R.profondeur+1)",
				"", "R.id_secteur", "0,100")) {
 
			$id_secteur = null;
			$ids = array();
			while ($row = array_shift($rows)) {
				if ($row['id_secteur'] !== $id_secteur) {
					if (count($ids)) {
						sql_updateq("spip_rubriques", array("id_secteur" => $id_secteur, 'profondeur' => $prof + 1),
							sql_in('id_rubrique', $ids));
					}
					$id_secteur = $row['id_secteur'];
					$ids = array();
				}
				$ids[] = $row['id'];
			}
			if (count($ids)) {
				sql_updateq("spip_rubriques", array("id_secteur" => $id_secteur, 'profondeur' => $prof + 1),
					sql_in('id_rubrique', $ids));
			}
		}
 
 
		// Toutes les rubriques de profondeur $prof+1 qui n'ont pas un parent de profondeur $prof sont decalees
		$maxiter2 = $maxiter;
		while ($maxiter2--
			and $rows = sql_allfetsel(
				"id_rubrique as id",
				"spip_rubriques",
				"profondeur=" . intval($prof + 1) . " AND id_parent NOT IN (" . sql_get_select("zzz.id_rubrique",
					"spip_rubriques AS zzz", "zzz.profondeur=" . intval($prof)) . ")", '', '', '0,100')) {
			$rows = array_map('reset', $rows);
			sql_updateq("spip_rubriques", array('profondeur' => $prof + 2), sql_in("id_rubrique", $rows));
		}
 
		// ici on a fini de valider $prof+1, toutes les rubriques de prondeur 0 a $prof+1 sont OK
		// si pas de rubrique a profondeur $prof+1 pas la peine de continuer
		// si il reste des rubriques non vues, c'est une branche morte ou reference circulaire (base foireuse)
		// on arrete les frais
		if (sql_countsel("spip_rubriques", "profondeur=" . intval($prof + 1))) {
			$prof++;
			$continuer = true;
		}
	} while ($continuer and $maxiter--);
 
	// loger si la table des rubriques semble foireuse
	// et mettre un id_secteur=0 sur ces rubriques pour eviter toute selection par les boucles
	if (sql_countsel("spip_rubriques", "profondeur>" . intval($prof + 1))) {
		spip_log("Les rubriques de profondeur>" . ($prof + 1) . " semblent suspectes (branches morte ou reference circulaire dans les parents)",
			_LOG_CRITIQUE);
		sql_update("spip_rubriques", array('id_secteur' => 0), "profondeur>" . intval($prof + 1));
	}
 
	// reparer les articles
	$r = sql_select("A.id_article AS id, R.id_secteur AS secteur", "spip_articles AS A, spip_rubriques AS R",
		"A.id_rubrique = R.id_rubrique AND A.id_secteur <> R.id_secteur");
 
	while ($row = sql_fetch($r)) {
		sql_update("spip_articles", array("id_secteur" => $row['secteur']), "id_article=" . intval($row['id']));
	}
 
	// avertir les plugins qui peuvent faire leur mises a jour egalement
	pipeline('trig_propager_les_secteurs', '');
}

Le commentaire au format « docblock » peut être complété des éléments suivants sécifiques
à SPIP.

Sur un entête de fichier :

  • @package SPIP\Core\x (pour un fichier du core, x dépendant du fichier)
  • @package SPIP\Nom\x (pour un fichier de plugin, Nom étant le nom du plugin)

Sur un entête de fonction :

  • @pipeline x : indique que la fonction est une utilisation d’un pipeline
  • @pipeline_appel x : indique que la fonction appelle le pipeline indiqué
  • @balise : indique que la fonction est une compilation de balise
  • @filtre : indique un |filtre
  • @critere : indique que la fonction est une compilaiton de critère
  • @boucle : indique que la fonction est une compilaiton de boucle
Vous inscrire sur ce site

L’espace privé de ce site est ouvert aux visiteurs, après inscription. Une fois enregistré, vous pourrez consulter les articles en cours de rédaction, proposer des articles et participer à tous les forums.

Identifiants personnels

Indiquez ici votre nom et votre adresse email. Votre identifiant personnel vous parviendra rapidement, par courrier électronique.