ada3d45c1f816670818bce099a2fcda48b3ca8f1
3 * Gestion du téléporteur HTTP.
5 * @plugin SVP pour SPIP
7 * @package SPIP\SVP\Teleporteur
11 * Téléporter et déballer un composant HTTP
13 * @uses teleporter_http_recuperer_source()
14 * @uses teleporter_nettoyer_vieille_version()
16 * @param string $methode
17 * Méthode de téléportation : http|git|svn|...
18 * @param string $source
19 * URL de la source HTTP
21 * Chemin du répertoire de destination
22 * @param array $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');
28 * Texte d'erreur si erreur,
29 * True si l'opération réussie.
31 function teleporter_http_dist($methode, $source, $dest, $options = array()) {
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));
38 $res = teleporter_http_recuperer_source($source, $fichier);
39 if (!is_array($res)) {
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));
48 $old = teleporter_nettoyer_vieille_version($dest);
50 if (!$target = $deballe($fichier, $dest, $tmp)) {
51 // retablir l'ancien sinon
56 return _T('svp:erreur_teleporter_echec_deballage_archive', array('fichier' => $fichier));
63 * Récupérer la source et détecter son extension
65 * @uses teleporter_http_extension()
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)
75 function teleporter_http_recuperer_source($source, $dest_tmp) {
77 # securite : ici on repart toujours d'une source neuve
78 if (file_exists($dest_tmp)) {
79 spip_unlink($dest_tmp);
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);
91 if (preg_match(",^Content-Type:\s*?(.*)$,Uims", $head, $m)
92 and include_spip('base/typedoc')
95 // passer du mime a l'extension !
96 if ($e = array_search($mime, $GLOBALS['tables_mime'])) {
102 // cas des extensions incertaines car mime-type ambigu
103 or in_array($extension, array('bin', 'gz'))
105 if (preg_match(",^Content-Disposition:\s*attachment;\s*filename=(.*)['\"]?$,Uims", $head, $m)
106 and $e = teleporter_http_extension($m[1])
110 // au cas ou, si le content-type n'est pas la
111 // mais que l'extension est explicite
113 $extension = teleporter_http_extension($source);
117 # format de fichier inconnu
119 spip_log("Type de fichier inconnu pour la source $source", "teleport" . _LOG_ERREUR
);
121 return _T('svp:erreur_teleporter_type_fichier_inconnu', array('source' => $source));
124 $dest_tmp = preg_replace(";\.[\w]{2,3}$;i", "", $dest_tmp) . ".$extension";
126 if (!defined('_SVP_PAQUET_MAX_SIZE')) {
127 define('_SVP_PAQUET_MAX_SIZE', 67108864);
129 include_spip('inc/distant');
130 $dest_tmp = copie_locale($source, 'force', $dest_tmp, _SVP_PAQUET_MAX_SIZE
);
132 or !file_exists($dest_tmp = _DIR_RACINE
. $dest_tmp)
134 spip_log("Chargement impossible de la source $source", "teleport" . _LOG_ERREUR
);
136 return _T('svp:erreur_teleporter_chargement_source_impossible', array('source' => $source));
139 return array($dest_tmp, $extension);
143 * Retrouve l'extension d'un fichier
146 * Retourne tgz pour un fichier .tar.gz
148 * @param string $file
151 * Extension du fichier, sinon vide
153 function teleporter_http_extension($file) {
154 $e = pathinfo($file, PATHINFO_EXTENSION
);
156 // cas particuliers : redresser .tar.gz
158 and preg_match(',tar\.gz,i', $file)
167 * Cherche la plus longue racine commune à tous les fichiers
170 * Liste de chemin de fichiers
172 * Chemin commun entre tous les fichiers
174 function http_deballe_recherche_racine($list) {
175 // on cherche la plus longue racine commune a tous les fichiers
176 // pour l'enlever au deballage
179 foreach ($list as $n) {
181 foreach (explode('/', $n['filename']) as $n => $x) {
185 $sofar = join('/', $p);
186 if (!isset($paths[$n])) {
187 $paths[$n] = array();
189 if (!isset($paths[$n][$sofar])) {
190 $paths[$n][$sofar] = 0;
192 $paths[$n][$sofar]++
;
195 $max_n = min($n, $max_n);
198 $total = $paths[0][''];
200 while (isset($paths[$i])
201 and count($paths[$i]) <= 1
202 and array_values($paths[$i]) == array($total)) {
208 $racine = array_keys($paths[$i - 1]);
209 $racine = array_pop($racine) . '/';