source: spip-zone/_outils_/spip_loader/trunk/spip_loader.php

Last change on this file was 111806, checked in by jack@…, 3 months ago

La version et le commentaire avaient sauté

File size: 38.1 KB
Line 
1<?php
2/**
3 * SPIP Loader recupere et installe SPIP
4 *
5 * Configuration
6 * -------------
7 * Pour les mises a jour effectuees avec ce script,
8 * toutes les constantes ci-dessous peuvent etre surchargees
9 * dans config/mes_options.php
10 */
11
12if (file_exists('spip_loader_config.php')) {
13  include_once('spip_loader_config.php');
14}
15/**
16 * Auteur(s) autorise(s) a proceder aux mises a jour : '1:2:3'
17 *
18 * @note En tete, sinon defini trop tard !
19 */
20if (!defined('_SPIP_LOADER_UPDATE_AUTEURS')) {
21        define('_SPIP_LOADER_UPDATE_AUTEURS', '1');
22}
23
24/**
25 * Branche installee par defaut.
26 *
27 * Au choix parmi la liste des branches déclarées ('dev', '3.2', '3.1', ...)
28 * @see lister_branches_proposees()
29 */
30if (!defined('_DEFAUT_BRANCHE_MAJ')) {
31        define('_DEFAUT_BRANCHE_MAJ', '3.2');
32}
33
34/**
35 * Liste des branches possibles
36 * (avec l’adresse du zip et la version minimale de PHP)
37 *
38 * @param string|null $branche
39 *     Pour retourner l’info d’une branche spécifique
40 * @return array|false
41 *     Descriptif des branches, ou d’une seule branche
42 */
43function lister_branches_proposees($branche = null) {
44        $branches = array(
45                'dev' => array(
46                        'zip' => 'spip/dev/SPIP-svn.zip',
47                        'php' => '5.4.0',
48                ),
49                '3.2' => array(
50                        'zip' => 'spip/stable/spip-3.2.zip',
51                        'php' => '5.4.0',
52                ),
53                '3.1' => array(
54                        'zip' => 'spip/stable/spip-3.1.zip',
55                        'php' => '5.1.0',
56                ),
57                '3.0' => array(
58                        'zip' => 'spip/stable/spip-3.0.zip',
59                        'php' => '5.1.0',
60                ),
61                '2.1' => array(
62                        'zip' => 'spip/stable/spip-2.1.zip',
63                        'php' => '4.0.8',
64                ),
65        );
66
67        if (!is_null($branche)) {
68                return isset($branches[$branche]) ? $branches[$branche] : false;
69        }
70        return $branches;
71}
72
73/**
74 * Version de SPIP Loader
75 *
76 * Historique
77 * ----------
78 * - 2.1    : introduction du parametre d'URL chemin
79 * - 2.2    : introduction du parametre d'URL dest
80 * - 2.3    : introduction du parametre d'URL range
81 * - 2.4    : redirection par meta refresh au lieu de header Location
82 * - 2.5    : affichage de la version à installer, de la version déjà installée (si elle existe),
83 * -          compatibilite PHP, loader obsolete
84 * - 2.5.10 : on télécharge maintenant SPIP 3.2
85 * - 2.5.11 : coquille empechant des mises à jour
86 * - 2.6.0  : déclaration simplifiée des branches / zips + sélecteur de branche
87 * - 3.0.0  : le SPIP loader analyse et déplace les fichiers obsolètes dans un répertoire 'fichiers_obsoletes_{date}'
88 *            pour les répertoires appartenant à SPIP (ecrire, prive, plugins-dist, squelettes-dist).
89 *            /!\ si vous avez ajouté des plugins dans plugins-dist, ils seront aussi déplacés !!
90 * - 3.0.1  : le sélecteur choisit par défaut la branche actuel du SPIP déjà installé, s’il la connait.
91 * - 3.0.2  : Un répertoire obsolète n’est pas déplacé s’il contient un fichier '.spip_loader_keep'
92 * - 3.0.3  : Isoler les define dans une fichier de configuration dédié spip_loader.php
93 *            spip_loader peut se mettre à jour
94 * - 3.0.4  : Correction d’une URL.
95 * - 3.0.5  : Création des dossiers plugins/auto et lib
96 */
97define('_SPIP_LOADER_VERSION', '3.0.5');
98
99
100
101/**
102 * Notre branche de destination par défaut
103 *
104 * - ignoré si la constante _CHEMIN_FICHIER_ZIP est forcée
105 * - ignoré si un SPIP est déjà installé (tentera de rester sur la même branche par défaut)
106 */
107$notre_branche = lister_branches_proposees(_DEFAUT_BRANCHE_MAJ);
108if (!$notre_branche) {
109        die("Mauvaise définition de la constante _DEFAUT_BRANCHE_MAJ. <code>Branche " . _DEFAUT_BRANCHE_MAJ . " inconnue</code>");
110}
111
112
113if (!defined('_CHEMIN_FICHIER_ZIP')) {
114        /**
115         * Chemin du zip installé par défaut
116         *
117         * Si la constante _CHEMIN_FICHIER_ZIP est déjà définie,
118         * alors le zip défini sera utilisé.
119         *
120         * Sinon, on prend par défaut le zip de la branche installée par défaut.
121         */
122        define('_CHEMIN_FICHIER_ZIP', $notre_branche['zip']);
123} else {
124        // éviter d’afficher le sélecteur de branche dans ces cas là.
125        define('_CHEMIN_FICHIER_ZIP_FORCEE', true);
126}
127
128
129# repertoires d'installation
130if (!defined('_DIR_BASE')) {
131        define('_DIR_BASE', './');
132}
133if (!defined('_DIR_PLUGINS')) {
134        define('_DIR_PLUGINS', _DIR_BASE . 'plugins/');
135}
136
137# adresse du depot
138if (!defined('_URL_SPIP_DEPOT')) {
139        define('_URL_SPIP_DEPOT', 'https://files.spip.net/');
140}
141
142
143# Adresse des librairies necessaires a spip_loader
144# (pclzip et fichiers de langue)
145if (!defined('_URL_LOADER_DL')) {
146        define('_URL_LOADER_DL', 'https://www.spip.net/spip-dev/INSTALL/');
147}
148# telecharger a travers un proxy
149if (!defined('_URL_LOADER_PROXY')) {
150        define('_URL_LOADER_PROXY', '');
151}
152
153# surcharger le script
154if (!defined('_NOM_PAQUET_ZIP')) {
155        define('_NOM_PAQUET_ZIP', 'spip');
156}
157// par defaut le morceau de path a enlever est le nom : spip
158if (!defined('_REMOVE_PATH_ZIP')) {
159        define('_REMOVE_PATH_ZIP', _NOM_PAQUET_ZIP);
160}
161
162if (!defined('_SPIP_LOADER_PLUGIN_RETOUR')) {
163        define('_SPIP_LOADER_PLUGIN_RETOUR', 'ecrire/?exec=admin_plugin&voir=tous');
164}
165if (!defined('_SPIP_LOADER_SCRIPT')) {
166        define('_SPIP_LOADER_SCRIPT', 'spip_loader.php');
167}
168
169// "habillage" optionnel
170// liste separee par virgules de fichiers inclus dans spip_loader
171// charges a la racine comme spip_loader.php et pclzip.php
172// selon l'extension: include .php , .css et .js dans le <head> genere par spip_loader
173if (!defined('_SPIP_LOADER_EXTRA')) {
174        define('_SPIP_LOADER_EXTRA', '');
175}
176
177
178if (!defined('_DEST_PAQUET_ZIP')) {
179        define('_DEST_PAQUET_ZIP', '');
180}
181if (!defined('_PCL_ZIP_SIZE')) {
182        define('_PCL_ZIP_SIZE', 249587);
183}
184if (!defined('_PCL_ZIP_RANGE')) {
185        define('_PCL_ZIP_RANGE', 200);
186}
187/**
188 * Le SPIP Loader ne place pas dans le répertoire obsolète
189 * un répertoire qui contiendrait un fichier avec ce nom.
190 */
191if (!defined('_SPIP_LOADER_KEEP')) {
192        define('_SPIP_LOADER_KEEP', '.spip_loader_keep');
193}
194
195
196#######################################################################
197
198# langues disponibles
199$langues = array (
200        'ar' => "&#1593;&#1585;&#1576;&#1610;",
201        'ast' => "asturianu",
202        'br' => "brezhoneg",
203        'ca' => "catal&#224;",
204        'cs' => "&#269;e&#353;tina",
205        'de' => "Deutsch",
206        'en' => "English",
207        'eo' => "Esperanto",
208        'es' => "Espa&#241;ol",
209        'eu' => "euskara",
210        'fa' => "&#1601;&#1575;&#1585;&#1587;&#1609;",
211        'fr' => "fran&#231;ais",
212        'fr_tu' => "fran&#231;ais copain",
213        'gl' => "galego",
214        'hr' => "hrvatski",
215        'id' => "Indonesia",
216        'it' => "italiano",
217        'km' => "Cambodian",
218        'lb' => "L&euml;tzebuergesch",
219        'nap' => "napulitano",
220        'nl' => "Nederlands",
221        'oc_lnc' => "&ograve;c lengadocian",
222        'oc_ni' => "&ograve;c ni&ccedil;ard",
223        'pt_br' => "Portugu&#234;s do Brasil",
224        'ro' => "rom&#226;n&#259;",
225        'sk' => "sloven&#269;ina",      // (Slovakia)
226        'sv' => "svenska",
227        'tr' => "T&#252;rk&#231;e",
228        'wa' => "walon",
229        'zh_tw' => "&#21488;&#28771;&#20013;&#25991;", // chinois taiwan (ecr. traditionnelle)
230);
231
232// Url du fichier archivelist permettant de créer les zips de spip
233if (!defined('_URL_ARCHIVELIST')) {
234        define('_URL_ARCHIVELIST', 'https://core.spip.net/projects/spip/repository/raw/archivelist.txt');
235}
236// Url du fichier spip_loader permettant de tester sa version distante
237if (!defined('_URL_SPIP_LOADER')) {
238        define('_URL_SPIP_LOADER', _URL_LOADER_DL . 'spip_loader.php');
239}
240//
241// Renvoie un tableau des versions SPIP dont l'index correspond à au chemin du fichier zip tel
242// qu'utilisé par spip_loader
243//
244function lister_versions_spip() {
245
246        $versions = array();
247
248        // Récupération du fichier archivelist.txt du core
249        $archivelist = recuperer_page(_URL_ARCHIVELIST);
250        $contenu = explode("\n", $archivelist);
251
252        // on supprime les retours chariot
253        $contenu = array_filter($contenu, 'trim');
254        // on supprime les lignes vides
255        $contenu = array_filter($contenu);
256
257        if ($contenu) {
258                // On lit le fichier ligne par ligne et on
259                foreach ($contenu as $ligne) {
260                        if (substr($ligne, 0, 1) != '#') {
261                                // C'est une ligne de definition d'un paquet :
262                                $parametres = explode(';', $ligne);
263                                // - et on extrait la version de spip du chemin svn
264                                $arbo_svn = rtrim($parametres[0], '/');
265                                $version = str_replace('spip-', '', basename($arbo_svn));
266                                // - on separe calcul le nom complet du zip
267                                $chemin = 'spip/' . $parametres[1] . '.zip';
268                                // - on determine l'état de l'archive (stable, dev, archives)
269                                $etat = substr($parametres[1], 0, strpos($parametres[1], '/'));
270                                // Ajout au tableau des versions
271                                $versions[$chemin] = array(
272                                        'version' => $version,
273                                        'etat' => $etat);
274                        }
275                }
276        }
277
278        return $versions;
279}
280
281function branche_spip($version) {
282        if ($version == 'spip') {
283                return 'dev';
284        }
285        $v = explode('.', $version);
286        $branche = $v[0] . '.' . (isset($v[1]) ? $v[1] : '0');
287        return $branche;
288}
289
290// faut il mettre à jour le spip_loader ?
291function spip_loader_necessite_maj() {
292        return version_compare(_SPIP_LOADER_VERSION, spip_loader_recupere_version(), '<');
293}
294
295// trouver le numéro de version du dernier spip_loader
296function spip_loader_recupere_version() {
297        static $version = null;
298        if (is_null($version)) {
299                $version = false;
300                $spip_loader = recuperer_page(_URL_SPIP_LOADER);
301                if (preg_match("/define\('_SPIP_LOADER_VERSION', '([0-9.]*)'\)/", $spip_loader, $m)) {
302                        $version = $m[1];
303                }
304        }
305        return $version;
306}
307
308
309//
310// Traduction des textes de SPIP
311//
312function _TT($code, $args = array()) {
313        global $lang;
314        $code = str_replace('tradloader:', '', $code);
315        $text = $GLOBALS['i18n_tradloader_'.$lang][$code];
316        while (list($name, $value) = @each($args)) {
317                $text = str_replace("@$name@", $value, $text);
318        }
319        return $text;
320}
321
322//
323// Ecrire un fichier de maniere un peu sure
324//
325function ecrire_fichierT($fichier, $contenu) {
326
327        $fp = @fopen($fichier, 'wb');
328        $s = @fputs($fp, $contenu, $a = strlen($contenu));
329
330        $ok = ($s == $a);
331
332        @fclose($fp);
333
334        if (!$ok) {
335                @unlink($fichier);
336        }
337
338        return $ok;
339}
340
341function mkdir_recursif($chemin, $chmod) {
342        $dirs = explode('/', $chemin);
343        $d = array_shift($dirs);
344        foreach ($dirs as $dir) {
345                $d = "$d/$dir";
346                if (!is_dir($d)) {
347                        mkdir($d, $chmod);
348                }
349        }
350        return is_dir($chemin);
351}
352
353function move_all($src, $dest) {
354        global $chmod;
355        $dest = rtrim($dest, '/');
356
357        if ($dh = opendir($src)) {
358                while (($file = readdir($dh)) !== false) {
359                        if (in_array($file, array('.', '..'))) {
360                                continue;
361                        }
362                        $s = "$src/$file";
363                        $d = "$dest/$file";
364                        if (is_dir($s)) {
365                                if (!is_dir($d)) {
366                                        if (!mkdir_recursif($d, $chmod)) {
367                                                die("impossible de creer $d");
368                                        }
369                                }
370                                move_all($s, $d);
371                                rmdir($s);
372                                // verifier qu'on en a pas oublie (arrive parfois il semblerait ...)
373                                // si cela arrive, on fait un clearstatcache, et on recommence un move all...
374                                if (is_dir($s)) {
375                                        clearstatcache();
376                                        move_all($s, $d);
377                                        rmdir($s);
378                                }
379                        } else {
380                                if (is_file($s)) {
381                                        rename($s, $d);
382                                }
383                        }
384                }
385                // liberer le pointeur sinon windows ne permet pas le rmdir eventuel
386                closedir($dh);
387        }
388}
389
390function regler_langue_navigateurT() {
391        $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
392        if (is_array($accept_langs)) {
393                foreach ($accept_langs as $s) {
394                        if (preg_match('#^([a-z]{2,3})(-[a-z]{2,3})?(;q=[0-9.]+)?$#i', trim($s), $r)) {
395                                $lang = strtolower($r[1]);
396                                if (isset($GLOBALS['langues'][$lang])) {
397                                        return $lang;
398                                }
399                        }
400                }
401        }
402        return false;
403}
404
405function menu_languesT($lang, $script = '', $hidden = array()) {
406        $r = '';
407        if (preg_match(',action=([a-z_]+),', $script, $m)) {
408                $r .= "<input type='hidden' name='action' value='".$m[1]."' />";
409                $script .= '&amp;';
410        } else {
411                $script .= '?';
412        }
413
414        foreach ($hidden as $k => $v) {
415                if ($v and $k!='etape') {
416                        $script .= "$k=$v&amp;";
417                }
418        }
419        $r .= '<select name="lang"
420                onchange="window.location=\''.$script.'lang=\'+this.value;">';
421
422        foreach ($GLOBALS['langues'] as $l => $nom) {
423                $r .= '<option value="'.$l.'"' . ($l == $lang ? ' selected="selected"' : '')
424                        . '>'.$nom."</option>\n";
425        }
426        $r .= '</select> <noscript><div><input type="submit" name="ok" value="ok" /></div></noscript>';
427        return $r;
428}
429
430/**
431 * Affiche un sélecteur de menu pour choisir le zip (la branche) à utiliser.
432 *
433 * @param array $active Chemin du paquet à télécharger actuellement sélectionné
434 * @param string $version_installee Version de SPIP actuellement installée
435 * @return string
436 */
437function menu_branches($active, $version_installee) {
438        $select = '';
439        if (!defined('_CHEMIN_FICHIER_ZIP_FORCEE')) {
440                $script = _DIR_BASE . _SPIP_LOADER_SCRIPT . '?';
441                $select .= "<div style='float:" . $GLOBALS['spip_lang_right'] . "'>";
442                $select .= '<select name="chemin" onchange="window.location=\'' . $script . 'chemin=\'+this.value;">';
443                foreach (lister_branches_proposees() as $branche => $desc) {
444                        if ($branche == 'dev' or !$version_installee or version_compare(branche_spip($version_installee), $branche, '<=')) {
445                                $select .= '<option value="' . $desc['zip'] . '"' . ($active == $desc['zip'] ? ' selected="selected"' : '') . '>'
446                                        . 'SPIP ' . $branche 
447                                        . "</option>\n";
448                        }
449                }
450                $select .= '</select> <noscript><div><input type="submit" name="ok" value="ok" /></div></noscript>';
451                $select .= '</div>';
452        }
453        return $select;
454}
455
456
457//
458// Gestion des droits d'acces
459//
460function tester_repertoire() {
461        global $chmod;
462
463        $ok = false;
464        $self = basename($_SERVER['PHP_SELF']);
465        $uid = @fileowner('.');
466        $uid2 = @fileowner($self);
467        $gid = @filegroup('.');
468        $gid2 = @filegroup($self);
469        $perms = @fileperms($self);
470
471        // Comparer l'appartenance d'un fichier cree par PHP
472        // avec celle du script et du repertoire courant
473        @rmdir('test');
474        @unlink('test'); // effacer au cas ou
475        @touch('test');
476        if ($uid > 0 && $uid == $uid2 && @fileowner('test') == $uid) {
477                $chmod = 0700;
478        } else {
479                if ($gid > 0 && $gid == $gid2 && @filegroup('test') == $gid) {
480                        $chmod = 0770;
481                } else {
482                        $chmod = 0777;
483                }
484        }
485        // Appliquer de plus les droits d'acces du script
486        if ($perms > 0) {
487                $perms = ($perms & 0777) | (($perms & 0444) >> 2);
488                $chmod |= $perms;
489        }
490        @unlink('test');
491
492        // Verifier que les valeurs sont correctes
493
494        @mkdir('test', $chmod);
495        @chmod('test', $chmod);
496        $ok = (is_dir('test') && is_writable('test')) ? $chmod : false;
497        @rmdir('test');
498
499        return $ok;
500}
501// creer repertoire
502function creer_repertoires_plugins($chmod) {
503         // créer les répertoires plugins/auto et lib
504         
505    if (!is_dir('plugins')) {
506        @mkdir('plugins', $chmod);
507    }
508    if (!is_dir('plugins/auto')) {
509        @mkdir('plugins/auto', $chmod);
510    }
511    if (!is_dir('lib')) {
512        @mkdir('lib', $chmod);
513    }
514       
515        return  'cretion des repertoires tentee';
516}
517//
518// Demarre une transaction HTTP (s'arrete a la fin des entetes)
519// retourne un descripteur de fichier
520//
521function init_http($get, $url, $refuse_gz = false) {
522        //global $http_proxy;
523        $fopen = false;
524        if (!preg_match(",^http://,i", _URL_LOADER_PROXY)) {
525                $http_proxy = '';
526        } else {
527                $http_proxy = _URL_LOADER_PROXY;
528        }
529
530        $t = @parse_url($url);
531        $host = $t['host'];
532        if ($t['scheme'] == 'http') {
533                $scheme = 'http';
534                $scheme_fsock = '';
535        } else {
536                $scheme = $t['scheme'];
537                $scheme_fsock = $scheme.'://';
538        }
539        if (!isset($t['port']) or !($port = $t['port'])) {
540                $port = 80;
541        }
542        $query = isset($t['query']) ? $t['query'] : '';
543        if (!isset($t['path']) or !($path = $t['path'])) {
544                $path = "/";
545        }
546
547        if ($http_proxy) {
548                $t2 = @parse_url($http_proxy);
549                $proxy_host = $t2['host'];
550                $proxy_user = $t2['user'];
551                $proxy_pass = $t2['pass'];
552                if (!($proxy_port = $t2['port'])) {
553                        $proxy_port = 80;
554                }
555                $f = @fsockopen($proxy_host, $proxy_port);
556        } else {
557                $f = @fsockopen($scheme_fsock.$host, $port);
558        }
559
560        if ($f) {
561                if ($http_proxy) {
562                        fputs(
563                                $f,
564                                "$get $scheme://$host" . (($port != 80) ? ":$port" : "") .
565                                $path . ($query ? "?$query" : "") . " HTTP/1.0\r\n"
566                        );
567                } else {
568                        fputs($f, "$get $path" . ($query ? "?$query" : "") . " HTTP/1.0\r\n");
569                }
570                $version_affichee = isset($GLOBALS['spip_version_affichee'])?$GLOBALS['spip_version_affichee']:"xx";
571                fputs($f, "Host: $host\r\n");
572                fputs($f, "User-Agent: SPIP-$version_affichee (https://www.spip.net/)\r\n");
573
574                // Proxy authentifiant
575                if (isset($proxy_user) and $proxy_user) {
576                        fputs($f, "Proxy-Authorization: Basic "
577                        . base64_encode($proxy_user . ":" . $proxy_pass) . "\r\n");
578                }
579        } elseif (!$http_proxy) {
580                // fallback : fopen
581                $f = @fopen($url, "rb");
582                $fopen = true;
583        } else {
584                // echec total
585                $f = false;
586        }
587
588        return array($f, $fopen);
589}
590
591//
592// Recupere une page sur le net
593// et au besoin l'encode dans le charset local
594//
595// options : get_headers si on veut recuperer les entetes
596function recuperer_page($url) {
597
598        // Accepter les URLs au format feed:// ou qui ont oublie le http://
599        $url = preg_replace(',^feed://,i', 'http://', $url);
600        if (!preg_match(',^[a-z]+://,i', $url)) {
601                $url = 'http://'.$url;
602        }
603
604        // dix tentatives maximum en cas d'entetes 301...
605        for ($i = 0; $i < 10; $i++) {
606                list($f, $fopen) = init_http('GET', $url);
607
608                // si on a utilise fopen() - passer a la suite
609                if ($fopen) {
610                        break;
611                } else {
612                        // Fin des entetes envoyees par SPIP
613                        fputs($f, "\r\n");
614
615                        // Reponse du serveur distant
616                        $s = trim(fgets($f, 16384));
617                        if (preg_match(',^HTTP/[0-9]+\.[0-9]+ ([0-9]+),', $s, $r)) {
618                                $status = $r[1];
619                        } else {
620                                return;
621                        }
622
623                        // Entetes HTTP de la page
624                        $headers = '';
625                        while ($s = trim(fgets($f, 16384))) {
626                                $headers .= $s."\n";
627                                if (preg_match(',^Location: (.*),i', $s, $r)) {
628                                        $location = $r[1];
629                                }
630                                if (preg_match(",^Content-Encoding: .*gzip,i", $s)) {
631                                        $gz = true;
632                                }
633                        }
634                        if ($status >= 300 and $status < 400 and $location) {
635                                $url = $location;
636                        } elseif ($status != 200) {
637                                return;
638                        } else {
639                                break; # ici on est content
640                        }
641                        fclose($f);
642                        $f = false;
643                }
644        }
645
646        // Contenu de la page
647        if (!$f) {
648                return false;
649        }
650
651        $result = '';
652        while (!feof($f)) {
653                $result .= fread($f, 16384);
654        }
655        fclose($f);
656
657        // Decompresser le flux
658        if (isset($_GET['gz']) and $gz = $_GET['gz']) {
659                $result = gzinflate(substr($result, 10));
660        }
661
662        return $result;
663}
664
665function telecharger_langue($lang, $droits) {
666
667        $fichier = 'tradloader_'.$lang.'.php';
668        $GLOBALS['idx_lang'] = 'i18n_tradloader_'.$lang;
669        if (!file_exists(_DIR_BASE.$fichier)) {
670                $contenu = recuperer_page(_URL_LOADER_DL.$fichier.".txt");
671                if ($contenu and $droits) {
672                        ecrire_fichierT(_DIR_BASE.$fichier, $contenu);
673                        include(_DIR_BASE.$fichier);
674                        return true;
675                } elseif ($contenu and !$droits) {
676                        eval('?'.'>'.$contenu);
677                        return true;
678                } else {
679                        return false;
680                }
681        } else {
682                include(_DIR_BASE.$fichier);
683                return true;
684        }
685}
686
687function selectionner_langue($droits) {
688        global $langues; # langues dispo
689
690        $lang = '';
691
692        if (isset($_COOKIE['spip_lang_ecrire'])) {
693                $lang = $_COOKIE['spip_lang_ecrire'];
694        }
695
696        if (isset($_REQUEST['lang'])) {
697                $lang = $_REQUEST['lang'];
698        }
699
700        # reglage par defaut selon les preferences du brouteur
701        if (!$lang or !isset($langues[$lang])) {
702                $lang = regler_langue_navigateurT();
703        }
704
705        # valeur par defaut
706        if (!isset($langues[$lang])) {
707                $lang = 'fr';
708        }
709
710        # memoriser dans un cookie pour l'etape d'apres *et* pour l'install
711        setcookie('spip_lang_ecrire', $lang);
712
713        # RTL
714        if ($lang == 'ar' or $lang == 'he' or $lang == 'fa') {
715                $GLOBALS['spip_lang_right']='left';
716                $GLOBALS['spip_lang_dir']='rtl';
717        } else {
718                $GLOBALS['spip_lang_right']='right';
719                $GLOBALS['spip_lang_dir']='ltr';
720        }
721
722        # code de retour = capacite a telecharger le fichier de langue
723        $GLOBALS['idx_lang'] = 'i18n_tradloader_'.$lang;
724        return telecharger_langue($lang, $droits) ? $lang : false;
725}
726
727function debut_html($corps = '', $hidden = array()) {
728
729        global $lang, $spip_lang_dir, $spip_lang_right, $version_installee;
730
731        if ($version_installee) {
732                $titre = _TT('tradloader:titre_maj', array('paquet'=>strtoupper(_NOM_PAQUET_ZIP)));
733        } else {
734                $titre = _TT('tradloader:titre', array('paquet'=>strtoupper(_NOM_PAQUET_ZIP)));
735        }
736        $css = $js = '';
737        foreach (explode(',', _SPIP_LOADER_EXTRA) as $fil) {
738                switch (strrchr($fil, '.')) {
739                        case '.css':
740                                $css .= '
741        <!-- css pour tuning optionnel, au premier chargement, il manquera si pas droits ... -->
742        <link rel="stylesheet" href="' . basename($fil) . '" type="text/css" media="all" />';
743                                break;
744                        case '.js':
745                                $js .= '
746        <!-- js pour tuning optionnel, au premier chargement, il manquera... -->
747        <script src="' . basename($fil) . '" type="text/javascript"></script>';
748                                break;
749                }
750        }
751
752        $hid = '';
753        foreach ($hidden as $k => $v) {
754                $hid .= "<input type='hidden' name='$k' value='$v' />\n";
755        }
756        $script = _DIR_BASE . _SPIP_LOADER_SCRIPT;
757        echo
758        "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
759        <html 'xml:lang=$lang' dir='$spip_lang_dir'>
760        <head>
761        <title>$titre</title>
762        <meta http-equiv='Expires' content='0' />
763        <meta http-equiv='cache-control' content='no-cache,no-store' />
764        <meta http-equiv='pragma' content='no-cache' />
765        <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
766        <style type='text/css'>
767        body {
768                font-family:Verdana, Geneva, sans-serif;
769                font-size:.9em;
770                color: #222;
771                background-color: #f8f7f3;
772        }
773        #main {
774                margin:5em auto;
775                padding:3em 2em;
776                background-color:#fff;
777                border-radius:2em;
778                box-shadow: 0 0 20px #666;
779                width:34em;
780        }
781        a {
782                color: #E86519;
783        }
784        a:hover {
785                color:#FF9900;
786        }
787        h1 {
788                color:#5F4267;
789                display:inline;
790                font-size:1.6em;
791        }
792        h2 {
793                font-weigth: normal;
794                font-size: 1.2em;
795        }
796        div {
797                line-height:140%;
798        }
799        div.progression {
800                margin-top:2em;
801                font-weight:bold;
802                font-size:1.4em;
803                text-align:center;
804        }
805        .bar {border:1px solid #aaa;}
806        .bar div {background:#aaa;height:1em;}
807        .version {background:#eee;margin:1em 0;padding:.5em;}
808        .version-courante {color:#888;}
809        .erreur {border-left:4px solid #f00; padding:1em 1em 1em 2em; background:#FCD4D4;}
810        .info {border-left:4px solid #FFA54A; padding:1em 1em 1em 2em; background:#FFEED9; margin:1em 0;}
811        </style>$css$js
812        </head>
813        <body>
814        <div id='main'>
815        <form action='" . $script . "' method='get'>" .
816        "<div style='float:$spip_lang_right'>" .
817        menu_languesT($lang, $script, $hidden) .
818        "</div>
819        <div>
820        <h1>" . $titre . "</h1>". $corps .
821        $hid .
822        "</div></form>";
823}
824
825function fin_html()
826{
827        global $taux;
828        echo ($taux ? '
829        <div id="taux" style="display:none">'.$taux.'</div>' : '') .
830        '
831        <p style="text-align:right;font-size:x-small;">spip_loader '
832        . _SPIP_LOADER_VERSION
833        .'</p>
834        </div>
835        </body>
836        </html>
837        ';
838
839        // forcer l'envoi du buffer par tous les moyens !
840        echo(str_repeat("<br />\r\n", 256));
841        while (@ob_get_level()) {
842                @ob_flush();
843                @flush();
844                @ob_end_flush();
845        }
846}
847
848function nettoyer_racine($fichier) {
849
850        @unlink($fichier);
851        @unlink(_DIR_BASE.'pclzip.php');
852        $d = opendir(_DIR_BASE);
853        while (false !== ($f = readdir($d))) {
854                if (preg_match('/^tradloader_(.+).php$/', $f)) {
855                        @unlink(_DIR_BASE.$f);
856                }
857        }
858        closedir($d);
859        return true;
860}
861
862
863/**
864 * Déplace les fichiers qui sont en trop entre le contenu du zip et le répertoire destination.
865 *
866 * @param array $content Liste des fichiers issus de pclZip
867 * @param string $dir Répertoire où ils ont été copiés.
868 */
869function nettoyer_superflus($content, $dir) {
870        global $chmod;
871        $diff = comparer_contenus($content, $dir);
872        if ($diff) {
873                @mkdir($old = _DIR_BASE . 'fichiers_obsoletes_' . date('Ymd_His'), $chmod);
874                if (!is_dir($old)) {
875                        return false;
876                }
877                $old .= '/';
878                foreach ($diff as $file => $isDir) {
879                        $root = $isDir ? $file : dirname($file);
880                        if (!is_dir($old . $root)) {
881                                mkdir_recursif($old . $root, $chmod);
882                        }
883                        if ($isDir) {
884                                move_all(_DIR_BASE . $root, $old . $root);
885                                rmdir(_DIR_BASE . $root);
886                        } else {
887                                rename(_DIR_BASE . $file, $old . $file);
888                        }
889                }
890        }
891}
892
893/**
894 * Retourne la liste des fichiers/répertoires en trop entre le zip et la destination,
895 * pour certains répertoires seulement.
896 */
897function comparer_contenus($content, $dir) {
898        $base = _REMOVE_PATH_ZIP . "/";
899        if ($content[0]['filename'] !== $base) {
900                return false;
901        }
902
903        $len = strlen($base);
904
905        // On se considère dans SPIP et on vérifie seulement ces répertoires
906        $repertoires_testes = array(
907                'ecrire', 
908                'prive', 
909                'plugins-dist', 
910                'squelettes-dist',
911                'extensions', // spip 2.1 hum.
912        );
913
914        // Liste des contenus sources (chemin => isdir?)
915        $contenus_source = array();
916        foreach ($content as $c) {
917                $fichier = substr($c['filename'], $len);
918                $root = explode('/', $fichier, 2);
919                $root = reset($root);
920                if (!in_array($root, $repertoires_testes)) {
921                        continue;
922                }
923                $contenus_source[substr($c['filename'], $len)] = $c['folder'];
924        }
925
926        // Liste des contenus destination (chemin => isdir?)
927        $diff = lister_contenus_superflus($contenus_source, $dir, '', $repertoires_testes);
928        return $diff;
929}
930
931/**
932 * Liste les contenus en trop dans certains répertoires, en fonction d’une liste de fichiers
933 *
934 * Un répertoire superflu, mais contenant un fichier .spip_loader_keep est conservé,
935 * c'est à dire qu’il ne sera pas retourné dans cette liste de fichiers/répertoire obsolètes.
936 *
937 * @param array $contenus_source liste(chemin => isDir?)
938 * @param string $dir Chemin du répertoire à tester
939 * @param string $base Répertoire en cours d’analyse (pour récursivité)
940 * @param array|null $repertoires_testes Liste de répertoires à uniquement parcourrir si défini.
941 * @return array liste(chemin => isDir?) des fichiers/répertoire en trop.
942 */
943function lister_contenus_superflus($contenus_source, $dir, $base, $repertoires_testes = null) {
944        $liste = array();
945        // trop gentils de gerer PHP 4...
946        if ($dh = opendir($dir)) {
947                while (($file = readdir($dh)) !== false) {
948                        if (in_array($file, array('.', '..', '.ok'))) {
949                                continue;
950                        }
951                        if ($repertoires_testes and !in_array($file, $repertoires_testes)) {
952                                continue;
953                        }
954                        $_base = $base . $file;
955                        if (is_dir($dir . '/' . $file)) {
956                                // répertoire présent ou en trop ?
957                                if (!isset($contenus_source[$_base . '/'])) {
958                                        // ne pas rendre obsolète si un fichier de conservation est présent.
959                                        if (file_exists($dir . '/' . $file. '/' . _SPIP_LOADER_KEEP)) {
960                                                continue;
961                                        }
962                                        $liste[$_base . '/'] = true;
963                                } else {
964                                        $liste = array_merge(
965                                                $liste, 
966                                                lister_contenus_superflus($contenus_source, $dir . '/' . $file, $_base . '/')
967                                        );
968                                }
969                        } else {
970                                // fichier présent ou en trop ?
971                                if (!isset($contenus_source[$_base])) {
972                                        $liste[$_base] = false;
973                                }
974                        }
975                }
976                closedir($dh);
977        }
978        return $liste;
979}
980
981
982// un essai pour parer le probleme incomprehensible des fichiers pourris
983function touchCallBack($p_event, &$p_header)
984{
985        // bien extrait ?
986        if ($p_header['status'] == 'ok') {
987                // allez, on touche le fichier, le @ est pour les serveurs sous Windows qui ne comprennent pas touch()
988                @touch($p_header['filename']);
989        }
990        return 1;
991}
992function microtime_float()
993{
994        list($usec, $sec) = explode(" ", microtime());
995        return ((float)$usec + (float)$sec);
996}
997
998function verifie_zlib_ok()
999{
1000        global $taux;
1001        if (!function_exists("gzopen") and !function_exists("gzopen64")) {
1002                return false;
1003        }
1004
1005        if (!file_exists($f = _DIR_BASE . 'pclzip.php')) {
1006                $taux = microtime_float();
1007                $contenu = recuperer_page(_URL_LOADER_DL . 'pclzip.php.txt');
1008                if ($contenu) {
1009                        ecrire_fichierT($f, $contenu);
1010                }
1011                $taux = _PCL_ZIP_SIZE / (microtime_float() - $taux);
1012        }
1013        include $f;
1014        $necessaire = array();
1015        foreach (explode(',', _SPIP_LOADER_EXTRA) as $fil) {
1016                        $necessaire[$fil] = strrchr($fil, '.') == '.php' ? '.txt' : '';
1017        }
1018        foreach ($necessaire as $fil => $php) {
1019                if (!file_exists($f = _DIR_BASE . basename($fil))) {
1020                        $contenu = recuperer_page(_URL_LOADER_DL . $fil . $php);
1021                        if ($contenu) {
1022                                        ecrire_fichierT($f, $contenu);
1023                        }
1024                }
1025                if ($php) {
1026                        include $f;
1027                }
1028        }
1029        return true;
1030}
1031
1032function spip_loader_reinstalle() {
1033        if (!defined('_SPIP_LOADER_UPDATE_AUTEURS')) {
1034                define('_SPIP_LOADER_UPDATE_AUTEURS', '1');
1035        }
1036        if (!isset($GLOBALS['auteur_session']['statut']) or
1037                $GLOBALS['auteur_session']['statut'] != '0minirezo' or
1038                !in_array($GLOBALS['auteur_session']['id_auteur'], explode(':', _SPIP_LOADER_UPDATE_AUTEURS))) {
1039                include_spip('inc/headers');
1040                include_spip('inc/minipres');
1041                http_status('403');
1042                install_debut_html();
1043                echo _T('ecrire:avis_non_acces_page');
1044                install_fin_html();
1045                exit;
1046        }
1047}
1048
1049function spip_deballe_paquet($paquet, $fichier, $dest, $range) {
1050        global $chmod;
1051
1052        // le repertoire temporaire est invariant pour permettre la reprise
1053        @mkdir($tmp = _DIR_BASE.'zip_'.md5($fichier), $chmod);
1054        $ok = is_dir($tmp);
1055
1056        $zip = new PclZip($fichier);
1057        $content = $zip->listContent();
1058        $max_index = count($content);
1059        $start_index = isset($_REQUEST['start']) ? intval($_REQUEST['start']) : 0;
1060
1061        if ($start_index < $max_index) {
1062                if (!$range) {
1063                        $range = _PCL_ZIP_RANGE;
1064                }
1065                $end_index = min($start_index + $range, $max_index);
1066                $ok &= $zip->extractByIndex(
1067                        "$start_index-$end_index",
1068                        PCLZIP_OPT_PATH,
1069                        $tmp,
1070                        PCLZIP_OPT_SET_CHMOD,
1071                        $chmod,
1072                        PCLZIP_OPT_REPLACE_NEWER,
1073                        PCLZIP_OPT_REMOVE_PATH,
1074                        _REMOVE_PATH_ZIP."/",
1075                        PCLZIP_CB_POST_EXTRACT,
1076                        'touchCallBack'
1077                );
1078        }
1079
1080        if (!$ok or $zip->error_code < 0) {
1081                debut_html();
1082                echo _TT('tradloader:donnees_incorrectes', array('erreur' => $zip->errorInfo()));
1083                fin_html();
1084        } else {
1085                // si l'extraction n'est pas finie, relancer
1086                if ($start_index < $max_index) {
1087
1088                        $url = _DIR_BASE._SPIP_LOADER_SCRIPT
1089                        .  (strpos(_SPIP_LOADER_SCRIPT, '?') ? '&' : '?')
1090                        . "etape=fichier&chemin=$paquet&dest=$dest&start=$end_index";
1091                        $progres = $start_index/$max_index;
1092                        spip_redirige_boucle($url, $progres);
1093                }
1094
1095                if ($dest) {
1096                        @mkdir(_DIR_PLUGINS, $chmod);
1097                        $dir = _DIR_PLUGINS . $dest;
1098                        $url = _DIR_BASE . _SPIP_LOADER_PLUGIN_RETOUR;
1099                } else {
1100                        $dir =  _DIR_BASE;
1101                        $url = _DIR_BASE . _SPIP_LOADER_URL_RETOUR;
1102                }
1103                move_all($tmp, $dir);
1104                rmdir($tmp);
1105                nettoyer_superflus($content, $dir);
1106                nettoyer_racine($fichier);
1107                header("Location: $url");
1108        }
1109}
1110
1111function spip_redirige_boucle($url, $progres = ''){
1112        //@apache_setenv('no-gzip', 1); // provoque page blanche chez certains hebergeurs donc ne pas utiliser
1113        @ini_set('zlib.output_compression', '0'); // pour permettre l'affichage au fur et a mesure
1114        @ini_set('output_buffering', 'off');
1115        @ini_set('implicit_flush', 1);
1116        @ob_implicit_flush(1);
1117        $corps = '<meta http-equiv="refresh" content="0;'.$url.'">';
1118        if ($progres) {
1119                $corps .="<div class='progression'>".round($progres*100)."%</div>
1120                                  <div class='bar'><div style='width:".round($progres*100)."%'></div></div>
1121                                ";
1122        }
1123        debut_html($corps);
1124        fin_html();
1125        exit;
1126}
1127
1128function spip_presente_deballe($fichier, $paquet, $dest, $range) {
1129        global $version_installee;
1130
1131        $nom = (_DEST_PAQUET_ZIP == '') ?
1132                        _TT('tradloader:ce_repertoire') :
1133                        (_TT('tradloader:du_repertoire').
1134                                ' <tt>'._DEST_PAQUET_ZIP.'</tt>');
1135
1136        $hidden = array(
1137                'chemin' => $paquet,
1138                'dest' => $dest,
1139                'range' => $range,
1140                'etape' => file_exists($fichier) ? 'fichier' : 'charger'
1141        );
1142
1143        // Version proposée à l'installation par défaut
1144        $versions_spip = lister_versions_spip();
1145        $version_future = $versions_spip[$paquet]['version'];
1146        if ($versions_spip[$paquet]['etat'] == 'dev') {
1147                $version_future .= '-dev';
1148        }
1149        $version_future_affichee = 'SPIP ' . $version_future;
1150
1151        if ($version_installee) {
1152                // Mise à jour
1153                $bloc_courant =
1154                        '<div class="version-courante">'
1155                        . _TT('tradloader:titre_version_courante')
1156                        . '<strong>'. 'SPIP ' . $version_installee .'</strong>'
1157                        . '</div>';
1158                $bouton = _TT('tradloader:bouton_suivant_maj');
1159        } else {
1160                // Installation nue
1161                $bloc_courant = '';
1162                $bouton = _TT('tradloader:bouton_suivant');
1163        }
1164
1165        // Détection d'une incompatibilité avec la version de PHP installée
1166        $branche_future = branche_spip($versions_spip[$paquet]['version']);
1167        $version_php_installee = phpversion();
1168        $version_php_spip = lister_branches_proposees($branche_future);
1169        $version_php_spip = $version_php_spip['php'];
1170
1171        $php_incompatible = version_compare($version_php_spip, $version_php_installee, '>');
1172        if ($php_incompatible) {
1173                $bouton =
1174                        '<div class="erreur">'
1175                        . _TT('tradloader:echec_php', array('php1' => $version_php_installee, 'php2' => $version_php_spip))
1176                        . '</div>';
1177        } elseif (version_compare($version_installee, $version_future, '>') and ($version_future !== 'spip-dev')) {
1178                // Épargnons un downgrade aux personnes étourdies
1179                $bouton =
1180                        "<div style='text-align:".$GLOBALS['spip_lang_right']."'>"
1181                        . '<input type="submit" disabled="disabled" value="' . $bouton . '" />'
1182                        . '</div>';
1183        } else {
1184                $bouton =
1185                        "<div style='text-align:".$GLOBALS['spip_lang_right']."'>"
1186                        . '<input type="submit" value="' . $bouton . '" />'
1187                        . '</div>';
1188        }
1189
1190        // Construction du corps
1191        $corps =
1192                _TT('tradloader:texte_intro', array('paquet'=>strtoupper(_NOM_PAQUET_ZIP),'dest'=> $nom))
1193                . '<div class="version">'
1194                . $bloc_courant
1195                . '<div class="version-future">'
1196                . _TT('tradloader:titre_version_future')
1197                . '<strong>'. $version_future_affichee. '</strong>'
1198                . menu_branches($paquet, $version_installee)
1199                . '</div>'
1200                . '</div>'
1201                . $bouton;
1202
1203        if (spip_loader_necessite_maj()) {
1204                $corps .=
1205                        "<div class='info'><a href='" . _URL_SPIP_LOADER . "'>"
1206                        . _TT('tradloader:spip_loader_maj', array('version' => spip_loader_recupere_version()))
1207                        . "</a>"
1208                        . "<div style='text-align:".$GLOBALS['spip_lang_right']."'>"
1209                        . "<input type='submit' name='spip_loader_update' value='"._TT('tradloader:bouton_suivant_maj')."' />"
1210                        . "</div></div>";
1211        }
1212
1213        debut_html($corps, $hidden);
1214        fin_html();
1215}
1216
1217function spip_recupere_paquet($paquet, $fichier, $dest, $range)
1218{
1219        $contenu = recuperer_page(_URL_SPIP_DEPOT . $paquet);
1220
1221        if (!($contenu and ecrire_fichierT($fichier, $contenu))) {
1222                debut_html();
1223                echo _TT('tradloader:echec_chargement'), "$paquet, $fichier, $range" ;
1224                fin_html();
1225        } else {
1226                // Passer a l'etape suivante (desarchivage)
1227                $sep = strpos(_SPIP_LOADER_SCRIPT, '?') ? '&' : '?';
1228                header("Location: "._DIR_BASE._SPIP_LOADER_SCRIPT.$sep."etape=fichier&chemin=$paquet&dest=$dest&range=$range");
1229        }
1230}
1231
1232function spip_deballe($paquet, $etape, $dest, $range)
1233{
1234        $fichier = _DIR_BASE . basename($paquet);
1235
1236        if ($etape == 'fichier' and file_exists($fichier)) {
1237                // etape finale: deploiement de l'archive
1238                spip_deballe_paquet($paquet, $fichier, $dest, $range);
1239
1240        } elseif ($etape == 'charger') {
1241
1242                // etape intermediaire: charger l'archive
1243                spip_recupere_paquet($paquet, $fichier, $dest, $range);
1244
1245        } else {
1246                // etape intiale, afficher la page de presentation
1247                spip_presente_deballe($fichier, $paquet, $dest, $range);
1248        }
1249}
1250
1251///////////////////////////////////////////////
1252// debut du process
1253//
1254
1255error_reporting(E_ALL ^ E_NOTICE);
1256
1257// PHP >= 5.3 rale si cette init est absente du php.ini et consorts
1258// On force a defaut de savoir anticiper l'erreur (il doit y avoir mieux)
1259if (function_exists('date_default_timezone_set')) {
1260        date_default_timezone_set('Europe/Paris');
1261}
1262$GLOBALS['taux'] = 0; // calcul eventuel du taux de transfert+dezippage
1263
1264// En cas de reinstallation, verifier que le demandeur a les droits avant tout
1265// definir _FILE_CONNECT a autre chose que machin.php si on veut pas
1266$version_installee = '';
1267if (@file_exists('ecrire/inc_version.php')) {
1268        define('_SPIP_LOADER_URL_RETOUR', "ecrire/?exec=accueil");
1269        include_once 'ecrire/inc_version.php';
1270        $version_installee = $GLOBALS['spip_version_branche'];
1271        if ((defined('_FILE_CONNECT') and
1272                _FILE_CONNECT and
1273                strpos(_FILE_CONNECT, '.php')) or
1274                defined('_SITES_ADMIN_MUTUALISATION')) {
1275                spip_loader_reinstalle();
1276        }
1277} else {
1278        define('_SPIP_LOADER_URL_RETOUR', "ecrire/?exec=install");
1279}
1280
1281$droits = tester_repertoire();
1282
1283$GLOBALS['lang'] = selectionner_langue($droits);
1284
1285if (!$GLOBALS['lang']) {
1286        //on ne peut pas telecharger
1287        $GLOBALS['lang'] = 'fr'; //francais par defaut
1288        $GLOBALS['i18n_tradloader_fr']['titre'] = 'T&eacute;l&eacute;chargement de SPIP';
1289        $GLOBALS['i18n_tradloader_fr']['echec_chargement'] = '<h4>Le chargement a &eacute;chou&eacute;.'.
1290        ' Veuillez r&eacute;essayer, ou utiliser l\'installation manuelle.</h4>';
1291        debut_html();
1292        echo _TT('tradloader:echec_chargement');
1293        fin_html();
1294} elseif (!$droits) {
1295        //on ne peut pas ecrire
1296        debut_html();
1297        $q = $_SERVER['QUERY_STRING'];
1298        echo _TT(
1299                'tradloader:texte_preliminaire',
1300                array(
1301                        'paquet' => strtoupper(_NOM_PAQUET_ZIP),
1302                        'href'   => ('spip_loader.php' . ($q ? "?$q" : '')),
1303                        'chmod'  => sprintf('%04o', $chmod)
1304                )
1305        );
1306        fin_html();
1307} elseif (!verifie_zlib_ok()) {
1308        // on ne peut pas decompresser
1309        die('fonctions zip non disponibles');
1310} else {
1311
1312        //Update himself
1313        if (!empty($_REQUEST['spip_loader_update'])) {
1314                $spip_loader = recuperer_page(_URL_SPIP_LOADER);
1315                if (defined('_SPIP_LOADER_UPDATE_AUTEURS')) {
1316                        $spip_loader = preg_replace(
1317                                "/(define\(['\"]_SPIP_LOADER_UPDATE_AUTEURS['\"],).*/",
1318                                "$1'"._SPIP_LOADER_UPDATE_AUTEURS."');",
1319                                $spip_loader
1320                        );
1321                }
1322                ecrire_fichierT(_SPIP_LOADER_SCRIPT, $spip_loader);
1323                spip_redirige_boucle(_DIR_BASE._SPIP_LOADER_SCRIPT);
1324        }
1325
1326        // y a tout ce qu'il faut pour que cela marche
1327        $dest = '';
1328        $paquet = _CHEMIN_FICHIER_ZIP;
1329        if (isset($_REQUEST['dest']) and preg_match('/^[\w-_.]+$/', $_REQUEST['dest'])) {
1330                $dest = $_REQUEST['dest'];
1331        }
1332        if (isset($_REQUEST['chemin']) and $_REQUEST['chemin']) {
1333                $paquet = urldecode($_REQUEST['chemin']);
1334        } elseif ($version_installee and !defined('_CHEMIN_FICHIER_ZIP_FORCEE')) {
1335                if ($branche = lister_branches_proposees(branche_spip($version_installee))) {
1336                        $paquet = $branche['zip'];
1337                } elseif ((strpos($version_installee, '-dev') !== false) and $branche = lister_branches_proposees('dev')) {
1338                        $paquet = $branche['zip'];
1339                }
1340        }
1341
1342        if ((strpos($paquet, '../') !== false) or (substr($paquet, -4, 4) != '.zip')) {
1343                die("chemin incorrect $paquet");
1344        } else {
1345                spip_deballe(
1346                        $paquet,
1347                        (isset($_REQUEST['etape']) ? $_REQUEST['etape'] : ''),
1348                        $dest,
1349                        intval(isset($_REQUEST['range']) ? $_REQUEST['range'] : 0) 
1350                );
1351               
1352                creer_repertoires_plugins($droits);
1353        }
1354}
Note: See TracBrowser for help on using the repository browser.