2fd43e070520dcdb3f93f778f8ef5596f81949aa
[ptitvelo/web/www.git] / www / plugins / spip-bonux-3 / public / spip_bonux_criteres.php
1 <?php
2 /**
3 * Plugin Spip-Bonux
4 * Le plugin qui lave plus SPIP que SPIP
5 * (c) 2008 Mathieu Marcillaud, Cedric Morin, Romy Tetue
6 * Licence GPL
7 *
8 */
9
10 if (!defined('_ECRIRE_INC_VERSION')) return;
11
12 /**
13 * http://www.spip-contrib.net/Classer-les-articles-par-nombre-de#forum409210
14 * Permet de faire un comptage par table liee
15 * exemple
16 * <BOUCLE1(AUTEURS){compteur articles}{par compteur_articles}>
17 * #ID_AUTEUR : #COMPTEUR{articles}
18 * </BOUCLE1>
19 * pour avoir les auteurs classes par articles et le nombre d'article de chacun
20 *
21 * @param unknown_type $idb
22 * @param unknown_type $boucles
23 * @param unknown_type $crit
24 */
25 function critere_compteur($idb, &$boucles, $crit, $left=false){
26 $boucle = &$boucles[$idb];
27
28 $_fusion = calculer_liste($crit->param[1], array(), $boucles, $boucle->id_parent);
29 $params = $crit->param;
30 $table = reset($params);
31 $table = $table[0]->texte;
32 $op = false;
33 if(preg_match(',^(\w+)([<>=])([0-9]+)$,',$table,$r)){
34 $table=$r[1];
35 if (count($r)>=3) $op=$r[2];
36 if (count($r)>=4) $op_val=$r[3];
37 }
38 $type = objet_type($table);
39 $type_id = id_table_objet($type);
40
41 /**
42 * Si la clé primaire est une clé multiple, on prend la première partie
43 * Utile pour compter les versions de spip_versions par exemple
44 */
45 if(count($types = explode(',',$type_id)) > 1)
46 $type_id = $types[0];
47 $table_sql = table_objet_sql($type);
48
49 $trouver_table = charger_fonction('trouver_table','base');
50 $arrivee = array($table, $trouver_table($table, $boucle->sql_serveur));
51 $depart = array($boucle->id_table,$trouver_table($boucle->id_table, $boucle->sql_serveur));
52
53 // noter les jointures deja installees
54 $joins = array_keys($boucle->from);
55 if ($compt = calculer_jointure($boucle,$depart,$arrivee)){
56 if ($_fusion!="''"){
57 // en cas de jointure, on ne veut pas du group_by sur la cle primaire !
58 // cela casse le compteur !
59 foreach($boucle->group as $k=>$group)
60 if ($group == $boucle->id_table.'.'.$boucle->primary)
61 unset($boucle->group[$k]);
62 $boucle->group[] = '".($gb='.$_fusion.')."';
63 }
64
65 $boucle->select[]= "COUNT($compt.$type_id) AS compteur_$table";
66 if ($op)
67 $boucle->having[]= array("'".$op."'", "'compteur_".$table."'",$op_val);
68 if ($left){
69 foreach($boucle->from as $k=>$val){
70 if (!in_array($k, $joins)){
71 $boucle->from_type[$k] = 'left';
72 }
73 }
74 }
75 }
76 }
77
78 /**
79 * {compteur_left xxx} permet de faire la meme chose que {compteur xxx}
80 * mais avec un LEFT JOIN pour ne pas ignorer ceux qui ont un compteur nul
81 * @param <type> $idb
82 * @param <type> $boucles
83 * @param <type> $crit
84 */
85 function critere_compteur_left($idb, &$boucles, $crit){
86 critere_compteur($idb, $boucles, $crit, true);
87 }
88
89 /** Critere {somme champ} #SOMME{champ} */
90 function critere_somme($idb, &$boucles, $crit){
91 calcul_critere_fonctions(array('SUM'=>'somme'), $idb, $boucles, $crit);
92 }
93
94 /** Critere {compte champ} #COMPTE{champ} */
95 function critere_compte($idb, &$boucles, $crit){
96 calcul_critere_fonctions(array('COUNT'=>'compte'), $idb, $boucles, $crit);
97 }
98
99 /** Critere {moyenne champ} #MOYENNE{champ} */
100 function critere_moyenne($idb, &$boucles, $crit){
101 calcul_critere_fonctions(array('AVG'=>'moyenne'), $idb, $boucles, $crit);
102 }
103
104 /** Critere {minimum champ} #MINIMUM{champ} */
105 function critere_minimum($idb, &$boucles, $crit){
106 calcul_critere_fonctions(array('MIN'=>'minimum'), $idb, $boucles, $crit);
107 }
108
109 /** Critere {maximum champ} #MAXIMUM{champ} */
110 function critere_maximum($idb, &$boucles, $crit){
111 calcul_critere_fonctions(array('MAX'=>'maximum'), $idb, $boucles, $crit);
112 }
113
114 /** Critere {stats champ} calcul la totale : somme, compte, minimum, moyenne, maximum */
115 function critere_stats($idb, &$boucles, $crit){
116 calcul_critere_fonctions(array(
117 'SUM'=>'somme',
118 'COUNT'=>'compte',
119 'AVG'=>'moyenne',
120 'MIN'=>'minimum',
121 'MAX'=>'maximum',
122 ), $idb, $boucles, $crit);
123 }
124
125 /* $func : array(FUNC => balise) */
126 function calcul_critere_fonctions($func, $idb, &$boucles, $crit) {
127 $boucle = &$boucles[$idb];
128
129 $params = $crit->param;
130 $champ = reset($params);
131 $champ = $champ[0]->texte;
132
133 // option DISTINCT {compte DISTINCT(id_article) }
134 $filter="";
135 if (preg_match('/^([a-zA-Z]+)\(\s*([a-zA-Z_]+)\s*\)$/', trim($champ), $r)) {
136 $filter = $r[1]; // DISTINCT
137 $champ = $r[2]; // id_article
138 }
139
140 $sel = $filter ? "$filter($champ)" : $champ;
141 foreach ($func as $f => $as) {
142 $boucle->select[]= "$f($sel) AS $as" . "_$champ";
143 }
144 }
145
146
147 ?>