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

Last change on this file was 118965, checked in by bruno@…, 3 months ago

bump version

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