source: spip-zone/_plugins_/fabrique/trunk/inc/futilitaire.php @ 115409

Last change on this file since 115409 was 88209, checked in by marcimat@…, 6 years ago

Pas de fermetures de PHP dans la fabrique, ni dans les fichiers php générés par la fabrique.

File size: 10.2 KB
Line 
1<?php
2
3/**
4 * Ce fichier contient des fonctions utiles pour
5 * lancer des actions effectués après la création du plugin
6 * dans le script "post_creation" de la Fabrique
7 *
8 * Ces fonctions sont encapsulées dans une classe "Futilitaire"
9 *
10 * @note
11 *     /!\   Partie experimentale.   /!\
12 *     Cette API est susceptible d'évoluer.
13 *
14 * @package SPIP\Fabrique\Futilitaire
15**/
16
17/** Fichier de log des actions. */
18define('_FABRIQUE_LOG_SCRIPTS', 'fabrique_scripts');
19
20
21/**
22 * Encapsule les fonctions d'aides
23 *
24 * @example
25 *     ```
26 *     $futil = new Futilitaire($data, $destination_plugin, $destination_ancien_plugin);
27 *     ```
28**/
29Class Futilitaire {
30        /**
31         * Chemin de l'ancien plugin
32         *
33         * Celui que l'on recrée et que l'on a copié en sauvegarde avant
34         *
35         * @var string
36         */
37        public $dir_backup = "";
38       
39        /**
40         * Chemin de destination de notre plugin
41         * @var string
42         */
43        public $dir_dest = "";
44
45        /**
46         * Information complète des saisies du formulaire de création de la fabrique
47         * complétee de quelques raccourcis
48         * @var array
49         */
50        public $data = array();
51
52        /**
53         * @var Futilitaire_Lignes[] Stockage des modifications de lignes à réaliser
54         */
55        public $lignes = array();
56
57        /**
58         * Le constructeur charge les infos utiles :
59         *
60         * - le tableau $data contenant les saisies utilisateurs
61         * - le lieu de destination du plugin
62         * - le lieu de sauvegarde de la precedente creation du plugin
63         *   (qui contient donc peut etre des informations/fichiers que l'on veut recuperer)
64         *
65         * @param array $data
66         *     Information complète des saisies du formulaire de création de la fabrique
67         *     complétee de quelques raccourcis
68         * @param string $dir_dest
69         *     Chemin de destination de notre plugin
70         * @param string $dir_backup
71         *     Chemin de l'ancien plugin (celui que l'on recrée et que l'on a copié en sauvegarde avant)
72        **/
73        public function __construct($data, $dir_dest, $dir_backup) {
74                $this->data = $data;
75                $this->dir_dest = $dir_dest;
76                $this->dir_backup = $dir_backup;
77        }
78
79        /**
80         * Log une erreur
81         *
82         * @param string $texte
83         *     Le texte à logguer.
84        **/
85        public function log($texte = '') {
86                spip_log($texte, _FABRIQUE_LOG_SCRIPTS);
87        }
88
89
90        /**
91         * Déplacer une liste de fichiers du backup vers le nouveau plugin
92         * et créer les repertoires manquants si besoin dans le nouveau plugin.
93         *
94         * @example
95         *     ```
96         *     $futil->deplacer_fichiers(array(
97         *        'base/importer_spip_villes.php',
98         *        'base/importer_spip_villes_donnees.gz',
99         *     ));
100         *     ```
101         *
102         * @param string|array $fichiers
103         *     Liste des fichiers à déplacer
104        **/
105        public function deplacer_fichiers($fichiers) {
106                static $dirs = array();
107
108                if (!$fichiers OR !$this->dir_dest OR !$this->dir_backup) {
109                        $this->log("deplacer_fichiers: Info manquante");
110                        return;
111                }
112
113                if (!is_array($fichiers)) {
114                        $fichiers = array($fichiers);
115                }
116
117                foreach ($fichiers as $f) {
118                        if (!$f) {
119                                $this->log("deplacer_fichiers: Fichier vide");
120                                continue;
121                        }
122                        $source = $this->dir_backup . $f;
123                        $dest   = $this->dir_dest   . $f;
124                        if (!file_exists($source)){
125                                $this->log("deplacer_fichiers: Fichier $f introuvable dans le backup : $dest");
126                                continue;
127                        }
128
129                        // cree l'arborescence depuis le chemin
130                        $this->creer_arborescence_destination($f);
131
132                        if (!copy($source, $dest)) {
133                                $this->log("deplacer_fichiers: Copie ratee de $source vers $dest");
134                        }
135                }
136        }
137
138        /**
139         * Déplacer une liste de dossiers/répertoires
140         * du backup vers le nouveau plugin
141         * et créer les repertoires manquants si besoin dans le nouveau plugin.
142         *
143         * @example
144         *     ```
145         *     $futil->deplacer_dossiers('lib');
146         *     $futil->deplacer_dossiers(array('lib','actions'));
147         *     ```
148         *
149         * @param string|array $dossiers
150         *     Liste des fichiers a déplacer
151        **/
152        public function deplacer_dossiers($dossiers) {
153                static $dirs = array();
154
155                if (!$dossiers OR !$this->dir_dest OR !$this->dir_backup) {
156                        $this->log("deplacer_dossiers: Info manquante");
157                        return;
158                }
159
160                if (!is_array($dossiers)) {
161                        $dossiers = array($dossiers);
162                }
163
164                foreach ($dossiers as $d) {
165                        if (!$d) {
166                                $this->log("deplacer_dossiers: Dossier vide");
167                                continue;
168                        }
169                        $source = $this->dir_backup . $d;
170                        $dest   = $this->dir_dest   . $d;
171                        if (!is_dir($source)){
172                                $this->log("deplacer_dossiers: Dossier $d introuvable dans le backup : $dest");
173                                continue;
174                        }
175
176                        // cree l'arborescence depuis le chemin
177                        $this->creer_arborescence_destination($d, false);
178
179                        // copie recursive
180                        // http://stackoverflow.com/a/7775949
181                        foreach ($iterator =
182                                        new RecursiveIteratorIterator(
183                                                new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
184                                                        RecursiveIteratorIterator::SELF_FIRST) as $item
185                                ) {
186                                if ($item->isDir()) {
187                                        if (!mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) {
188                                                $this->log("deplacer_dossiers: Creation ratee de " . $iterator->getSubPathName());
189                                        }
190                                } else {
191                                        if (!copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName())) {
192                                                $this->log("deplacer_dossiers: Creation ratee de " . $iterator->getSubPathName());
193                                        }
194                                }
195                        }
196                }
197        }
198
199
200
201        /**
202         * Crée les répertoires manquants dans le plugin crée
203         * par rapport au chemin désiré
204         *
205         * @example
206         *     ```
207         *     $this->creer_arborescence_destination("inclure/config.php");
208         *     ```
209         *
210         * @param string $chemin
211         *      Destination depuis la racine du plugin
212         * @param bool $is_file
213         *      Est-ce un fichier (true) ou un répertoire (false) ?
214         * @return bool
215         *     Est-ce que c'est bien crée ?
216        **/
217        public function creer_arborescence_destination($chemin, $is_file = true) {
218                // repertoire de destination deja crees.
219                static $reps = array();
220
221                if (!$this->dir_dest) {
222                        $this->log("creer_chemin: Destination inconnue");
223                        return false;
224                }
225
226                // si c'est un fichier,
227                // on retrouve le nom du fichier et la base du chemin de destination
228                if ($is_file) {
229                        $dest = explode('/', $chemin);
230                        $nom = array_pop($dest);
231                        $chemin_dest = implode('/', $dest);
232                } else {
233                        $chemin_dest = $chemin;
234                }
235
236                // ne pas creer systematiquement les repertoires tout de meme.
237                if (!isset($reps[$chemin_dest])) {
238                        sous_repertoire_complet($this->dir_dest . $chemin_dest);
239                        $reps[$chemin_dest] = true;
240                }
241
242                return true;
243        }
244
245
246        /**
247         * Insère du code dans un fichier indiqué
248         *
249         * @example
250         *     ```
251         *     $futil->ajouter_lignes('lang/geoniche_fr.php', -3, 0, fabrique_tabulations($lignes, 1));
252         *     ```
253         *
254         * @param string $chemin
255         *     Chemin du fichier depuis la racine du plugin
256         * @param int $debut
257         *      Ligne du départ de l'insertion
258         *      Peut être négatif : -3 indique 3 lignes avant la fin de fichier
259         * @param int $fin
260         *      Indique combien de lignes seront supprimées du fichier à partir du début choisi
261         *      0 (zero) pour conserver tout le code existant dans le fichier
262         * @param string $code
263         *      Le code à insérer.
264         * @return bool
265         *      Operation reussie ou pas.
266        **/
267        public function ajouter_lignes($chemin, $debut, $fin, $code) {
268
269                if (!$this->dir_dest) {
270                        $this->log("ajouter_lignes: Destination inconnue");
271                        return false;
272                }
273
274                $dest = $this->dir_dest . $chemin;
275                if (!file_exists($dest)) {
276                        $this->log("ajouter_lignes: Fichier inexistant $dest");
277                        return false;
278                }
279
280                lire_fichier($dest, $contenu);
281                if (is_null($contenu)) {
282                        $this->log("ajouter_lignes: Lecture echouee de $dest");
283                        return false;
284                }
285
286                $contenu = explode("\n", $contenu);
287                $code = explode("\n", $code);
288                array_splice($contenu, $debut, $fin, $code);
289                $contenu = implode("\n", $contenu);
290                ecrire_fichier($dest, $contenu);
291        }
292
293        /**
294         * Facilitateur d'écriture
295         *
296         * Crée une nouvelle ligne, la stocke et retourne l'objet crée pour modifications
297         *
298         * @example
299         *     ```
300         *     $futil->inserer($chemin, $debut, $fin, $tabulation)->contenu = X;
301         *     $futil->inserer($chemin, $debut, $fin, $tabulation)->contenu = <<<EOT
302         *     contenu
303         *     EOT;
304         *
305         *     $futil->appliquer_lignes();
306         *     ```
307         *
308         * @param string $chemin
309         *     Chemin du fichier à traiter
310         * @param int $debut
311         *     Numero de la ligne à modifier
312         * @param int $fin
313         *     Nombre de lignes supprimées
314         * @param int $tabulation
315         *     Ajout de n caractères de tabulations en début de chaque ligne
316         * @param string $contenu
317         *     Contenu à insérer
318         * @return Futilitaire_Ligne
319         *     Retourne l'objet créé, ce qui permet de le modifier, tout en gardant
320         *     ici au passage ce qui a été modifié.
321        **/
322        public function inserer($chemin, $debut, $fin=0, $tabulation=0, $contenu="") {
323                return $this->lignes[] = new Futilitaire_Lignes($chemin, $debut, $fin, $tabulation, $contenu);
324        }
325
326        /**
327         * Applique les modifications de lignes qui ont été définies avec `set_lignes()`
328        **/
329        public function appliquer_lignes() {
330                // insertion des parties
331                foreach ($this->lignes as $ligne) {
332                        $this->ajouter_lignes(
333                                $ligne->fichier,
334                                $ligne->numero,
335                                $ligne->remplace,
336                                fabrique_tabulations($ligne->contenu, $ligne->tabulation));
337                }
338                // ces lignes ont été prises en compte !
339                $this->lignes = array();
340        }
341}
342
343
344/**
345 * Espace de rangement d'information pour la modification de contenu d'un fichier
346 *
347**/
348class Futilitaire_Lignes {
349
350        /**
351         * Contenu à insérer
352         * @var string */
353        public $contenu = "";
354        /**
355         * Chemin du fichier à traiter
356         * @var string */
357        public $fichier = "";
358        /**
359         * Numero de la ligne à modifier
360         * @var int */
361        public $numero  = 0;
362        /**
363         * Nombre de lignes supprimées
364         * @var int */
365        public $remplace = 0;
366        /**
367         * Ajout de n caractères de tabulations en début de chaque ligne
368         * @var int */
369        public $tabulation = 0;
370
371        /**
372         * Constructeur
373         *
374         * Définit toutes les propriétés
375         *
376         * @param string $fichier
377         *     Chemin du fichier à traiter
378         * @param int $numero
379         *     Numero de la ligne à modifier
380         * @param int $remplace
381         *     Nombre de lignes supprimées
382         * @param int $tabulation
383         *     Ajout de n caractères de tabulations en début de chaque ligne
384         * @param string $contenu
385         *     Contenu à insérer
386         */
387        public function __construct($fichier, $numero, $remplace=0, $tabulation=0, $contenu="") {
388                $this->fichier    = $fichier;
389                $this->numero     = $numero;
390                $this->remplace   = $remplace;
391                $this->tabulation = $tabulation;
392                $this->contenu    = $contenu;
393        }
394}
Note: See TracBrowser for help on using the repository browser.