[SPIP] ~maj v3.0.14-->v3.0.17
[ptitvelo/web/www.git] / www / prive / formulaires / editer_liens.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
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 **/
18 if (!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 */
36 function 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 */
76 function 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 include_spip('inc/autoriser');
92 $editable = ($editable and autoriser('associer'.$table_source, $objet, $id_objet) and autoriser('modifier',$objet,$id_objet));
93
94 if (!$editable AND !count(objet_trouver_liens(array($objet_lien=>'*'),array(($objet_lien==$objet_source?$objet:$objet_source)=>'*'))))
95 return false;
96
97 $valeurs = array(
98 'id'=>"$table_source-$objet-$id_objet-$objet_lien", // identifiant unique pour les id du form
99 '_vue_liee' => $table_source."_lies",
100 '_vue_ajout' => $table_source."_associer",
101 '_objet_lien' => $objet_lien,
102 'id_lien_ajoute'=>_request('id_lien_ajoute'),
103 'objet'=>$objet,
104 'id_objet'=>$id_objet,
105 'objet_source'=>$objet_source,
106 'table_source' => $table_source,
107 'recherche'=>'',
108 'visible'=>0,
109 'ajouter_lien'=>'',
110 'supprimer_lien'=>'',
111 '_oups' => _request('_oups'),
112 'editable' => $editable,
113 );
114
115 return $valeurs;
116 }
117
118 /**
119 * Traiter le post des informations d'édition de liens
120 *
121 * Les formulaires postent dans trois variables ajouter_lien et supprimer_lien
122 * et remplacer_lien
123 *
124 * Les deux premieres peuvent etre de trois formes differentes :
125 * ajouter_lien[]="objet1-id1-objet2-id2"
126 * ajouter_lien[objet1-id1-objet2-id2]="nimportequoi"
127 * ajouter_lien['clenonnumerique']="objet1-id1-objet2-id2"
128 * Dans ce dernier cas, la valeur ne sera prise en compte
129 * que si _request('clenonnumerique') est vrai (submit associe a l'input)
130 *
131 * remplacer_lien doit etre de la forme
132 * remplacer_lien[objet1-id1-objet2-id2]="objet3-id3-objet2-id2"
133 * ou objet1-id1 est celui qu'on enleve et objet3-id3 celui qu'on ajoute
134 *
135 * @param string $a
136 * @param string|int $b
137 * @param int|string $c
138 * @param bool $editable
139 * @return array
140 */
141 function formulaires_editer_liens_traiter_dist($a,$b,$c,$editable=true){
142 $res = array('editable'=>$editable?true:false);
143 list($table_source,$objet,$id_objet,$objet_lien) = determine_source_lien_objet($a,$b,$c);
144 if (!$table_source OR !$objet OR !$objet_lien)
145 return $res;
146
147
148 if (_request('tout_voir'))
149 set_request('recherche','');
150
151 include_spip('inc/autoriser');
152 if (autoriser('modifier',$objet,$id_objet)) {
153 // annuler les suppressions du coup d'avant !
154 if (_request('annuler_oups')
155 AND $oups = _request('_oups')
156 AND $oups = unserialize($oups)){
157 if ($oups_objets = charger_fonction("editer_liens_oups_{$table_source}_{$objet}_{$objet_lien}","action",true)){
158 $oups_objets($oups);
159 }
160 else {
161 $objet_source = objet_type($table_source);
162 include_spip('action/editer_liens');
163 foreach($oups as $oup) {
164 if ($objet_lien==$objet_source)
165 objet_associer(array($objet_source=>$oup[$objet_source]), array($objet=>$oup[$objet]),$oup);
166 else
167 objet_associer(array($objet=>$oup[$objet]), array($objet_source=>$oup[$objet_source]),$oup);
168 }
169 }
170 # oups ne persiste que pour la derniere action, si suppression
171 set_request('_oups');
172 }
173
174 $supprimer = _request('supprimer_lien');
175 $ajouter = _request('ajouter_lien');
176
177 // il est possible de preciser dans une seule variable un remplacement :
178 // remplacer_lien[old][new]
179 if ($remplacer = _request('remplacer_lien')){
180 foreach($remplacer as $k=>$v){
181 if ($old = lien_verifier_action($k,'')){
182 foreach(is_array($v)?$v:array($v) as $kn=>$vn)
183 if ($new = lien_verifier_action($kn,$vn)){
184 $supprimer[$old] = 'x';
185 $ajouter[$new] = '+';
186 }
187 }
188 }
189 }
190
191 if ($supprimer){
192 if ($supprimer_objets = charger_fonction("editer_liens_supprimer_{$table_source}_{$objet}_{$objet_lien}","action",true)){
193 $oups = $supprimer_objets($supprimer);
194 }
195 else {
196 include_spip('action/editer_liens');
197 $oups = array();
198
199 foreach($supprimer as $k=>$v) {
200 if ($lien = lien_verifier_action($k,$v)){
201 $lien = explode("-",$lien);
202 list($objet_source,$ids,$objet_lie,$idl) = $lien;
203 if ($objet_lien==$objet_source){
204 $oups = array_merge($oups, objet_trouver_liens(array($objet_source=>$ids), array($objet_lie=>$idl)));
205 objet_dissocier(array($objet_source=>$ids), array($objet_lie=>$idl));
206 }
207 else{
208 $oups = array_merge($oups, objet_trouver_liens(array($objet_lie=>$idl), array($objet_source=>$ids)));
209 objet_dissocier(array($objet_lie=>$idl), array($objet_source=>$ids));
210 }
211 }
212 }
213 }
214 set_request('_oups',$oups?serialize($oups):null);
215 }
216
217 if ($ajouter){
218 if ($ajouter_objets = charger_fonction("editer_liens_ajouter_{$table_source}_{$objet}_{$objet_lien}","action",true)){
219 $ajout_ok = $ajouter_objets($ajouter);
220 }
221 else {
222 $ajout_ok = false;
223 include_spip('action/editer_liens');
224 foreach($ajouter as $k=>$v){
225 if ($lien = lien_verifier_action($k,$v)){
226 $ajout_ok = true;
227 list($objet1,$ids,$objet2,$idl) = explode("-",$lien);
228 if ($objet_lien==$objet1)
229 objet_associer(array($objet1=>$ids), array($objet2=>$idl));
230 else
231 objet_associer(array($objet2=>$idl), array($objet1=>$ids));
232 set_request('id_lien_ajoute',$ids);
233 }
234 }
235 }
236 # oups ne persiste que pour la derniere action, si suppression
237 # une suppression suivie d'un ajout dans le meme hit est un remplacement
238 # non annulable !
239 if ($ajout_ok)
240 set_request('_oups');
241 }
242 }
243
244
245 return $res;
246 }
247
248
249 /**
250 * Retrouver l'action de liaision demandée
251 *
252 * Les formulaires envoient une action dans un tableau ajouter_lien
253 * ou supprimer_lien
254 *
255 * L'action est de la forme : objet1-id1-objet2-id2
256 *
257 * L'action peut-être indiquée dans la clé ou dans la valeur.
258 * Si elle est indiquee dans la valeur et que la clé est non numérique,
259 * on ne la prend en compte que si un submit avec la clé a été envoyé
260 *
261 * @param string $k Clé du tableau
262 * @param string $v Valeur du tableau
263 * @return string Action demandée si trouvée, sinon ''
264 */
265 function lien_verifier_action($k,$v){
266 if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+,",$k))
267 return $k;
268 if (preg_match(",^\w+-[\w*]+-[\w*]+-[\w*]+,",$v)){
269 if (is_numeric($k))
270 return $v;
271 if (_request($k))
272 return $v;
273 }
274 return '';
275 }
276 ?>