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

Last change on this file was 118016, checked in by cam.lafit, 7 weeks ago

Ne pas oublier de monter de version : 3.0.8

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