source: spip-zone/_plugins_/roles_documents/trunk/roles_documents_pipelines.php @ 115939

Last change on this file since 115939 was 115939, checked in by tcharlss@…, 6 weeks ago

Correction d'un bug vicelard : les documents avec le rôle logo étaient exclus par défaut des boucles DOCUMENTS, fort bien. Sauf que cette exclusion ne doit avoir lieu que quand il y a une jointure sur la table de liens, sinon ça exclut des documents pour rien. Exemple : dans ce cas, il n'y a aucune raison d'exclure le document s'il est utilisé comme logo quelque part.

  • Property svn:executable set to *
File size: 11.5 KB
Line 
1<?php
2/**
3 * Plugin Rôles de documents
4 * (c) 2015
5 * Licence GNU/GPL
6 */
7
8if (!defined('_ECRIRE_INC_VERSION')) {
9        return;
10}
11
12/**
13 * Ajout de contenu dans le bloc «actions» des documents
14 *
15 * - Formulaire pour définir les rôles des documents
16 *
17 * @pipeline document_desc_actions
18 *
19 * @param  array $flux Données du pipeline
20 * @return array       Données du pipeline
21 */
22function roles_documents_document_desc_actions($flux) {
23        include_spip('inc/autoriser');
24
25        $texte               = '';
26        $exec                = trouver_objet_exec(_request('exec'));
27        $objet_exec          = $exec['type'];
28        $id_table_objet_exec = $exec['id_table_objet'];
29        $id_objet_exec       = intval(_request($id_table_objet_exec));
30        // soit objet et id_objet sont passés en paramètre, soit on prend l'objet édité sur la page
31        $objet               = !empty($flux['args']['objet']) ? $flux['args']['objet'] : $objet_exec;
32        $id_objet            = !empty($flux['args']['id_objet']) ? $flux['args']['id_objet'] : $id_objet_exec;
33
34        if (
35                $exec !== false // page d'un objet éditorial
36                and $exec['edition'] === false // pas en mode édition
37                and $flux['args']['variante'] != 'editer_logo'
38                and $id_document = intval($flux['args']['id_document'])
39                and autoriser('modifier', 'document', $id_document)
40                and $objet
41                and $id_objet
42        ) {
43                // bloc à recharger
44                $ajaxreload = !empty($flux['args']['ajaxreload']) ? $flux['args']['ajaxreload'] : '.liste_items.documents';
45                // mini-formulaire
46                $form = recuperer_fond(
47                        'prive/squelettes/inclure/editer_roles_document',
48                        array(
49                                'id_document' => $id_document,
50                                'objet'       => $objet,
51                                'id_objet'    => $id_objet,
52                                'options'     => array(
53                                        'ajaxReload' => $ajaxreload,
54                                ),
55                        )
56                );
57                $texte = $form;
58        }
59
60        if ($texte) {
61                $flux['data'] .= $texte;
62        }
63
64        return $flux;
65}
66
67
68/**
69 * Synchroniser les champs "vu" et "rang_lien" lors de la création d'un nouveau lien de document portant un rôle.
70 *
71 * @pipeline post_edition_liens
72 *
73 * @param  array $flux Données du pipeline
74 * @return array       Données du pipeline
75 */
76function roles_documents_post_edition_lien($flux) {
77        if (
78                $flux['args']['action'] == 'insert'             // il s'agit d'une création de lien
79                and $flux['args']['objet_source'] == 'document' // on a affaire à un document
80                and isset($flux['args']['role'])
81                and $role = $flux['args']['role']
82                and strlen($role)                               // et il y a un role donné
83                and isset($flux['args']['colonne_role'])
84                and $colonne_role = $flux['args']['colonne_role']
85                and $id_document = intval($flux['args']['id_objet_source'])
86                and $objet = $flux['args']['objet']
87                and $id_objet = intval($flux['args']['id_objet'])
88        ) {
89                // le champ 'rang_lien' n'est présent qu'à partir de SPIP 3.2 (ou avec le plugin ordoc)
90                $champs_synchronises = array('vu', 'rang_lien');
91
92                $trouver_table = charger_fonction('trouver_table', 'base');
93                $desc = $trouver_table('spip_documents_liens');
94                $champs_presents = array_flip(array_intersect_key(array_flip($champs_synchronises), $desc['field']));
95
96                $qualifier = sql_fetsel(
97                        $champs_presents,
98                        'spip_documents_liens',
99                        array(
100                                'id_document=' . $id_document,
101                                'objet=' . sql_quote($objet),
102                                'id_objet=' . $id_objet,
103                                $colonne_role . '=' . sql_quote('document')
104                        )
105                );
106                if ($qualifier) {
107                        include_spip('action/editer_liens');
108                        objet_qualifier_liens(
109                                array('document' => $id_document),
110                                array($objet => $id_objet),
111                                array($colonne_role => $role) + $qualifier
112                        );
113                }
114        }
115
116        return $flux;
117}
118
119
120/**
121 * Après la modif d'un objet, synchroniser le vu de tous les document liés ayant un rôle
122 * avec celui du lien de base (ayant le rôle par défaut)
123 *
124 * @pipeline post_edition
125 *
126 * @param  array $flux Données du pipeline
127 * @return array       Données du pipeline
128 */
129function roles_documents_post_edition($flux) {
130        if (
131                isset($flux['args']['action'])
132                and $flux['args']['action'] == 'modifier'       // on modifie un objet
133                and $flux['args']['table'] !== 'spip_documents'  // mais pas un document
134                and $objet = $flux['args']['type']
135                and $id_objet = intval($flux['args']['id_objet'])
136        ) {
137                include_spip('action/editer_liens');
138
139                // on regarde s'il y a des documents liés à l'objet modifié
140                if (count($liens = objet_trouver_liens(array('document'=>'*'), array($objet=>$id_objet)))) {
141                        foreach ($liens as $l) {
142                                // on récupère le champ "vu" du lien avec le rôle par défaut
143                                $vu = sql_getfetsel(
144                                        'vu',
145                                        'spip_documents_liens',
146                                        'id_document=' .$l['id_document'] .' AND objet='.sql_quote($objet) .'
147                                                AND id_objet='.$id_objet .' AND role='.sql_quote('document')
148                                );
149                                // on met à jour tous les autres liens avec rôle
150                                sql_updateq(
151                                        'spip_documents_liens',
152                                        array('vu'=>$vu),
153                                        'id_document=' .$l['id_document'] .' AND objet='.sql_quote($objet) .'
154                                                AND id_objet='.$id_objet .' AND role!='.sql_quote('document')
155                                );
156                        }
157                }
158        }
159
160        return $flux;
161}
162
163
164/**
165 * Empêcher les logos de sortir dans les boucles DOCUMENTS lorsqu'il y a une jointure sur la table de liens (et donc des rôles actifs).
166 *
167 * C'est nécessaire pour la rétro-compatibilité avec les squelettes existants.
168 * Pour voir les logos dans les boucles DOCUMENTS, il faut utiliser
169 * explicitement le critère {tout} ou {role=logo} ou {role?}
170 *
171 * @pipeline pre_boucle
172 * @param  array $boucle Données du pipeline
173 * @return array       Données du pipeline
174 */
175function roles_documents_pre_boucle($boucle) {
176
177        // Boucle DOCUMENTS
178        if ($boucle->type_requete === 'documents') {
179
180                // Vérifier s'il y a une jointure sur la table de liens
181                $jointure_documents = false;
182                if ($boucle->join) {
183                        foreach($boucle->join as $join) {
184                                if (array_search(sql_quote('documents'), $join) !== false) {
185                                        $jointure_documents = true;
186                                        break;
187                                }
188                        }
189                }
190
191                // Vérifier la présence du critère {role}
192                // [FIXME] vérifier sa valeur (=logo)
193                $utilise_critere_logo = false;
194                foreach ($boucle->criteres as $critere) {
195                        if ($critere->type === 'critere') {
196                                if (
197                                        (isset($critere->param[0][0]) and $critere->param[0][0]->texte === 'role')
198                                        or ($critere->op === 'role')
199                                ) {
200                                        $utilise_critere_logo = true;
201                                }
202                        }
203                }
204
205                // Gros hack : on évite le traitement pour certains squelettes,
206                // afin  d'éviter de les surcharger
207                $bypass = false;
208                $squelettes_bypass = array(
209                        array(
210                                'sourcefile' => 'document_desc.html',
211                                'id_boucle'  => '_docslies',
212                        )
213                );
214                foreach($squelettes_bypass as $squelette) {
215                        if (substr($boucle->descr['sourcefile'], -strlen($squelette['sourcefile'])) == $squelette['sourcefile']
216                                and $boucle->id_boucle == $squelette['id_boucle']
217                        ) {
218                                $bypass = true;
219                        }
220                }
221
222                // Go go go
223                if (
224                        $jointure_documents
225                        and !$utilise_critere_logo
226                        and (empty($boucle->modificateur['tout']) or $boucle->modificateur['tout'] === false)
227                        and !$bypass
228                ) {
229                        $table_liens = 'spip_documents_liens';
230                        $abbrev_table_lien = array_search($table_liens, $boucle->from);
231
232                        if ($abbrev_table_lien) {
233                                $boucle->where[] = array(
234                                        "'!='",
235                                        "'SUBSTR($abbrev_table_lien.role, 1, 4)'",
236                                        "'\'logo\''"
237                                );
238                        }
239                }
240        }
241
242        return $boucle;
243}
244
245
246/**
247 * Modifier le tableau retourné par la fonction charger d'un formulaire
248 *
249 * Ajout du champ 'role' sur le formulaire d'ajout de document
250 *
251 * @pipeline formulaire_charger
252 *
253 * @param  array $flux Données du pipeline
254 * @return array       Données du pipeline
255 */
256function roles_documents_formulaire_charger($flux) {
257
258        // Formulaire d'ajout de document
259        if ($flux['args']['form'] == 'joindre_document') {
260                $flux['data']['roles'] = '';
261        }
262
263        return $flux;
264}
265
266
267/**
268 * Complèter le tableau de réponse ou faire des traitements supplémentaires pour un formulaire
269 *
270 * Qualifier le lien crée avec le rôle choisi
271 *
272 * @pipeline formulaire_traiter
273 *
274 * @param  array $flux Données du pipeline
275 * @return array       Données du pipeline
276 */
277function roles_documents_formulaire_traiter($flux) {
278
279        // Formulaire d'ajout de document
280        // En présence d'un role sélectionne, on requalifie le lien créé
281        // sauf si c'est le rôle par défaut
282        if ($flux['args']['form'] == 'joindre_document'
283                and $roles = _request('roles')
284                and $objet = $flux['args']['args'][2]
285                and $id_objet = $flux['args']['args'][1]
286                and !empty($flux['data']['ids'])
287        ) {
288                foreach ($flux['data']['ids'] as $id_document) {
289                        if (!is_array($roles)) {
290                                $roles = array($roles);
291                        }
292                        foreach ($roles as $role) {
293                                if ($role != 'document') {
294                                        $update = sql_updateq(
295                                                'spip_documents_liens',
296                                                array('role' => $role),
297                                                array(
298                                                        'id_document=' . intval($id_document),
299                                                        'objet='       . sql_quote($objet),
300                                                        'id_objet='    . intval($id_objet),
301                                                        'role='        . sql_quote('document'),
302                                                )
303                                        );
304                                }
305                        }
306                }
307        }
308
309        return $flux;
310}
311
312
313/**
314 * Modifier le résultat du calcul d’un squelette donné.
315 *
316 * Formulaire d'ajout de document : ajout du sélecteur de rôle, et rendre les identifiants uniques pour éviter un pb de JS quand le form est présent plusieurs fois sur la page.
317 *
318 * @pipeline recuperer_fond
319 *
320 * @param  array $flux Données du pipeline
321 * @return array       Données du pipeline
322 */
323function roles_documents_recuperer_fond($flux) {
324
325        // Ajout de document
326        if ($flux['args']['fond'] == 'formulaires/inc-upload_document'
327                and isset($flux['args']['contexte']['objet'])
328                and isset($flux['args']['contexte']['id_objet'])
329        ) {
330
331                // 1) Ajout du sélecteur de rôle
332
333                // Est-ce qu'il s'agit d'un ajout de logo ?
334                $editer_logo = !empty($flux['args']['contexte']['editer_logo']);
335                $principaux = $editer_logo ? true : false;
336
337                // Retrouver les rôles restant à associer
338                $objet = $flux['args']['contexte']['objet'];
339                $id_objet = $flux['args']['contexte']['id_objet'];
340                $roles = roles_documents_presents_sur_objet($objet, $id_objet, 0, $principaux);
341                $roles_attribuables = isset($flux['args']['contexte']['roles_attribuables']) ?
342                        $flux['args']['contexte']['roles_attribuables'] :
343                        ($editer_logo ?
344                                $roles['attribuables'] :
345                                $roles['possibles']
346                        );
347                $multiple = $editer_logo ? null : (count($roles_attribuables) > 1 ? 'oui' : null);
348                $contexte = array(
349                        'roles'              => $flux['args']['contexte']['roles'],
350                        'roles_attribuables' => $roles_attribuables,
351                        'multiple'           => $multiple,
352                );
353
354                // On place le sélecteur au début (compliqué de le placer juste avant les boutons, déplacés en JS, et des blocs cachés)
355                $selecteur_roles = recuperer_fond('formulaires/inc-selecteur_role', $contexte);
356                $flux['data']['texte'] = $selecteur_roles . $flux['data']['texte'];
357
358                // 2) Rendre les identifiants vraiment uniques pour le JS
359
360                if (preg_match('/id=["\']defaultsubmit([^"\']+)/i', $flux['data']['texte'], $res)) {
361                        $domid = $res[1]; // L'identifiant pas si unique présent par défaut
362                        $uniqid = $domid . '_' . uniqid(); // Identifiant vraiement unique
363                        $flux['data']['texte'] = str_replace($domid, $uniqid, $flux['data']['texte']);
364                }
365
366        }
367
368        return $flux;
369}
370
371
372/**
373 * Modifier le résultat du calcul d’un squelette de formulaire.
374 *
375 * - Formulaire d'édition de logo : on a besoin de bénéficier des éventuelles modifications effectuées auu formulaire joindre_document.
376 *   Pour se faire on appelle le même pipeline à nouveau en se faisant passer pour ce dernier.
377 *
378 * @param array $flux
379 * @return array
380 **/
381function roles_documents_formulaire_fond($flux) {
382
383        if ($flux['args']['form'] == 'editer_logo'
384                //and !empty($flux['args']['contexte']['_bigup_rechercher_fichiers'])
385        ) {
386                $flux_joindre_document = $flux;
387                $flux_joindre_document['args']['form'] = 'joindre_document';
388                $data = pipeline('formulaire_fond', $flux_joindre_document);
389                $flux['data'] = $data;
390        }
391
392        return $flux;
393}
Note: See TracBrowser for help on using the repository browser.