source: spip-zone/_plugins_/groupes_mots_arborescents/gma_fonctions.php @ 91784

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

Pas de fermeture de PHP

File size: 7.9 KB
Line 
1<?php
2
3/**
4 * Plugin Groupes arborescents de mots clés
5 * (c) 2012 Marcillaud Matthieu
6 * Licence GNU/GPL
7 */
8
9if (!defined('_ECRIRE_INC_VERSION')) return;
10
11
12/**
13 * Gère des héritages sur les groupes et mots
14 *
15 * Sur les tables groupes
16 * - définir les groupes racines
17 * - définir les configs héritées (de la racine)
18 * Sur les mots
19 * - définir les groupes racines
20 *
21 * @example
22 *              gma_definir_heritages();  // recalcule tout
23 *              gma_definir_heritages(3); // recalcule le groupe 3 et ses enfants
24 *
25 * @param int $id_parent
26 *              Identifiant du groupe à modifier
27 *              C'est le seul paramètre éventuellement a passer
28 * @param null|array $heritage
29 *              Config a heriter aux enfants
30 * @param bool $update_mots
31 *              Met a jour les mots au passage (id_groupe_racine)
32 * @return void
33**/
34function gma_definir_heritages($id_groupe = null, $heritage=null, $update_mots=true) {
35        // liste des champs de config
36        static $champs_herites = null;
37        static $champs = array('id_groupe', 'id_parent', 'id_groupe_racine');
38
39        if (is_null($champs_herites)) {
40                // liste des champs qui doivent hériter du groupe racine automatiquement
41                $champs_herites = pipeline('groupes_mots_arborescents_heritages', array(
42                        'unseul', 'obligatoire', 'comite', 'forum', 'minirezo', 'tables_liees'
43                ));
44                // ajout des héritages à la liste des champs
45                $champs += $champs_herites;
46        }
47
48        // pas de groupe spécifique ?
49        if (is_null($id_groupe)) {
50                // on applique notre fonction à tous les groupes racines
51                $groupes = sql_allfetsel($champs, 'spip_groupes_mots', 'id_parent=' . sql_quote(0));
52                foreach ($groupes as $groupe) {
53                        $id_groupe = $groupe['id_groupe'];
54                        // le reste est la config a faire hériter
55                        unset($groupe['id_groupe'], $groupe['id_parent']);
56                        $groupe['id_groupe_racine'] = $id_groupe;
57                        gma_definir_heritages($id_groupe, $groupe);
58                }
59                return true;
60        }
61
62        // pas de vide par erreur
63        if (!$id_groupe) {
64                return false;
65        }
66
67        // pour le groupe en cours
68        // on retrouve la racine et la config s'ils ne sont pas connus,
69        // si possible dans le groupe parent (s'il existe)
70        if (is_null($heritage)) {
71                $heritage = sql_fetsel($champs, 'spip_groupes_mots', 'id_groupe=' . sql_quote($id_groupe));
72                if (!$heritage) {
73                        return false;
74                }
75                if ($heritage['id_parent']) {
76                        $heritage = sql_fetsel($champs, 'spip_groupes_mots', 'id_groupe=' . sql_quote($heritage['id_parent']));
77                }
78                // le reste est la config a faire hériter
79                unset($heritage['id_groupe'], $heritage['id_parent']);
80        }
81
82        // a ce stade, on a la racine et la config
83        // pour chaque groupe enfant, on les transmets
84        $groupes = calcul_branche_groupe_in($id_groupe);
85        sql_updateq('spip_groupes_mots', $heritage, sql_in('id_groupe', $groupes));
86
87        // pour chaque mots du groupe, on definit la racine
88        if ($update_mots) {
89                sql_updateq('spip_mots',
90                        array('id_groupe_racine' => $heritage['id_groupe_racine']),
91                        sql_in('id_groupe', $groupes));
92        }
93
94}
95
96
97
98
99/**
100 * Calcul d'une branche de groupes de mots
101 *
102 * Liste des id_groupes contenus dans un groupe de mots donné
103 * pour le critere {branche_groupe}
104 *
105 * @internal
106 *     Fonction quasiment identique a inc_calcul_branche_in_dist() du core
107 *
108 * @param string|int|array $id
109 *     Identifiant du groupe dont on veut récuperer toute la branche
110 * @return string
111 *     Liste des ids, séparés par des virgules
112 */
113function calcul_branche_groupe_in($id) {
114        static $b = array();
115
116        // normaliser $id qui a pu arriver comme un array, comme un entier, ou comme une chaine NN,NN,NN
117        if (!is_array($id)) $id = explode(',',$id);
118        $id = join(',', array_map('intval', $id));
119        if (isset($b[$id]))
120                return $b[$id];
121
122        // Notre branche commence par la rubrique de depart
123        $branche = $r = $id;
124
125        // On ajoute une generation (les filles de la generation precedente)
126        // jusqu'a epuisement
127        while ($filles = sql_allfetsel(
128                                        'id_groupe',
129                                        'spip_groupes_mots',
130                                        sql_in('id_parent', $r)." AND ". sql_in('id_groupe', $r, 'NOT')
131                                        )) {
132                $r = join(',', array_map('array_shift', $filles));
133                $branche .= ',' . $r;
134        }
135
136        # securite pour ne pas plomber la conso memoire sur les sites prolifiques
137        if (strlen($branche)<10000)
138                $b[$id] = $branche;
139        return $branche;
140}
141
142
143
144/**
145 * Sélectionne dans une boucle les éléments appartenant à une branche d'un groupe de mot
146 *
147 * Calcule une branche d'un groupe de mots et conditionne la boucle avec.
148 * Cherche l'identifiant du groupe en premier paramètre du critère {branche_groupe XX}
149 * sinon dans les boucles parentes ou par jointure.
150 *
151 * @internal
152 *              Copie quasi identique de critere_branche_dist()
153 *
154 * @param string $idb
155 *              Identifiant de la boucle
156 * @param array $boucles
157 *              AST du squelette
158 * @param Critere $crit
159 *              Paramètres du critère dans cette boucle
160 * @return
161 *              AST complété de la condition where au niveau de la boucle,
162 *              restreignant celle ci aux groupes de la branche
163**/
164function critere_branche_groupe_dist($idb, &$boucles, $crit){
165
166        $not = $crit->not;
167        $boucle = &$boucles[$idb];
168        // prendre en priorite un identifiant en parametre {branche_groupe XX}
169        if (isset($crit->param[0])) {
170                $arg = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
171        }
172        // sinon on le prend chez une boucle parente
173        else {
174                $arg = kwote(calculer_argument_precedent($idb, 'id_groupe', $boucles));
175        }
176       
177        //Trouver une jointure
178        $champ = "id_groupe";
179        $desc = $boucle->show;
180        //Seulement si necessaire
181        if (!array_key_exists($champ, $desc['field'])){
182                $cle = trouver_jointure_champ($champ, $boucle);
183                $trouver_table = charger_fonction("trouver_table", "base");
184                $desc = $trouver_table($boucle->from[$cle]);
185                if (count(trouver_champs_decomposes($champ, $desc))>1){
186                        $decompose = decompose_champ_id_objet($champ);
187                        $champ = array_shift($decompose);
188                        $boucle->where[] = array("'='", _q($cle.".".reset($decompose)), '"'.sql_quote(end($decompose)).'"');
189                }
190        }
191        else $cle = $boucle->id_table;
192
193        $c = "sql_in('$cle".".$champ', calcul_branche_groupe_in($arg)"
194             .($not ? ", 'NOT'" : '').")";
195        $boucle->where[] = !$crit->cond ? $c :
196                ("($arg ? $c : ".($not ? "'0=1'" : "'1=1'").')');
197}
198
199
200
201/**
202 * Boucle HIERARCHIE_GROUPES_MOTS
203**/
204function boucle_HIERARCHIE_GROUPES_MOTS_dist($id_boucle, &$boucles) {
205        return boucle_HIERARCHIE_PARENT_dist($id_boucle, $boucles, 'id_groupe', 'spip_groupes_mots');
206}
207
208
209
210if (!function_exists('boucle_HIERARCHIE_PARENT_dist')) {
211/**
212 * Boucle HIERARCHIE mais
213 * qui n'est pas dependante d'un id_rubrique
214 *
215**/
216function boucle_HIERARCHIE_PARENT_dist($id_boucle, &$boucles, $primary, $table) {
217        $boucle = &$boucles[$id_boucle];
218        $id_table = $boucle->id_table . "." . $primary;
219
220        // Si la boucle mere est une boucle de $TABLE il faut ignorer la feuille
221        // sauf en presence du critere {tout} (vu par phraser_html)
222        // ou {id_article} qui positionne aussi le {tout}
223
224        $boucle->hierarchie = 'if (!($id_objet = intval('
225        . calculer_argument_precedent($boucle->id_boucle, $primary, $boucles)
226        . ")))\n\t\treturn '';\n\t"
227        . '$hierarchie = '
228        . (isset($boucle->modificateur['tout']) ? '",$id_objet"' : "''")
229        . ";\n\t"
230        . 'while ($id_objet = sql_getfetsel("id_parent","' . $table . '","' . $primary . '=" . $id_objet,"","","", "", $connect)) {
231                $hierarchie = ",$id_objet$hierarchie";
232        }
233        if (!$hierarchie) return "";
234        $hierarchie = substr($hierarchie,1);';
235
236        // On enlève l'ancien critère "id_truc" du where
237        // provenant de <BOUCLE_h(HIERARCHIE_TRUC){id_truc} />
238        foreach ($boucle->where as $cle=>$where) {
239                if (count($where) == 3
240                        and ($where[0] == "'='" or $where[0] == '"="')
241                        and ($where[1] == "'$id_table'" or $where[1] == '"'.$id_table.'"')){
242                                unset($boucle->where[$cle]);
243                                $boucle->where = array_values($boucle->where); // recalculer les cles du tableau
244                }
245        }
246
247        $boucle->where[] = array("'IN'", "'$id_table'", '"($hierarchie)"');
248
249        $order = "FIELD($id_table, \$hierarchie)";
250
251        if (!isset($boucle->default_order[0]) OR $boucle->default_order[0] != " DESC")
252                $boucle->default_order[] = "\"$order\"";
253        else
254                $boucle->default_order[0] = "\"$order DESC\"";
255        return calculer_boucle($id_boucle, $boucles); 
256}
257}
Note: See TracBrowser for help on using the repository browser.