source: spip-zone/_plugins_/champs_extras_core/trunk/inc/cextras.php @ 99134

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

Complément sur r99133 : je m'étais entourloupé avec l'option 'id_auteur' qui n'a pas à exister.
On ajoute plutôt un paramètre $id_objet, puisque c'est en fait ça que l'on attend peut être
pour tester les autorisations (et pas un identifiant d'auteur, je m'étais trompé car j'ai
repris un code que j'utilisais sur un formulaire de profil sur l'objet auteur).

Et sinon un moyen (pas spécialement chouette) d'avoir le comportement souhaité pour le formulaire
d'inscription de newsletter peut être d'appeler aussi le pipeline pre_insertion dessus, tel que :

`
function demo_formulaire_charger($flux) {

if ($fluxargs?form? == 'newsletter_subscribe') {

include_spip('inc/cextras');
if ($saisies = cextras_obtenir_saisies_champs_extras('mailsubscribers')) {

$flux_champs_extras_saisies? = $saisies;

}

}
return $flux;

}

function demo_pre_insertion($flux) {

if ($fluxargs?table? == 'spip_mailsubscribers') {

include_spip('cextras_pipelines');
$_flux = $flux;
$_fluxargs?id_objet? = null;
$_flux = cextras_pre_edition($_flux);
$fluxdata? = $_fluxdata?;

}
return $flux;

}
`

On exécute juste le pipeline de champs extra (mais il attend 'id_objet' en plus)

Voilà… SAD quand tu nous tiens.

File size: 12.8 KB
Line 
1<?php
2
3/**
4 * Déclaration d'autorisations pour les champs extras
5 *
6 * @package SPIP\Cextras\Fonctions
7**/
8
9// sécurité
10if (!defined("_ECRIRE_INC_VERSION")) return;
11
12
13/**
14 * Log une information
15 *
16 * @param mixed $contenu
17 *     Contenu à loger
18 * @param bool $important
19 *     Est-ce une info importante à loger ?
20 */
21function extras_log($contenu, $important=false) {
22        if ($important) {
23                spip_log($contenu, 'extras.'. _LOG_INFO);
24        } else {
25                spip_log($contenu, 'extras.'. _LOG_INFO_IMPORTANTE);
26        }
27}
28
29
30/**
31 * Retourne la liste des objets valides utilisables
32 *
33 * C'est à dire les objets dont on peut afficher les champs dans les
34 * formulaires, ce qui correspond aux objets éditoriaux déclarés
35 * comme avec l'option principale.
36 *
37 * @return array
38 *    Couples (table sql => description de l'objet éditorial)
39 */
40function cextras_objets_valides(){
41
42        $objets = array();
43        $tables = lister_tables_objets_sql();
44        ksort($tables);
45
46        foreach($tables as $table => $desc) {
47                if (($desc['editable'] == 'oui') and ($desc['principale'] == 'oui')) {
48                        $objets[$table] = $desc;
49                }
50        }
51
52        return $objets;
53}
54
55
56
57/**
58 * Liste les saisies ayant une definition SQL
59 *
60 * S'assurer de l'absence de clé, qui fait croire à saisies que le tableau est déjà à plat
61 * alors que ce n'est pas forcément encore le cas (ie: il peut y avoir des fieldset à prendre
62 * en compte).
63 *
64 * @param Array $saisies liste de saisies
65 * @return array Liste de ces saisies triees par nom ayant une option sql définie
66 */
67function champs_extras_saisies_lister_avec_sql($saisies) {
68        if (!function_exists('saisies_lister_avec_sql')) {
69                include_spip('inc/saisies');
70        }
71
72        return saisies_lister_avec_sql(array_values($saisies));
73}
74
75
76
77/**
78 * Liste les saisies ayant des traitements
79 *
80 * Retourne uniquement les saisies ayant traitements à appliquer sur
81 * les champs tel que des traitements typo ou traitements raccourcis.
82 *
83 * @param array $saisies
84 *     Liste de saisies
85 * @param String $tri
86 *     Tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
87 * @return array
88 *     Liste de ces saisies triées par nom ayant des traitements définis
89**/
90function saisies_lister_avec_traitements($saisies, $tri = 'nom') {
91        return saisies_lister_avec_option('traitements', $saisies, $tri);
92}
93
94
95
96/**
97 * Créer les champs extras (colonnes en base de données)
98 * definies par le lot de saisies donné
99 *
100 * @param string $table
101 *     Nom de la table SQL
102 * @param array $saisies
103 *     Description des saisies
104 * @return bool|void
105 *     False si pas de table ou aucune saisie de type SQL
106**/
107function champs_extras_creer($table, $saisies) {
108        if (!$table) {
109                return false;
110        }
111        if (!is_array($saisies) OR !count($saisies)) {
112                return false;
113        }
114
115        // uniquement les saisies décrivant SQL
116        $saisies = champs_extras_saisies_lister_avec_sql($saisies);
117
118        if (!$saisies) {
119                return false;
120        }
121
122        $desc = lister_tables_objets_sql($table);
123
124        // parcours des saisies et ajout des champs extras nouveaux dans
125        // la description de la table
126        foreach ($saisies as $saisie) {
127                $nom = $saisie['options']['nom'];
128                // le champ ne doit pas deja exister !
129                if (!isset($desc['field'][$nom])) {
130                        $desc['field'][$nom] = $saisie['options']['sql'];
131                }
132        }
133       
134        // executer la mise a jour
135        include_spip('base/create');
136        creer_ou_upgrader_table($table, $desc, true, true);
137}
138
139
140/**
141 * Supprimer les champs extras (colonne dans la base de données)
142 * definies par le lot de saisies donné
143 *
144 * @param string $table
145 *     Nom de la table SQL
146 * @param array $saisies
147 *     Description des saisies
148 * @return bool
149 *     False si pas de table, aucune saisie de type SQL, ou une suppression en erreur
150 *     True si toutes les suppressions sont OK
151**/
152function champs_extras_supprimer($table, $saisies) {
153        if (!$table) {
154                return false;
155        }
156        if (!is_array($saisies) OR !count($saisies)) {
157                return false;
158        }
159
160        $saisies = champs_extras_saisies_lister_avec_sql($saisies);
161
162        if (!$saisies) {
163                return false;
164        }       
165       
166        $desc = lister_tables_objets_sql($table);
167
168        $ok = true;
169        foreach ($saisies as $saisie) {
170                $nom = $saisie['options']['nom'];       
171                if (isset($desc['field'][$nom])) {
172                        $ok &= sql_alter("TABLE $table DROP COLUMN $nom");
173                }
174        }
175        return $ok;
176}
177
178
179/**
180 * Modifier les champs extras (colonne dans la base de données)
181 * definies par le lot de saisies donné   
182 *
183 * Permet de changer la structure SQL ou le nom de la colonne
184 * des saisies
185 *
186 * @param string $table
187 *     Nom de la table SQL
188 * @param array $saisies_nouvelles
189 *     Description des saisies nouvelles
190 * @param array $saisies_anciennes
191 *     Description des saisies anciennes
192 * @return bool
193 *     True si les changement SQL sont correctement effectués
194**/
195function champs_extras_modifier($table, $saisies_nouvelles, $saisies_anciennes) {
196        $ok = true;
197        foreach ($saisies_nouvelles as $id => $n) {
198                $n_nom = $n['options']['nom'];
199                if (isset($n['options']['sql'])) {
200                        $n_sql = $n['options']['sql'];
201                        $a_nom = $saisies_anciennes[$id]['options']['nom'];
202                        $a_sql = $saisies_anciennes[$id]['options']['sql'];
203                        if ($n_nom != $a_nom OR $n_sql != $n_sql) {
204                                $ok &= sql_alter("TABLE $table CHANGE COLUMN $a_nom $n_nom $n_sql");
205                        }
206                }
207        }
208        return $ok;
209}
210
211
212/**
213 * Complète un tableau de mise à jour de plugin afin d'installer les champs extras.
214 *
215 * @example
216 *     ```
217 *     cextras_api_upgrade(motus_declarer_champs_extras(), $maj['create']);
218 *     ```
219 *
220 * @param array $declaration_champs_extras
221 *     Liste de champs extras à installer, c'est à dire la liste de saisies
222 *     présentes dans le pipeline declarer_champs_extras() du plugin qui demande l'installation
223 * @param array $maj_item
224 *     Un des éléments du tableau d'upgrade $maj,
225 *     il sera complété des actions d'installation des champs extras demandés
226 *
227 * @return bool
228 *     false si les déclarations sont mal formées
229 *     true sinon
230**/
231function cextras_api_upgrade($declaration_champs_extras, &$maj_item) {
232        if (!is_array($declaration_champs_extras)) {
233                return false;
234        }
235        if (!is_array($maj_item)) {
236                $maj_item = array();
237        }
238        foreach($declaration_champs_extras as $table=>$champs) {
239                $maj_item[] = array('champs_extras_creer',$table, $champs);
240        }
241
242        return true;
243}
244
245
246/**
247 * Supprime les champs extras declarés
248 *
249 * @example
250 *     ```
251 *     cextras_api_vider_tables(motus_declarer_champs_extras());
252 *     ```
253 *
254 * @param array $declaration_champs_extras
255 *     Liste de champs extras à désinstaller, c'est à dire la liste de saisies
256 *     présentes dans le pipeline declarer_champs_extras() du plugin qui demande la désinstallation
257 *
258 * @return bool
259 *     false si déclaration mal formée
260 *     true sinon
261**/
262function cextras_api_vider_tables($declaration_champs_extras) {
263        if (!is_array($declaration_champs_extras)) {
264                return false;
265        }
266        foreach($declaration_champs_extras as $table=>$champs) {
267                champs_extras_supprimer($table, $champs);
268        }
269        return true;
270}
271
272
273/*
274 *
275 * Rechercher les champs non declares mais existants
276 * dans la base de donnee en cours
277 * (code d'origine : _fil_)
278 *
279 */
280
281/**
282 * Liste les tables et les champs que le plugin et spip savent gérer
283 * mais qui ne sont pas déclarés à SPIP
284 *
285 * @param string $connect
286 *     Nom du connecteur de base de données
287 * @return array
288 *     Tableau (table => couples(colonne => description SQL))
289 */
290function extras_champs_utilisables($connect='') {
291        $tout = extras_champs_anormaux($connect);
292        $objets = cextras_objets_valides();
293        $utilisables = array_intersect_key($tout, $objets);
294        ksort($utilisables);
295        return $utilisables;
296}
297
298/**
299 * Liste les champs anormaux par rapport aux définitions de SPIP
300 *
301 * @note
302 *     Aucune garantie que $connect autre que la connexion principale fasse quelque chose
303 *
304 * @param string $connect
305 *     Nom du connecteur de base de données
306 * @return array
307 *     Tableau (table => couples(colonne => description SQL))
308 */
309function extras_champs_anormaux($connect='') {
310        static $tout = false;
311        if ($tout !== false) {
312                return $tout;
313        }
314        // recuperer les tables et champs de la base de donnees
315        // les vrais de vrai dans la base sql...
316        $tout = extras_base($connect);
317
318        // recuperer les champs SPIP connus
319        // si certains ne sont pas declares alors qu'ils sont presents
320        // dans la base sql, on pourra proposer de les utiliser comme champs
321        // extras (plugin interface).
322        include_spip('base/objets');
323        $tables_spip = lister_tables_objets_sql();
324
325        // chercher ce qui est different
326        $ntables = array();
327        $nchamps = array();
328        // la table doit être un objet editorial
329        $tout = array_intersect_key($tout, $tables_spip);
330        foreach ($tout as $table => $champs) {
331                // la table doit être un objet editorial principal
332                if ($tables_spip[$table]['principale'] == 'oui') {
333                        // pour chaque champ absent de la déclaration, on le note dans $nchamps.
334                        foreach($champs as $champ => $desc) {
335                                if (!isset($tables_spip[$table]['field'][$champ])) {
336                                        if (!isset($nchamps[$table])) {
337                                                $nchamps[$table] = array(); 
338                                        }
339                                        $nchamps[$table][$champ] = $desc;
340                                }
341                        }
342                }
343        }
344
345        if($nchamps) {
346                $tout = $nchamps;
347        } else {
348                $tout = array();
349        }
350
351        return $tout;
352}
353
354/**
355 * Établit la liste de tous les champs de toutes les tables de la connexion
356 * sql donnée
357 *
358 * Ignore la table 'spip_test'
359 *
360 * @param string $connect
361 *     Nom du connecteur de base de données
362 * @return array
363 *     Tableau (table => couples(colonne => description SQL))
364 */
365function extras_base($connect='') {
366        $champs = array();
367       
368        foreach (extras_tables($connect) as $table) {
369                if ($table != 'spip_test') {
370                        $champs[$table] = extras_champs($table, $connect);
371                }
372        }
373        return $champs;
374}
375
376
377/**
378 * Liste les tables SQL disponibles de la connexion sql donnée
379 *
380 * @param string $connect
381 *     Nom du connecteur de base de données
382 * @return array
383 *     Liste de tables SQL
384 */
385function extras_tables($connect='') {
386        $a = array();
387        $taille_prefixe = strlen( $GLOBALS['connexions'][$connect ? $connect : 0]['prefixe'] );
388
389        if ($s = sql_showbase(null, $connect)) {
390                while ($t = sql_fetch($s, $connect)) {
391                                $t = 'spip' . substr(array_pop($t), $taille_prefixe);
392                                $a[] = $t;
393                }
394        }
395        return $a;
396}
397
398
399/**
400 * Liste les champs dispos dans la table SQL de la connexion sql donnée
401 *
402 * @param string $table
403 *     Nom de la table SQL
404 * @param string $connect
405 *     Nom du connecteur de base de données
406 * @return array
407 *     Couples (colonne => description SQL)
408 */
409function extras_champs($table, $connect) {
410        $desc = sql_showtable($table, true, $connect);
411        if (is_array($desc['field'])) {
412                return $desc['field'];
413        } else {
414                return array();
415        }
416}
417
418
419
420/**
421 * Retourne les saisies de champs extras d'un objet éditorial indiqué
422 *
423 * Les saisies sont filtrées, par défaut par l'autorisation de modifier chaque champs extras.
424 * Des options peuvent modifier le comportement.
425 *
426 * @param string $objet
427 *     Type de l'objet éditorial
428 * @param int|null $id_objet
429 *     Identifiant de l'objet (si connu) peut servir aux autorisations.
430 * @param array $options {
431 *     @var string $autoriser
432 *         'voir' ou 'modifier' (par défaut) : type d'autorisation testé, appellera voirextra ou modifierextra…
433 *     @var string[] $whitelist
434 *         Liste blanche de noms de champs : ces champs seront à afficher, et uniquement eux (modulo l'autorisation sur chaque champ)
435 *     @var string[] $blacklist
436 *         Liste noire de noms de champs : ces champs ne seront pas affichés (quelque soit l'autorisation sur chaque champ)
437 * }
438 * @return array
439 *     Liste de saisies, les champs extras sur l'objet indiqué
440**/
441function cextras_obtenir_saisies_champs_extras($objet, $id_objet = null, $options = array()) {
442
443        $options += array(
444                'autoriser' => 'modifier',
445                'whitelist' => array(),
446                'blacklist' => array(),
447        );
448
449        include_spip('cextras_pipelines');
450        if ($saisies = champs_extras_objet( table_objet_sql($objet) )) {
451
452                // type d'autorisation
453                if (!in_array($options['autoriser'], array('voir', 'modifier'))) {
454                        $options['autoriser'] = 'modifier';
455                }
456
457                // listes inclusions et exclusions
458                $whitelist = array_unique(array_filter($options['whitelist']));
459                $blacklist = array_unique(array_filter($options['blacklist']));
460
461                // Conserver uniquement les saisies souhaitées
462                if (count($whitelist)) {
463                        foreach ($saisies as $i => $saisie) {
464                                if (empty($saisie['options']['nom']) or !in_array($saisie['options']['nom'], $whitelist)) {
465                                        unset($saisies[$i]);
466                                }
467                        }
468                }
469
470                // Enlever les saisies non souhaitées
471                if (count($blacklist)) {
472                        foreach ($saisies as $i => $saisie) {
473                                if (in_array($saisie['options']['nom'], $blacklist)) {
474                                        unset($saisies[$i]);
475                                }
476                        }
477                }
478
479                // filtrer simplement les saisies que la personne en cours peut voir
480                $saisies = champs_extras_autorisation($options['autoriser'], $objet, $saisies, array('id_objet' => $id_objet));
481
482                if ($saisies) {
483                        // pour chaque saisie presente, de type champs extras (hors fieldset et autres) ajouter un flag d'edition
484                        $saisies = champs_extras_ajouter_drapeau_edition($saisies);
485                        $valeurs['_saisies'] = $saisies;
486                }
487
488        }
489
490        return $saisies;
491}
492
Note: See TracBrowser for help on using the repository browser.