source: spip-zone/_plugins_/polyhierarchie/trunk/polyhier_fonctions.php @ 96156

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

dans une rubrique, la boite polyhiearchie liste tous les types d'objet lies, du moment qu'ils ont un squelette liste

File size: 9.1 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
33        if ($boucle->type_requete == 'rubriques' or isset($exceptions_des_tables[$boucle->id_table]['id_parent'])) {
34                $id_parent = isset($exceptions_des_tables[$boucle->id_table]['id_parent']) ?
35                        $exceptions_des_tables[$boucle->id_table]['id_parent'] :
36                        'id_parent';
37                $mparent = $boucle->id_table . '.' . $id_parent;
38        }
39        else {
40                $mparent = $boucle->id_table . '.id_rubrique';
41        }
42
43        $where = array();
44
45        if ($tous!=='indirects') {
46                $where[] = "is_array(\$r=$arg)?sql_in('$mparent',\$r):array('=', '$mparent', \$r)";
47        }
48
49        if ($tous !== 'directs'
50          AND in_array(table_objet_sql($boucle->type_requete),array_keys(lister_tables_objets_sql()))){
51                $type = objet_type($boucle->type_requete);
52                $cond = "is_array(\$r=$arg)?sql_in('rl.id_parent',\$r):'rl.id_parent='.\$r";
53                $sous = "sql_get_select('rl.id_objet','spip_rubriques_liens as rl',$cond.' AND rl.objet=\'$type\'')";
54                $where[] = "array('IN', '" . $boucle->id_table . "." . $boucle->primary . "', '(SELECT * FROM('.$sous.') AS subquery)')";
55        }
56       
57        if (count($where) == 2) {
58                $where = array("'OR'", $where[0], $where[1]);
59        }
60        else {
61                $where = reset($where);
62        }
63
64        $boucle->where[]= $where;
65}
66
67function critere_enfants_directs_dist($idb, &$boucles, $crit) {
68        critere_enfants($idb, $boucles, $crit, 'directs');
69}
70
71function critere_enfants_indirects_dist($idb, &$boucles, $crit) {
72        critere_enfants($idb, $boucles, $crit, 'indirects');
73}
74
75/**
76 * {parents}
77 * renvoit tous les parents d'une rubrique ou article
78 * {parents #ID_RUBRIQUE}
79 * renvoit tous les parents d'une rubrique
80 * directs (liens ascendants) ou indirects (liens transverses)
81 *
82 * @global <type> $exceptions_des_tables
83 * @param <type> $idb
84 * @param <type> $boucles
85 * @param <type> $crit
86 * @param <type> $tous
87 */
88function critere_parents($idb, &$boucles, $crit, $tous=true) {
89        global $exceptions_des_tables;
90       
91        $boucle = &$boucles[$idb];
92        $boucle_parent = $boucles[$boucle->id_parent];
93
94        $primary = $boucle->id_table.".".$boucle->primary;
95
96        $where = array();
97
98        if ($tous !== 'indirects') {
99                $argp = kwote(calculer_argument_precedent($idb, $boucle_parent->type_requete == 'rubriques' ? 'id_parent' : 'id_rubrique', $boucles));
100                $where[] = "is_array(\$r=$argp)?sql_in('$primary',\$r):array('=', '$primary', \$r)";
101        }
102
103        if ($tous !== 'directs'
104          AND in_array(table_objet_sql($boucle_parent->type_requete),array_keys(lister_tables_objets_sql()))){
105                $arg = kwote(calculer_argument_precedent($idb, id_table_objet(objet_type($boucle_parent->type_requete)), $boucles));
106                $type = objet_type($boucle_parent->type_requete);
107                $sous = "sql_get_select('rl.id_parent','spip_rubriques_liens as rl','rl.id_objet='.$arg.' AND rl.objet=\'$type\'')";
108                $where[] = array("'IN'", "'$primary'", "'(SELECT * FROM('.$sous.') AS subquery)'");
109        }
110       
111        if (count($where) == 2) {
112                $where = array("'OR'", $where[0], $where[1]);
113        }
114        else {
115                $where = reset($where);
116        }
117
118        $boucle->where[] = $where;
119}
120
121function critere_parents_directs_dist($idb, &$boucles, $crit) {
122        critere_parents($idb, $boucles, $crit, 'directs');
123}
124function critere_parent($idb, &$boucles, $crit) {
125        critere_parents($idb, $boucles, $crit, 'directs');
126}
127function critere_parents_indirects_dist($idb, &$boucles, $crit) {
128        critere_parents($idb, $boucles, $crit, 'indirects');
129}
130
131
132/**
133 * Calcul d'une branche
134 * (liste des id_rubrique contenues dans une rubrique donnee)
135 * pour le critere {branche}
136 *
137 * @param <type> $id
138 * @return <type>
139 */
140function calcul_branche_polyhier_in($id, $tous=true) {
141        // normaliser $id qui a pu arriver comme un array, comme un entier, ou comme une chaine NN,NN,NN
142        if (!is_array($id)) {
143                $id = explode(',', $id);
144        }
145        $id = array_map('intval', $id);
146       
147        // Notre branche commence par la rubrique de depart
148        $branche = $id;
149       
150        // On ajoute une generation (les filles de la generation precedente)
151        // jusqu'a epuisement
152        while (
153                $id = array_merge(
154                        $filles_directes = ($tous!=='indirects' ? array_map('reset', sql_allfetsel('id_rubrique', 'spip_rubriques', sql_in('id_parent', $id))) : array()),
155                        $filles_indirectes = ($tous!=='directs' ? array_map('reset', sql_allfetsel('id_objet', 'spip_rubriques_liens', "objet='rubrique' AND " . sql_in('id_parent', $id))) : array())
156                )
157        ) {
158                // enlever les rubriques deja trouvee, sinon on risque de tourner en rond a l'infini en cas
159                // de polyhierarchie bouclee
160                $id = array_diff($id, $branche);
161                $branche = array_merge($branche, $id);
162        }
163       
164        return implode(',', $branche);
165}
166
167
168
169/**
170 * {branche ?} ou {branche #ID_RUBRIQUE}
171 * {branche_directe ?} ou {branche_directe #ID_RUBRIQUE}
172 * {branche_principale ?} ou {branche_principale #ID_RUBRIQUE}
173 * {branche_complete ?} ou {branche_complete #ID_RUBRIQUE}
174 *
175 *
176 * @param <type> $idb
177 * @param <type> $boucles
178 * @param <type> $crit
179 */
180function critere_branche($idb, &$boucles, $crit, $tous='elargie') {
181        $not = $crit->not;
182        $boucle = &$boucles[$idb];
183       
184        // On cherche la ou les rubriques dont on demande la branche
185        if (isset($crit->param[0])) {
186                $arg = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
187        }
188        else {
189                $arg = kwote(calculer_argument_precedent($idb, 'id_rubrique', $boucles));
190        }
191       
192        //Trouver une jointure
193        $champ = "id_rubrique";
194        $desc = $boucle->show;
195        //Seulement si necessaire
196        if (!array_key_exists($champ, $desc['field'])){
197                $cle = trouver_jointure_champ($champ, $boucle);
198                $trouver_table = charger_fonction("trouver_table", "base");
199                $desc = $trouver_table($boucle->from[$cle]);
200                if (count(trouver_champs_decomposes($champ, $desc))>1){
201                        $decompose = decompose_champ_id_objet($champ);
202                        $champ = array_shift($decompose);
203                        $boucle->where[] = array("'='", _q($cle.".".reset($decompose)), '"'.sql_quote(end($decompose)).'"');
204                }
205        }
206        else {
207                $cle = $boucle->id_table;
208        }
209
210        $where = array();
211
212        // On construit en avance la liste des rubriques
213        $boucle->hash .= "
214        // {branche}
215        if ($arg) {
216                \$in_rub = calcul_branche_polyhier_in($arg," . ($tous === true ? 'true' : "'directs'") . ");
217        }
218        ";
219       
220        // Si c'est tout ou que directs ET qu'on a trouvé un "id_rubrique" quelque part
221        // on ajoute le critère de branche principale, avec le champ id_rubrique
222        if ($tous !== 'indirects' and $cle) {
223                $where[] = "sql_in(
224                        '{$cle}.{$champ}',
225                        \$in_rub"
226                        . ($not ? ", 'NOT'" : '')
227                . ")";
228        }
229       
230        // Si c'est tout ou que indirects, on ajoute le critère de branche secondaire, avec la table de liens
231        if ($tous !== 'directs') {
232                $type = objet_type($boucle->type_requete);
233                $primary = $boucle->id_table.".".$boucle->primary;
234               
235                $sous = "sql_get_select('rl.id_objet','spip_rubriques_liens as rl',sql_in('rl.id_parent',\$in_rub" . ($not ? ", 'NOT'" : '') . ").' AND rl.objet=\'$type\'')";
236                $where[] = "array('IN', '$primary', '(SELECT * FROM('.$sous.') AS subquery)')";
237        }
238       
239        // S'il y a les deux critères, c'est l'un ou l'autre
240        if (count($where) == 2) {
241                $where = "array('OR'," . $where[0] . "," . $where[1] . ")";
242        }
243        else {
244                $where = reset($where);
245        }
246       
247        $boucle->where[] = !$crit->cond ? $where : ("($arg ? $where : " . ($not ? "'0=1'" : "'1=1'") . ')');
248}
249
250function critere_branche_principale_dist($idb, &$boucles, $crit) {
251        critere_branche($idb, $boucles, $crit, 'directs');
252}
253// un alias
254function critere_branche_directe_dist($idb, &$boucles, $crit) {
255        critere_branche($idb, $boucles, $crit, 'directs');
256}
257function critere_branche_indirecte_dist($idb, &$boucles, $crit) {
258        critere_branche($idb, $boucles, $crit, 'indirects');
259}
260function critere_branche_complete_dist($idb, &$boucles, $crit) {
261        critere_branche($idb, $boucles, $crit, true);
262}
263
264/*
265 * Déclarer un fonction générique pour pouvoir chercher dans les champs des rubriques liées
266 *
267 */
268function inc_rechercher_joints_objet_rubrique_dist($table, $table_liee, $ids_trouves, $serveur) {
269        $cle_depart = id_table_objet($table);
270       
271        $s = sql_select(
272                "id_objet as $cle_depart, id_parent as id_rubrique",
273                'spip_rubriques_liens',
274                array("objet='$table'", sql_in('id_parent', $ids_trouves)),
275                '', '', '', '', $serveur
276        );
277       
278        return array($cle_depart, 'id_rubrique', $s);
279}
280
281
282/**
283 * Filtre pour appeler polyhier_get_enfants depuis un squelette
284 * @param $id_parent
285 * @param string $objet
286 * @param string $serveur
287 * @return array
288 */
289function filtre_polyhier_get_enfants_dist($id_parent, $objet='', $serveur='') {
290        include_spip('inc/polyhier');
291        return polyhier_get_enfants($id_parent, $objet, $serveur);
292}
293
294function filtre_polyhier_lister_enfants($objet,$ids){
295        $fond = "prive/objets/liste/".table_objet($objet);
296        if (trouver_fond($fond)){
297                $primary = id_table_objet($objet);
298                return recuperer_fond($fond,array($primary=>$ids));
299        }
300}
Note: See TracBrowser for help on using the repository browser.