Cette page est obsolète voir ActionAttach
Ma solution pour gérer l'upload de fichier comporte 2 fichiers :
- attach.php qui contient une action à mettre dans le répertoire "actions"
- upload.php qui contient un handler à mettre dans le répertoire "handlers/page" (Modification par NM, 15.01.2004)
L'action {{attach}}
Permet de lier un fichier à une page, d'uploader ce fichier. Le fichier uploadé peut être de n'importe quel type. Si l'extension de ce fichier est gif, jpeg, png, ou jpg (par défaut) alors il est traité comme une image et affiché. Dans le cas ou c'est une image, on peut associer un lien à l'image. Ce lien peut être un mot wiki, un URL ou un lien interwiki. Les images supportent également les classes de styles ayant pour nom
.image_XXXX et définies dans
wakka.css avec
XXXX le nom utilisé dans le paramètre class.
Telle qu'elle est actuellement, l'action fonctionne correctement et est utilisée par plusieurs site
WikiNi.
Paramètres :
- file : nom du fichier sur le serveur (obligatoire)
- desc : description du fichier (obligatoire)
- delete : si non vide alors supprime le fichier du serveur
- link : si non vide ET que le fichier est une image alors l'image est un lien vers l'URL passé comme valeur de ce paramètre. Les URL de type http://www.domaine.com/path/to/page et le nom de page WikiNi? sont supportées.
- class : indique le nom de la ou des classes de styles à utiliser pour afficher l'image. Les noms des classes sont séparés un espace.
Compatibilité avec d'anciennes versions :
- attachfile = file
- attachdesc = desc
- attachdelete = delete
- attachlink = link
Exemples :
Lier un fichier :
{{attach attachfile="filename" attachdesc="description"}}
Une image sensible :
{{attach file="filename" desc="description" link="PagePrincipale" class="noborder left"}}
- avec les classes de style :
- .image_left { float: left; } /* bloc flotant à gauche */
- .image_noborder { border-width: 0px; } /* pas de bordure */
Supprimer un fichier :
{{attach attachfile="filename" attachdesc="description" attachdelete="yes"}}
Configuration :
Dans le fichier
wakka.config.php, ajouter la ligne suivante :
- $wakkaConfig['upload_path'] = "/path/to/upload/directory"; //pas de "/" a la fin !!!
- ou /path/to/upload/directory est le chemin d'accès au répertoire des uploads. Ce chemin peut être absolu ou relatif au fichier wakka.php à la racine du wiki. Cela permet d'indiquer le répertoire dans lequel seront stockés les fichiers. Créer le répertoire designé par le paramètre de configuration upload_path. Ce répertoire doit être accessible en écriture. Attention aux droits si le safe_mode est actif, et il faudra peut être créer ce répertoire a la main via FTP.
- $wakkaConfig['attach_images'] = "gif|jpeg|png|jpg";
- Liste des extensions de fichiers devant être considérés comme des images (insensible à la casse).
- $wakkaConfig['attach_script'] = "php|asp|vb|vbs|js";
- Liste des extensions de fichiers devant être considérés comme des scripts coté serveur (insensible à la casse). Les liens vers de tels fichiers auront un suffixe _attach ajouté pour eviter leur exécution sur le serveur.
Évolutions envisagées
- Un gestionnaire de download pour éviter les problèmes lié à l'extension du fichier et donc supprimer le suffixe _attach
- Une gestion de versions permettant de lier un fichier à une version de la page et donc d'avoir plusieurs versions du même fichier. L'idée serait de prendre l'ID de la page au moment de l'upload du fichier et d'ajouter cet ID au nom du fichier. Si une nouvelle version de la page est créée, le fichier lié serait le fichier ayant le plus haut ID inferieur à l'ID de la page actuel. Ce système nécessite un gestionnaire de download. L'avantage est de ne pas modifier la base de données. Les fichiers obsolètes car la page à été effacée seront supprimés par l'action attach (puisque appelée à chaque visualisation de page).
Voici le code de attach.php
<?php
# Permet de lier un fichier à une page, d'uploader ce fichier.
# Le fichier uploadé peut être de n'import quel type. Si l'extension de ce
# fichier est gif,jpeg,png,jpg alors il est traité comme une image et affiché.
# Dans le cas ou c'est une image, on peut associer un liens à l'image. Ce lien
# peut etre un mot wiki, un URL ou un lien interwiki.
# Les images supportent également les classes de style ayant pour nom
# ".image_XXXX" et définies dans wakka.css avec XXXX le nom utilise dans le
# parametre class
#
# Paramètres : file : nom du fichier sur le serveur (obligatoire)
# desc : description du fichier (obligatoire)
# delete : si non vide alors supprime le fichier du serveur
# link : si non vide ET que le fichier est une image alors
# l'image est un lien vers l'URL passé comme valeur de
# ce paramètre. Les URL de type http://www.domaine.com/path/to/page
# et le nom de page WikiNi? sont supportées.
# class : indique le nom de la ou les classes de style a utiliser
# pour afficher l'image. les nom des classes sont séparés
# un espace.
# Compatibilite avec d'ancienne versions :
# attachfile = file
# attachdesc = desc
# attachdelete = delete
# attachlink = link
#
# Lier un fichier : {{attach attachfile="filename" attachdesc="description"}}
# Une image sensible :
# {{attach file="filename" desc="description" link="PagePrincipale" class="noborder left"}}
# avec les classes de style :
# .image_left { float: left; } /* bloc flotant à gauche */
# .image_noborder { border-width: 0px; } /* pas de bordure */
# Supprimer un fichier : {{attach attachfile="filename" attachdesc="description" attachdelete="yes"}}
#
# Necessite le fichier handler/page/upload.php pour fonctionner
#*******************************************************************************
# Configuration :
# Dans le fichier wakka.config.php, ajouter la ligne suivante :
#
# $wakkaConfig['upload_path'] = "/path/to/upload/directory"; //pas de "/" a la fin !!!
# ou "/path/to/upload/directory" est le chemin d'accès au repertoire des uploads.
# ce chemin peut être absolu ou relatif au fichier wakka.php à la racine du wiki
#
# $wakkaConfig['attach_images'] = "gif|jpeg|png|jpg";
# liste des extension de fichier devant être considéré comme des images (insenssible
# a la casse)
#
# $wakkaConfig['attach_script'] = "php|asp|vb|vbs|js";
# liste des extension de fichier devant être considéré comme des scripts coté
# serveurimages (insenssible a la casse). Les lien vers de tel fichiers auront
# un suffix "_attach" ajouté pour eviter leur execution sur le serveur
#
# Cela permet d'indiquer le repertoire dans lequel seront stockes les fichiers.
# Créer le répertoire designé par le parametre de configuration 'upload_path'.
# Ce repertoire doit être accessible en écriture. Attention aux droit si le safe_mode
# est actif, et il faudra peut etre creer ce repertoire a la main via FTP.
#*******************************************************************************
# copyrigth Eric Feldstein 2003
#*******************************************************************************
if (! function_exists('mkdir_recursif')) {
function mkdir_recursif ($dir) {
if (strlen($dir) == 0) return 0;
if (is_dir($dir)) return 1;
elseif (dirname($dir) == $dir) return 1;
$res = mkdir($dir,0755);
chmod($dir,0755);
return (mkdir_recursif(dirname($dir)) and $res);
}
}
if (! function_exists('GetScriptPath')) {
function GetScriptPath () {
global $_SERVER;
if (preg_match("/.(php)$/i",$_SERVER["PHP_SELF"])){
$a = explode('/',$_SERVER["PHP_SELF"]);
$a[count($a)-1] = '';
$path = implode('/',$a);
}else{
$path = $_SERVER["PHP_SELF"];
}
return !empty($_SERVER["SERVER_HOST"])? 'http://'.$_SERVER["SERVER_HOST"].$path : 'http://'.$_SERVER["SERVER_NAME"].$path ;
}
}
unset($file);
unset($desc);
unset($delete);
unset($link);
//extension des fichiers particulier
//fichier considéré comme des images
$ext_image = $this->GetConfigValue("attach_images");
if (empty($ext_image)) $ext_image = "gif|jpeg|png|jpg";
//fichier dont l'extension doit être modifiée pour ne pas être executable sur le serveur
$ext_script = $this->GetConfigValue("attach_script");
if (empty($ext_script)) $ext_script = "php|asp|vb|vbs|js";
//recuperation des parametres
$file = $this->GetParameter("attachfile");
if (empty($file)) $file = $this->GetParameter("file");
$desc = $this->GetParameter("attachdesc");
if (empty($desc)) $desc = $this->GetParameter("desc");
$delete = $this->GetParameter("attachdelete");
if (empty($delete)) $delete = $this->GetParameter("delete");
$link = $this->GetParameter("attachlink");//url de lien - uniquement si c'est une image
if (empty($link)) $link = $this->GetParameter("link");
$scriptPath = GetScriptPath();
//récupération des classes CSS à utiliser
if ($this->GetParameter("class")) {
$array_classes = explode(" ", $this->GetParameter("class"));
foreach ($array_classes as $c) { $classes = $classes . "image_" . $c . " "; }
}
if ((empty($file)) || (empty($desc))) {
echo $this->Format("//action attach : paramètres invalides//---");
}else{
//repertoire d'upload
if ($this->config['upload_path'] == '') $this->config['upload_path'] = 'files';
//test le safe_mode
if (ini_get("safe_mode")) { //safe_mode actif : fichier destination dans le repertoire "upload" avec le nom NomPage_NomFichier.ext
$upload_path = $this->config['upload_path'];
$full_file_name = $upload_path.'/'.$this->GetPageTag().'_'.$file;
}else{ //safe_mode inactif : fichier destination dans le repertoire "NomPage"
$upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
if (! is_dir($upload_path)) mkdir_recursif($upload_path);
$full_file_name = $upload_path.'/'.$file;
}
//blocage des scripts (securite) : ajout de _attach a la fin du nom du fichier
if (preg_match("/.(".$ext_script.")$/i",$full_file_name)) $full_file_name .= "_attach";
//test si commande de suppression
if (file_exists($full_file_name)){
if ($delete) {
unlink("./".$full_file_name);
}
}
//test si le fichier lié existe
if (file_exists($full_file_name)){
//fichier existe : test si c'est une image
if (preg_match("/.(".$ext_image.")$/i",$file)){
//c'est une image : balise <IMG..../>
$img .= "<img src=\"".$scriptPath.$full_file_name."\" ".
// ($classes?"class=\"$classes\" ":"").
"alt=\"".$desc.($link?"\nLien vers: $link":"")."\" />";
//test si c'est une image sensible
if(!empty($link)){
//c'est une image sensible
//test si le lien est un lien interwiki
if (preg_match("/^([A-Z][A-Z,a-z]+)[:]([A-Z,a-z,0-9]*)$/s", $link, $matches))
{ //modifie $link pour être un lien vers un autre wiki
$link = $this->GetInterWikiUrl($matches[1], $matches[2]);
}
//calcul du lien
$output = $this->Format('[['.$link." $file]]");
$output = eregi_replace(">$file<",">$img<",$output);//insertion du tag <img...> dans le lien
}else{
//ce n'est pas une image sensible
$output = $img;
}
$output = ($classes?"<div class=\"$classes\">$output</div>":$output);
echo $output;
}else{
//ce n'est pas une image
echo $this->Link($scriptPath.$full_file_name,"",$desc);
}
}else{
//fichier inexistant => affiche le nom du fichier
if($delete) { //si commande delete alors affichage du fichier barré
echo $this->Format('@@'.$file.'@@')."<a href=\"".$this->href("upload",$this->GetPageTag(),"file=$file")."\">?</a>";
}else{
echo $file."<a href=\"".$this->href("upload",$this->GetPageTag(),"file=$file")."\">?</a>";
}
}
}
?>
Voici le code de upload.php
<?php
# Execute l'upload des fichier lier par l'action {{attach}}
#
# Necessite le fichier actions/attach.php pour fonctionner
#
#*******************************************************************************
# copyrigth Eric Feldstein 2003
#*******************************************************************************
//vérification de sécurité
if (!eregi("wakka.php", $_SERVER['PHP_SELF'])) {
die ("accès direct interdit");
}
echo $this->Header();
?>
<div class="page">
<?php
echo $this->Format("====Formulaire d'envoi de fichier====\n---");
if ($HasAccessWrite=$this->HasAccess("write")){
//recuperation des extension considere comme des scripts
$ext_script = $this->GetConfigValue("attach_script");
if (empty($ext_script)) $ext_script = "php|asp|vb|vbs|js";
switch ($_SERVER["REQUEST_METHOD"]) {
case "GET" :
$file = $_GET['file'];
echo $this->Format("**Envois du fichier $file :**\n")
."<form enctype=\"multipart/form-data\" name=\"frmUpload\" method=\"POST\" action=\"".$_SERVER["PHP_SELF"]."\">\n"
." <input type=\"hidden\" name=\"wiki\" value=\"".$this->GetPageTag()."/upload\" />\n"
." <input type=\"hidden\" name=\"file\" value=\"$file\" />\n"
." <input type=\"file\" name=\"upFile\" size=\"50\" /><br />\n"
." <input type=\"submit\" value=\"Envoyer\" />\n"
."</form>\n";
break;
case "POST":
$file = $_POST['file'];
//blocage des scripts (securite) : ajout de _attach a la fin du nom du fichier
if (preg_match("/.(".$ext_script.")$/i",$file)) $file .= "_attach";
//test le safe_mode
if (ini_get("safe_mode")) { //safe_mode actif : fichier destination = NomPage_NomFichier.ext
$destFile = $this->config['upload_path'].'/'.$this->GetPageTag().'_'.$file;
}else{ //safe_mode inactif : fichier destination dans le repertoire "NomPage"
//repertoire d'upload
$upload_path = $this->config['upload_path'].'/'.$this->GetPageTag();
$destFile = $upload_path.'/'.$file;
}
if ($_FILES['upFile']['error']==0){
$srcFile = $_FILES['upFile']['tmp_name'];
if (move_uploaded_file($srcFile,$destFile)){
chmod($destFile,0644);
header("Location: ".$this->href("",$this->GetPageTag(),""));
}else{
echo $this->Format("//Erreur lors du déplacement du fichier temporaire//---");
echo $this->Format("Retour à la page ".$this->GetPageTag());
}
}else{
switch ($_FILES['upFile']['error']){
case 1:
echo $this->Format("//Le fichier téléchargé excède la taille de upload_max_filesize, configuré dans le php.ini.//---");
break;
case 2:
echo $this->Format("//Le fichier téléchargé excède la taille de MAX_FILE_SIZE, qui a été spécifiée dans le formulaire HTML.//---");
break;
case 3:
echo $this->Format("//Le fichier n'a été que partiellement téléchargé.//---");
break;
case 4:
echo $this->Format("//Aucun fichier n'a été téléchargé.//---");
break;
}
echo $this->Format("Retour à la page ".$this->GetPageTag());
}
break;
default : echo $this->Format("//Methode de requete invalide//---");
}
}else{
echo $this->Format("//Vous n'avez pas l'accès en écriture à cette page//---");
echo $this->Format("Retour à la page ".$this->GetPageTag());
}
?>
</div>
<?php echo $this->Footer(); ?>