source: spip-zone/_plugins_/polyhierarchie/branches/v2.0/polyhier_fonctions.php @ 96181

Last change on this file since 96181 was 96181, checked in by cedric@…, 5 years ago

Ameliorer le critere branche quand on l'utilise sur une boucle EVENEMENTS dont l'article est en polyhierarchie :

  • si on a besoin d'une jointure pour id_rubrique, verifier qu'on en a pas une sous la main qui fait l'affaire
  • si on utilise une jointure pour id_rubrique, alors c'est le type/id de l'objet joint qu'il faut checher dans spip_rubriques_liens (ie l'article et pas l'evenement)
File size: 8.4 KB
Line 
1<?php
2/*
3 * Plugin Polyhierarchie
4 * (c) 2009-2010 Cedric Morin
5 * Distribue sous licence GPL
6 *
7 */
8
9if (!defined("_ECRIRE_INC_VERSION")) return;
10
11/**
12 * {enfants} ou {enfants #ID_RUBRIQUE}
13 * renvoit tous les enfants d'une rubrique ou article
14 * directs (liens descendants) ou indirects (liens transverses)
15 *
16 * @global <type> $exceptions_des_tables
17 * @param <type> $idb
18 * @param <type> $boucles
19 * @param <type> $crit
20 * @param <type> $tous
21 */
22function critere_enfants($idb, &$boucles, $crit, $tous=true) {
23        global $exceptions_des_tables;
24        $boucle = &$boucles[$idb];
25
26        if (isset($crit->param[0])){
27                $arg = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
28        }
29        else
30                $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles));
31
32        if ($boucle->type_requete == 'rubriques' OR isset($exceptions_des_tables[$boucle->id_table]['id_parent'])) {
33                $id_parent = isset($exceptions_des_tables[$boucle->id_table]['id_parent']) ?
34                        $exceptions_des_tables[$boucle->id_table]['id_parent'] :
35                        'id_parent';
36                $mparent = $boucle->id_table . '.' . $id_parent;
37        }
38        else {
39                $mparent = $boucle->id_table . '.id_rubrique';
40        }
41
42        $where = array();
43
44        if ($tous!=='indirects')
45                $where[] = "is_array(\$r=$arg)?sql_in('$mparent',\$r):array('=', '$mparent', \$r)";
46
47        if ($tous!=='directs'
48          AND in_array(table_objet_sql($boucle->type_requete),array_keys(lister_tables_objets_sql()))){
49                $type = objet_type($boucle->type_requete);
50                $cond = "is_array(\$r=$arg)?sql_in('rl.id_parent',\$r):'rl.id_parent='.\$r";
51                $sous = "sql_get_select('rl.id_objet','spip_rubriques_liens as rl',$cond.' AND rl.objet=\'$type\'')";
52                $where[] = "array('IN', '".$boucle->id_table.".".$boucle->primary."', '(SELECT * FROM('.$sous.') AS subquery)')";
53        }
54        if (count($where)==2)
55                $where = array("'OR'",$where[0],$where[1]);
56        else
57                $where = reset($where);
58
59        $boucle->where[]= $where;
60}
61
62function critere_enfants_directs_dist($idb, &$boucles, $crit) {
63        critere_enfants($idb, $boucles, $crit, 'directs');
64}
65
66function critere_enfants_indirects_dist($idb, &$boucles, $crit) {
67        critere_enfants($idb, $boucles, $crit, 'indirects');
68}
69
70/**
71 * {parents}
72 * renvoit tous les parents d'une rubrique ou article
73 * {parents #ID_RUBRIQUE}
74 * renvoit tous les parents d'une rubrique
75 * directs (liens ascendants) ou indirects (liens transverses)
76 *
77 * @global <type> $exceptions_des_tables
78 * @param <type> $idb
79 * @param <type> $boucles
80 * @param <type> $crit
81 * @param <type> $tous
82 */
83function critere_parents($idb, &$boucles, $crit, $tous=true) {
84        global $exceptions_des_tables;
85        $boucle = &$boucles[$idb];
86        $boucle_parent = $boucles[$boucle->id_parent];
87
88        $primary = $boucle->id_table.".".$boucle->primary;
89
90        $where = array();
91
92        if ($tous!=='indirects'){
93                $argp = kwote(calculer_argument_precedent($idb, $boucle_parent->type_requete == 'rubriques' ? 'id_parent' : 'id_rubrique', $boucles));
94                $where[] = "is_array(\$r=$argp)?sql_in('$primary',\$r):array('=', '$primary', \$r)";
95        }
96
97        if ($tous!=='directs'
98          AND in_array(table_objet_sql($boucle_parent->type_requete),array_keys(lister_tables_objets_sql()))){
99                $arg = kwote(calculer_argument_precedent($idb, id_table_objet(objet_type($boucle_parent->type_requete)), $boucles));
100                $type = objet_type($boucle_parent->type_requete);
101                $sous = "sql_get_select('rl.id_parent','spip_rubriques_liens as rl','rl.id_objet='.$arg.' AND rl.objet=\'$type\'')";
102                $where[] = array("'IN'", "'$primary'", "'(SELECT * FROM('.$sous.') AS subquery)'");
103        }
104        if (count($where)==2)
105                $where = array("'OR'",$where[0],$where[1]);
106        else
107                $where = reset($where);
108
109        $boucle->where[]= $where;
110}
111
112function critere_parents_directs_dist($idb, &$boucles, $crit) {
113        critere_parents($idb, $boucles, $crit, 'directs');
114}
115function critere_parent($idb, &$boucles, $crit) {
116        critere_parents($idb, $boucles, $crit, 'directs');
117}
118
119function critere_parents_indirects_dist($idb, &$boucles, $crit) {
120        critere_parents($idb, $boucles, $crit, 'indirects');
121}
122
123
124/**
125 * Calcul d'une branche
126 * (liste des id_rubrique contenues dans une rubrique donnee)
127 * pour le critere {branche}
128 *
129 * @param <type> $id
130 * @return <type>
131 */
132function calcul_branche_polyhier_in($id, $tous=true) {
133
134        // normaliser $id qui a pu arriver comme un array, comme un entier, ou comme une chaine NN,NN,NN
135        if (!is_array($id)) $id = explode(',',$id);
136        $id = array_map('intval', $id);
137
138        // Notre branche commence par la rubrique de depart
139        $branche = $id;
140
141        // On ajoute une generation (les filles de la generation precedente)
142        // jusqu'a epuisement
143        while (
144                $id = array_merge(
145                $filles_directes = ($tous!=='indirects'?array_map('reset',sql_allfetsel('id_rubrique', 'spip_rubriques',sql_in('id_parent', $id))):array()),
146                $filles_indirectes = ($tous!=='directs'?array_map('reset',sql_allfetsel('id_objet', 'spip_rubriques_liens',"objet='rubrique' AND " . sql_in('id_parent', $id))):array())
147                )) {
148
149                // enlever les rubriques deja trouvee, sinon on risque de tourner en rond a l'infini en cas
150                // de polyhierarchie bouclee
151                $id = array_diff($id,$branche);
152                $branche = array_merge($branche,$id);
153        }
154
155        return implode(',',$branche);
156}
157
158
159
160/**
161 * {branche ?} ou {branche #ID_RUBRIQUE}
162 * {branche_directe ?} ou {branche_directe #ID_RUBRIQUE}
163 * {branche_principale ?} ou {branche_principale #ID_RUBRIQUE}
164 * {branche_complete ?} ou {branche_complete #ID_RUBRIQUE}
165 *
166 *
167 * @param <type> $idb
168 * @param <type> $boucles
169 * @param <type> $crit
170 */
171function critere_branche($idb, &$boucles, $crit, $tous='elargie') {
172
173        $not = $crit->not;
174        $boucle = &$boucles[$idb];
175        if (isset($crit->param[0])){
176                $arg = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
177        }
178        else
179                $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles));
180
181        $type = objet_type($boucle->type_requete);
182        $primary = $boucle->id_table.".".$boucle->primary;
183
184        //Trouver une jointure
185        $champ = "id_rubrique";
186        $desc = $boucle->show;
187        //Seulement si necessaire
188        if (!array_key_exists($champ, $desc['field'])){
189                $trouver_table = charger_fonction("trouver_table", "base");
190                $cle = "";
191                // peut-etre deja une jointure qui fournit id_rubrique ?
192                foreach($boucle->from as $k=>$t){
193                        $desc = $trouver_table($t);
194                        if (isset($desc['field']['id_rubrique'])){
195                                $cle = $k;
196                                break;
197                        }
198                }
199                if (!$cle){
200                        $cle = trouver_jointure_champ($champ, $boucle);
201                        $desc = $trouver_table($boucle->from[$cle]);
202                        if (count(trouver_champs_decomposes($champ, $desc))>1){
203                                $decompose = decompose_champ_id_objet($champ);
204                                $champ = array_shift($decompose);
205                                $boucle->where[] = array("'='", _q($cle.".".reset($decompose)), '"'.sql_quote(end($decompose)).'"');
206                        }
207                }
208                // si le champ id_rubrique est recuperer par jointure, c'est le type et la primary de la table jointe
209                // qu'il faut chercher dans la table spip_rubriques_liens (ie cas des evenements)
210                if ($cle AND $desc) {
211                        $type = objet_type($boucle->from[$cle]);
212                        $primary = $cle . "." . id_table_objet($boucle->from[$cle]);
213                }
214        }
215        else $cle = $boucle->id_table;
216
217
218        $c = "sql_in('$cle" . ".$champ', \$b = calcul_branche_polyhier_in($arg,".($tous===true?'true':"'directs'").")"
219          . ($not ? ", 'NOT'" : '') . ")";
220        $where[] = $c;
221       
222        if ($tous!=='directs'
223          AND in_array(table_objet_sql($boucle->type_requete),array_keys(lister_tables_objets_sql()))){
224                $sous = "sql_get_select('rl.id_objet','spip_rubriques_liens as rl',sql_in('rl.id_parent',\$b" . ($not ? ", 'NOT'" : '') . ").' AND rl.objet=\'$type\'')";
225                $where[] = "array('IN', '$primary', '(SELECT * FROM('.$sous.') AS subquery)')";
226        }
227
228        if (count($where)==2)
229                $where = "array('OR',".$where[0].",".$where[1].")";
230        else
231                $where = reset($where);
232
233        $boucle->where[]= !$crit->cond ? $where :
234          ("($arg ? $where : " . ($not ? "'0=1'" : "'1=1'") .')');
235}
236
237function critere_branche_principale_dist($idb, &$boucles, $crit) {
238        critere_branche($idb, $boucles, $crit, 'directs');
239}
240// un alias
241function critere_branche_directe_dist($idb, &$boucles, $crit) {
242        critere_branche($idb, $boucles, $crit, 'directs');
243}
244
245function critere_branche_complete_dist($idb, &$boucles, $crit) {
246        critere_branche($idb, $boucles, $crit, true);
247}
248
249/*
250 * Déclarer un fonction générique pour pouvoir chercher dans les champs des rubriques liées
251 *
252 */
253function inc_rechercher_joints_objet_rubrique_dist($table, $table_liee, $ids_trouves, $serveur){
254        $cle_depart = id_table_objet($table);
255        $s = sql_select(
256                "id_objet as $cle_depart, id_parent as id_rubrique",
257                'spip_rubriques_liens',
258                array("objet='$table'", sql_in('id_parent', $ids_trouves)),
259                '','','','',$serveur
260        );
261        return array($cle_depart, 'id_rubrique', $s);
262}
263
264?>
Note: See TracBrowser for help on using the repository browser.