source: spip-zone/_plugins_/roles/trunk/formulaires/editer_liens.php @ 64116

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

Quelques améliorations de l'interface suite aux retours de différentes personnes (realEt, franck...)

  • Dans la partie associer, on ajoute un title et une icone pour mieux comprendre que l'on peut sélectionner plusieurs rôles

+ Corrections graphiques :

  • couleurs de chosen moins flashy,
  • largeur homogène (là c'est moins simple car chosen calcule une taille par défaut basée sur la taille du sélect d'origine, mais sa taille change au fur et à mesure des ajouts d'élément dans les cellules du tableau par choosen. C'est cela qui faisait que la taille augmentait peu à peu. On recalcule donc la taille à la fin de tous les chosen !

+ Garder la sélection des roles dans la liste d'association, lorsqu'on ajoute un auteur.

File size: 11.4 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2012                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
9 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11\***************************************************************************/
12
13/**
14 * Gestion du formulaire d'édition de liens
15 *
16 * @package SPIP\Formulaires
17**/
18if (!defined('_ECRIRE_INC_VERSION')) return;
19
20
21/**
22 * Retrouve la source et l'objet de la liaison
23 *
24 * À partir des 3 premiers paramètres transmis au formulaire,
25 * la fonction retrouve :
26 * - l'objet dont on utilise sa table de liaison (table_source)
27 * - l'objet et id_objet sur qui on lie des éléments (objet, id_objet)
28 * - l'objet que l'on veut lier dessus (objet_lien)
29 *
30 * @param string $a
31 * @param string|int $b
32 * @param int|string $c
33 * @return array
34 *   ($table_source,$objet,$id_objet,$objet_lien)
35 */
36function determine_source_lien_objet($a,$b,$c){
37        $table_source = $objet_lien = $objet = $id_objet = null;
38        // auteurs, article, 23 :
39        // associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens
40        if (is_numeric($c) AND !is_numeric($b)){
41                $table_source = table_objet($a);
42                $objet_lien = objet_type($a);
43                $objet = objet_type($b);
44                $id_objet = $c;
45        }
46        // article, 23, auteurs
47        // associer des auteurs à l'article 23, sur la table pivot spip_articles_liens
48        if (is_numeric($b) AND !is_numeric($c)){
49                $table_source = table_objet($c);
50                $objet_lien = objet_type($a);
51                $objet = objet_type($a);
52                $id_objet = $b;
53        }
54
55        return array($table_source,$objet,$id_objet,$objet_lien);
56}
57
58/**
59 * Chargement du formulaire d'édition de liens
60 *
61 * #FORMULAIRE_EDITER_LIENS{auteurs,article,23}
62 *   pour associer des auteurs à l'article 23, sur la table pivot spip_auteurs_liens
63 * #FORMULAIRE_EDITER_LIENS{article,23,auteurs}
64 *   pour associer des auteurs à l'article 23, sur la table pivot spip_articles_liens
65 * #FORMULAIRE_EDITER_LIENS{articles,auteur,12}
66 *   pour associer des articles à l'auteur 12, sur la table pivot spip_articles_liens
67 * #FORMULAIRE_EDITER_LIENS{auteur,12,articles}
68 *   pour associer des articles à l'auteur 12, sur la table pivot spip_auteurs_liens
69 *
70 * @param string $a
71 * @param string|int $b
72 * @param int|string $c
73 * @param bool $editable
74 * @return array
75 */
76function formulaires_editer_liens_charger_dist($a,$b,$c,$editable=true){
77
78        list($table_source,$objet,$id_objet,$objet_lien) = determine_source_lien_objet($a,$b,$c);
79        if (!$table_source OR !$objet OR !$objet_lien OR !$id_objet)
80                return false;
81
82        $objet_source = objet_type($table_source);
83        $table_sql_source = table_objet_sql($objet_source);
84
85        // verifier existence de la table xxx_liens
86        include_spip('action/editer_liens');
87        if (!objet_associable($objet_lien))
88                return false;
89       
90        // L'éditabilité :) est définie par un test permanent (par exemple "associermots") ET le 4ème argument
91        $editable = ($editable and autoriser('associer'.$table_source, $objet, $id_objet));
92       
93        if (!$editable AND !count(objet_trouver_liens(array($objet_lien=>'*'),array(($objet_lien==$objet_source?$objet:$objet_source)=>'*'))))
94                return false;
95
96        // squelettes de vue et de d'association
97        // ils sont différents si des rôles sont définis.
98        $skel_vue   = $table_source."_lies";
99        $skel_ajout = $table_source."_associer";
100
101        // description des roles
102        include_spip('inc/roles');
103        if ($roles = roles_presents($objet_source, $objet)) {
104                // on demande de nouveaux squelettes en conséquence
105                $skel_vue   = $table_source."_roles_lies";
106                $skel_ajout = $table_source."_roles_associer";
107        }
108
109        $valeurs = array(
110                'id'=>"$table_source-$objet-$id_objet-$objet_lien", // identifiant unique pour les id du form
111                '_vue_liee' => $skel_vue,
112                '_vue_ajout' => $skel_ajout,
113                '_objet_lien' => $objet_lien,
114                'id_lien_ajoute'=>_request('id_lien_ajoute'),
115                'objet'=>$objet,
116                'id_objet'=>$id_objet,
117                'objet_source'=>$objet_source,
118                'table_source' => $table_source,
119                'recherche'=>'',
120                'roles' => $roles, # description des roles
121                'visible'=>0,
122                'ajouter_lien'=>'',
123                'supprimer_lien'=>'',
124                'definir_roles'=>'',
125                '_oups' => _request('_oups'),
126                'editable' => $editable,
127        );
128
129        return $valeurs;
130}
131
132/**
133 * Traiter le post des informations d'édition de liens
134 *
135 * Les formulaires peuvent poster dans quatre variables
136 * - ajouter_lien et supprimer_lien
137 * - remplacer_lien
138 * - definir_roles
139 *
140 * Les deux premières peuvent être de trois formes différentes :
141 * ajouter_lien[]="objet1-id1-objet2-id2"
142 * ajouter_lien[objet1-id1-objet2-id2]="nimportequoi"
143 * ajouter_lien['clenonnumerique']="objet1-id1-objet2-id2"
144 * Dans ce dernier cas, la valeur ne sera prise en compte
145 * que si _request('clenonnumerique') est vrai (submit associé a l'input)
146 *
147 * remplacer_lien doit être de la forme
148 * remplacer_lien[objet1-id1-objet2-id2]="objet3-id3-objet2-id2"
149 * ou objet1-id1 est celui qu'on enleve et objet3-id3 celui qu'on ajoute
150 *
151 * definir_roles doit être de la forme, et sert en complément de ajouter_lien
152 * definir_roles[objet1-id1-objet2-id2] = array("role", "autre_role")
153 *
154 * @param string $a
155 * @param string|int $b
156 * @param int|string $c
157 * @param bool $editable
158 * @return array
159 */
160function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
161        $res = array('editable'=>$editable?true:false);
162        list($table_source,$objet,$id_objet,$objet_lien) = determine_source_lien_objet($a,$b,$c);
163        if (!$table_source OR !$objet OR !$objet_lien)
164                return $res;
165
166
167        if (_request('tout_voir'))
168                set_request('recherche','');
169
170
171        if (autoriser('modifier',$objet,$id_objet)) {
172                // annuler les suppressions du coup d'avant !
173                if (_request('annuler_oups')
174                        AND $oups = _request('_oups')
175                        AND $oups = unserialize($oups)){
176                        $objet_source = objet_type($table_source);
177                        include_spip('action/editer_liens');
178                        foreach($oups as $oup) {
179                                if ($objet_lien==$objet_source)
180                                        objet_associer(array($objet_source=>$oup[$objet_source]), array($objet=>$oup[$objet]),$oup);
181                                else
182                                        objet_associer(array($objet=>$oup[$objet]), array($objet_source=>$oup[$objet_source]),$oup);
183                        }
184                        # oups ne persiste que pour la derniere action, si suppression
185                        set_request('_oups');
186                }
187
188                $supprimer = _request('supprimer_lien');
189                $ajouter = _request('ajouter_lien');
190
191                // il est possible de preciser dans une seule variable un remplacement :
192                // remplacer_lien[old][new]
193                if ($remplacer = _request('remplacer_lien')){
194                        foreach($remplacer as $k=>$v){
195                                if ($old = lien_verifier_action($k,'')){
196                                        foreach(is_array($v)?$v:array($v) as $kn=>$vn)
197                                                if ($new = lien_verifier_action($kn,$vn)){
198                                                        $supprimer[$old] = 'x';
199                                                        $ajouter[$new] = '+';
200                                                }
201                                }
202                        }
203                }
204
205                if ($supprimer){
206                        include_spip('action/editer_liens');
207                        $oups = array();
208                        foreach($supprimer as $k=>$v) {
209                                if ($lien = lien_verifier_action($k,$v)){
210                                        $lien = explode("-", $lien);
211                                        list($objet_source,$ids,$objet_lie,$idl,$role) = $lien;
212                                        // appliquer une condition sur le rôle si défini ('*' pour tous les roles)
213                                        $cond = $role ? array('role' => $role) : array();
214                                        if ($objet_lien==$objet_source){
215                                                $oups = array_merge($oups,  objet_trouver_liens(array($objet_source=>$ids), array($objet_lie=>$idl), $cond));
216                                                objet_dissocier(array($objet_source=>$ids), array($objet_lie=>$idl), $cond);
217                                        }
218                                        else{
219                                                $oups = array_merge($oups,  objet_trouver_liens(array($objet_lie=>$idl), array($objet_source=>$ids), $cond));
220                                                objet_dissocier(array($objet_lie=>$idl), array($objet_source=>$ids), $cond);
221                                        }
222                                }
223                        }
224                        set_request('_oups',$oups?serialize($oups):null);
225                }
226               
227                if ($ajouter){
228                        $ajout_ok = false;
229                        include_spip('action/editer_liens');
230                        foreach($ajouter as $k=>$v){
231                                if ($lien = lien_verifier_action($k,$v)) {
232                                        $ajout_ok = true;
233                                        list($objet1,$ids,$objet2,$idl) = explode("-",$lien);
234                                        $roles = lien_retrouver_roles_postes($lien);
235                                        if ($objet_lien==$objet1) {
236                                                lien_ajouter_liaison($objet1, $ids, $objet2, $idl, $roles);
237                                        } else {
238                                                lien_ajouter_liaison($objet2, $idl, $objet1, $ids, $roles);
239                                        }
240                                        set_request('id_lien_ajoute',$ids);
241                                }
242                        }
243                        # oups ne persiste que pour la derniere action, si suppression
244                        # une suppression suivie d'un ajout dans le meme hit est un remplacement
245                        # non annulable !
246                        if ($ajout_ok)
247                                set_request('_oups');
248                }
249        }
250
251       
252        return $res;
253}
254
255/**
256 * Retrouver l'action de liaision demandée
257 *
258 * Les formulaires envoient une action dans un tableau ajouter_lien
259 * ou supprimer_lien
260 *
261 * L'action est de la forme : objet1-id1-objet2-id2
262 * ou de la forme : objet1-id1-objet2-id2-role
263 *
264 * L'action peut-être indiquée dans la clé ou dans la valeur.
265 * Si elle est indiquee dans la valeur et que la clé est non numérique,
266 * on ne la prend en compte que si un submit avec la clé a été envoyé
267 *
268 * @internal
269 * @param string $k Clé du tableau
270 * @param string $v Valeur du tableau
271 * @return string Action demandée si trouvée, sinon ''
272 */
273function lien_verifier_action($k,$v) {
274        $action = '';
275        if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+(-[\w*])?,",$k))
276                $action = $k;
277        if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+(-[\w*])?,",$v)){
278                if (is_numeric($k))
279                        $action = $v;
280                if (_request($k))
281                        $action = $v;
282        }
283        // ajout un role null fictif (plus pratique) si pas défini
284        if ($action and count(explode("-", $action)) == 4) {
285                $action .= '-';
286        }
287        return $action;
288}
289
290
291/**
292 * Retrouve le ou les roles postés avec une liaison demandée
293 *
294 * @internal
295 * @param string $lien    Action du lien
296 * @return array          Liste des rôles. Tableau vide s'il n'y en a pas.
297**/
298function lien_retrouver_roles_postes($lien) {
299        // un role est défini dans la liaison
300        $defs = explode('-', $lien);
301        list(,,,,$role) = $defs;
302        if ($role) return array($role);
303
304        // retrouver les rôles postés pour cette liaison, s'il y en a.
305        $roles = _request('definir_roles');
306        if (!$roles OR !is_array($roles)) {
307                return array();
308        }
309
310        // pas avec l'action complete (incluant le role)
311        if (!isset($roles[$lien]) OR !$roles = $roles[$lien]) {
312                // on tente avec l'action sans le role
313                array_pop($defs);
314                $lien = implode('-', $defs);
315                if (!isset($roles[$lien]) OR !$roles = $roles[$lien]) {
316                        $roles = array();
317                }
318        }
319
320        // pas de rôle vide
321        return array_filter($roles);
322}
323
324/**
325 * Ajoute les liens demandés en prenant éventuellement en compte le rôle
326 *
327 * Appelle la fonction objet_associer. L'appelle autant de fois qu'il y
328 * a de rôles demandés pour cette liaison.
329 *
330 * @internal
331 * @param string $objet_source   Objet source de la liaison (qui a la table de liaison)
332 * @param array|string $ids      Identifiants pour l'objet source
333 * @param string $objet_lien     Objet à lier
334 * @param array|string $idl      Identifiants pour l'objet lié
335 * @return void
336**/
337function lien_ajouter_liaison($objet_source, $ids, $objet_lien, $idl, $roles) {
338
339        // retrouver la colonne de roles s'il y en a a lier
340        if ($roles and $colonne_role = roles_colonne($objet_source, $objet_lien)) {
341                foreach ($roles as $role) {
342                        objet_associer(array($objet_source=>$ids), array($objet_lien=>$idl), array($colonne_role => $role));
343                }
344        } else {
345                objet_associer(array($objet_source=>$ids), array($objet_lien=>$idl));
346        }
347}
348
349?>
Note: See TracBrowser for help on using the repository browser.