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

Last change on this file since 118015 was 118015, checked in by cam.lafit, 2 months ago

Eviter des conflits avec les méthodes natives SPIP

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