source: spip-zone/_plugins_/step/inc/step_actionneur.php @ 34526

Last change on this file since 34526 was 34526, checked in by marcimat@…, 10 years ago
  • Mieux gérer l'installation en la faisant au hit suivant
  • Mieux gérer les cas tordus à l'activation d'un plugin : charger systématiquement le fichier cache des fonctions de plugin charger_fonction.php pour éviter de charger le nouveau fichier contenant les nouvelles fonctions qui dépendent peut-être de fonctions déclarées dans le fichier d'option du plugin (qui n'est pas chargé à ce stade - vu que charger_options.php ne connaissait pas encore ce plugin au moment de son appel)
File size: 20.4 KB
Line 
1<?php
2
3// l'actionneur calcule l'ordre des actions
4// et permet de les stocker et de les effectuer.
5
6class Actionneur {
7
8        var $decideur;
9
10        // loggue t'on ?
11        var $log = false;
12
13        // actions au debut (avant analyse)
14        var $start = array();
15
16        // actions en cours d'analyse
17        var $middle = array(
18                'off' => array(),
19                'lib' => array(),
20                'on' => array(),
21                'neutre' => array(),
22        );
23
24        // actions a la fin (apres analyse, et dans l'ordre)
25        var $end = array();  // a faire...
26        var $done = array(); // faites
27        var $work = array(); // en cours
28
29        function Actionneur(){
30                include_spip('inc/step_decideur');
31                $this->decideur = new Decideur();
32                $this->decideur->start();
33        }
34
35
36        function log($quoi) {
37                if ($this->log) {
38                        spip_log($quoi,'actionneur');
39                }
40        }
41
42        function clear() {
43                $this->middle = array(
44                        'off' => array(),
45                        'lib' => array(),
46                        'on' => array(),
47                        'neutre' => array(),
48                );
49                $this->end = array();
50                $this->done = array();
51                $this->work = array();
52        }
53
54        function ajouter_actions($todo) {
55                foreach ($todo as $id => $action) {
56                        $this->start[$id] = $action;
57                }
58                $this->ordonner_actions();
59        }
60
61
62        // ajouter une librairie a installer.
63        function add_lib($nom, $source) {
64                if (!$this->decideur->est_presente_lib($nom)) {
65                        if (is_writable(_DIR_LIB)) {
66                                $this->middle['lib'][$nom] = array(
67                                        'todo'=>'lib',
68                                        'n'=>$nom,
69                                        'p'=>$nom,
70                                        'v'=>$source,
71                                        's'=>$source,
72                                );
73                        } else {
74                                // erreur : impossible d'ecrire dans _DIR_LIB !
75                                // TODO : message et retour d'erreur a gerer...
76                                return false;
77                        }
78                }
79                return true;
80        }
81
82
83        function ordonner_actions() {
84                // il faut deja definir quels sont des
85                // actions graduellement realisables.
86                // Pour tout ce qui est a installer : ordre des dependances
87                // Pour tout ce qui est a desinstaller : ordre inverse des dependances.
88
89                // on commence par separer
90                // - ce qui est a desinstaller.
91                // - ce qui est a installe
92                // - les actions neutres (get, up sur non actif, kill)
93
94                // on commencera par faire ce qui est a desinstaller
95                // (il est possible que certains plugins necessitent la desinstallation
96                //  d'autres present - tel que : 1 seul service d'envoi de mail)
97                // puis ce qui est a installer
98                // puis les actions neutres
99                $this->clear();
100
101                foreach ($this->start as $id=>$action) {
102                        $i = $this->decideur->infos_courtes_id($id);
103                        $i = $i['i'][$id];
104                        switch ($action) {
105                                case 'on':
106                                        $this->on($i, $action);
107                                        break;
108                                case 'up':
109                                        if ($i['a'] == 'oui') {
110                                                $this->on($i, $action);
111                                        } else {
112                                                $this->neutre($i, $action);
113                                        }
114                                        break;
115                                case 'upon':
116                                        $this->on($i, $action);
117                                        break;
118                                case 'off':
119                                case 'stop':
120                                        $this->off($i, $action);
121                                        break;
122                                case 'get':
123                                case 'kill':
124                                        $this->neutre($i, $action);
125                                        break;
126                        }
127                }
128
129                // c'est termine, on passe tout dans la fin...
130                foreach ($this->middle as $acts) {
131                        $this->end = array_merge($this->end, $acts);
132                }
133                #$this->log($this->middle);
134        }
135
136
137        // a chaque fois qu'une action arrive,
138        // on compare avec celles deja presentes
139        // pour savoir si on doit la traiter avant ou apres
140
141        function on($info, $action) {
142                $info['todo'] = $action;
143                $p = $info['p'];
144                $this->log("ON: $p $action");
145
146                // si dependance, il faut le mettre avant !
147                $in = $out = array();
148                // raz des cles pour avoir les memes que $out (utile reellement ?)
149                $this->middle['on'] = array_values($this->middle['on']);
150                // ajout des dependance et des librairies si besion
151                foreach ($info['dn'] as $dep) {
152                        if ($dep['id'] != 'SPIP') {
153                                if (strpos($dep['id'],'lib:')===0) {
154                                        if ($lib = substr($dep['id'], 4)) {
155                                                // il faudrait gerer un retour d'erreur eventuel !
156                                                $this->add_lib($lib, $dep['src']);
157                                        }
158                                } else {
159                                        $in[]  = $dep['id'];
160                                }
161                        }
162                }
163                foreach ($this->middle['on'] as $inf)   {$out[] = $inf['p'];}
164
165                if (!$in) {
166                        // pas de dependance, on le met en premier !
167                        $this->log("- placer $p tout en haut");
168                        array_unshift($this->middle['on'], $info);
169                } else {
170                        // intersection = dependance presente aussi
171                        // on place notre action juste apres la derniere dependance
172                        if ($diff = array_intersect($in, $out)) {
173                                $key = array();
174                                foreach($diff as $d) {$key[] = array_search($d, $out);}
175                                $key = max($key);
176                                $this->log("- placer $p apres " . $this->middle['on'][$key]['p']);
177                                if ($key == count($this->middle['on'])) {
178                                        $this->middle['on'][] = $info;
179                                } else {
180                                        array_splice($this->middle['on'], $key+1, 0, array($info));
181                                }
182                        } else {
183                                $this->log("- placer $p tout en bas");
184                                $this->middle['on'][] = $info;
185                        }
186                }
187                unset($diff, $in, $out);
188        }
189
190
191
192        function neutre($info, $action) {
193                $info['todo'] = $action;
194                $this->log("NEUTRE:  $info[p] $action");
195                $this->middle['neutre'][] = $info;
196        }
197
198
199        function off($info, $action) {
200                $info['todo'] = $action;
201                $p = $info['p'];
202                $this->log("OFF: $p $action");
203
204                // si dependance, il faut le mettre avant !
205                $in = $out = array();
206                // raz des cles pour avoir les memes que $out (utile reellement ?)
207                $this->middle['off'] = array_values($this->middle['off']);
208                foreach ($info['dn'] as $dep)                   {
209                        if (($dep['id'] != 'SPIP') and (strpos($dep['id'],'lib:')!==0)) {
210                                $in[]  = $dep['id'];
211                        }
212                }
213                foreach ($this->middle['off'] as $inf)  {$out[] = $inf['p'];}
214
215                if (!$in) {
216                        // pas de dependance, on le met en dernier !
217                                $this->log("- placer $p tout en bas");
218                                $this->middle['off'][] = $info;
219                } else {
220                        // intersection = dependance presente aussi
221                        // on place notre action juste avant la premiere dependance
222                        if ($diff = array_intersect($in, $out)) {
223                                $key = array();
224                                foreach($diff as $d) {$key[] = array_search($d, $out);}
225                                $key = min($key);
226                                $this->log("- placer $p avant " . $this->middle['off'][$key]['p']);
227                                array_splice($this->middle['off'], $key, 0, array($info));
228                        } else {
229                                // pas de dependance, on le met en premier !
230                                $this->log("- placer $p tout en haut");
231                                array_unshift($this->middle['on'], $info);
232                        }
233                }
234                unset($diff, $in, $out);
235        }
236
237
238
239
240        function presenter_actions() {
241                $affiche = "";
242                if ($this->end or $this->done) {
243                        $affiche .= "<ul>";
244                        foreach ($this->done as $i) {
245                                $affiche .= "\t<li>$i[todo] de «" . typo($i['n']) . "» ($i[v])". ($i['done'] ? " <span class='done_ok'>[ok]</span>" : " <span class='done_err'>[fail]</span>") . "</li>\n";
246                        }
247                        foreach ($this->end as $i) {
248                                $affiche .= "\t<li>$i[todo] de «" . typo($i['n']) . "» ($i[v])</li>\n";
249                        }
250                        $affiche .= "</ul>\n";
251                }
252                return $affiche;
253        }
254
255
256        function sauver_actions() {
257                $contenu = serialize(array(
258                        'todo' => $this->end,
259                        'done' => $this->done,
260                        'work' => $this->work,
261                ));
262                ecrire_fichier(_DIR_TMP . 'step_actions.txt', $contenu);
263        }
264
265
266        function get_actions() {
267                lire_fichier(_DIR_TMP . 'step_actions.txt', $contenu);
268                $infos = unserialize($contenu);
269                $this->end  = $infos['todo'];
270                $this->work = $infos['work'];
271                $this->done = $infos['done'];
272        }
273
274
275        function one_action() {
276                if (count($this->end)) {
277                        $action = $this->work = array_shift($this->end);
278                        $this->sauver_actions();
279                        $this->do_action();
280                        return $action;
281                }
282                return false;
283        }
284
285        function do_action() {
286                if ($do = $this->work) {
287                        $todo = 'do_' . $do['todo'];
288                        lire_metas(); // avoir les metas a jour
289                        $do['done'] = $this->$todo($do);
290                        $this->done[] = $do;
291                        $this->work = array();
292                        $this->sauver_actions();
293                }
294        }
295
296
297        // activer un plugin
298        // soit il est la... soit il est a telecharger...
299        function do_on($info) {
300                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
301                if ($i['id_zone'] > 0) {
302                        // a telecharger et activer
303                        if ($dirs = $this->get_paquet_id($i)) {
304                                $this->activer_plugin_dossier($dirs['dossier'], $i, '_DIR_PLUGINS');
305                                return true;
306                        }
307                } else {
308                        // a activer uniquement
309                        // il faudra prendre en compte les autres _DIR_xx
310                        if ($i['constante'] == '_DIR_PLUGINS') {
311                                $dossier = rtrim($i['dossier'],'/');
312                                $this->activer_plugin_dossier($dossier, $i);
313                                return true;
314                        }
315                }
316                return false;
317        }
318
319
320
321        // mettre a jour un plugin
322        function do_up($info) {
323                // ecriture du nouveau
324                // suppression de l'ancien (si dans auto, et pas au meme endroit)
325                // OU suppression des anciens fichiers
326                if (!defined('_DIR_PLUGINS_AUTO') or !_DIR_PLUGINS_AUTO or !is_writable(_DIR_PLUGINS_AUTO)) {
327                        $this->log("Pas de _DIR_PLUGINS_AUTO defini !");
328                        return false;
329                }
330
331                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
332
333                // on cherche la mise a jour...
334                if ($maj = sql_fetsel('*','spip_plugins',array(
335                        'prefixe='.sql_quote($info['p']),
336                        'version='.sql_quote($info['maj']),
337                        'superieur='.sql_quote('oui')))) {
338                                if ($dirs = $this->get_paquet_id($maj)) {
339                                        // Si le plugin a jour n'est pas dans le meme dossier que l'ancien...
340                                        // il faut :
341                                        // - activer le plugin sur son nouvel emplacement (uniquement si l'ancien est actif)...
342                                        // - supprimer l'ancien (si faisable)
343                                        if (($dirs['dossier'] . '/') != $i['dossier']) {
344                                                if ($i['actif'] == 'oui') {
345                                                        $this->activer_plugin_dossier($dirs['dossier'], $maj);
346                                                }
347
348                                                if (substr($i['dossier'],0,5) == 'auto/') {
349                                                        if ($this->deleteDirectory($dirs['dir'])) {
350                                                                sql_delete('spip_plugins', 'id_plugin=' . sql_quote($info['i']));
351                                                        }
352                                                }
353                                        }
354
355                                        $this->ajouter_plugin_interessants_meta($dirs['dossier']);
356                                        return $dirs;
357                                }
358                }
359                return false;
360        }
361
362
363        // mettre a jour et activer un plugin
364        function do_upon($info) {
365                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
366                if ($dirs = $this->do_up($info)) {
367                        $this->activer_plugin_dossier($dirs['dossier'], $i, '_DIR_PLUGINS');
368                        return true;
369                }
370                return false;
371        }
372
373
374        // desactiver un plugin
375        function do_off($info) {
376                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
377                // il faudra prendre en compte les autres _DIR_xx
378                if ($i['constante'] == '_DIR_PLUGINS') {
379                        include_spip('inc/plugin');
380                        ecrire_plugin_actifs(array(rtrim($i['dossier'],'/')), false, 'enleve');
381                        sql_updateq('spip_plugins', array('actif'=>'non', 'installe'=>'non'), 'id_plugin='.sql_quote($info['i']));
382                        $this->actualiser_plugin_interessants();
383                        // ce retour est un rien faux...
384                        // il faudrait que la fonction ecrire_plugin_actifs()
385                        // retourne au moins d'eventuels message d'erreur !
386                        return true;
387                }
388                return false;
389        }
390
391
392        // desinstaller un plugin
393        function do_stop($info) {
394                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
395                // il faudra prendre en compte les autres _DIR_xx
396                if ($i['constante'] == '_DIR_PLUGINS') {
397                        include_spip('inc/plugin');
398                        $dossier = rtrim($i['dossier'],'/');
399                        $infos = plugin_get_infos($dossier);
400                        if (isset($infos['install'])){
401                                // desinstaller
402                                $etat = desinstalle_un_plugin($dossier, $infos);
403
404                                // desactiver si il a bien ete desinstalle
405                                if (!$etat) {
406                                        ecrire_plugin_actifs(array($dossier), false, 'enleve');
407                                        sql_updateq('spip_plugins', array('actif'=>'non', 'installe'=>'non'), 'id_plugin='.sql_quote($info['i']));
408                                        return true;
409                                }
410                                // echec de la desinstallation
411                        }
412                        // pas de desinstallation possible !
413                }
414                $this->actualiser_plugin_interessants();
415                return false;
416        }
417
418
419        // effacer les fichiers d'un plugin
420        function do_kill($info) {
421                // on reverifie que c'est bien un plugin auto !
422                // il faudrait aussi faire tres attention sur un site mutualise
423                // cette option est encore plus delicate que les autres...
424                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
425
426                if ($i['constante'] == '_DIR_PLUGINS'
427                and substr($i['dossier'],0,5) == 'auto/') {
428                        $dir = constant($i['constante']) . $i['dossier'];
429                        if ($this->deleteDirectory($dir)) {
430                                sql_delete('spip_plugins', 'id_plugin=' . sql_quote($info['i']));
431                                return true;
432                        }
433                }
434
435                return false;
436        }
437
438
439        // installer une librairie
440        function do_lib($info) {
441                if (!defined('_DIR_LIB') or !_DIR_LIB or !is_writable(_DIR_LIB)) {
442                        $this->log("Pas de _DIR_LIB defini !");
443                        return false;
444                }
445
446                $zip = $info['s'];
447                if ($files = $this->get_zip($zip, _DIR_LIB)) {
448                        $dest = $files[0]['stored_filename'];
449                        $dest = rtrim($dest, '/');
450                        $dir = _DIR_LIB . $dest;
451
452                        $this->log("Suppression des anciens fichiers de $dir");
453                        $this->remove_older_files($dir, $files);
454
455                        return true;
456                }
457
458                return false;
459        }
460
461
462        // telecharger un plugin
463        function do_get($info) {
464                if (!defined('_DIR_PLUGINS_AUTO') or !_DIR_PLUGINS_AUTO or !is_writable(_DIR_PLUGINS_AUTO)) {
465                        $this->log("Pas de _DIR_PLUGINS_AUTO defini !");
466                        return false;
467                }
468
469                $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($info['i']));
470                if ($i['paquet']) {
471                        if ($adresse = sql_getfetsel('adresse','spip_zones_plugins','id_zone='.sql_quote($i['id_zone']))) {
472                                $adresse = dirname($adresse);
473                                $zip = $adresse . '/' . $i['paquet'];
474                                if ($files = $this->get_zip($zip, _DIR_PLUGINS_AUTO)) {
475                                        $dest = $files[0]['stored_filename'];
476                                        // rendre obsolete ce paquet distant
477                                        // (ca le fera tout seul au moment d'actualiser les paquets locaux)
478                                        // trouver le nouveau paquet et le mettre dans les interessants...
479                                        $dest = 'auto/' . rtrim($dest, '/');
480                                        $this->ajouter_plugin_interessants_meta($dest);
481                                        // c'est la ou _DIR_PLUGINS_AUTO
482                                        // ne sert pas a grand chose... a ameliorer
483                                        return true;
484                                }
485                        }
486                }
487
488                return false;
489        }
490
491
492
493        // lancer l'installation d'un plugin
494        function do_install($info) {
495                include_spip('inc/plugin');
496                $dossier = $info['dossier'];
497                $this->installe_plugin($dossier);
498                return true;
499        }
500
501
502        // adresse du dossier, et row SQL du plugin en question
503        function activer_plugin_dossier($dossier, $i, $constante="") {
504                include_spip('inc/plugin');
505
506                //il faut absolument que tous les fichiers de cache
507                // soient inclus avant modification, sinon un appel ulterieur risquerait
508                // de charger des fichiers deja charges par un autre !
509                // C'est surtout le ficher de fonction le probleme (options et pipelines
510                // sont normalement deja charges).
511                if (@is_readable(_CACHE_PLUGINS_OPT)) {include_once(_CACHE_PLUGINS_OPT);}
512                if (@is_readable(_CACHE_PLUGINS_FCT)) {include_once(_CACHE_PLUGINS_FCT);}
513                if (@is_readable(_CACHE_PIPELINES))   {include_once(_CACHE_PIPELINES);}
514
515                ecrire_plugin_actifs(array($dossier), false, 'ajoute');
516                $installe = $i['version_base'] ? 'oui' : 'non';
517                if ($installe == 'oui') {
518                        // installer le plugin au prochain tour
519                        $new_action = array_merge($this->work, array(
520                                'todo'=>'install',
521                                'dossier'=>$dossier,
522                        ));
523                        array_unshift($this->end, $new_action);
524                        #$this->installe_plugin($dossier);
525                }
526
527                $this->ajouter_plugin_interessants_meta($dossier);
528                $this->actualiser_plugin_interessants();
529        }
530
531
532        // actualiser les plugins interessants
533        function actualiser_plugin_interessants() {
534                // Chaque fois que l'on valide des plugins,
535                // on memorise la liste de ces plugins comme etant "interessants",
536                // avec un score initial, qui sera decremente a chaque tour :
537                // ainsi un plugin active pourra reter visible a l'ecran,
538                // jusqu'a ce qu'il tombe dans l'oubli.
539                $plugins_interessants = @unserialize($GLOBALS['meta']['plugins_interessants']);
540                if (!is_array($plugins_interessants)) {
541                        $plugins_interessants = array();
542                }
543                $dossiers = array();
544                foreach($plugins_interessants as $p => $score) {
545                        if (--$score > 0) {
546                                $plugins_interessants[$p] = $score;
547                                $dossiers[$p.'/'] = true;
548                        } else {
549                                unset($plugins_interessants[$p]);
550                                // ATTENTION, il faudra prendre en compte les _DIR_xx
551                                sql_updateq('spip_plugins',array('recent'=>0),'dossier='.sql_quote($p));
552                        }
553                }
554
555                $plugs = sql_select('dossier','spip_plugins','actif='.sql_quote('oui'));
556
557                while ($plug = sql_fetch($plugs)) {
558                        $dossiers[$plug['dossier']] = true;
559                        $plugins_interessants[ rtrim($plug['dossier'],'/') ] = 30; // score initial
560                }
561
562                $plugs = sql_updateq('spip_plugins', array('recent'=>1), sql_in('dossier', array_keys($dossiers)));
563                ecrire_meta('plugins_interessants', serialize($plugins_interessants));
564        }
565
566
567
568        function ajouter_plugin_interessants_meta($dir) {
569                $plugins_interessants = @unserialize($GLOBALS['meta']['plugins_interessants']);
570                if (!is_array($plugins_interessants)) {
571                        $plugins_interessants = array();
572                }
573                $plugins_interessants[$dir] = 30;
574                ecrire_meta('plugins_interessants', serialize($plugins_interessants));
575        }
576
577
578        function installe_plugin($dossier){
579                $infos = plugin_get_infos($dossier);
580                if (isset($infos['install'])) {
581                        if (installe_un_plugin($dossier, $infos)) {
582                                $meta_plug_installes = @unserialize($GLOBALS['meta']['plugin_installes']);
583                                if (!$meta_plug_installes) $meta_plug_installes=array();
584                                $meta_plug_installes[] = $dossier;
585                                ecrire_meta('plugin_installes',serialize($meta_plug_installes), 'non');
586                                return true;
587                        }
588                }
589                return false;
590        }
591
592
593
594        // serait mieux dans inc/flock...
595        // necessite PHP 5
596        // vient de http://www.php.net/manual/en/function.rmdir.php#92050
597        function deleteDirectory($dir) {
598                if (!file_exists($dir)) return true;
599                if (!is_dir($dir) || is_link($dir)) return unlink($dir);
600                foreach (scandir($dir) as $item) {
601                        if ($item == '.' || $item == '..') continue;
602                        if (!$this->deleteDirectory($dir . "/" . $item)) {
603                                chmod($dir . "/" . $item, 0777);
604                                if (!$this->deleteDirectory($dir . "/" . $item)) return false;
605                        };
606                }
607                return rmdir($dir);
608        }
609
610
611        // telecharge un paquet
612        // et supprime les fichiers obsoletes (si presents)
613        function get_paquet_id($id_or_row) {
614                // on peut passer direct le row sql...
615                if (!is_array($id_or_row)) {
616                        $i = sql_fetsel('*','spip_plugins','id_plugin='.sql_quote($id_or_row));
617                } else {
618                        $i = $id_or_row;
619                }
620                unset($id_or_row);
621
622                if ($i['paquet']) {
623                        if ($adresse = sql_getfetsel('adresse','spip_zones_plugins','id_zone='.sql_quote($i['id_zone']))) {
624                                $adresse = dirname($adresse);
625                                $zip = $adresse . '/' . $i['paquet'];
626                                // on recupere la mise a jour...
627                                if ($files = $this->get_zip($zip, _DIR_PLUGINS_AUTO)) {
628                                        $dest = $files[0]['stored_filename'];
629                                        $dest = 'auto/' . rtrim($dest, '/');
630                                        $dir = _DIR_PLUGINS . $dest;
631
632                                        // la c'est ennuyant : il faut supprimer les vieux fichiers...
633                                        $this->log("Suppression des anciens fichiers de $dir");
634                                        $this->remove_older_files($dir, $files);
635
636                                        return array(
637                                                'dir'=>$dir,
638                                                'dossier'=>$dest,
639                                        );
640                                }
641                        }
642                }
643                return false;
644        }
645
646
647        function get_zip($zip, $dir_dest) {
648
649                # si premiere lecture, destination temporaire des fichiers
650                $tmp = sous_repertoire(_DIR_CACHE, 'chargeur');
651
652                # $extract = sous_repertoire($tmp, 'extract');
653                $extract = $dir_dest;
654
655                $fichier = $tmp . basename($zip);
656                include_spip('inc/distant');
657                $contenu = recuperer_page($zip, $fichier, false, _COPIE_LOCALE_MAX_SIZE);
658                if (!$contenu) {
659                        $this->log('Impossible de charger : '. $zip);
660                        return false;
661                }
662
663                include_spip('inc/pclzip');
664                $uzip = new PclZip($fichier);
665
666                // On extrait, mais dans tmp/
667                $ok = $uzip->extract(
668                        PCLZIP_OPT_PATH,
669                        $extract,
670                        PCLZIP_OPT_SET_CHMOD,
671                        _SPIP_CHMOD,
672                        PCLZIP_OPT_REPLACE_NEWER
673                );
674
675                if ($uzip->error_code < 0) {
676                        $this->log('Impossible de decompresser : '. $zip);
677                        $this->log('> erreur '. $uzip->error_code .' : ' . $uzip->errorName(true));
678                        return false;
679                }
680
681                # spip_log($ok, 'ok');
682                # spip_log($uzip->listContent(), 'ok');
683                // ok contient toute la liste des fichiers installes :)
684                // ainsi que leur localisation et quelques infos.
685                // [0] est le nom du premier repertoire
686                /*
687                          0 =>
688                          array (
689                                'filename' => '../plugins/auto/aa/',
690                                'stored_filename' => 'aa/',
691                                'size' => 0,
692                                'compressed_size' => 0,
693                                'mtime' => 1262386900,
694                                'comment' => '',
695                                'folder' => true,
696                                'index' => 0,
697                                'status' => 'ok',
698                          ),
699                */
700                return $ok;
701        }
702
703
704        function remove_older_files($dir, $files = array()) {
705                static $ok = false;
706                if ($ok === false) {
707                        $ok = array();
708                        foreach ($files as $f) {
709                                $ok[$f['filename']] = true;
710                        }
711                }
712
713                if (!file_exists($dir)) return true;
714                if (!is_dir($dir) || is_link($dir)) {
715                        if (!isset($ok[$dir])) {
716                                $this->log('- supp :' . $dir);
717                                unlink($dir);
718                        }
719                        return true;
720                }
721
722                $dir = rtrim($dir, '/');
723                foreach (scandir($dir) as $item) {
724                        if ($item == '.' || $item == '..') continue;
725                        $this->remove_older_files($dir . "/" . $item);
726                }
727
728                return true;
729        }
730
731}
732
733
734
735// scandir pour php4
736// http://fr2.php.net/manual/fr/function.scandir.php#73062
737if (!function_exists('scandir')) {
738function scandir($dir, $listDirectories=false, $skipDots=true) {
739    $dirArray = array();
740    if ($handle = opendir($dir)) {
741        while (false !== ($file = readdir($handle))) {
742            if (($file != "." && $file != "..") || $skipDots == true) {
743                if($listDirectories == false) { if(is_dir($file)) { continue; } }
744                array_push($dirArray,basename($file));
745            }
746        }
747        closedir($handle);
748    }
749    return $dirArray;
750}
751}
752
753?>
Note: See TracBrowser for help on using the repository browser.