liberatator

liberatator est un (pas si) petit script PHP qui vise à automatiser l'adaptation de Dokuwiki chez free.fr. Les curieux iront voir la page php chez free.fr pour les problèmes liés à PHP chez free et la page Dokuwiki chez free pour les détails sur la manière de résoudre les problèmes.

Les autres se contenteront de télécharger le script liberatator.php et de le mettre dans le même répertoire que celui qui contient doku.php1) et de l'exécuter via leur navigateur web.

Il faudra le relancer avec un autre nom de libération après chaque mise à jour de dokuwiki, ou installation d'un thème ou greffon.

Versions de Doku et de PHP

À ce jour, 20101/09, La plus récente version de PHP disponible chez free.fr est PHP 5.1.3RC4-dev. à partir de la version 2013-05-10a “Weatherwax”, DokuWiki nécesite au minimum PHP 5.2. La dernière version de DokuWiki qu'on peut installer chez free.fr est donc 2012-10-13 “Adora Belle”

Téléchargement sur 2012-10-13 “Adora Belle” : 2012-10-13 “Adora Belle”.

Pour les nulls et pour m'amuser, j'ai fait un tuto vidéo sur l'installation de dokuwiki grâce à liberatator.

Voilà, bon DokuWiki

Remerciements

Que soient remerciés ici, publiquement, les contributeuses et contributeurs à liberatator, cités par ordre d'apparition dans ma boite mail :

  1. Damien Gaignon. Signalement du problème avec le greffon translation et la fonction array_fill_keys; test de la solution.
    Voir le site web de Damien Gaignon.

Ça marche, faites le savoir

Ben, oui kwoa, prévenez les autres que ça fonctionnne (et faites vous de la pub pour votre site2))

Ça fonctionne pour moi, Merci !
  _   __   ___    ____ __  __   ____
 | | / /  / _ \  / __/ \ \/ /  / __/
 | |/ /  / ___/ _\ \    \  /  / _/  
 |___/  /_/    /___/    /_/  /_/

Date Nom version site
@@meta.date.format.d/m/Y@@ @@Nom@@ @@Version@@ @@Site@@
18/05/2020 MEYER - "version dokuwiki 2018-04-22c "Greebo" 2012-09-10 “Adora Belle” http://saraheric.meyer.free.fr/
26/05/2011 Schplurtz le Déboulonné 2011-05-25 “Rincewind” http://schplurtz.free.fr

Problèmes corrigés par liberatator

Cf Dokuwiki chez free

Problèmes non corrigés par liberatator

Certains problèmes ne peuvent pas être corrigés par liberatator, notamment :

  • Les problèmes liés à l'absence de connexion de PHP vers des URL quelconques.

Le programme

Liberatator est un logiciel expérimental.

Liberatator est un logiciel libre, diffusé sous licence libre CeCILL 2. À ce titre, il est distribué “en l'état”, et ma responsabilité ne saurait être engagée quant au conséquences de l'utilisation, de l'incapacité à utiliser liberatator. Il n'y a quasiment aucune garantie qu'il fonctionne, qu'il fera ce que vous voulez, qu'il n'utilise indument aucun brevet, nom ou technique déposée quelque part d'une manière ou d'une autre.

Pour les détails exacts, veuillez vous reporter au texte de la license CeCILL 2 :

Si vous n'êtes pas d'accord, n'utilisez pas liberatator.

CLiquez sur le nom pour télécharger liberatator

liberatator.php
<?php
/*
 
                     Copyright Schplurtz Le Déboulonné, 2011
 
                 Schplurtz le Déboulonné <Schplurtz@laposte.net>
 
               FRENCH                 |             ENGLISH
 -------------------------------------+--------------------------------------
 Ce logiciel est un programme         |  This software is a computer program
 informatique servant à rendre        |  whose purpose is to make DokuWiki
 utilisable DokuWiki chez             |  run at free.fr.
 l'hébergeur français free            |
                                      |
 Ce logiciel est régi par la licence  |  This software is governed by the
 CeCILL soumise au droit français et  |  CeCILL license under French law and
 respectant les principes de          |  abiding by the rules of
 diffusion des logiciels libres.      |  distribution of free software.  You
 Vous pouvez utiliser, modifier       |  can  use, modify and/ or
 et/ou redistribuer ce programme      |  redistribute the software under the
 sous les conditions de la licence    |  terms of the CeCILL license as
 CeCILL telle que diffusée par le     |  circulated by CEA, CNRS and INRIA
 CEA, le CNRS et l'INRIA sur le site  |  at the following URL
 "http://www.cecill.info/".           |  "http://www.cecill.info/".
                                      |
 En contrepartie de l'accessibilité   |  As a counterpart to the access to
 au code source et des droits de      |  the source code and  rights to
 copie, de modification et de         |  copy, modify and redistribute
 redistribution accordés par cette    |  granted by the license, users are
 licence, il n'est offert aux         |  provided only with a limited
 utilisateurs qu'une garantie         |  warranty  and the software's
 limitée.  Pour les mêmes raisons,    |  author,  the holder of the economic
 seule une responsabilité restreinte  |  rights,  and the successive
 pèse sur l'auteur du programme,  le  |  licensors  have only  limited
 titulaire des droits patrimoniaux    |  liability.
 et les concédants successifs.        |
                                      |
 A cet égard  l'attention de          |  In this respect, the user's
 l'utilisateur est attirée sur les    |  attention is drawn to the risks
 risques associés au chargement,  à   |  associated with loading,  using,
 l'utilisation,  à la modification    |  modifying and/or developing or
 et/ou au développement et à la       |  reproducing the software by the
 reproduction du logiciel par         |  user in light of its specific
 l'utilisateur étant donné sa         |  status of free software, that may
 spécificité de logiciel libre, qui   |  mean  that it is complicated to
 peut le rendre complexe à manipuler  |  manipulate,  and  that  also
 et qui le réserve donc à des         |  therefore means  that it is
 développeurs et des professionnels   |  reserved for developers  and
 avertis possédant  des               |  experienced professionals having
 connaissances  informatiques         |  in-depth computer knowledge. Users
 approfondies.  Les utilisateurs      |  are therefore encouraged to load
 sont donc invités à charger  et      |  and test the software's suitability
 tester  l'adéquation  du logiciel à  |  as regards their requirements in
 leurs besoins dans des conditions    |  conditions enabling the security of
 permettant d'assurer la sécurité de  |  their systems and/or data to be
 leurs systèmes et ou de leurs        |  ensured and,  more generally, to
 données et, plus généralement, à     |  use and operate it in the same
 l'utiliser et l'exploiter dans les   |  conditions as regards security.
 mêmes conditions de sécurité.        |
                                      |
 Le fait que vous puissiez accéder à  |   The fact that you are presently
 cet en-tête signifie que vous avez   |   reading this means that you have
 pris connaissance de la licence      |   had knowledge of the CeCILL license
 CeCILL, et que vous en avez accepté  |   and that you accept its terms.
 les termes.                          |
*/
 
if(function_exists('date_default_timezone_set') && '' == ini_get('date.timezone'))
	date_default_timezone_set( 'Europe/Paris' );
 
$debug=false;
$ici=dirname($_SERVER['SCRIPT_FILENAME']).'/';
define( 'DOKU_INC', $ici );
 
$statut=array(
	'debut_fait' => false,
	'fin_fait' => false,
	'debut_form' => false,
	'fin_form' => false,
	'asauver' => false,
);
$progres=array(
	'etat' => 'dir_non_verifie',
	'liberation' => false,
	'etape' => array(0 => false),
);
$pointeur_fic=0;
function debut_doc() {
	global $statut,$progres;
	if( $statut['debut_fait'] )
		return;
	$statut['debut_fait']=true;
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"
 lang="fr" dir="ltr">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>liberatator</title>
 
  <meta name="generator" content="schplurtz"/>
  <meta name="robots" content="index,nofollow"/>
  <meta name="date" content="<?php date( DATE_ISO8601 )?>"/>
  <meta name="keywords" content="liberatator"/>
<style type="text/css">
<!--
body { font: 84% Verdana,Helvetica,Arial,sans-serif; margin: 0 auto; width: 90%; }
h1 { text-align: center; }
tt, pre { color:black; background-color:#F2EFED; font-size: 110%; }
span.ok { /* medium spring green */ color:#00fa9a; }
span.ook { /* pale green */ color:#98fb98; }
span.er { /* IndianRed */ color:#cd5c5c; }
div.message, div.attention, div.erreur {
	margin-left: 1.5em;
	font-size: .8em;
	border: dashed 1px;
}
div.attention{ /* orange3 */ background-color: #cd8500; }
div.erreur{ /* IndianRed */ background-color:#cd5c5c; }
-->
</style>
 
</head><body>
<?php # echo "<pre>etat\n";/*var_dump(*/print_r($statut); echo "\nprogres\n"; print_r($progres);echo '</pre>'; ?>
<h1><a href="http://schplurtz.free.fr/wiki/schplurtziel/liberatator">liberatator</a></h1>
<?php
	if( $progres['liberation'] ){
		echo '<h2>Récapitulation</h2>';
		echo 'Libération: ', $progres['liberation'], '<br />';
		$count = count($progres['etape']);
		for ($i = 1; $i < $count; $i++) {
			echo '<br />étape ', $i, ' ', $progres['etape'][$i];
		}
		echo '<h2>étape courante</h2>';
	}
}
function fin_doc() {
	global $statut;
	if( $statut['fin_fait'] )
		return;
	echo '</body></html>';
}
function div( $type,$msg ) {
	debut_doc();
	echo '<div class="', $type, '"><p>', $msg, '</p></div>';
}
function message( $msg ) {
	div("message", $msg);
}
function attention( $msg ) {
	div("attention", $msg);
}
function erreur( $msg ) {
	div("erreur", $msg);
}
 
# Assurons nous d'avoir un répertoire pour sauvegarder tout notre bazar.
$statut['workdir']=$ici.'liberatator.tmp';
if( !is_dir( $statut['workdir'] )) {
	if(!mkdir( $statut['workdir'] )) {
		erreur( "Impossible de créer le répertoire «{$statut['workdir']}»,<br />Arret.");
		fin_doc();
		exit();
	}
}
elseif(!is_writable($statut['workdir'])) {
	erreur( "Le répertoire «{$statut['workdir']}» existe mais n'est pas <i>écriturable</i>,<br />Arret.");
	fin_doc();
	exit();
}
$statut['workdir'].='/';
# Essayons de créer un fichier .htaccess pour interdir le téléchargement des
# fichiers temporaires. cela n'est pas crucial, donc non fatal en cas d'erreur.
if(!file_exists($statut['workdir'].'.htaccess')) {
	if($pe=fopen($statut['workdir'].'.htaccess','w')){
		@fwrite($pe,"## no access to the liberatator working directory\norder allow,deny\ndeny from all\nSatisfy All\n");
		@fclose($pe);
	}
}
 
function myopendir( $dir ){
	if( is_dir( $dir )) return @opendir( $dir );
	return false;
}
$freefrdirtrash=$_SERVER['DOCUMENT_ROOT'].'/poubelle';
function myrmdir( $d ) {
	global $freefrdirtrash;
	if(!is_dir($d))
		return false;
	$h=opendir($d);
	while(false!==($s=readdir($h))) {
		if( $s != '.' && $s != '..' ) {
			closedir($h);
			return false;
		}
	}
	closedir($h);
	return rename($d, $freefrdirtrash);
}
function myglob( $patt, $ignored='dummy' ) {
	$dir=dirname( $patt );
	$pat=basename( $patt );
 
	$reponse=array();
	if (is_dir($dir) && ($d = @opendir($dir))) {
		$gl = array( '/\./', '/\*/', '/\?/', '/^/', '/$/'  );
		$re = array( '\.',   '.*',   '.',    '/^',  '\$/' );
		$newpat=preg_replace( $gl, $re, $pat );
			while (($filename = @readdir($d)) !== false) {
				if( $filename == '.' || $filename == '..' )
					continue;
				if( preg_match( $newpat, $filename )) {
					$reponse[]= $dir . '/' . $filename;
				}
		}
	}
	return $reponse;
}
 
function req_vers_dir( $v ) {
	$x=( '/' == $v[0] ) ? $v : DOKU_INC.$v;
	return ('/' != $x[strlen($x)-1]) ? $x.'/' : $x;
}
function hidden() {
	global $progres;
	echo '<input type="hidden" name="liberation" value="', $progres['liberation'], '" />';
	if( !array_key_exists( 'hidden', $progres ))
		return;
	foreach( $progres['hidden'] as $k => $v ){
		echo '<input type="hidden" name="', $k, '" value="', $v, '" />';
	}
}
function sauvevaleur( $nom, &$mixed, $f=false) {
	global $statut, $progres, $pointeur_fic;
	$f=$statut['workdir'].$nom.'.'.$progres['liberation'];
	if( $f === false && file_exists( $f )) {
		sauvevaleur( $nom.'.ecr', $mixed, true );
		rename( $fn.'.ecr', $fn );
		return;
	}
	$fh=fopen($f,'w');
	fwrite( $fh, serialize( $mixed ));
	fclose( $fh );
}
function chargevaleur($nom, &$mixed) {
	global $statut, $progres;
	$fn=$statut['workdir'].$nom.'.'.$progres['liberation'];
	if(!file_exists( $fn ))
		return;
	$fh=fopen($fn, 'r');
	$mixed=unserialize(fread($fh, filesize($fn)));
	fclose($fh);
}
 
 
function debut_form() {
	global $progres, $statut;
	if($statut['debut_form']) return;
	debut_doc();
	$statut['debut_form']=true;
	echo '<form action="', $_SERVER['PHP_SELF'], '" method="POST">';
	hidden();
}
function fin_form() {
	global $statut;
	if($statut['fin_form']) return;
	$statut['fin_form']=true;
	echo '<input type="submit" value="Suivant" />';
	echo "</form>";
}
define('OK','<span class="ok">réussi</span>');
define('ER','<span class="er">erreur</span>');
define('EC','<span class="ek">en cours</span>');
function etape($txt,$modif_derp){
	global $progres;
	if(!$modif_derp)
		$progres['etape'][]=$txt;
	else{
		$count=count($progres['etape']);
		if($count>1)
			$progres['etape'][$count-1]=$txt;
	}
}
function ok($etape){
	etape($etape.OK, false);
}
function er($etape){
	etape($etape.ER, false);
}
function ec($etape){
	etape($etape.EC, false);
}
function suivant() {
	debut_form(); fin_form(); fin_doc(); exit();
}
# boolean
function dos_haut( $nomfic ) {
	global $progres, $content;
	$nom=$nomfic.'.'.$progres['liberation'];
	if( file_exists( $nom ))
		return true;
	if( !($pl=fopen($nomfic, 'rb')))
		return false;
	if(!($pe=fopen($nom,'wb'))) {
		fclose($pl);
		return false;
	}
	@fwrite($pe,fread($pl,($taille=filesize($nomfic))));
	@fclose($pe);
	@fclose($pl);
	if( $taille!=filesize($nom)) {
		@unlink($nom);
		return false;
	}
	return true;
 
	while(false !== ($data=fread($pl,65536))){
		if(false === fwrite($pe,$data)) {
			fclose($pe);
			fclose($pl);
			@unlink($nom);
			return false;
		}
	}
	if(!feof($pl)) {
		fclose($pe);
		fclose($pl);
		@unlink($nom);
		return false;
	}
	fclose($pe);
	fclose($pl);
	return true;
}
 
function installe_precharge() {
	global $progres;
	$fn=$progres['inc'].'preload.php';
	$fnh=html($fn);
	if(file_exists($fn)) {
		message( 'Un fichier preload.php existe déja<br /><tt>'.html($fn).'</tt><br />Je considère ce fichier convenable (en fait j\'vois pas c\'que ça pourrait êt\' d\'aut\' qu\'le fichier qu\'j\'m\'apprêt\' à installer...).' );
		return $fn;
	}
	/*
	if(file_exists($fn) && ! array_key_exists( 'ecrase_preload', $_REQUEST )) {
		$progres['hidden']['ecrase_preload']=1;
		attention( "Le fichier « {$fnh} » existe déjà. Si vous poursuivez, il sera remplacé.</p><p>Sinon, abandonnez l'idée d'utiliser liberatator" );
		suivant();
	}
	*/
	if( !($fh=fopen($fn, 'w'))) {
		erreur( "Impossible de créer le fichier « $fn ».<br />Vérifiez la présence du répertoire « ".dirname($fn)." », et les droits d'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)");
		message( "Cliquez sur le bouton « suivant » pour réessayer");
		suivant();
	}
	fwrite( $fh, '<?php
$freefrdirtrash=$_SERVER[\'DOCUMENT_ROOT\'].\'/poubelle\';
 
function myglob( $patt, $drp=0 ) {
	$dir=dirname( $patt );
	$pat=basename( $patt );
	$md=($drp & GLOB_MARK)==GLOB_MARK;
	$reponse=array();
	if (is_dir($dir) && ($d = @opendir($dir))) {
		$gl = array( \',/,\', \'/\./\', \'/\*/\', \'/\?/\', \'/^/\', \'/$/\', \',/\.\*,\', \',^/\^\.\*,\'  );
		$re = array( \'\\/\', \'\.\',   \'.*\',   \'.\',    \'/^\',  \'\$/\', \'/[^.].*\', \'/^[^.].*\' );
		$newpat=preg_replace( $gl, $re, $pat );
			while (($filename = @readdir($d)) !== false) {
				if( $filename == \'.\' || $filename == \'..\' )
					continue;
				if( preg_match( $newpat, $filename )) {
					$reponse[]= $dir . \'/\' . $filename . (($md && is_dir($dir.\'/\'.$filename)) ? \'/\' : \'\');
				}
		}
	}
	if(($drp & GLOB_NOCHECK)&&count($reponse)==0)
		return array($patt);
	if($drp & GLOB_NOSORT)
		return $reponse;
	sort( $reponse );
	return $reponse;
}
 
function myrmdir( $d ) {
	global $freefrdirtrash;
	if(!is_dir($d))
		return false;
	$h=opendir($d);
	while(false!==($s=readdir($h))) {
		if( $s != \'.\' && $s != \'..\' ) {
			closedir($h);
			return false;
		}
	}
	closedir($h);
	return rename($d, $freefrdirtrash);
}
 
function myopendir($x, $y=null) {
	if(!is_dir($x)) return false;
	return is_null($y) ? @opendir($x) : @opendir($x,$y);
}
 
function myumask($x=null) {
	return 022;
}
 
if(!function_exists(\'array_fill_keys\')) {
	function array_fill_keys($keys, $value = \'\') {
		return is_array($keys) ?
			array_combine($keys,array_fill(0,count($keys),$value))
			: null;
	}
}
' );
 
	fclose( $fh );
	return $fn;
}
function augmente_precharge() {
	global $progres;
	$fn=$progres['inc'].'preload.php';
	$fnh=html($fn);
	if(!file_exists($fn)) {
		erreur( 'Aucun fichier preload.php n\'existe. Bizarre et normalement impossible<br />Veuillez relancer complètement liberatator avec un autre nom de libération !' );
		suivant();
	}
	if(false===($contenu=file($fn))) {
		erreur( "Étrange ! le fichier « $fn » existe mais on ne peut pas le lire...<br />Vérifiez la présence du répertoire « ".dirname($fn)." », et les droits d'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)");
		message( "Cliquez sur le bouton « suivant » pour réessayer");
		suivant();
	}
	# si array_fill_keys est présent, on rentre. rien à faire.
	foreach( $contenu as $ligne ) {
		if(!(false===strstr($ligne,'array_fill_keys')))
			return 'déjà présente';
	}
	if( !($fh=fopen($fn, 'a'))) {
		erreur( "Impossible d\'ajouter au fichier « $fn ».<br />Vérifiez la présence du répertoire « ".dirname($fn)." », et les droits d'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)");
		message( "Cliquez sur le bouton « suivant » pour réessayer");
		suivant();
	}
	fwrite( $fh, '
if(!function_exists(\'array_fill_keys\')) {
	function array_fill_keys($keys, $value = \'\') {
		return is_array($keys) ?
			array_combine($keys,array_fill(0,count($keys),$value))
			: null;
	}
}
' );
 
	fclose( $fh );
	return 'installée';
}
function verifie_session() {
	$sess=$_SERVER['DOCUMENT_ROOT'].'/sessions';
	if(!file_exists($sess)){
		if(!mkdir($sess)){
			erreur( "Impossible de créer le répertoire « {$sess} ».<br />Vérifiez la présence du répertoire « {$_SERVER['DOCUMENT_ROOT']} », et les droits d'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)");
			message( "Cliquez sur le bouton « suivant » pour réessayer");
			suivant();
		}
	}
	return $sess;
}
function verifie_php5(){
	if(version_compare(PHP_VERSION, '5.0.0') >= 0) {
		return;
	}
	$fn=$ici.'.htaccess';
	$err=true;
	if($fh=fopen($fn, 'a')){
		fwrite( $fh, "\nphp 1\n");
		$err=!fclose($fh);
	}
	if($err) {
		erreur( "Impossible d'activer php5 (création/modification du fichier « $fn ».<br />Vérifiez la présence du répertoire « {$ici} », et les droits d'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)");
		message( "Cliquez sur le bouton « suivant » pour réessayer");
		suivant();
	}
}
function videlock(){
	global $conf;
	if( ! is_writeable( $conf['savedir'] ) ) {
		erreur( 'Incroyable : Le dossier des verrous n\'est pas écriturable !!!<br />Vérifiez la présence du répertoire « ' . html( $conf['savedir'] ) . ' », et les droits d\'accès (heu chez free les droits sont <em><b><i><u><big>forcément</big></u></i></b></em> OK)');
		message( "Cliquez sur le bouton « suivant » pour réessayer");
		suivant();
	}
	foreach( myglob( $conf['savedir'] . '/locks/[0-9a-f]{32}' ) as $elem ) {
		myrmdir( $elem );
		if( is_file( $elem ) ) 
			unlink( $elem );
	}
	$elem=$conf['savedir'] . '/locks/_indexer.lock';
	myrmdir( $elem );
	if( is_file( $elem ) ) 
		unlink( $elem );
}
function prepare_parcours(){
	global $progres, $pointeur_fic;
	$fn=$progres['reclist'];
	$progres['fichiers']=file($fn, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
	$pointeur_fic=0;
	sauvevaleur('pointeur_fic', $pointeur_fic);
}
function html(&$string){
	return htmlspecialchars($string,ENT_NOQUOTES,'UTF-8');
}
function ecrit_tableau( $nomf, &$tab ) {
	if(!($pf=fopen($nomf, 'w'))) {
		return false;
	}
	$max=count($tab);
	for($i=0;$i<$max;++$i) {
		if(false===fwrite($pf,$tab[$i])) {
			fclose($pf);
			unlink($nomf);
			return false;
		}
	}
	return fclose($pf);
}
 
# In this function, we are under PHP5
function regcallback(&$l) {
	global $rec, $repl, $changement, $pointeur_fic, $numligne, $changements;
	$numligne++;
	$n=preg_replace( $rec, $repl, $l );
	if( $n !== $l ) {
		$changement++;
		$changements[]=array( 'num' => $pointeur_fic, 'numlig' => $numligne, 'ancien' => $l, 'nouveau' => $n );
	}
	return $n;
}
 
# In this function, we are under PHP5
function parcours() {
	global $progres, $pointeur_fic, $rec, $repl, $changement, $changements, $numligne;
 
	chargevaleur('pointeur_fic', $pointeur_fic);
	chargevaleur('chgt', $changements);
	$max=count($progres['fichiers']);
        $pref='/(^|([ \t(.{[,;@]))';
        $suf='(([]} \t,(])|$)/m';
        $rec=array(
                    $pref.'rmdir'.$suf,
                    $pref.'glob'.$suf,
                    $pref.'opendir'.$suf,
                    $pref.'umask'.$suf,
        );  
        $repl = array(
                    '$2myrmdir$3',
                    '$2myglob$3',
                    '$2myopendir$3',
                    '$2myumask$3',
        );  
 
	if( $pointeur_fic > 0 )
		ok( 'vérifié fichiers : '. $pointeur_fic.'/'.count($progres['fichiers']), false );
	else
		$changements=array();
	if( $pointeur_fic == count($progres['fichiers'])) {
		parcours_resultat();
		return;
	}
	debut_doc(); flush();
	echo '<p>Cette page va peut-être «&nbsp;pédaler dans la choucroute&nbsp;». <em>C\'est pas grave !</em><br />',
		'Attendez la fin du chargement et rechargez la en cliquant sur le bouton «&nbsp;suivant&nbsp;» ci dessous; ',
		'les opérations de remplacement continueront là où elle se seront arrêtées<br /><br />',
		'Répétez cette opération autant de fois que nécessaire, jusqu\'à ce que liberatator passe à l\'étape suivante.</p>';
	debut_form();fin_form();
	echo '<div class="listefic" id="listefic">';
	/*
	 * méthodes essayées :
	 * file_get_contents, preg_replace : ça marche pas sur les 'gros' fichiers (regexp trop lentes?)
	 * $tab=file(..), fwrite(implode($tab,'')) : ça bloque je sais pas pourquoi
	 * méthode actuelle :
	 * $tab=file(..); write ligne par ligne.
	 */
	for( $i=$pointeur_fic; $i < $max; ++$i ) {
		$donnees=file($progres['fichiers'][$i]);
		echo '<tt>', html( $progres['fichiers'][$i] ), '</tt> : '; flush();
		$changement=$numligne=0;
		$nouvdonnees=array_map('regcallback', $donnees );
		if( !$changement ) {
			echo '<span class="ook">Pas de changement</span><br />'; flush();
			$pointeur_fic++;
			sauvevaleur('pointeur_fic', $pointeur_fic);
			continue;
		}
		unset($donnees);
		if(!dos_haut($progres['fichiers'][$i])) {
			echo '<span class="er">Ne peut sauvegarder. Non modifié</span><br />';
			flush();
			continue;
		}
		if( false === ecrit_tableau( $progres['fichiers'][$i].'nouv',$nouvdonnees )) {
			echo '<span class="er">Ne peut créer version modifiée. Original conservé</span><br />';
			flush();
			continue;
		}
		unset($nouvdonnees);
		if(!unlink($progres['fichiers'][$i])) {
			echo '<span class="er">Ne peut enlever original. Fichier inchangé.</span><br />';
			flush();
			continue;
		}
		if(!rename($progres['fichiers'][$i].'nouv', $progres['fichiers'][$i] )){
			echo '<span class="er">Ne peut remplacer original par version modifiée. Original conservé.</span><br />';
			flush();
			unlink($progres['fichiers'][$i].'nouv');
			continue;
		}
		$pointeur_fic++;
		sauvevaleur('pointeur_fic', $pointeur_fic);
		sauvevaleur('chgt', $changements );
		echo '<span class="ok">modifié OK !</span><br />';
		flush();
	}
	echo '</div>';
}
function parcours_resultat() {
	global $statut, $progres, $changements;
	$progres['etat'] = 'fini';
	sauvevaleur('sauve', $progres);
	chargevaleur('chgt', $changements);
	debut_doc();
	echo "<a name=\"haut\"></a><h2>C'est fini !</h2>",
		'<p>Dokuwiki est modifié et maintenant prêt à fonctionner chez free</p>',
		'<p>Vous trouverez ci dessous la <a href="#modif">liste des fichiers modifiés</a> et une série de commande FTP pour <a href="#defaire">défaire ce qui a été fait</a>.</p>',
		'<p>Vous devriez sauvegarder ce fichier de résultat</p>',
		'<p>Vous pouvez maintenant</p><ul>';
	$base=dirname(rtrim($progres['conf'], '/')).'/';
	$root=rtrim($_SERVER['DOCUMENT_ROOT'], '/');
	$moi=basename($root);
	$chemin=str_replace($root, '', $base);
	$url="http://{$moi}.free.fr{$chemin}/";
	echo '<li><a href="', $url, 'install.php', '">installer votre wiki</a>,</li><li>ou ',
		'<a href="', $url, 'doku.php', '">utiliser votre wiki</a> si vous l\'aviez déjà installé.</li></ul>';
	echo '<a name="modif"></a><h2>Fichiers modifiés</h2>';
	$max=count($changements);
	# $changements[]=array( 'num' => $pointeur_fic, 'numlig' => $numligne, 'ancien' => $l, 'nouveau' => $n );
	echo '<ol>';
	$li=0;
	for($i=0;$i<$max;++$i){
		if(!$i || $changements[$i]['num'] != $changements[$i-1]['num']){
			if($i) echo '</pre></li>';
			echo '<li><tt>', $progres['fichiers'][$changements[$i]['num']], '</tt><br />',
				'fichier original <tt>', $progres['fichiers'][$changements[$i]['num']],'.',$progres['liberation'],
				'</tt><p>changements effectués</p><pre>';
			$li=1;
		}
		#echo '<pre>';
		printf("%5d < | %s", $changements[$i]['numlig'], $changements[$i]['ancien'] );
		printf("%5d > | %s", $changements[$i]['numlig'], $changements[$i]['nouveau'] );
		#echo '</pre>';
	}
	if($li) echo '</li>';
	echo '</ol></div>';
	echo '<p><a href="#haut">retour début</a></p><a name="defaire"></a><h2>Commandes pour défaire les modifications</h2><p>Voilà les commandes que vous pouvez utiliser avec votre client ftp en ligne de commande. Si vous utilisez lftp, remplacez <tt>rename</tt> par <tt>mv</tt></p><p><b>nb</b><br />ces commandes ne prennent pas en compte l\'installation éventuelle du fichier <tt>preload.php</tt> qui a pu avoir lieu. Ce fichier, s\'il a été installé, est de toutes les façons sans effet sur un DokuWiki non modifié.</p><pre>';
	$vu=array();
	for($i=0;$i<$max;++$i){
		if( array_key_exists( $changements[$i]['num'], $vu ) )
			continue;
		$vu[$changements[$i]['num']]++;
		echo 'rename ', $progres['fichiers'][$changements[$i]['num']],'.',$progres['liberation'],
		             ' ',
		             $progres['fichiers'][$changements[$i]['num']], "\n";
	}
	echo '</pre>';
	fin_doc();
	exit;
}
 
if( array_key_exists( 'liberation', $_REQUEST ))
	$progres['liberation']=$_REQUEST['liberation'];
if( ! $progres['liberation'] ) {
	debut_doc();
?><h2>bienvenue !</h2><p>Bonjour et bienvenue dans le programme liberatator -- le premier des (pas encore) fameux <u>outils tators</u> (<i>tator tools</i> en anglais)--, programme qui va vous permettre de faire fonctionner <a href="http://www.dokuwiki.org/">DokuWiki</a> chez l'hébergeur free.</p>
<P>Vous serez guidés tout au long du processus. Avant toute modification, liberatator effectue une copie de sauvegarde des fichiers. Liberatator vous indiquera aussi la liste des fichiers modifiés. Le nom des fichiers sauvegardés sera le nom d'origine des fichiers, suivi du nom de la session de libération, nom que <em>vous</em> allez choisir maintenant.</p>
<p><em><big>Attention, liberatator est totalement expérimental !</big></em></p>
<p>Liberatator est distribué sous les termes de la licence libre CeCILL version 2</p><ul><li>Version Française <a href="http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html">http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html</a></li><li>English version <a href="http://www.cecill.info/licences/Licence_CeCILL_V2-en.html">http://www.cecill.info/licences/Licence_CeCILL_V2-en.html</a></li></ul></p>
<div><pre style="text-align:left;">
              FRANÇAIS                |        ENGLISH
--------------------------------------+--------------------------------------
L'avertissement ci-dessous n'est      | This is only a short warning.
qu'une mis en garde. Lisez complète-  | Read the full licence.
ment la licence d'utilisation.        |
--------------------------------------+--------------------------------------
 En contrepartie de l'accessibilité   |  As a counterpart to the access to
 au code source et des droits de      |  the source code and  rights to
 copie, de modification et de         |  copy, modify and redistribute
 redistribution accordés par cette    |  granted by the license, users are
 licence, il n'est offert aux         |  provided only with a limited
 utilisateurs qu'une garantie         |  warranty  and the software's
 limitée.  Pour les mêmes raisons,    |  author,  the holder of the economic
 seule une responsabilité restreinte  |  rights,  and the successive
 pèse sur l'auteur du programme,  le  |  licensors  have only  limited
 titulaire des droits patrimoniaux    |  liability.
 et les concédants successifs.        |
                                      |
 A cet égard  l'attention de          |  In this respect, the user's
 l'utilisateur est attirée sur les    |  attention is drawn to the risks
 risques associés au chargement,  à   |  associated with loading,  using,
 l'utilisation,  à la modification    |  modifying and/or developing or
 et/ou au développement et à la       |  reproducing the software by the
 reproduction du logiciel par         |  user in light of its specific
 l'utilisateur étant donné sa         |  status of free software, that may
 spécificité de logiciel libre, qui   |  mean  that it is complicated to
 peut le rendre complexe à manipuler  |  manipulate,  and  that  also
 et qui le réserve donc à des         |  therefore means  that it is
 développeurs et des professionnels   |  reserved for developers  and
 avertis possédant  des               |  experienced professionals having
 connaissances  informatiques         |  in-depth computer knowledge. Users
 approfondies.  Les utilisateurs      |  are therefore encouraged to load
 sont donc invités à charger  et      |  and test the software's suitability
 tester  l'adéquation  du logiciel à  |  as regards their requirements in
 leurs besoins dans des conditions    |  conditions enabling the security of
 permettant d'assurer la sécurité de  |  their systems and/or data to be
 leurs systèmes et ou de leurs        |  ensured and,  more generally, to
 données et, plus généralement, à     |  use and operate it in the same
 l'utiliser et l'exploiter dans les   |  conditions as regards security.
 mêmes conditions de sécurité.        |
                                      |
 Le fait que vous puissiez accéder à  |   The fact that you are presently
 cet en-tête signifie que vous avez   |   reading this means that you have
 pris connaissance de la licence      |   had knowledge of the CeCILL license
 CeCILL, et que vous en avez accepté  |   and that you accept its terms.
 les termes.                          |
</pre></div>
<p>Si vous n'êtes pas d'accord, n'utilisez pas liberatator, détruisez toutes les copies en votre possession.</p>
<h2>continuer</h2>
<?php
debut_form();
$passe=array();
foreach( myglob( $statut['workdir'].'sauve.*') as $toto) {
	$passe[]=str_replace('sauve.', '', basename($toto));
}
if(count($passe)){
	echo '<p>Libération passées ou en cours :</p><ul>';
	foreach( $passe as $pl )
		echo '<li>',html($pl),'</li>';
	echo '</ul><hr>';
}
$maintenant=date('Y-m-d_H.i.s');
echo '<p>Nom de cette libération. lettres sans accent seulement, chiffres, tiret  et soulignés (par exemple <tt>liber001</tt> ou <tt>', $maintenant, '</tt>)<br />nom de libération: <input type="text" name="liberation" value="', $maintenant, '" /></p>';
	suivant();
}
 
chargevaleur('sauve', $progres);
################################## conf dir ###############
$conf=DOKU_INC . 'conf/';
if( array_key_exists( 'conf', $progres )) $conf=$progres['conf'];
if( array_key_exists( 'conf', $_REQUEST )) {
	$conf=req_vers_dir($_REQUEST['conf']);
	$statut['asauver']=true;
}
 
if( !is_dir( $conf )) {
	debut_doc();
	echo 'dossier \'conf\' pas trouvé<br />';
	debut_form();
	echo 'nom du dossier \'conf\'<input type="text" name="conf" /><br />';
	suivant();
}
define( 'DOKU_CONF', $conf );
$progres['conf']=DOKU_CONF;
if($statut['asauver']) { ok('Dossier « conf » : '); sauvevaleur('sauve', $progres); $statut['asauver']=false; echo $progres['etape'][count($progres['etape'])-1]; }
############################# inc dir #################
$inc=DOKU_INC . 'inc/';
if( array_key_exists( 'inc', $progres )) $inc=$progres['inc'];
if( array_key_exists( 'inc', $_REQUEST )) {
	$inc=req_vers_dir($_REQUEST['inc']);
	$statut['asauver']=true;
}
 
if( !is_dir( $inc )) {
	debut_doc();
	echo 'dossier \'inc\' pas trouvé<br />';
	debut_form();
	echo 'nom du dossier \'inc\'<input type="text" name="inc" /><br />';
	suivant();
}
define( 'DOKU_INCLUDE', $inc );
$progres['inc']=DOKU_INCLUDE;
if($statut['asauver']) { ok('Dossier « inc » : '); sauvevaleur('sauve',$progres); $statut['asauver']=false; echo $progres['etape'][count($progres['etape'])-1]; }
############################# lib dir #################
#echo "go for lib";flush();
$lib=DOKU_INC . 'lib/';
if( array_key_exists( 'lib', $progres )) $lib=$progres['lib'];
if( array_key_exists( 'lib', $_REQUEST )) {
	$lib=req_vers_dir($_REQUEST['lib']);
	$statut['asauver']=true;
}
 
if( !is_dir( $lib )) {
	debut_doc();
	echo 'dossier \'lib\' pas trouvé<br />';
	debut_form();
	echo 'nom du dossier \'lib\'<input type="text" name="lib" /><br />';
	suivant();
}
define( 'DOKU_LIB', $lib );
$progres['lib']=DOKU_LIB;
if($statut['asauver']) { ok('Dossier « lib » : '); sauvevaleur('sauve',$progres); $statut['asauver']=false; echo $progres['etape'][count($progres['etape'])-1]; }
############################### liberatator working dir
if( $progres['etat'] == 'dir_non_verifie' )
	$progres['etat']='dir_travail_ok';
############################### doku rec listing ###########
# must be performed in one single step.otherwise, we can't
# do anything
#########################################################
# returns true or false
function do_reclist( $dir, $wfh, &$ign ) {
	global $progres;
	if( ! ($d=myopendir( $dir )) ) return false;
	while( false != ($name=readdir($d)) ) {
		# skip the 'lang' 'conf' 'geshi' subdir. Nothing
		# interresting in there.
		if( '.' == $name || '..' == $name || 'lang' == $name || 'geshi' == $name || 'conf' == $name )
			continue;
		if( is_dir( $dir.$name )) {
			do_reclist( $dir.$name.'/', $wfh, $ign );
		}
		elseif(fnmatch('*.php', $name)&&!array_key_exists($dir.$name,$ign)){
			fprintf( $wfh, "%s\n", $dir.$name, $ign );
		}
	}
	return true;
}
 
function reclist() {
	global $progres;
	global $statut;
	$fn=$statut['workdir'].'reclist.'.$progres['liberation'];
	$progres['reclist']=$fn;
	if( $progres['etat'] == 'commence_liste_fic' ) {
		debut_doc();
 
		$ignore=array(DOKU_INCLUDE.'preload.php'=>true);
		$filelist=fopen( $fn, 'w' );
		if( do_reclist( DOKU_INCLUDE, $filelist, $ignore )) {
			if(!fclose($filelist))
				return;
			$progres['etat']='dir_include_list_ok';
			sauvevaleur('sauve',$progres);
			ok('fichiers .php 1/2 : ');
			message( "La première partie de l'obtention de la liste des fichiers s'est déroulée correctement" );
			message( "l'étape suivante est d'obtenir la seconde partie de cette liste" );
		}
		return;
	}
	if( $progres['etat'] == 'dir_include_list_ok' ) {
		if(!copy($fn, $fn.'.ecr'))
			return;
		$ignore=array();
		$filelist=fopen( $fn.'.ecr', 'a' );
		if( do_reclist( DOKU_LIB, $filelist, $ignore )) {
			if(!fclose($filelist))
				return;
			if(!rename($fn.'.ecr', $fn))
				return;
			$progres['etat']='dir_lib_list_ok';
			ok('fichiers .php (1/2  et 2/2) : ');
			sauvevaleur('sauve',$progres);
			message( "La seconde partie de l'obtention de la liste des fichiers s'est déroulée correctement" );
			message( "L'étape suivante consistera à examiner chacun des fichiers et à lesmodifier si besoin");
		}
		return;
	}
}
 
 
global $conf; $conf=array();
include( DOKU_CONF.'dokuwiki.php' );
if( file_exists( DOKU_CONF.'local.php' ) )
	include( DOKU_CONF.'local.php' );
switch( $progres['etat'] ) {
case 'dir_travail_ok':
	debut_doc();
	$progres['etat']='installe_precharge';
	sauvevaleur('sauve',$progres);
	$progres['etat']='verifie_session';
	ok('détermination des répertoires de <a href="http://www.dokuwiki.org/">DokuWiki</a>.');
	echo $progres['etape'][count($progres['etape'])-1];
	message( "L'étape suivante consiste à installer un fichier <i>preload.php</i>. <a href=\"http://www.dokuwiki.org/\">DokuWiki</a> prend en compte ce fichier automatiquement;. Il ne contient que des définitions de fonctions. Ce fichier sera nécessaire au fonctionnement de <a href=\"http://www.dokuwiki.org/\">DokuWiki</a> lorsqu'il aura été modifié. Ce fichier ne représente <em>aucune</em> gêne pour un <a href=\"http://www.dokuwiki.org/\">DokuWiki</a> non modifié." );
	suivant();
break;
case 'installe_precharge':
	debut_doc();
	$n=installe_precharge();
	ok("Installation « {$n} » : ");
	$progres['etat']='precharge_contient_array_fill_keys';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "L'étape suivante consiste à vérifier si le fichier <i>preload.php</i> est une ancienne version. Si c'est le cas, la définition conditionnelle de la fonction <i>array_fill_keys</i> sera ajoutée" );
	suivant();
break;
case 'precharge_contient_array_fill_keys' :
	debut_doc();
	$n=augmente_precharge();
	ok("fonction « array_fill_keys » {$n} : ");
	$progres['etat']='verifie_session';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "L'étape suivante consiste à vérifier la présence d'un répertoire « sessions », nécessaire à PHP, et donc à <a href=\"http://www.dokuwiki.org/\">DokuWiki</a>, pour gérer les sessions." );
	suivant();
break;
case 'verifie_session':
	debut_doc();
	$n=verifie_session();
	ok("Répertoire de sessions « {$n} » : ");
	$progres['etat']='verifie_php5';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "L'étape suivante consiste à vérifier que PHP version 5 est activé. Les versions de <a href=\"http://www.dokuwiki.org/\">DokuWiki</a> postérieures à décembre 2010 ont besoin de PHP version 5." );
	suivant();
break;
case 'verifie_php5':
	debut_doc();
	verifie_php5();
	ok("PHP version 5 : ");
	$progres['etat']='vide_vieux_locks';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "Au cours de l'étape suivante, je vais faire le ménage dans le répertoire des verrous." );
	suivant();
break;
case 'vide_vieux_locks':
	debut_doc();
	videlock();
	ok( 'Vieux locks vidés : ' );
	$progres['etat']='commence_liste_fic';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "L'étape suivante consiste à déterminer la liste de tous les fichiers d'extension <i>.php</i> contenus dans votre installation de <a href=\"http://www.dokuwiki.org/\">DokuWiki</a>.</p><p>Si cette étape échoue, il faudra recommencer." );
	suivant();
case 'commence_liste_fic': case 'dir_include_list_ok':
	debut_doc();
	reclist();
	suivant();
break;
case 'dir_lib_list_ok':
	debut_doc();
	prepare_parcours();
	ok('Fin prêt pour démarrer les modifications des fichiers <i>.php</i> : ');
	$progres['etat']='parcours';
	sauvevaleur('sauve',$progres);
	echo $progres['etape'][count($progres['etape'])-1];
	message( "Au cours de l'étape suivante liberatator va effectivement modifier les fichiers d'extension <i>.php</i> contenus dans votre installation de <a href=\"http://www.dokuwiki.org/\">DokuWiki</a>.</p><p>Si cette étape échoue, il suffira de recommencer." );
# echo '<pre>';print_r($progres);echo'</pre>';
	suivant();
break;
case 'parcours':
	parcours();
break;
case 'fini':
	parcours_resultat();
break;
default:
	echo 'b';
break;
}
 
suivant();

Comment ça fonctionne

liberatator

  • active PHP 5 si besoin,
  • crée si besoin le répertoire /sessions indispensable,
  • installe un fichier inc/preload.php, qui sera préchargé par DokuWiki et contient les fonctions myopendir, myrmdir, myglob, myumask et array_fill_keys3),
  • nettoye le répertoire de verrous,
  • crée la liste de fichiers PHP qui peuvent contenir des constructions problématiques en parcourant l'arborescence de dokuwiki à la recherche de tous les fichiers PHP – en omettant les répertoires conf, lang et geshi qui ne contiennent rien de problématique –,
  • analyse un à un tous les fichiers de la liste à la recherche d'un appel à l'une des fonctions suivantes opendir, rmdir, glob, umask et les remplace par des appels respectifs à myopendir, myrmdir, myglob et myumask,
  • sauvegarde tout fichier avant modification,
  • présente un résultat, le journal etc…

À noter, liberatator est prévu pour résister aux interruptions intempestives. Soit une étape est réalisée, soit elle ne l'est pas. Soit un fichier est modifié, soit il ne l'est pas. il n'y a pas d'état intermédiaire.

Liberatator peut être lancé de nombreuses fois sur la la même arborescence sans aucun problème. Il est même prévu exactement pour cette utilisation.

voir aussi

1)
ou tout autre nom que vous lui avez donné
2)
même si le taux de visite sur ma page est pas des plus fameux…
3)
nécessaire seulement pour le greffon translattion