array( # 'http://telechargements.pluxml.org/download.php' 'https://www.pluxml.org/download/pluxml-latest.zip' ), ROOT.'plugins' => array( 'https://kazimentou.fr/pluxml-plugins2/index.php?plugin=kzUploader&download' ) ); const L_URL = 0; const L_ZIP = 1; const L_EXIT = 2; const L_LIB = 3; const L_BAD_ZIP = 4; const L_FAIL = 5; const L_UNWRITABLE = 6; const L_TOO_MUCH_FILES= 7; const L_FOLDER = 8; $all_langs = array( 'en' => array( "Downloading from %s", "Unzipping to folder : %s\n", "Please, press the F5 key within 60 seconds for reaching %s", "The following libraries are required :", "Bad Zip archive", "Downloading for %s fails", "The folder %s is unwritable", "The folder %s must have only the ". __FILE__ ." script", "Folder" ), 'fr' => array( "Téléchargement depuis %s", "Déployement dans le dossier : %s\n", "Vous avez 60 secondes pour appuyer sur la touche F5 pour accéder à %s", "Les bibliothèques suivantes sont nécessaires :", "Archive Zip incorrecte", "Échec au téléchargement depuis %s", "Aucun droit en écriture pour le dossier %s", "Le dossier %s doit contenir uniquement le script ".__FILE__, "Dossier" ), 'es' => array( "descargando desde %s", "descomprimir en la carpeta : %s\n", "Por favor, presione la tecla F5 dentro de 60 segundos para llegar a %s", "Se requieren las siguientes bibliotecas :", "mal archivo zip", "La descarga de %s falla", "No permiso de escritura para la carpeta %s", "The folder %s must have only this PHP script", "Targeta" ), 'de' => array( "Herunterladen von %s", "Entpacken in Ordner : %s\n", "Drücken Sie die Taste F5 innerhalb von 60 Sekunden, um %s zu erreichen", "Die folgenden Bibliotheken sind erforderlich :", "schlechtes Zip-Archiv", "Das Herunterladen für %s schlägt fehl", "Keine Schreibberechtigung für den %s-Ordner", "The folder %s must have only this PHP script", "Folder" ) ); define('PUBLIC_NETWORK', filter_input( INPUT_SERVER, 'SERVER_ADDR', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE )); const PATTERN = '{*,.htaccess,.git*}'; const HOMEPAGE = '/install.php'; define('WORKDIR', __DIR__ ); define('REPORTFILE', WORKDIR.'/'.basename(__FILE__, '.php').'.json'); define('REPORT_URL', preg_replace('@\.php(?:\?[^/]*)?$@', '.json', $_SERVER['PHP_SELF'])); define('NEW_LOCATION', rtrim(dirname($_SERVER['PHP_SELF']), '/').HOMEPAGE); const ID_PATTERN = 'U%02d'; function i18n($text, $value=false, $return=false) { global $all_langs; if($return) { return sprintf($all_langs[LANG][$text], $value); } printf($all_langs[LANG][$text]."\n", $value); } function error($msg) { header('Content-type: text/plain;charset=utf-8'); echo $msg; } $dashboard = array( 'begin' => false, 'urls' => array(), 'end' => false, 'msgId' => 0 ); /* write $dashboard to file */ function report() { global $dashboard; $fp = fopen(REPORTFILE, 'w'); fwrite($fp, json_encode($dashboard)); fclose($fp); } function progressbar($resource, $total_download, $partiel_download, $total_upload, $partiel_upload) { global $dashboard; $key = curl_getinfo($resource, CURLINFO_PRIVATE); if( array_key_exists($key, $dashboard['urls']) and ( $partiel_download - $dashboard['urls'][$key]['partiel'] > 8192 or $partiel_download == $total_download ) ) { $dashboard['urls'][$key]['total'] = $total_download; $dashboard['urls'][$key]['partiel'] = $partiel_download; $dashboard['msgId']++; report(); } } function unzip($filename, $target) { if(!empty($filename)) { $zip = new ZipArchive(); if($zip->open($filename) === true) { $target = trim($target, '/ \\'); $tt = WORKDIR; if(!empty($target)) { $tt .= "/$target"; } $zip->extractTo($tt); $root = $zip->getNameIndex(0); $zip->close(); unlink($filename); # Clean up ! # At Github, $root change on every release. $root = substr($root, 0, strpos($root, '/')); $newName = preg_replace('@-?[\d.]*$@', '', $root); # for release from Github if($newName != $root) { rename("$tt/$root", "$tt/$newName"); } return true; } else { return false; } } } function browseFolder($folder='') { if(defined('')) { return glob(WORKDIR."/$folder".PATTERN, GLOB_BRACE + GLOB_NOESCAPE); } else { $result = Array(); echo "ROOT : ".ROOT."\n"; foreach(explode(',', trim(PATTERN, '{}')) as $pattern) { $mask = WORKDIR."/$folder".$pattern; echo "$mask\n"; $buf = glob($mask); print_r($buf); if(!empty($buf)) { $result = array_merge($result, $buf); } } return $result; } } function install($URLS, &$dashboard) { $offset_time = filemtime(__FILE__); $dashboard['begin'] = time() - $offset_time; $chs = array(); $fps = array(); $filenames = array(); $n = 0; $mh = curl_multi_init(); foreach($URLS as $target=>$urls_list) { $filenames[$target] = array(); foreach($urls_list as $url) { $fn = tempnam(sys_get_temp_dir(), 'KZX'); $filenames[$target][] = $fn; $fps[$n] = fopen($fn, 'w'); $key = sprintf(ID_PATTERN, $n); $dashboard['urls'][$key] = array( 'total' => 0, 'partiel' =>0 ); $chs[$n] = curl_init($url); curl_setopt_array($chs[$n], array( CURLOPT_FOLLOWLOCATION => true, CURLOPT_HEADER => false, CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'], CURLOPT_NOPROGRESS => false, CURLOPT_PROGRESSFUNCTION => 'progressbar', CURLOPT_FILE => $fps[$n], CURLOPT_PRIVATE => $key )); curl_multi_add_handle($mh, $chs[$n]); $n++; } } report(); $active = true; while($active) { usleep(200000); $cme = curl_multi_exec($mh, $active); } for($i=0; $i<$n; $i++) { curl_multi_remove_handle($mh, $chs[$i]); curl_close($chs[$i]); fclose($fps[$i]); } curl_multi_close($mh); # Some site doesn't introduce the full size of theirs files for downloading. For E.G. : github foreach(array_keys($dashboard['urls']) as $key) { if($dashboard['urls'][$key]['total'] == 0) { $dashboard['urls'][$key]['total'] = $dashboard['urls'][$key]['partiel']; } } foreach($filenames as $target=>$fileslist) { foreach($fileslist as $filename1) { unzip($filename1, $target); unlink($filename1); } } # final step $sources = browseFolder(ROOT); $offset = strlen(WORKDIR.'/'.ROOT) - 1; foreach($sources as $src) { rename($src, WORKDIR.substr($src, $offset)); } rmdir(WORKDIR.'/'.ROOT); $dashboard['end'] = time() - $offset_time; report(); } /* =========== main ========== */ header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Expires: Fri, 14 Jul 2000 12:00:00 GMT'); header('Pragma: no-cache'); if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { foreach(explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $accept_lang) { $lg = substr($accept_lang, 0, 2); if(array_key_exists($lg, $all_langs)) { define('LANG', $lg); break; } } } if(!defined('LANG')) { define('LANG', 'en'); } $missing_libs = array(); if(!function_exists('curl_init')) { $missing_libs[] = ' - Curl'; } if(!class_exists('ZipArchive')) { $missing_libs[] = ' - ZipArchive'; } if(!function_exists('json_encode')) { $missing_libs[] = ' - Json'; } if(!function_exists('filter_has_var')) { $missing_libs[] = ' - Filter'; } if(!empty($missing_libs)) { error(i18n(L_LIB).implode("\n", $missing_libs)); } elseif(!is_writable(__DIR__)) { error(i18n(L_UNWRITABLE, __DIR__)); } elseif(filter_has_var(INPUT_GET, 'install')) { # New install install($URLS, $dashboard); } elseif(!empty($_GET) or !empty($_POST)) { # Forbidden request die; } else { if( file_exists(__DIR__ . HOMEPAGE) and time() - filemtime(REPORTFILE) < 300 ) { # If a fresh install, jump to HOMEPAGE header('Location: '.NEW_LOCATION); # Auto-destruction if not in private range if(PUBLIC_NETWORK) { unlink(__FILE__); } exit; } # this script must be the only filename or folder in WORKDIR $sources = browseFolder(); if(count($sources) != 1 or $sources[0] != __FILE__) { error(i18n(L_TOO_MUCH_FILES, __DIR__)); print_r($sources); exit; } ?> kzInstall-2.0 by Kazimentou.fr