source: spip-zone/_plugins_/fabrique/trunk/formulaires/fabriquer_plugin.php @ 100903

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

Respecter les PSR de SPIP

File size: 32.7 KB
Line 
1<?php
2
3/**
4 * Gestion du formulaire de fabrication de plugin
5 *
6 * @package SPIP\Fabrique\Formulaires
7**/
8if (!defined("_ECRIRE_INC_VERSION")) return;
9
10/**
11 * Hash du formulaire de fabrication de plugin
12 *
13 * @return string
14 *     Hash du formulaire
15**/
16function formulaires_fabriquer_plugin_identifier_dist(){
17        return serialize(true);
18}
19
20/**
21 * Chargement du formulaire de fabrication de plugin
22 *
23 * @return array
24 *     Environnement du formulaire
25**/
26function formulaires_fabriquer_plugin_charger_dist() {
27
28        // v_spip = 3.0.0-beta2
29        // v_futur = 3.0.*
30        $v_spip = $GLOBALS['spip_version_branche'];
31        $v_futur = explode('.', $v_spip);
32        array_pop($v_futur);
33        $v_futur = implode('.', $v_futur) . '.*';
34        $contexte = array(
35                'fabrique' => array(), // ne sert pas dans ce formulaire, mais un jour peut être
36                'paquet' => array(
37                        'prefixe' => '',// 'Nouveau plugin',
38                        'version' => '1.0.0',
39                        'auteur' => $GLOBALS['visiteur_session']['nom'],
40                        'auteur_lien' => $GLOBALS['visiteur_session']['url_site'],
41                        'categorie' => '',
42                        'etat' => 'dev', // c'est du développement au debut, normalement.
43                        'compatibilite' => '[' . $v_spip . ';' . $v_futur . ']',
44                        'licence' => 'GNU/GPL',
45                        'schema' => '1.0.0',
46                        'fichiers' => array(),
47                        'exemples' => '', // inserer des exemples, de l'aide dans les fichiers.
48                ),
49                'objets' => array(),
50        );
51
52        // On initialise la session si elle est vide
53        if (is_null($fabrique = session_get(FABRIQUE_ID))){
54                session_set(FABRIQUE_ID, $contexte);
55                $fabrique = array();
56        }
57
58        // ça merge que la profondeur 1, c'est surtout la 2 qui interesse
59        #$contexte = array_merge($contexte, $fabrique);
60        foreach ($contexte as $c=>$v) {
61                if (isset($fabrique[$c])) {
62                        $contexte[$c] = array_merge($contexte[$c], $fabrique[$c]);
63                }
64        }
65
66        //on ajoute des informations d'image qui peuvent servir dans notre tableau de données.
67        $contexte = fabrique_completer_contexte_images($contexte);
68
69        //on ajoute des informations qui servent souvent dans notre tableau de données.
70        $contexte = fabrique_completer_contexte($contexte);
71
72        // et quelques autres informations de destination
73        $destination = fabrique_destination();
74        $contexte['destination'] = $destination;
75        if (!$prefixe = $contexte['paquet']['prefixe']) {
76                $prefixe = 'prefixe';
77        }
78        $contexte['destination_plugin']        = $destination  . $prefixe . '/';
79        $contexte['destination_ancien_plugin'] = $destination  . '.backup/' . $prefixe . '/';
80
81
82        // on ouvre sur la tab d'un nouvel objet lorsqu'il est cree
83        $tab = _request('open_tab', '');
84        $contexte['open_tab'] = $tab;
85
86        // on ouvre du coup le 2e accordion par defaut.
87        // si l'objet a deja ete rempli une fois
88        $accordion = _request('open_accordion', array());
89        foreach ($contexte['objets'] as $c => $o) {
90                if (isset($o['champs']) and count($o['champs'])) {
91                        $accordion[$c+1] = 1;
92                }
93        }
94        $contexte['open_accordion'] = $accordion;
95
96        // relou pour passer un message en plus depuis le traiter.
97        $contexte['_message_info'] = _request('message_info');
98        $contexte['_message_diff'] = _request('message_diff');
99        $contexte['_message_diff_suppressions'] = _request('message_diff_suppressions');
100
101        // es-t-on webmestre
102        $contexte['webmestre'] = autoriser('webmestre');
103
104        return $contexte;
105}
106
107
108
109
110/**
111 * Vérifications du formulaire de fabrication de plugin
112 *
113 * @return array
114 *     Erreurs du formulaire
115**/
116function formulaires_fabriquer_plugin_verifier_dist(){
117
118        // cas d'action qui n'ont pas a être testées ici.
119        if (_request('f_action')) {
120                return array(); // forcer aucune erreur
121        }
122
123        $erreurs = array();
124
125        $paquet = _request('paquet');
126        foreach (array('prefixe', 'version', 'categorie', 'etat', 'nom') as $obli) {
127                if (!$paquet[$obli]) {
128                        $erreurs['paquet'][$obli] = _T("info_obligatoire");
129                }
130        }
131
132        $objets = _request('objets');
133        if (is_array($objets)) {
134                foreach ($objets as $c => $o) {
135                        foreach (array('nom', 'table') as $obli) {
136                                if (!$o[$obli]) {
137                                        $erreurs['objets'][$c][$obli] = _T("info_obligatoire");
138                                }
139                        }
140                        if (is_array($o['champs'])) {
141                                foreach ($o['champs'] as $n => $champ) {
142                                        foreach (array('nom', 'champ', 'sql') as $obli) {
143                                                if (!$champ[$obli]) {
144                                                        $erreurs['objets'][$c]['champs'][$n][$obli] = _T("info_obligatoire");
145                                                }
146                                        }
147                                }
148                        }
149                }
150        }
151
152        if (count($erreurs)) {
153                $erreurs['message_erreur'] = _T("fabrique:erreurs");
154        }
155
156        return $erreurs;
157}
158
159
160
161
162/**
163 * Traitements du formulaire de fabrication de plugin
164 *
165 * @return array
166 *     Retours du traitement
167**/
168function formulaires_fabriquer_plugin_traiter_dist(){
169        include_spip('fabrique_fonctions');
170        include_spip('formulaires/fabriquer_plugin_actions');
171
172        $paquet = _request('paquet');
173        $objets = _request('objets');
174        if (!is_array($objets)) {
175                $objets = array();
176        }
177
178        $data = array(
179                'fabrique' => array('version' => FABRIQUE_VERSION),
180                'paquet' => $paquet,
181                'objets' => $objets,
182        );
183
184        // gerer les cas d'envoi d'images.
185        // (avant les éventuels retours sur l'ajout / suppression d'objet !)
186        fabrique_recuperer_et_stocker_les_images($data);
187
188
189        // Gerer les actions de la fabrique,
190        // avec des input.submit name=f_action[type]
191        // exemple : ajouter / supprimer un objet, supprimer des logos,
192        // deplacer des champs, tabs ...
193        if ($f_action = _request('f_action')) {
194                return fabrique_action_modification_formulaire($f_action, $data);
195        }
196
197
198        // calcul automatique de certains champs lorsqu'ils ne sont pas remplis
199        foreach ($data['objets'] as $c => $o) {
200                if ($o['table'] and !$o['cle_primaire']) {
201                        $data['objets'][$c]['cle_primaire'] = id_table_objet($o['table']);
202                }
203                if ($o['table'] and !$o['cle_primaire_sql']) {
204                        $data['objets'][$c]['cle_primaire_sql'] = "bigint(21) NOT NULL";
205                }
206                if ($o['table'] and !$o['table_type']) {
207                        $data['objets'][$c]['table_type'] = objet_type($data['objets'][$c]['cle_primaire']);
208                }
209        }
210
211        // sinon c'est creation du plugin
212        session_set(FABRIQUE_ID, $data);
213
214        // creation du repertoire de stockage du plugin cree dans
215        // plugins/fabrique/$prefixe (si possible), sinon dans
216        // tmp/cache/fabrique/$prefixe/
217        $destination = fabrique_destination();
218        $prefixe = $paquet['prefixe']; // il nous sert souvent ce prefixe !
219
220        // $_d... pour eviter des rtrim '/' en dessous
221        $_destination_plugin        = $destination . $prefixe;
222        $_destination_backup        = $destination . '.backup';
223        $_destination_ancien_plugin = $_destination_backup . '/' . $prefixe;
224
225        $destination_plugin         = $_destination_plugin . '/';
226        $destination_backup         = $_destination_backup  . '/';
227        $destination_ancien_plugin  = $_destination_ancien_plugin . '/';
228
229        // liste des variables disponibles pour l'execution de scripts
230        // (en plus de $data)
231        $contexte_scripts = compact(
232                'prefixe',
233                'destination',
234                'destination_plugin',
235                'destination_backup',
236                'destination_ancien_plugin');
237
238        // executer des actions si demandees
239        fabrique_executer_script('pre_copie', $data, $contexte_scripts);
240
241        // on efface l'eventuelle sauvegarde et on colle l'eventuel plugin deja genere a la place
242        supprimer_repertoire($_destination_ancien_plugin);
243        sous_repertoire_complet($_destination_backup);
244        // si la sauvegarde est encore présente, c'est que la suppression s'est mal passée
245        // il vaut mieux quitter en indiquant une erreur
246        if (is_dir($_destination_ancien_plugin)) {
247                fabrique_remettre_contexte($data);
248                return array(
249                        'editable'=>'oui',
250                        'message_erreur' => _T('fabrique:erreur_suppression_sauvegarde', array('dir'=>$_destination_ancien_plugin))
251                );
252        }
253
254        if (is_dir($_destination_plugin)) {
255                // try ne fonctionne pas sur rename()
256                if (!@rename($_destination_plugin, $_destination_ancien_plugin)) {
257                        // une erreur sur le rename signifie qu'on a pas les droits suffisants sur $_destination_plugin
258                        fabrique_remettre_contexte($data);
259                        return array(
260                                'editable'=>'oui',
261                                'message_erreur' => _T('fabrique:erreur_copie_sauvegarde', array('dir'=>$_destination_plugin))
262                        );
263                }
264        }
265        if (is_dir($_destination_plugin)) {
266                supprimer_repertoire($_destination_plugin);
267        }
268        sous_repertoire_complet($_destination_plugin);
269
270        // inutiles maintenant
271        unset($_destination_plugin, $_destination_ancien_plugin, $_destination_backup);
272
273        // sauver le descriptif de creation.
274        // ce qui permet de pouvoir restaurer toutes les donnees de construction
275        // afin de relancer la procédure avec des versions ulterieures du plugin
276
277        // on nettoie les noms de fichiers images locaux avant
278        $images = session_get(FABRIQUE_ID_IMAGES);
279        foreach ($images['paquet']['logo'] as $taille => $im) {
280                if (is_array($im)) { // evitons une fatale erreur (mais ca ne devrait pas arriver !)
281                        unset($images['paquet']['logo'][$taille]['fichier']);
282                }
283        }
284        foreach ($images['objets'] as $c => $objet) {
285                if (isset($objet['logo']) and is_array($objet['logo'])) {
286                        foreach ($objet['logo'] as $taille => $im) {
287                                if (is_array($im)) { // evitons une fatale erreur (mais ca ne devrait pas arriver !)
288                                        unset($images['objets'][$c]['logo'][$taille]['fichier']);
289                                }
290                        }
291                }
292        }
293        // on nettoie les saisies checkbox de vue_liens qui peuvent ne rien envoyer
294        // on nettoie une eventuelle table ayant servi a pre-remplir l'objet
295        foreach ($data['objets'] as $c => $o) {
296                if (!isset($o['vue_liens']) OR !is_array($o['vue_liens'])) {
297                        $o['vue_liens'] = array();
298                }
299                unset($data['objets'][$c]['renseigner_avec_table']);
300        }
301
302
303        // cas particulier data (+images) pour l'export.
304        fabriquer_fichier("fabrique_prefixe.php", array_merge($data, array('data'=>array_merge($data, array('images' => $images)))));
305        fabrique_sauvegarde_tournante_export($destination_plugin . "fabrique_$prefixe.php", $destination_backup);
306
307        // pour tous les autres, on ajoute des informations dans notre tableau de données
308        $data = fabrique_completer_contexte_images($data); // liste des fichiers images presents (pour paquet.xml)
309        $data = fabrique_completer_contexte($data); // raccourcis
310
311        // definir les fichiers indispensables au paquet.xml / plugin :
312        // si des fichiers sont indispensables aux objets
313        // a cause des options d'un objet, on les ajoute a ceux deja demandes
314        $fichiers = fabrique_fichiers_paquets($data);
315
316        // creer le paquet.xml
317        // en declarant tous les fichiers necessaires
318        $fichiers_coches = isset($data['paquet']['fichiers']) ? $data['paquet']['fichiers'] : array();
319        $data['paquet']['fichiers'] = $fichiers;
320        fabriquer_fichier("paquet.xml", $data);
321        // on remet ce qu'avait saisi l'utilisateur
322        $data['paquet']['fichiers'] = $fichiers_coches;
323
324        // creer la langue du paquet.
325        fabriquer_fichier("lang/paquet-prefixe_fr.php", $data);
326
327        // creer la langue du plugin
328        fabriquer_fichier("lang/prefixe_fr.php", $data);
329
330        // creer le formulaire de configuration
331        if ($paquet['formulaire_config']) {
332                // creer le squelette d'appel du formulaire
333                fabriquer_fichier("prive/squelettes/contenu/configurer_prefixe.html", $data);
334
335                // creer le formulaire de config (simple, type CFG avec un champ d'exemple)
336                fabriquer_fichier("formulaires/configurer_prefixe.html", $data);
337        }
338
339        // creer le fichier d'administrations
340        if ($paquet['administrations'] or count($data['objets'])) {
341                fabriquer_fichier("prefixe_administrations.php", $data);
342        }
343
344
345        // creer le fichier d'options, de fonctions, autorisations et de pipelines
346        foreach($fichiers as $fichier) {
347                fabriquer_fichier("prefixe_$fichier.php", $data);
348        }
349
350
351        // gerer plus specifiquement les objets
352        if (count($data['objets'])) {
353
354                // creer le fichier de declaration de tables SQL
355                fabriquer_fichier("base/prefixe.php", $data);
356
357                // pour chaque objet
358                foreach ($data['objets'] as $c => $objet) {
359
360                        // des raccourcis de plus pour les squelettes specifiques aux objets
361                        $data['objet']       = $objet;
362                        $data['id_objet']    = $objet['id_objet'];
363                        $data['type']        = $objet['type'];
364                        $data['table']       = $objet['table'];
365                        $data['mobjet']      = $objet['mobjet']; // m = majuscule
366                        $data['lobjet']      = $objet['objet'];  // l = lower, minuscule, car on ne peut pas utiliser 'objet'
367                        $data['mtype']       = $objet['mtype'];  // m = majuscule
368                        $data['mid_objet']   = $objet['mid_objet']; // m = majuscule
369                        $data['parent']      = $objet['parent'];
370
371                        // creer les langues
372                        fabriquer_fichier("lang/objet_fr.php", $data);
373
374                        // créer le formulaire d'edition
375                        fabriquer_fichier("formulaires/editer_objet.html", $data);
376                        fabriquer_fichier("formulaires/editer_objet.php", $data);
377
378                        // créer la vue du contenu d'un objet
379                        fabriquer_fichier("prive/objets/contenu/objet.html", $data);
380
381                        // créer la liste d'un objet
382                        fabriquer_fichier("prive/objets/liste/objets.html", $data);
383
384                        // appel du formulaire d'édition, si liens ou parenté directe autre que rubrique
385                        if (option_presente($objet, 'vue_liens') or option_presente($objet, 'liaison_directe')) {
386                                fabriquer_fichier("prive/squelettes/contenu/objet_edit.html", $data);
387                        }
388
389                        // si parenté autre que rubrique, créer des squelettes de hiérarchie
390                        if (option_presente($objet, 'liaison_directe')) {
391                                fabriquer_fichier("prive/squelettes/hierarchie/objet.html", $data);
392                                fabriquer_fichier("prive/squelettes/hierarchie/objet_edit.html", $data);
393                        }
394
395                        // s'il a des enfants connus ici, créer le fichier d'info pour avoir le nombre d'enfants affichés
396                        if (fabrique_objets_enfants_directs($objet, $objets)) {
397                                fabriquer_fichier("prive/objets/infos/objet.html", $data);
398                        }
399
400                        // créer les listes de liaison
401                        if (option_presente($objet, 'vue_liens')) {
402                                fabriquer_fichier("prive/objets/liste/objets_lies.html", $data);
403                                fabriquer_fichier("prive/objets/liste/objets_lies_fonctions.php", $data); // pff
404                                fabriquer_fichier("prive/objets/liste/objets_associer.html", $data);
405                                fabriquer_fichier("prive/objets/liste/objets_associer_fonctions.php", $data); // pff
406
407                                // la meme chose avec des roles s'il y en a
408                                if (option_presente($objet, 'roles')) {
409                                        fabriquer_fichier("prive/objets/liste/objets_roles_lies.html", $data);
410                                        fabriquer_fichier("prive/objets/liste/objets_roles_lies_fonctions.php", $data); // pff
411                                        fabriquer_fichier("prive/objets/liste/objets_roles_associer.html", $data);
412                                        fabriquer_fichier("prive/objets/liste/objets_roles_associer_fonctions.php", $data); // pff
413                                }
414
415                                // lister aussi les liaisons sur la vue de cet objet
416                                if (option_presente($objet, 'afficher_liens')) {
417                                        fabriquer_fichier("prive/objets/liste/\objets_lies_objet.html", $data);
418                                        fabriquer_fichier("prive/squelettes/contenu/objet.html", $data); // fichier habituellement échafaudé
419                                }
420                        }
421
422                        // si traductions demandees, creer le fichier de pre-chargement
423                        if (champ_present($objet, 'id_trad')) {
424                                fabriquer_fichier("inc/precharger_objet.php", $data);
425                        }
426
427                        // si inclusion dans plan du site
428                        if (champ_present($objet, 'id_rubrique') and option_presente($objet, 'plan')) {
429                                fabriquer_fichier("prive/squelettes/inclure/plan-objets.html", $data);
430                        }
431
432                        // fichiers demandés explicitement (échafaudés normalement par SPIP ou autres spécifiques)
433                        if (isset($objet['fichiers']) AND is_array($objet['fichiers'])) {
434                                foreach ($objet['fichiers'] as $type => $fichiers) {
435                                        // type : echafaudages | explicites
436                                        if (is_array($fichiers)) {
437                                                foreach ($fichiers as $fichier) {
438                                                        fabriquer_fichier($fichier, $data);
439                                                }
440                                        }
441                                }
442                        }
443
444                        // saisies demandees
445                        if (isset($objet['saisies']) and is_array($objet['saisies'])) {
446                                foreach ($objet['saisies'] as $saisie) {
447                                        fabriquer_fichier('saisies/' . $saisie . '.html', $data);
448                                        fabriquer_fichier('saisies-vues/' . $saisie . '.html', $data);
449                                        // si parentee presente, saisie propose un mode recursif
450                                        if (champ_present($objet, 'id_parent')) {
451                                                fabriquer_fichier('saisies/_' . $saisie . '_recurs.html', $data);
452                                        }
453                                }
454                        }
455
456                        // Si l'on n'a pas de statut pour cet objet, proposer un bouton de suppression et l'action correspondante.
457                        if (!champ_present($objet, 'statut')) {
458                                fabriquer_fichier("action/supprimer_objet.php", $data);
459                                // être certain d'avoir ce fichier (échafaudé)
460                                fabriquer_fichier("prive/objets/infos/objet.html", $data);
461                        }
462
463                }
464
465                unset($data['objet'],  $data['id_objet'], $data['type'],  $data['table']);
466                unset($data['mobjet'], $data['lobjet'],   $data['mtype'], $data['mid_objet']);
467        }
468
469        // creer les images
470        // logo du plugin
471        $images = session_get(FABRIQUE_ID_IMAGES);
472        if ($i = $images['paquet']['logo'][0]['fichier']) {
473                fabriquer_miniature($prefixe, $i, $prefixe, 128);
474                fabriquer_miniature($prefixe, $i, $prefixe, 64);
475                fabriquer_miniature($prefixe, $i, $prefixe, 32);
476        }
477        // logos des objets
478        foreach ($images['objets'] as $c => $image) {
479                $obj = $data['objets'][$c]['type'];
480                $i_precedent = '';
481                // on prend en priorite la taille desiree,
482                // sinon la plus proche, avant,
483                // sinon le logo de l'objet, sinon le logo du plugin.
484                foreach (array(32, 24, 16, 12) as $taille) {
485                        if ((isset($image['logo'][$taille]) AND $i = $image['logo'][$taille]['fichier'])
486                        OR ($i = $i_precedent)
487                        OR (isset($image['logo'][0]['fichier']) and $i = $image['logo'][0]['fichier'])
488                        OR (isset($images['paquet']['logo'][0]['fichier']) and $i = $images['paquet']['logo'][0]['fichier'])) {
489                                $i_precedent = $i; // privilegier l'image juste plus grande que la precedente
490                                fabriquer_miniature($prefixe, $i, $obj, $taille);
491                                if ($data['objets'][$c]['logo_variantes'] && $taille >= 16) {
492                                        fabriquer_miniature($prefixe, $i, $obj, $taille, 'new');
493                                        fabriquer_miniature($prefixe, $i, $obj, $taille, 'add');
494                                        fabriquer_miniature($prefixe, $i, $obj, $taille, 'del');
495                                        fabriquer_miniature($prefixe, $i, $obj, $taille, 'edit');
496                                } elseif ($taille == 16) {
497                                        // creer la variante 16+ qui sert a la barre outils_rapides
498                                        fabriquer_miniature($prefixe, $i, $obj, $taille, 'new');
499                                }
500                        }
501                }
502        }
503
504        // executer des actions si demandees
505        fabrique_executer_script('post_creation', $data, $contexte_scripts);
506
507
508        // supprimer tous les fichiers .ok des sous-répertoires de destination
509        $fichiers =
510                new RegexIterator(
511                new RecursiveIteratorIterator(
512                new RecursiveDirectoryIterator($destination . $prefixe)), '/[.]ok$/');
513        foreach ($fichiers as $f) {
514                supprimer_fichier((string)$f);
515        }
516        // activer un plugin peut creer un .ok a la racine de celui ci (avec skeleditor actif !).
517        supprimer_fichier($destination_ancien_plugin . '.ok');
518
519
520        // calcul du diff avec l'ancien plugin
521        fabrique_generer_diff($destination_ancien_plugin, $destination_plugin, $prefixe);
522
523        // ne pas prendre les champs postes
524        // ils sont sauves en session php
525        set_request('objets', null);
526        set_request('paquet', null);
527
528        // enlever les erreurs de plugin qui ont pu arriver
529        // si l'on recree un plugin actif dans fabrique_auto.
530        include_spip('inc/plugin');
531        actualise_plugins_actifs();
532
533        // indiquer qu'on peut creer le repertoire dans plugins.
534        if (!is_writable(_DIR_PLUGINS . rtrim(FABRIQUE_DESTINATION_PLUGINS, '/'))) {
535                set_request("message_info", _T('fabrique:repertoire_plugin_fabrique', array(
536                        'dir' => rtrim(FABRIQUE_DESTINATION_PLUGINS, '/'),
537                        'dir_cache' => rtrim(FABRIQUE_DESTINATION_CACHE, '/'))));
538        }
539
540        $res = array(
541                'editable'=>'oui',
542                'message_ok' => _T('fabrique:plugin_cree_succes_dans', array('dir'=>$destination_plugin))
543        );
544        return $res;
545}
546
547
548/**
549 * Cherche un fichier dans la fabrique,
550 * le calcule et le copie dans le répertoire du futur plugin
551 *
552 * @param string $chemin
553 *     Chemin du fichier (depuis la racine du répertoire de fabrique)
554 * @param array $data
555 *     Environnement du calcul
556**/
557function fabriquer_fichier($chemin, $data) {
558        static $reps = array(); // repertoire de destination deja crees.
559        static $chemins = array(); // fichiers sources deja utilises
560        // retrouver la destination de copie des fichiers
561        $destination = fabrique_destination();
562        $destination .= $data['paquet']['prefixe'] . '/';
563
564        // on retrouve le nom du fichier et la base du chemin de destination
565        $dest = explode('/', $chemin);
566        $chemin = str_replace("\o", "o", $chemin); // enlever l'échappement \objet
567        $nom = array_pop($dest);
568        $chemin_dest = implode('/', $dest);
569
570        // ne pas creer systematiquement les repertoires tout de meme.
571        if (!isset($reps[$chemin_dest])) {
572                sous_repertoire_complet($destination . $chemin_dest);
573                $reps[$chemin_dest] = true;
574        }
575
576        // on modifie le nom de destination :
577        // 'prefixe' => $prefixe.
578        // 'objet'   => $objet.
579        // mais on conserve si '\objets'
580        $nom = str_replace("\o", "\1o\\", $nom);
581        $nom = str_replace('prefixe', $data['paquet']['prefixe'], $nom);
582        if (isset($data['objet'])) {
583                $nom = str_replace('objets',  $data['objet']['lobjet'], $nom);
584                $nom = str_replace('objet',   $data['objet']['type'], $nom);
585        }
586        $nom = str_replace("\1o\\", "o", $nom);
587
588        // calcul du squelette et copie a destination du contenu.
589        $contenu = recuperer_fond(FABRIQUE_SKEL_SOURCE . $chemin, $data);
590        // Enlever les espaces de fins de ligne et toujours finir un fichier avec un saut de ligne
591        $contenu = str_replace(", \n", ",\n", str_replace("\n \n", "\n\n", str_replace("} \n", "}\n", str_replace("; \n", ";\n", $contenu))))."\n";
592
593        ecrire_fichier($destination . $chemin_dest . '/' . $nom, $contenu);
594}
595
596
597
598/**
599 * Réduit une image dont l'adresse est donnée,
600 * et la place dans prive/themes/spip/images du futur plugin
601 *
602 * @param string $prefixe
603 *     Préfixe du plugin
604 * @param string $src
605 *     Source de l'image
606 * @param string $nom
607 *     Nom du fichier d'image
608 * @param int $taille
609 *     Taille de l'image en pixels
610 * @param string $variante
611 *     Variante tel que `del`, `edit`, `new`, `add`
612**/
613function fabriquer_miniature($prefixe, $src, $nom, $taille=128, $variante='') {
614        // retrouver la destination de copie des fichiers
615        $destination = fabrique_destination();
616        $destination .= $prefixe . '/';
617        // creer une fois l'arborescence de destination
618        static $chemin = false;
619        if (!$chemin) {
620                $chemin = "prive/themes/spip/images";
621                sous_repertoire_complet($destination . $chemin);
622        }
623
624        include_spip('inc/filtres_images');
625        // passer en png
626        $img = filtrer('image_format', $src, 'png');
627        // reduire et graver
628        $img = filtrer('image_passe_partout', $img, $taille, $taille);
629        if ($variante and $img_variante = find_in_path("prive/themes/spip/images/$variante-$taille.png")) {
630                $img = filtrer('image_masque', $img, $img_variante, 'mode=normal');
631        }
632        $img = filtrer('image_graver', $img);
633        $src_img = extraire_attribut($img, 'src');
634        // pas de ?date pour recuperer le contenu
635        $src_img = explode('?', $src_img);
636        $src_img = array_shift($src_img);
637        $contenu = spip_file_get_contents($src_img);
638        if ($contenu) {
639                $nom = $nom . ($variante ? "-$variante" : ''). "-$taille.png";
640                ecrire_fichier($destination . "$chemin/$nom", $contenu);
641        }
642}
643
644
645/**
646 * Complète la description du paquet des fichiers indispensables
647 * pour les objets demandés
648 *
649 * @param array $data
650 *     Informations sur le plugin à construire
651 * @return array
652 *     Liste des fichiers indispensables au plugin (et ceux qui étaient déjà demandés)
653**/
654function fabrique_fichiers_paquets($data) {
655        $fichiers = array();
656        if (isset($data['paquet']['fichiers']) AND is_array($data['paquet']['fichiers'])) {
657                $fichiers = $data['paquet']['fichiers'];
658        }
659
660        // si tout est coche deja, on sort !
661        if (count($fichiers) == 4) {
662                return $fichiers;
663        }
664
665        if (!in_array('pipelines', $fichiers)) {
666                if (fabrique_necessite_pipeline($data['objets'], 'optimiser_base_disparus')
667                OR  fabrique_necessite_pipeline($data['objets'], 'affiche_enfants')
668                OR  fabrique_necessite_pipeline($data['objets'], 'affiche_auteurs_interventions')
669                OR  fabrique_necessite_pipeline($data['objets'], 'affiche_milieu')) {
670                        $fichiers[] = 'pipelines';
671                }
672        }
673
674        if (!in_array('autorisations', $fichiers)) {
675                if (fabrique_necessite_pipeline($data['objets'], 'autoriser')) {
676                        $fichiers[] = 'autorisations';
677                }
678        }
679
680        return $fichiers;
681}
682
683
684/**
685 * Remet les infos de contexte dans l'environnement
686 *
687 * Certaines infos sont remises dans l'environnement
688 * - parce qu'on en ajoute par rapport à ce qui est posté -
689 * afin de réafficher correctement le formulaire si on a des erreurs
690 * dans la partie traiter(), car dans ce cas, le formulaire ne repasse pas dans le charger().
691 *
692 * @param array $data
693 *     Les infos postées
694**/
695function fabrique_remettre_contexte($data) {
696        // on reintroduit le contexte complet, parce que l'erreur ne repasse pas dans charger() dans ce cas.
697        $data = fabrique_completer_contexte_images($data); // liste des fichiers images presents (pour paquet.xml)
698        $data = fabrique_completer_contexte($data); // raccourcis
699        foreach($data as $nom => $valeur) {
700                set_request($nom, $valeur);
701        }
702}
703
704
705/**
706 * Complète les données connues avec des données qui servent souvent
707 *
708 * Ceci pour se simplifier (un peu) les squelettes, et éviter de multiples calculs
709 * (type, table, id_objet, objet...)
710 *
711 * @param array $data
712 *     Les infos du plugin à construire connues
713 * @return array
714 *     Les mêmes infos complétées
715**/
716function fabrique_completer_contexte($data) {
717        $data['prefixe']  = $data['paquet']['prefixe'];
718        $data['mprefixe'] = strtoupper($data['paquet']['prefixe']); // m = majuscule
719        $data['exemples'] = $data['paquet']['exemples'];
720        if (!is_array($data['objets'])) $data['objets'] = array();
721        $data['les_objets'] = $data['les_types'] = $data['les_id_objets'] = array();
722        foreach( $data['objets'] as $c => $o ) {
723                // quelques raccourcis
724                if (isset($o['table']) and $o['table']) {
725                        $data['objets'][$c]['objets_surnoms'] = array();
726
727                        // si la table est different de spip_xxs
728                        // ou si elle possede des espaces spip_xx_yys
729                        // on indique qu'il faudra creer
730                        // des surnoms car ce n'est pas un nommage standard.
731                        // on s'appuie sur la table pour calculer l'objet (pluriel en general)
732                        $preparation_objet = preg_replace(',^spip_|^id_|s$,', '', $o['table']);
733                        // table avec espace
734                        if (false !== strpos($preparation_objet, '_')) {
735                                // on prend en surnom d'objet le type sans son espace
736                                $data['objets'][$c]['objets_surnoms'][] = str_replace('_', '', $preparation_objet); // xxyy = xx_yy
737                        }
738                        // table non standard sans s
739                        if (rtrim($o['table'], 's') == $o['table']) {
740                                // la table n'est pas standard.
741                                $data['objets'][$c]['objets_surnoms'][] = $o['table_type']; // xx
742                                $data['les_objets'][] = $data['objets'][$c]['objet'] = $preparation_objet;
743                        }
744                        // table standard avec s
745                        else {
746                                $data['les_objets'][] = $data['objets'][$c]['objet'] = table_objet($o['table']);
747                        }
748                        $data['les_types'][]     = $data['objets'][$c]['type']     = $o['table_type'];
749                        $data['les_id_objets'][] = $data['objets'][$c]['id_objet'] = $o['cle_primaire'];
750                        // l'objet en majuscule
751                        $data['objets'][$c]['mobjet']     = strtoupper($data['objets'][$c]['objet']);
752                        $data['objets'][$c]['mtype']      = strtoupper($data['objets'][$c]['type']);
753                        $data['objets'][$c]['mid_objet']  = strtoupper($data['objets'][$c]['id_objet']);
754                        // l'objet en minuscule
755                        $data['objets'][$c]['lobjet'] = $data['objets'][$c]['objet']; // etre coherent avec l'appel de squelettes specifiques a un objet
756                        // la table de liens
757                        if ($o['table_liens']) {
758                                $data['objets'][$c]['nom_table_liens'] = $o['table'] . '_liens';
759                        }
760                }
761                // mettre les majuscules sur les champs aussi dans mchamp
762                if (isset($o['champs']) and is_array($o['champs'])) {
763                        foreach ($o['champs'] as $j => $champ) {
764                                if (isset($champ['champ'])) {
765                                         $data['objets'][$c]['champs'][$j]['mchamp'] = strtoupper($champ['champ']);
766                                }
767                        }
768                }
769        }
770        // indiquer les parentés
771        foreach($data['objets'] as $c => $o) {
772                $data['objets'][$c]['parent'] = fabrique_parent($o, $data['objets']);
773        }
774        // fabrique_lister_tables() apres avoir ajoute les infos en plus sur les objets
775        // pour pouvoir les utiliser dedans.
776        $data['les_tables']        = fabrique_lister_tables($data['objets']);
777        $data['les_tables_objets'] = fabrique_lister_tables($data['objets'], 'objets');
778        $data['les_tables_liens']  = fabrique_lister_tables($data['objets'], 'liens');
779        return $data;
780}
781
782
783
784/**
785 * Complète les données connues avec les noms des fichiers d'images
786 *
787 * @param array $data
788 *     Les infos du plugin à construire connues
789 * @return array
790 *     Les mêmes infos complétées
791**/
792function fabrique_completer_contexte_images($data) {
793
794        // gestion des images
795        // en dehors des donnees postees
796        // pour ne pas surcharger le formulaire
797        // et poster à chaque fois les images.
798        $images = array(
799                'paquet' => array(
800                        'logo' => array(
801                                0 => array(
802                                        'fichier' => '',
803                                        'extension' => '',
804                                        'contenu' => '',
805                                )
806                        )
807                ),
808                'objets' => array()
809        );
810
811        // On initialise la session image si elle est vide
812        if (is_null($fabrique_images = session_get(FABRIQUE_ID_IMAGES)) OR !is_array($fabrique_images)){
813                session_set(FABRIQUE_ID_IMAGES, $images);
814                $fabrique_images = array();
815        }
816
817        // On merge avec ce que l'on a dans la session
818        foreach ($images as $c=>$v) {
819                if (isset($fabrique_images[$c])) {
820                        $images[$c] = array_merge($images[$c], $fabrique_images[$c]);
821                }
822        }
823
824        // on ajoute la localisation de l'image dans le contexte si presente
825        // logo de plugin
826        if (isset($images['paquet']['logo'][0]['fichier']) and $f = $images['paquet']['logo'][0]['fichier']) {
827                $data['paquet']['logo'][0]['fichier'] = $f;
828        }
829        // logo des objets
830        foreach ($images['objets'] as $c=>$image) {
831                foreach (array(0, 32, 24, 16, 12) as $taille) {
832                        if (isset($image['logo'][$taille]['fichier']) and $f = $image['logo'][$taille]['fichier']) {
833                                $data['objets'][$c]['logo'][$taille]['fichier'] = $f;
834                        }
835                }
836        }
837
838        return $data;
839}
840
841
842/**
843 * Complète les informations d'un objet
844 * en fonction de la table SQL qui a été demandé.
845 *
846 * On essaie d'extraire de la table le plus d'info possibles.
847 *
848 * @param array $objet
849 *     Description connue de l'objet éditorial désiré
850 * @return array $objet
851 *     Description éventuellement complétée si une table SQL source était renseignée
852**/
853function fabrique_renseigner_objet($objet) {
854        $table = $objet['renseigner_avec_table'];
855        if (!$table) {
856                return $objet;
857        }
858
859        // 'spip_articles' ou
860        // 'autreconnect:spip_articles'
861        list($connect, $table) = array_pad(explode(':', $table), 2, null);
862        if (!$table) {
863                $table = $connect;
864                $connect = '';
865        }
866
867        // extraire le prefixe si present, pour remettre spip_
868        $desc = sql_showtable($table, false, $connect); // avant l'utiliation de la globale connexions.
869        $connexion = $GLOBALS['connexions'][$connect ? $connect : 0];
870        if ($prefixe = $connexion['prefixe']) {
871                $table_spip = preg_replace("/^$prefixe/", 'spip', $table);
872        } else {
873                $table_spip = $table;
874        }
875
876        // prefixer systematiquement de spip_ la table
877        if (substr($table_spip,0,5) !== 'spip_') {
878                $table_spip = 'spip_' . $table_spip;
879        }
880
881        // definir la table et le nom.
882        $objet['table'] = $table_spip;
883        $objet['nom'] = ucfirst(str_replace('_', ' ', substr($table_spip, 5)));
884        $objet['nom_singulier'] = rtrim($objet['nom'], 's');
885
886        // analyser les champs
887        $fields = $desc['field'];
888
889        // id_rubrique
890        if (isset($fields['id_rubrique'])) {
891                if (!isset($objet['rubriques'])) {
892                        $objet['rubriques'] = array();
893                }
894                if (!in_array('id_rubrique', $objet['rubriques'])) {
895                        $objet['rubriques'][] = 'id_rubrique';
896                }
897                unset($fields['id_rubrique']);
898
899                // & id_secteur ?
900                if (!in_array('id_secteur', $objet['rubriques'])) {
901                        $objet['rubriques'][] = 'id_secteur';
902                }
903                unset($fields['id_secteur']);
904        }
905
906        // lang
907        if (isset($fields['lang'])) {
908                if (!isset($objet['langues'])) {
909                        $objet['langues'] = array();
910                }
911                if (!in_array('lang', $objet['langues'])) {
912                        $objet['langues'][] = 'lang';
913                }
914                unset($fields['lang'], $fields['langue_choisie']);
915        }
916
917        // id_trad
918        if (isset($fields['id_trad'])) {
919                if (!isset($objet['langues'])) {
920                        $objet['langues'] = array();
921                }
922                if (!in_array('id_trad', $objet['langues'])) {
923                        $objet['langues'][] = 'id_trad';
924                }
925                // il faut absolument lang pour id_trad !
926                if (!in_array('lang', $objet['langues'])) {
927                        $objet['langues'][] = 'lang';
928                }
929                unset($fields['id_trad']);
930        }
931
932
933        // on enleve la cle primaire (elle sera automatiquement ajoutée)
934        $pk = $desc['key']['PRIMARY KEY'];
935        unset($fields[$pk]);
936        $objet['cle_primaire'] = $pk;
937
938        // on enleve 'maj' (il sera automatiquement ajouté)
939        unset($fields['maj']);
940
941        // 'statut'
942        if (isset($fields['statut'])) {
943                unset($fields['statut']);
944                $objet['statut'] = 'on';
945        }
946
947        // champ titre
948        foreach (array('titre', 'nom') as $titre) {
949                if (isset($fields[$titre])) {
950                        $objet['champ_titre'] = $titre;
951                        break;
952                }
953        }
954
955        // champ date
956        foreach (array('date', 'date_publication') as $date) {
957                if (isset($fields[$date])) {
958                        $objet['champ_date'] = $date;
959                        // ce champ sera automatiquement ajouté
960                        unset($fields[$date]);
961                        break;
962                }
963        }
964
965        // pour tous les autres. Il faut les créer.
966        $champs = isset($objet['champs']) ? $objet['champs'] : array();
967
968        // on enleve tous les champs qui ne sont pas de cette table
969        foreach ($champs as $c => $champ) {
970                if (!isset($fields[$champ['champ']])) {
971                        unset($champs[$c]);
972                }
973        }
974        $champs = array_values($champs);
975
976        // on ajoute (ou modifie) tous les champs de cette table
977        foreach ($fields as $colonne => $sql) {
978                // on n'ajoute pas un champ qui existe deja
979                // on le modifie simplement
980                $present = false;
981                foreach ($champs as $c => $champ) {
982                        if ($champ['champ'] == $colonne) {
983                                $present = true;
984                                break;
985                        }
986                }
987                if (!$present) {
988                        $champs[] = array();
989                        $c = count($champs)-1;
990                }
991
992                $champs[$c]['champ'] = $colonne;
993                $champs[$c]['nom']   = ucfirst(str_replace('_', ' ', $colonne));
994                $champs[$c]['sql']   = $sql;
995        }
996        $objet['champs'] = $champs;
997
998        // On enleve les chaines de langue
999        unset($objet['chaines']);
1000
1001        return $objet;
1002}
Note: See TracBrowser for help on using the repository browser.