source: spip-zone/_core_/plugins/svp/teleporter/http.php

Last change on this file was 106359, checked in by cedric@…, 2 years ago

Revert de r106290 par svn merge -r106290:106289 . car entites_html n'est pas toujours chargee, donc erreurs fatales, et le probleme a ete traite en amont dans la fonction _T de maniere plus generique

File size: 5.5 KB
Line 
1<?php
2/**
3 * Gestion du téléporteur HTTP.
4 *
5 * @plugin SVP pour SPIP
6 * @license GPL
7 * @package SPIP\SVP\Teleporteur
8 */
9
10/**
11 * Téléporter et déballer un composant HTTP
12 *
13 * @uses  teleporter_http_recuperer_source()
14 * @uses  teleporter_nettoyer_vieille_version()
15 *
16 * @param string $methode
17 *   Méthode de téléportation : http|git|svn|...
18 * @param string $source
19 *     URL de la source HTTP
20 * @param string $dest
21 *     Chemin du répertoire de destination
22 * @param array $options
23 *     Tableau d'options.
24 *     Doit au moins avoir l'index :
25 *     - dir_tmp : Indique un répertoire temporaire pour stocker
26 *       les fichiers. Par exemple défini avec : sous_repertoire(_DIR_CACHE, 'chargeur');
27 * @return bool|string
28 *     Texte d'erreur si erreur,
29 *     True si l'opération réussie.
30 */
31function teleporter_http_dist($methode, $source, $dest, $options = array()) {
32
33        $tmp = $options['dir_tmp'];
34        # on ne se contente pas du basename qui peut etre un simple v1
35        # exemple de l'url http://nodeload.github.com/kbjr/Git.php/zipball/v0.1.1-rc
36        $fichier = $tmp . (basename($dest) . "-" . substr(md5($source), 0, 8) . "-" . basename($source));
37
38        $res = teleporter_http_recuperer_source($source, $fichier);
39        if (!is_array($res)) {
40                return $res;
41        }
42
43        list($fichier, $extension) = $res;
44        if (!$deballe = charger_fonction("http_deballe_" . preg_replace(",\W,", "_", $extension), "teleporter", true)) {
45                return _T('svp:erreur_teleporter_format_archive_non_supporte', array('extension' => $extension));
46        }
47
48        $old = teleporter_nettoyer_vieille_version($dest);
49
50        if (!$target = $deballe($fichier, $dest, $tmp)) {
51                // retablir l'ancien sinon
52                if ($old) {
53                        rename($old, $dest);
54                }
55
56                return _T('svp:erreur_teleporter_echec_deballage_archive', array('fichier' => $fichier));
57        }
58
59        return true;
60}
61
62/**
63 * Récupérer la source et détecter son extension
64 *
65 * @uses  teleporter_http_extension()
66 *
67 * @param string $source
68 *     URL de la source HTTP
69 * @param string $dest_tmp
70 *     Répertoire de destination
71 * @return array|string
72 *     - Texte d'erreur si une erreur survient,
73 *     - Liste sinon (répertoire de destination temporaire, extension du fichier source)
74 */
75function teleporter_http_recuperer_source($source, $dest_tmp) {
76
77        # securite : ici on repart toujours d'une source neuve
78        if (file_exists($dest_tmp)) {
79                spip_unlink($dest_tmp);
80        }
81
82        $extension = "";
83
84        # si on ne dispose pas encore du fichier
85        # verifier que le zip en est bien un (sans se fier a son extension)
86        #       en chargeant son entete car l'url initiale peut etre une simple
87        # redirection et ne pas comporter d'extension .zip
88        include_spip('inc/distant');
89        $head = recuperer_page($source, false, true, 0);
90
91        if (preg_match(",^Content-Type:\s*?(.*)$,Uims", $head, $m)
92                and include_spip('base/typedoc')
93        ) {
94                $mime = $m[1];
95                // passer du mime a l'extension !
96                if ($e = array_search($mime, $GLOBALS['tables_mime'])) {
97                        $extension = $e;
98                }
99        }
100
101        if (!$extension
102                // cas des extensions incertaines car mime-type ambigu
103                or in_array($extension, array('bin', 'gz'))
104        ) {
105                if (preg_match(",^Content-Disposition:\s*attachment;\s*filename=(.*)['\"]?$,Uims", $head, $m)
106                        and $e = teleporter_http_extension($m[1])
107                ) {
108                        $extension = $e;
109                }
110                // au cas ou, si le content-type n'est pas la
111                // mais que l'extension est explicite
112                else {
113                        $extension = teleporter_http_extension($source);
114                }
115        }
116
117        # format de fichier inconnu
118        if (!$extension) {
119                spip_log("Type de fichier inconnu pour la source $source", "teleport" . _LOG_ERREUR);
120
121                return _T('svp:erreur_teleporter_type_fichier_inconnu', array('source' => $source));
122        }
123
124        $dest_tmp = preg_replace(";\.[\w]{2,3}$;i", "", $dest_tmp) . ".$extension";
125
126        if (!defined('_SVP_PAQUET_MAX_SIZE')) {
127                define('_SVP_PAQUET_MAX_SIZE', 67108864);
128        } // 64Mo
129        include_spip('inc/distant');
130        $dest_tmp = copie_locale($source, 'force', $dest_tmp, _SVP_PAQUET_MAX_SIZE);
131        if (!$dest_tmp
132                or !file_exists($dest_tmp = _DIR_RACINE . $dest_tmp)
133        ) {
134                spip_log("Chargement impossible de la source $source", "teleport" . _LOG_ERREUR);
135
136                return _T('svp:erreur_teleporter_chargement_source_impossible', array('source' => $source));
137        }
138
139        return array($dest_tmp, $extension);
140}
141
142/**
143 * Retrouve l'extension d'un fichier
144 *
145 * @note
146 *     Retourne tgz pour un fichier .tar.gz
147 *
148 * @param string $file
149 *     Chemin du fichier
150 * @return string
151 *     Extension du fichier, sinon vide
152 **/
153function teleporter_http_extension($file) {
154        $e = pathinfo($file, PATHINFO_EXTENSION);
155
156        // cas particuliers : redresser .tar.gz
157        if ($e == 'gz'
158                and preg_match(',tar\.gz,i', $file)
159        ) {
160                $e = 'tgz';
161        }
162
163        return $e;
164}
165
166/**
167 * Cherche la plus longue racine commune à tous les fichiers
168 *
169 * @param array $list
170 *     Liste de chemin de fichiers
171 * @return string
172 *     Chemin commun entre tous les fichiers
173 **/
174function http_deballe_recherche_racine($list) {
175        // on cherche la plus longue racine commune a tous les fichiers
176        // pour l'enlever au deballage
177        $max_n = 999999;
178        $paths = array();
179        foreach ($list as $n) {
180                $p = array();
181                foreach (explode('/', $n['filename']) as $n => $x) {
182                        if ($n > $max_n) {
183                                continue;
184                        }
185                        $sofar = join('/', $p);
186                        if (!isset($paths[$n])) {
187                                $paths[$n] = array();
188                        }
189                        if (!isset($paths[$n][$sofar])) {
190                                $paths[$n][$sofar] = 0;
191                        }
192                        $paths[$n][$sofar]++;
193                        $p[] = $x;
194                }
195                $max_n = min($n, $max_n);
196        }
197
198        $total = $paths[0][''];
199        $i = 0;
200        while (isset($paths[$i])
201                and count($paths[$i]) <= 1
202                and array_values($paths[$i]) == array($total)) {
203                $i++;
204        }
205
206        $racine = '';
207        if ($i) {
208                $racine = array_keys($paths[$i - 1]);
209                $racine = array_pop($racine) . '/';
210        }
211
212        return $racine;
213}
Note: See TracBrowser for help on using the repository browser.