From f68be991ffc58b7e65fae4b74fe5ad06d2e79a60 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@users.sourceforge.net>
Date: Sun, 4 Oct 2009 17:18:09 +0000
Subject: [PATCH] Fix: Data in memory must always be encoded in utf8. PHP files
 functions need ISO, so we convert data just before and after using them.

---
 htdocs/categories/categorie.class.php         |   4 +-
 htdocs/document.php                           |  30 +-
 htdocs/html.formfile.class.php                |  14 +-
 htdocs/imports/import.php                     |  13 +-
 .../modules/commande/modules_commande.php     | 340 +++++++++---------
 .../modules/facture/modules_facture.php       |  24 +-
 .../modules/fichinter/modules_fichinter.php   |  46 +--
 .../modules/livraison/modules_livraison.php   |  12 +-
 .../modules/propale/modules_propale.php       | 336 ++++++++---------
 .../modules_commandefournisseur.php           |   8 +-
 htdocs/lib/files.lib.php                      |  39 +-
 htdocs/lib/functions.lib.php                  |  27 +-
 htdocs/product.class.php                      |  82 +++--
 htdocs/product/photos.php                     |   6 +-
 htdocs/viewimage.php                          |  15 +-
 15 files changed, 524 insertions(+), 472 deletions(-)

diff --git a/htdocs/categories/categorie.class.php b/htdocs/categories/categorie.class.php
index 1385c963899..31744796bfe 100644
--- a/htdocs/categories/categorie.class.php
+++ b/htdocs/categories/categorie.class.php
@@ -1094,7 +1094,7 @@ class Categorie
 		$filename = eregi_replace($dir,'',$file); // Nom du fichier
 
 		// On efface l'image d'origine
-		unlink($file);
+		dol_delete_file($file,1);
 
 		// Si elle existe, on efface la vignette
 		if (eregi('(\.jpg|\.bmp|\.gif|\.png|\.tiff)$',$filename,$regs))
@@ -1102,7 +1102,7 @@ class Categorie
 			$photo_vignette=eregi_replace($regs[0],'',$filename).'_small'.$regs[0];
 			if (file_exists($dirthumb.$photo_vignette))
 			{
-				unlink($dirthumb.$photo_vignette);
+				dol_delete_file($dirthumb.$photo_vignette,1);
 			}
 		}
 	}
diff --git a/htdocs/document.php b/htdocs/document.php
index f455692ab88..5a259898f80 100644
--- a/htdocs/document.php
+++ b/htdocs/document.php
@@ -454,23 +454,21 @@ if (eregi('\.\.',$original_file) || eregi('[<>|]',$original_file))
 }
 
 
-
-if ($action == 'remove_file')
+if ($action == 'remove_file')	// Remove a file
 {
-	/*
-	 * Suppression fichier
-	 */
 	clearstatcache();
-	$filename = basename($original_file);
 
-	dol_syslog("document.php remove $original_file $filename $urlsource", LOG_DEBUG);
+	dol_syslog("document.php remove $original_file $urlsource", LOG_DEBUG);
 
-	if (! file_exists($original_file))
+	// This test should be useless. We keep it to find bug more easily
+	$neworiginal_file=utf8_check($original_file)?utf8_decode($original_file):$original_file;
+	if (! file_exists($neworiginal_file))
 	{
 		dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$_GET["file"]));
 		exit;
 	}
-	unlink($original_file);
+
+	dol_delete_file($original_file);
 
 	dol_syslog("document.php back to ".urldecode($urlsource), LOG_DEBUG);
 
@@ -478,23 +476,23 @@ if ($action == 'remove_file')
 
 	return;
 }
-else
+else						// Open and return file
 {
-	/*
-	 * Open and return file
-	 */
 	clearstatcache();
+
 	$filename = basename($original_file);
 
+	// Output file on browser
 	dol_syslog("document.php download $original_file $filename content-type=$type");
+	$neworiginal_file=utf8_check($original_file)?utf8_decode($original_file):$original_file;
 
-	if (! file_exists($original_file))
+	// This test if file exists should be useless. We keep it to find bug more easily
+	if (! file_exists($neworiginal_file))
 	{
 		dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file));
 		exit;
 	}
 
-
 	// Les drois sont ok et fichier trouve, on l'envoie
 
 	if ($encoding)   header('Content-Encoding: '.$encoding);
@@ -506,7 +504,7 @@ else
 	header('Cache-Control: Public, must-revalidate');
 	header('Pragma: public');
 
-	readfile($original_file);
+	readfile($neworiginal_file);	// Need a path in ISO
 }
 
 ?>
diff --git a/htdocs/html.formfile.class.php b/htdocs/html.formfile.class.php
index 55ba868c6d1..a9085f32d3c 100644
--- a/htdocs/html.formfile.class.php
+++ b/htdocs/html.formfile.class.php
@@ -376,7 +376,7 @@ class FormFile
 			print '</a>';
 			if (!$iconPDF) print '</td>';
 			// Affiche taille fichier
-			if (!$iconPDF) print '<td align="right">'.dol_filesize($filedir."/".$file["name"]).'</td>';
+			if (!$iconPDF) print '<td align="right">'.dol_print_size(filesize($filedir."/".$file["name"])).'</td>';
 			// Affiche date fichier
 			if (!$iconPDF) print '<td align="right">'.dol_print_date(filemtime($filedir."/".$file["name"]),'dayhour').'</td>';
 
@@ -490,16 +490,4 @@ class FormFile
 
 }
 
-/**
- * Return size of a file with units
- *
- * @param 	$pathoffile
- * @return 	string		File size with units translated
- */
-function dol_filesize($pathoffile)
-{
-	global $langs;
-	return filesize($pathoffile). ' '.$langs->trans("Bytes");
-}
-
 ?>
diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
index ad86183b851..299d51f0192 100644
--- a/htdocs/imports/import.php
+++ b/htdocs/imports/import.php
@@ -535,10 +535,10 @@ if ($step == 3 && $datatoimport)
 	print '<input type="hidden" value="'.$datatoimport.'" name="datatoimport">';
 	print "</tr>\n";
 
-	$dir = $conf->import->dir_temp;
-
 	// Search available imports
-	$handle=@opendir($dir);
+	$dir = $conf->import->dir_temp;
+	$newdir=utf8_check($dir)?utf8_decode($dir):$dir;	// opendir need ISO
+	$handle=@opendir($newdir);
 	if ($handle)
 	{
 		//print '<tr><td colspan="4">';
@@ -548,6 +548,9 @@ if ($step == 3 && $datatoimport)
 		$i=0;
 		while (($file = readdir($handle))!==false)
 		{
+			// readdir return value in ISO and we want UTF8 in memory
+			if (! utf8_check($file)) $file=utf8_encode($file);
+
 			if (eregi('^\.',$file)) continue;
 
 			$modulepart='import';
@@ -558,9 +561,9 @@ if ($step == 3 && $datatoimport)
 			print '<td width="16">'.img_mime($file).'</td>';
 			print '<td>'.$file.'</td>';
 			// Affiche taille fichier
-			print '<td align="right">'.dol_filesize($dir.'/'.$file).'</td>';
+			print '<td align="right">'.dol_print_size(filesize($newdir.'/'.$newfile)).'</td>';
 			// Affiche date fichier
-			print '<td align="right">'.dol_print_date(filemtime($dir.'/'.$file),'dayhour').'</td>';
+			print '<td align="right">'.dol_print_date(filemtime($newdir.'/'.$newfile),'dayhour').'</td>';
 			// Del button
 			print '<td align="right"><a href="'.DOL_URL_ROOT.'/document.php?action=remove_file&step=3&format='.$format.'&modulepart='.$modulepart.'&file='.urlencode($relativepath);
 			print '&amp;urlsource='.urlencode($urlsource);
diff --git a/htdocs/includes/modules/commande/modules_commande.php b/htdocs/includes/modules/commande/modules_commande.php
index c112e19408b..ab461bc8202 100644
--- a/htdocs/includes/modules/commande/modules_commande.php
+++ b/htdocs/includes/modules/commande/modules_commande.php
@@ -22,12 +22,12 @@
  */
 
 /**
-		\file       htdocs/includes/modules/commande/modules_commande.php
-		\ingroup    commande
-		\brief      Fichier contenant la classe m�re de generation des commandes en PDF
-		            et la classe m�re de num�rotation des commandes
-		\version    $Id$
-*/
+ \file       htdocs/includes/modules/commande/modules_commande.php
+ \ingroup    commande
+ \brief      Fichier contenant la classe m�re de generation des commandes en PDF
+ et la classe m�re de num�rotation des commandes
+ \version    $Id$
+ */
 
 require_once(DOL_DOCUMENT_ROOT.'/lib/pdf.lib.php');
 require_once(DOL_DOCUMENT_ROOT.'/includes/fpdf/fpdfi/fpdi_protection.php');
@@ -36,118 +36,118 @@ require_once(DOL_DOCUMENT_ROOT.'/discount.class.php');
 
 
 /**
-		\class      ModelePDFCommandes
-		\brief      Classe m�re des mod�les de commandes
-*/
+ \class      ModelePDFCommandes
+ \brief      Classe m�re des mod�les de commandes
+ */
 class ModelePDFCommandes extends FPDF
 {
-    var $error='';
-
-   /**
-	*	\brief 	Renvoi le dernier message d'erreur de cr�ation de PDF de commande
-    */
-    function pdferror()
-    {
-        return $this->error;
-    }
-
-    /**
-     *      \brief      Renvoi la liste des mod�les actifs
-     *      \return    array        Tableau des modeles (cle=id, valeur=libelle)
-     */
-    function liste_modeles($db)
-    {
-    	global $conf;
-    	
-        $type='order';
-        $liste=array();
-        $sql = "SELECT nom as id, nom as lib";
-        $sql.= " FROM ".MAIN_DB_PREFIX."document_model";
-        $sql.= " WHERE type = '".$type."'";
-        $sql.= " AND entity = ".$conf->entity;
-
-        $resql = $db->query($sql);
-        if ($resql)
-        {
-            $num = $db->num_rows($resql);
-            $i = 0;
-            while ($i < $num)
-            {
-                $row = $db->fetch_row($resql);
-                $liste[$row[0]]=$row[1];
-                $i++;
-            }
-        }
-        else
-        {
-            $this->error=$db->error();
-            return -1;
-        }
-        return $liste;
-    }
+	var $error='';
+
+	/**
+	 *	\brief 	Renvoi le dernier message d'erreur de cr�ation de PDF de commande
+	 */
+	function pdferror()
+	{
+		return $this->error;
+	}
+
+	/**
+	 *      \brief      Renvoi la liste des mod�les actifs
+	 *      \return    array        Tableau des modeles (cle=id, valeur=libelle)
+	 */
+	function liste_modeles($db)
+	{
+		global $conf;
+
+		$type='order';
+		$liste=array();
+		$sql = "SELECT nom as id, nom as lib";
+		$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
+		$sql.= " WHERE type = '".$type."'";
+		$sql.= " AND entity = ".$conf->entity;
+
+		$resql = $db->query($sql);
+		if ($resql)
+		{
+			$num = $db->num_rows($resql);
+			$i = 0;
+			while ($i < $num)
+			{
+				$row = $db->fetch_row($resql);
+				$liste[$row[0]]=$row[1];
+				$i++;
+			}
+		}
+		else
+		{
+			$this->error=$db->error();
+			return -1;
+		}
+		return $liste;
+	}
 
 }
 
 
 
 /**
-        \class      ModeleNumRefCommandes
-            \brief      Classe m�re des mod�les de num�rotation des r�f�rences de commandes
-*/
+ \class      ModeleNumRefCommandes
+ \brief      Classe m�re des mod�les de num�rotation des r�f�rences de commandes
+ */
 
 class ModeleNumRefCommandes
 {
-    var $error='';
+	var $error='';
 
 	/**     \brief     	Return if a module can be used or not
-	*      	\return		boolean     true if module can be used
-	*/
+	 *      	\return		boolean     true if module can be used
+	 */
 	function isEnabled()
 	{
 		return true;
 	}
 
-    /**     \brief      Renvoi la description par defaut du modele de num�rotation
-     *      \return     string      Texte descripif
-     */
-    function info()
-    {
-        global $langs;
-        $langs->load("orders");
-        return $langs->trans("NoDescription");
-    }
-
-    /**     \brief      Renvoi un exemple de num�rotation
-     *      \return     string      Example
-     */
-    function getExample()
-    {
-        global $langs;
-        $langs->load("orders");
-        return $langs->trans("NoExample");
-    }
-
-    /**     \brief      Test si les num�ros d�j� en vigueur dans la base ne provoquent pas de
-     *                  de conflits qui empechera cette num�rotation de fonctionner.
-     *      \return     boolean     false si conflit, true si ok
-     */
-    function canBeActivated()
-    {
-        return true;
-    }
-
-    /**     \brief      Renvoi prochaine valeur attribu�e
-     *      \return     string      Valeur
-     */
-    function getNextValue()
-    {
-        global $langs;
-        return $langs->trans("NotAvailable");
-    }
+	/**     \brief      Renvoi la description par defaut du modele de num�rotation
+	 *      \return     string      Texte descripif
+	 */
+	function info()
+	{
+		global $langs;
+		$langs->load("orders");
+		return $langs->trans("NoDescription");
+	}
+
+	/**     \brief      Renvoi un exemple de num�rotation
+	 *      \return     string      Example
+	 */
+	function getExample()
+	{
+		global $langs;
+		$langs->load("orders");
+		return $langs->trans("NoExample");
+	}
+
+	/**     \brief      Test si les num�ros d�j� en vigueur dans la base ne provoquent pas de
+	 *                  de conflits qui empechera cette num�rotation de fonctionner.
+	 *      \return     boolean     false si conflit, true si ok
+	 */
+	function canBeActivated()
+	{
+		return true;
+	}
+
+	/**     \brief      Renvoi prochaine valeur attribu�e
+	 *      \return     string      Valeur
+	 */
+	function getNextValue()
+	{
+		global $langs;
+		return $langs->trans("NotAvailable");
+	}
 
 	/**     \brief      Renvoi version du module numerotation
-	*      	\return     string      Valeur
-	*/
+	 *      	\return     string      Valeur
+	 */
 	function getVersion()
 	{
 		global $langs;
@@ -162,12 +162,12 @@ class ModeleNumRefCommandes
 
 
 /*
-		\brief      Cr�e un bon de commande sur disque en fonction d'un mod�le
-		\param	    db  			objet base de donn�e
-		\param	    id				id de la propale � cr�er
-		\param	    modele			force le modele � utiliser ('' to not force)
-		\param		outputlangs		objet lang a utiliser pour traduction
-*/
+ \brief      Cr�e un bon de commande sur disque en fonction d'un mod�le
+ \param	    db  			objet base de donn�e
+ \param	    id				id de la propale � cr�er
+ \param	    modele			force le modele � utiliser ('' to not force)
+ \param		outputlangs		objet lang a utiliser pour traduction
+ */
 function commande_pdf_create($db, $id, $modele, $outputlangs)
 {
 	global $conf,$langs;
@@ -175,32 +175,32 @@ function commande_pdf_create($db, $id, $modele, $outputlangs)
 
 	$dir = DOL_DOCUMENT_ROOT."/includes/modules/commande/";
 	$modelisok=0;
-    $liste=array();
+	$liste=array();
 
-	// Positionne modele sur le nom du modele de commande � utiliser
+	// Positionne modele sur le nom du modele de commande � utiliser
 	$file = "pdf_".$modele.".modules.php";
 	if ($modele && file_exists($dir.$file))   $modelisok=1;
 
-    // Si model pas encore bon
+	// Si model pas encore bon
 	if (! $modelisok)
 	{
 		if ($conf->global->COMMANDE_ADDON_PDF) $modele = $conf->global->COMMANDE_ADDON_PDF;
-      	$file = "pdf_".$modele.".modules.php";
-    	if (file_exists($dir.$file))   $modelisok=1;
-    }
+		$file = "pdf_".$modele.".modules.php";
+		if (file_exists($dir.$file))   $modelisok=1;
+	}
 
-    // Si model pas encore bon
+	// Si model pas encore bon
 	if (! $modelisok)
 	{
 		$model=new ModelePDFCommandes();
 		$liste=$model->liste_modeles($db);
-        $modele=key($liste);        // Renvoie premiere valeur de cl� trouv� dans le tableau
-      	$file = "pdf_".$modele.".modules.php";
-    	if (file_exists($dir.$file))   $modelisok=1;
+		$modele=key($liste);        // Renvoie premiere valeur de cl� trouv� dans le tableau
+		$file = "pdf_".$modele.".modules.php";
+		if (file_exists($dir.$file))   $modelisok=1;
 	}
 
 	// Charge le modele
-    if ($modelisok)
+	if ($modelisok)
 	{
 		$classname = "pdf_".$modele;
 		require_once($dir.$file);
@@ -227,66 +227,68 @@ function commande_pdf_create($db, $id, $modele, $outputlangs)
 	}
 	else
 	{
-        if (! $conf->global->COMMANDE_ADDON_PDF)
-        {
+		if (! $conf->global->COMMANDE_ADDON_PDF)
+		{
 			print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_ADDON_PDF_NotDefined");
-        }
-        else
-        {
-    		print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file);
-        }
+		}
+		else
+		{
+			print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file);
+		}
 		return 0;
-   }
+	}
 }
 
 /**
-   \brief      Supprime l'image de pr�visualitation, pour le cas de r�g�n�ration de commande
-   \param	    db  		objet base de donn�e
-   \param	    commandeid	id de la commande � effacer
-   \param     commanderef r�f�rence de la commande si besoin
-*/
+ \brief      Supprime l'image de pr�visualitation, pour le cas de r�g�n�ration de commande
+ \param	    db  		objet base de donn�e
+ \param	    commandeid	id de la commande � effacer
+ \param     commanderef r�f�rence de la commande si besoin
+ */
 function commande_delete_preview($db, $commandeid, $commanderef='')
 {
-        global $langs,$conf;
-
-        if (!$commanderef)
-        {
-        	$com = new Commande($db,"",$commandeid);
-        	$com->fetch($commandeid);
-        	$commanderef = $com->ref;
-        }
-
-        if ($conf->commande->dir_output)
-        {
-        	$comref = dol_sanitizeFileName($commanderef);
-        	$dir = $conf->commande->dir_output . "/" . $comref ;
-        	$file = $dir . "/" . $comref . ".pdf.png";
-        	$multiple = $file . ".";
-
-        	if ( file_exists( $file ) && is_writable( $file ) )
-        	{
-        		if ( ! unlink($file) )
-        			{
-        				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
-        				return 0;
-        			}
-        	}
-        	else
-        	{
-        		for ($i = 0; $i < 20; $i++)
-        		{
-        			$preview = $multiple.$i;
-
-        		if ( file_exists( $preview ) && is_writable( $preview ) )
-        		{
-        			if ( ! unlink($preview) )
-        			{
-        				$this->error=$langs->trans("ErrorFailedToOpenFile",$preview);
-        				return 0;
-        			}
-        		}
-        	}
-        }
-      }
+	global $langs,$conf;
+
+	if (!$commanderef)
+	{
+		$com = new Commande($db,"",$commandeid);
+		$com->fetch($commandeid);
+		$commanderef = $com->ref;
+	}
+
+	if ($conf->commande->dir_output)
+	{
+		$comref = dol_sanitizeFileName($commanderef);
+		$dir = $conf->commande->dir_output . "/" . $comref ;
+		$file = $dir . "/" . $comref . ".pdf.png";
+		$multiple = $file . ".";
+
+		if ( file_exists( $file ) && is_writable( $file ) )
+		{
+			if ( ! dol_delete_file($file,1) )
+			{
+				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
+				return 0;
+			}
+		}
+		else
+		{
+			for ($i = 0; $i < 20; $i++)
+			{
+				$preview = $multiple.$i;
+
+				if ( file_exists( $preview ) && is_writable( $preview ) )
+				{
+					if ( ! dol_delete_file($preview,1) )
+					{
+						$this->error=$langs->trans("ErrorFailedToOpenFile",$preview);
+						return 0;
+					}
+				}
+			}
+		}
+	}
+
+	return 1;
 }
 ?>
diff --git a/htdocs/includes/modules/facture/modules_facture.php b/htdocs/includes/modules/facture/modules_facture.php
index b3a9f6da87d..05f52ac4d1b 100644
--- a/htdocs/includes/modules/facture/modules_facture.php
+++ b/htdocs/includes/modules/facture/modules_facture.php
@@ -58,7 +58,7 @@ class ModelePDFFactures extends FPDF
 	function liste_modeles($db)
 	{
 		global $conf;
-		
+
 		$type='invoice';
 		$liste=array();
 		$sql = "SELECT nom as id, nom as lib";
@@ -266,8 +266,8 @@ CLIENT=\"" . $client . "\"
 TOTAL_HT=\"" . $fac->total_ht . "\"
 TOTAL_TTC=\"" . $fac->total_ttc . "\"\n";
 
-	  		for ($i = 0 ; $i < $nblignes ; $i++)
-	  		{
+			for ($i = 0 ; $i < $nblignes ; $i++)
+			{
 	  	//Pour les articles
 	  	$meta .= "ITEM_" . $i . "_QUANTITY=\"" . $fac->lignes[$i]->qty . "\"
 ITEM_" . $i . "_UNIT_PRICE=\"" . $fac->lignes[$i]->price . "\"
@@ -280,16 +280,16 @@ ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n","",nl2br($fac->lignes[$i]->
 		fputs($fp,$meta);
 		fclose($fp);
 		if (! empty($conf->global->MAIN_UMASK))
-			@chmod($file, octdec($conf->global->MAIN_UMASK));
+		@chmod($file, octdec($conf->global->MAIN_UMASK));
 
 	}
 }
 
 
 /**
- \brief       Supprime l'image de previsualitation, pour le cas de regeneration de facture
- \param	    db  		objet base de donnee
- \param	    facid		id de la facture a creer
+ *	\brief      Supprime l'image de previsualitation, pour le cas de regeneration de facture
+ *	\param	    db  		objet base de donnee
+ *	\param	    facid		id de la facture a creer
  */
 function facture_delete_preview($db, $facid)
 {
@@ -306,12 +306,14 @@ function facture_delete_preview($db, $facid)
 
 		if ( file_exists( $file ) && is_writable( $file ) )
 		{
-	  if ( ! unlink($file) )
-	  {
-	  	return 0;
-	  }
+			if ( ! dol_delete_file($file,1) )
+			{
+				return 0;
+			}
 		}
 	}
+
+	return 1;
 }
 
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/modules/fichinter/modules_fichinter.php b/htdocs/includes/modules/fichinter/modules_fichinter.php
index c60866272ca..33e5142ffe4 100644
--- a/htdocs/includes/modules/fichinter/modules_fichinter.php
+++ b/htdocs/includes/modules/fichinter/modules_fichinter.php
@@ -22,8 +22,8 @@
 /**
  \file       htdocs/includes/modules/fichinter/modules_fichinter.php
  \ingroup    ficheinter
- \brief      Fichier contenant la classe m�re de generation des fiches interventions en PDF
- et la classe m�re de num�rotation des fiches interventions
+ \brief      Fichier contenant la classe m�re de generation des fiches interventions en PDF
+ et la classe m�re de num�rotation des fiches interventions
  \version    $Id$
  */
 
@@ -33,7 +33,7 @@ require_once(DOL_DOCUMENT_ROOT.'/includes/fpdf/fpdfi/fpdi_protection.php');
 
 /**
  \class      ModelePDFFicheinter
- \brief      Classe m�re des mod�les de fiche intervention
+ \brief      Classe m�re des mod�les de fiche intervention
  */
 class ModelePDFFicheinter extends FPDF
 {
@@ -48,7 +48,7 @@ class ModelePDFFicheinter extends FPDF
 	}
 
 	/**
-	 \brief      Renvoi le dernier message d'erreur de cr�ation de fiche intervention
+	 \brief      Renvoi le dernier message d'erreur de cr�ation de fiche intervention
 	 */
 	function pdferror()
 	{
@@ -56,12 +56,12 @@ class ModelePDFFicheinter extends FPDF
 	}
 
 	/**
-	 *      \brief      Renvoi la liste des mod�les actifs
+	 *      \brief      Renvoi la liste des mod�les actifs
 	 */
 	function liste_modeles($db)
 	{
 		global $conf;
-		
+
 		$type='ficheinter';
 		$liste=array();
 		$sql = "SELECT nom as id, nom as lib";
@@ -93,7 +93,7 @@ class ModelePDFFicheinter extends FPDF
 
 /**
  \class      ModeleNumRefFicheinter
- \brief      Classe m�re des mod�les de num�rotation des r�f�rences de fiches d'intervention
+ \brief      Classe m�re des mod�les de num�rotation des r�f�rences de fiches d'intervention
  */
 
 class ModeleNumRefFicheinter
@@ -108,7 +108,7 @@ class ModeleNumRefFicheinter
 		return true;
 	}
 
-	/**     \brief      Renvoi la description par defaut du modele de num�rotation
+	/**     \brief      Renvoi la description par defaut du modele de num�rotation
 	 *      \return     string      Texte descripif
 	 */
 	function info()
@@ -118,7 +118,7 @@ class ModeleNumRefFicheinter
 		return $langs->trans("NoDescription");
 	}
 
-	/**     \brief      Renvoi un exemple de num�rotation
+	/**     \brief      Renvoi un exemple de num�rotation
 	 *      \return     string      Example
 	 */
 	function getExample()
@@ -128,8 +128,8 @@ class ModeleNumRefFicheinter
 		return $langs->trans("NoExample");
 	}
 
-	/**     \brief      Test si les num�ros d�j� en vigueur dans la base ne provoquent pas de
-	 *                  de conflits qui empechera cette num�rotation de fonctionner.
+	/**     \brief      Test si les num�ros d�j� en vigueur dans la base ne provoquent pas de
+	 *                  de conflits qui empechera cette num�rotation de fonctionner.
 	 *      \return     boolean     false si conflit, true si ok
 	 */
 	function canBeActivated()
@@ -137,7 +137,7 @@ class ModeleNumRefFicheinter
 		return true;
 	}
 
-	/**     \brief      Renvoi prochaine valeur attribu�e
+	/**     \brief      Renvoi prochaine valeur attribu�e
 	 *      \return     string      Valeur
 	 */
 	function getNextValue()
@@ -163,10 +163,10 @@ class ModeleNumRefFicheinter
 
 
 /**
- \brief      Cr�e une fiche intervention sur disque en fonction du mod�le de FICHEINTER_ADDON_PDF
- \param	    db  			objet base de donn�e
+ \brief      Cr�e une fiche intervention sur disque en fonction du mod�le de FICHEINTER_ADDON_PDF
+ \param	    db  			objet base de donn�e
  \param	    object			Object fichinter
- \param	    modele			force le modele � utiliser ('' par defaut)
+ \param	    modele			force le modele � utiliser ('' par defaut)
  \param		outputlangs		objet lang a utiliser pour traduction
  \return     int         	0 si KO, 1 si OK
  */
@@ -177,7 +177,7 @@ function fichinter_create($db, $object, $modele='', $outputlangs='')
 
 	$dir = DOL_DOCUMENT_ROOT."/includes/modules/fichinter/";
 
-	// Positionne modele sur le nom du modele de facture � utiliser
+	// Positionne modele sur le nom du modele de facture � utiliser
 	if (! strlen($modele))
 	{
 		if ($conf->global->FICHEINTER_ADDON_PDF)
@@ -226,10 +226,10 @@ function fichinter_create($db, $object, $modele='', $outputlangs='')
 }
 
 /**
- \brief     Supprime l'image de pr�visualitation, pour le cas de r�g�n�ration de propal
- \param	    db  		objet base de donn�e
- \param	    propalid	id de la propal � effacer
- \param     propalref r�f�rence de la propal si besoin
+ \brief     Supprime l'image de pr�visualitation, pour le cas de r�g�n�ration de propal
+ \param	    db  		objet base de donn�e
+ \param	    propalid	id de la propal � effacer
+ \param     propalref r�f�rence de la propal si besoin
  */
 function fichinter_delete_preview($db, $fichinterid, $fichinterref='')
 {
@@ -251,7 +251,7 @@ function fichinter_delete_preview($db, $fichinterid, $fichinterref='')
 
 		if ( file_exists( $file ) && is_writable( $file ) )
 		{
-			if ( ! unlink($file) )
+			if ( ! dol_delete_file($file,1) )
 			{
 				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
 				return 0;
@@ -264,7 +264,7 @@ function fichinter_delete_preview($db, $fichinterid, $fichinterref='')
 				$preview = $multiple.$i;
 				if ( file_exists( $preview ) && is_writable( $preview ) )
 				{
-					if ( ! unlink($preview) )
+					if ( ! dol_delete_file($preview,1) )
 					{
 						$this->error=$langs->trans("ErrorFailedToOpenFile",$preview);
 						return 0;
@@ -273,6 +273,8 @@ function fichinter_delete_preview($db, $fichinterid, $fichinterref='')
 			}
 		}
 	}
+
+	return 1;
 }
 
 ?>
diff --git a/htdocs/includes/modules/livraison/modules_livraison.php b/htdocs/includes/modules/livraison/modules_livraison.php
index eed6c3d4c56..f99083a33f1 100644
--- a/htdocs/includes/modules/livraison/modules_livraison.php
+++ b/htdocs/includes/modules/livraison/modules_livraison.php
@@ -54,10 +54,10 @@ class ModelePDFDeliveryOrder extends FPDF
 	function liste_modeles($db)
 	{
 		global $conf;
-		
+
 		$type='delivery';
 		$liste=array();
-		
+
 		$sql = "SELECT nom as id, nom as lib";
 		$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
 		$sql.= " WHERE type = '".$type."'";
@@ -161,9 +161,9 @@ class ModeleNumRefDeliveryOrder
 
 /**
  *		\brief      Create object on disk
- *		\param	    db  			objet base de donn�e
+ *		\param	    db  			objet base de donn�e
  *		\param	    deliveryid		id object
- *		\param	    modele			force le modele � utiliser ('' to not force)
+ *		\param	    modele			force le modele � utiliser ('' to not force)
  *		\param		outputlangs		objet lang a utiliser pour traduction
  *      \return     int         	0 si KO, 1 si OK
  */
@@ -240,12 +240,14 @@ function delivery_order_delete_preview($db, $deliveryid)
 
 		if ( file_exists( $file ) && is_writable( $file ) )
 		{
-			if ( ! unlink($file) )
+			if ( ! dol_delete_file($file,1) )
 			{
 				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
 				return 0;
 			}
 		}
 	}
+
+	return 1;
 }
 ?>
diff --git a/htdocs/includes/modules/propale/modules_propale.php b/htdocs/includes/modules/propale/modules_propale.php
index 4c0f967af6b..d89015568b8 100644
--- a/htdocs/includes/modules/propale/modules_propale.php
+++ b/htdocs/includes/modules/propale/modules_propale.php
@@ -20,12 +20,12 @@
  */
 
 /**
-        \file       htdocs/includes/modules/propale/modules_propale.php
-		\ingroup    propale
-		\brief      Fichier contenant la classe m�re de generation des propales en PDF
-	                et la classe m�re de num�rotation des propales
-		\version    $Id$
-*/
+ \file       htdocs/includes/modules/propale/modules_propale.php
+ \ingroup    propale
+ \brief      Fichier contenant la classe m�re de generation des propales en PDF
+ et la classe m�re de num�rotation des propales
+ \version    $Id$
+ */
 
 require_once(DOL_DOCUMENT_ROOT.'/lib/pdf.lib.php');
 require_once(DOL_DOCUMENT_ROOT.'/includes/fpdf/fpdfi/fpdi_protection.php');
@@ -33,118 +33,118 @@ require_once(DOL_DOCUMENT_ROOT."/compta/bank/account.class.php");   // Requis ca
 
 
 /**
-    	\class      ModelePDFPropales
-		\brief      Classe mere des modeles de propale
-*/
+ \class      ModelePDFPropales
+ \brief      Classe mere des modeles de propale
+ */
 
 class ModelePDFPropales extends FPDF
 {
-    var $error='';
-
-    /**
-     *      \brief      Renvoi le dernier message d'erreur de creation de propale
-     */
-    function pdferror()
-    {
-        return $this->error;
-    }
-
-    /**
-     *      \brief      Renvoi la liste des modeles actifs
-     */
-    function liste_modeles($db)
-    {
-    	global $conf;
-    	
-    	$type='propal';
-      $liste=array();
-      
-      $sql = "SELECT nom as id, nom as lib";
-      $sql.= " FROM ".MAIN_DB_PREFIX."document_model";
-      $sql.= " WHERE type = '".$type."'";
-      $sql.= " AND entity = ".$conf->entity;
-
-      dol_syslog("modules_propale::liste_modeles sql=".$sql, LOG_DEBUG);
-      $resql = $db->query($sql);
-      if ($resql)
-      {
-      	$num = $db->num_rows($resql);
-        $i = 0;
-        while ($i < $num)
-        {
-        	$row = $db->fetch_row($resql);
-          $liste[$row[0]]=$row[1];
-          $i++;
-        }
-      }
-      else
-      {
-      	$this->error=$db->error();
-      	return -1;
-      }
-      return $liste;
-    }
+	var $error='';
+
+	/**
+	 *      \brief      Renvoi le dernier message d'erreur de creation de propale
+	 */
+	function pdferror()
+	{
+		return $this->error;
+	}
+
+	/**
+	 *      \brief      Renvoi la liste des modeles actifs
+	 */
+	function liste_modeles($db)
+	{
+		global $conf;
+
+		$type='propal';
+		$liste=array();
+
+		$sql = "SELECT nom as id, nom as lib";
+		$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
+		$sql.= " WHERE type = '".$type."'";
+		$sql.= " AND entity = ".$conf->entity;
+
+		dol_syslog("modules_propale::liste_modeles sql=".$sql, LOG_DEBUG);
+		$resql = $db->query($sql);
+		if ($resql)
+		{
+			$num = $db->num_rows($resql);
+			$i = 0;
+			while ($i < $num)
+			{
+				$row = $db->fetch_row($resql);
+				$liste[$row[0]]=$row[1];
+				$i++;
+			}
+		}
+		else
+		{
+			$this->error=$db->error();
+			return -1;
+		}
+		return $liste;
+	}
 }
 
 
 /**
-        \class      ModeleNumRefPropales
-        \brief      Classe mere des modeles de numerotation des references de propales
-*/
+ \class      ModeleNumRefPropales
+ \brief      Classe mere des modeles de numerotation des references de propales
+ */
 
 class ModeleNumRefPropales
 {
-    var $error='';
+	var $error='';
 
 	/**     \brief     	Return if a module can be used or not
-	*      	\return		boolean     true if module can be used
-	*/
+	 *      	\return		boolean     true if module can be used
+	 */
 	function isEnabled()
 	{
 		return true;
 	}
 
-    /**     \brief      Renvoi la description par defaut du modele de numerotation
-     *      \return     string      Texte descripif
-     */
-    function info()
-    {
-        global $langs;
-        $langs->load("propale");
-        return $langs->trans("NoDescription");
-    }
-
-    /**     \brief      Renvoi un exemple de numerotation
-     *      \return     string      Example
-     */
-    function getExample()
-    {
-        global $langs;
-        $langs->load("propale");
-        return $langs->trans("NoExample");
-    }
-
-    /**     \brief      Test si les numeros deja en vigueur dans la base ne provoquent pas de
-     *                  de conflits qui empechera cette numerotation de fonctionner.
-     *      \return     boolean     false si conflit, true si ok
-     */
-    function canBeActivated()
-    {
-        return true;
-    }
-
-    /**     \brief      Renvoi prochaine valeur attribuee
-     *      \return     string      Valeur
-     */
-    function getNextValue()
-    {
-        global $langs;
-        return $langs->trans("NotAvailable");
-    }
+	/**     \brief      Renvoi la description par defaut du modele de numerotation
+	 *      \return     string      Texte descripif
+	 */
+	function info()
+	{
+		global $langs;
+		$langs->load("propale");
+		return $langs->trans("NoDescription");
+	}
+
+	/**     \brief      Renvoi un exemple de numerotation
+	 *      \return     string      Example
+	 */
+	function getExample()
+	{
+		global $langs;
+		$langs->load("propale");
+		return $langs->trans("NoExample");
+	}
+
+	/**     \brief      Test si les numeros deja en vigueur dans la base ne provoquent pas de
+	 *                  de conflits qui empechera cette numerotation de fonctionner.
+	 *      \return     boolean     false si conflit, true si ok
+	 */
+	function canBeActivated()
+	{
+		return true;
+	}
+
+	/**     \brief      Renvoi prochaine valeur attribuee
+	 *      \return     string      Valeur
+	 */
+	function getNextValue()
+	{
+		global $langs;
+		return $langs->trans("NotAvailable");
+	}
 
 	/**     \brief      Renvoi version du module numerotation
-	*      	\return     string      Valeur
-	*/
+	 *      	\return     string      Valeur
+	 */
 	function getVersion()
 	{
 		global $langs;
@@ -159,13 +159,13 @@ class ModeleNumRefPropales
 
 
 /**
-		\brief      Cree une propale sur disque en fonction du modele de PROPALE_ADDON_PDF
-		\param	    db  			objet base de donnee
-		\param	    id				id de la propale � creer
-		\param	    modele			force le modele � utiliser ('' to not force)
-		\param		outputlangs		objet lang a utiliser pour traduction
-        \return     int         	0 si KO, 1 si OK
-*/
+ \brief      Cree une propale sur disque en fonction du modele de PROPALE_ADDON_PDF
+ \param	    db  			objet base de donnee
+ \param	    id				id de la propale � creer
+ \param	    modele			force le modele � utiliser ('' to not force)
+ \param		outputlangs		objet lang a utiliser pour traduction
+ \return     int         	0 si KO, 1 si OK
+ */
 function propale_pdf_create($db, $id, $modele, $outputlangs)
 {
 	global $langs;
@@ -178,28 +178,28 @@ function propale_pdf_create($db, $id, $modele, $outputlangs)
 	$file = "pdf_propale_".$modele.".modules.php";
 	if ($modele && file_exists($dir.$file)) $modelisok=1;
 
-    // Si model pas encore bon
+	// Si model pas encore bon
 	if (! $modelisok)
 	{
 		if ($conf->global->PROPALE_ADDON_PDF) $modele = $conf->global->PROPALE_ADDON_PDF;
-      	$file = "pdf_propale_".$modele.".modules.php";
-    	if (file_exists($dir.$file)) $modelisok=1;
+		$file = "pdf_propale_".$modele.".modules.php";
+		if (file_exists($dir.$file)) $modelisok=1;
 	}
 
-    // Si model pas encore bon
+	// Si model pas encore bon
 	if (! $modelisok)
 	{
 		$liste=array();
 		$model=new ModelePDFPropales();
 		$liste=$model->liste_modeles($db);
-    $modele=key($liste);        // Renvoie premiere valeur de cle trouve dans le tableau
-    $file = "pdf_propale_".$modele.".modules.php";
-    if (file_exists($dir.$file)) $modelisok=1;
+		$modele=key($liste);        // Renvoie premiere valeur de cle trouve dans le tableau
+		$file = "pdf_propale_".$modele.".modules.php";
+		if (file_exists($dir.$file)) $modelisok=1;
 	}
 
 
 	// Charge le modele
-    if ($modelisok)
+	if ($modelisok)
 	{
 		$classname = "pdf_propale_".$modele;
 		require_once($dir.$file);
@@ -226,66 +226,68 @@ function propale_pdf_create($db, $id, $modele, $outputlangs)
 	}
 	else
 	{
-        if (! $conf->global->PROPALE_ADDON_PDF)
-        {
+		if (! $conf->global->PROPALE_ADDON_PDF)
+		{
 			print $langs->trans("Error")." ".$langs->trans("Error_PROPALE_ADDON_PDF_NotDefined");
-        }
-        else
-        {
-    		print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file);
-        }
+		}
+		else
+		{
+			print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.$file);
+		}
 		return 0;
 	}
 }
 
 /**
-   \brief      Supprime l'image de previsualitation, pour le cas de regeneration de propal
-   \param	    db  		objet base de donn�e
-   \param	    propalid	id de la propal a effacer
-   \param     propalref reference de la propal si besoin
-*/
+ \brief      Supprime l'image de previsualitation, pour le cas de regeneration de propal
+ \param	    db  		objet base de donn�e
+ \param	    propalid	id de la propal a effacer
+ \param     propalref reference de la propal si besoin
+ */
 function propale_delete_preview($db, $propalid, $propalref='')
 {
-        global $langs,$conf;
-
-        if (!$propalref)
-        {
-        	$propal = new Propal($db,"",$propalid);
-        	$propal->fetch($propalid);
-        	$propalref = $propal->ref;
-        }
-
-        if ($conf->propale->dir_output)
-        {
-        	$propalref = dol_sanitizeFileName($propalref);
-        	$dir = $conf->propale->dir_output . "/" . $propalref ;
-        	$file = $dir . "/" . $propalref . ".pdf.png";
-        	$multiple = $file . ".";
-
-        	if ( file_exists( $file ) && is_writable( $file ) )
-        	{
-        		if ( ! unlink($file) )
-        			{
-        				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
-        				return 0;
-        			}
-        	}
-        	else
-        	{
-        		for ($i = 0; $i < 20; $i++)
-        		{
-        			$preview = $multiple.$i;
-
-        		if ( file_exists( $preview ) && is_writable( $preview ) )
-        		{
-        			if ( ! unlink($preview) )
-        			{
-        				$this->error=$langs->trans("ErrorFailedToOpenFile",$preview);
-        				return 0;
-        			}
-        		}
-        	}
-        }
-      }
+	global $langs,$conf;
+
+	if (!$propalref)
+	{
+		$propal = new Propal($db,"",$propalid);
+		$propal->fetch($propalid);
+		$propalref = $propal->ref;
+	}
+
+	if ($conf->propale->dir_output)
+	{
+		$propalref = dol_sanitizeFileName($propalref);
+		$dir = $conf->propale->dir_output . "/" . $propalref ;
+		$file = $dir . "/" . $propalref . ".pdf.png";
+		$multiple = $file . ".";
+
+		if ( file_exists( $file ) && is_writable( $file ) )
+		{
+			if ( ! dol_delete_file($file,1) )
+			{
+				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
+				return 0;
+			}
+		}
+		else
+		{
+			for ($i = 0; $i < 20; $i++)
+			{
+				$preview = $multiple.$i;
+
+				if ( file_exists( $preview ) && is_writable( $preview ) )
+				{
+					if ( ! unlink($preview) )
+					{
+						$this->error=$langs->trans("ErrorFailedToOpenFile",$preview);
+						return 0;
+					}
+				}
+			}
+		}
+	}
+
+	return 1;
 }
 ?>
diff --git a/htdocs/includes/modules/supplier_order/modules_commandefournisseur.php b/htdocs/includes/modules/supplier_order/modules_commandefournisseur.php
index 08ba4835d61..2388eb0227b 100644
--- a/htdocs/includes/modules/supplier_order/modules_commandefournisseur.php
+++ b/htdocs/includes/modules/supplier_order/modules_commandefournisseur.php
@@ -55,10 +55,10 @@ class ModelePDFSuppliersOrders extends FPDF
 	function liste_modeles($db)
 	{
 		global $conf;
-		
+
 		$type='supplier_order';
 		$liste=array();
-		
+
 		$sql = "SELECT nom as id, nom as lib";
 		$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
 		$sql.= " WHERE type = '".$type."'";
@@ -238,12 +238,14 @@ function supplier_order_delete_preview($db, $propalid)
 
 		if ( file_exists( $file ) && is_writable( $file ) )
 		{
-			if ( ! unlink($file) )
+			if ( ! dol_delete_file($file) )
 			{
 				$this->error=$langs->trans("ErrorFailedToOpenFile",$file);
 				return 0;
 			}
 		}
 	}
+
+	return 1;
 }
 ?>
diff --git a/htdocs/lib/files.lib.php b/htdocs/lib/files.lib.php
index 443e87d323f..540a32eea79 100644
--- a/htdocs/lib/files.lib.php
+++ b/htdocs/lib/files.lib.php
@@ -196,7 +196,7 @@ function dol_mimetype($file)
  */
 function dol_dir_is_emtpy($folder)
 {
-	$newfolder=utf8_check($folder)?utf8_decode($folder):$folder;	// The opendir need ISO strings
+	$newfolder=utf8_check($folder)?utf8_decode($folder):$folder;	// The is_dir and opendir need ISO strings
 	if (is_dir($newfolder))
 	{
 		$handle = opendir($newfolder);
@@ -244,4 +244,41 @@ function dol_count_nb_of_line($file)
 	return $nb;
 }
 
+
+/**
+ * Return size of a file
+ *
+ * @param 	$pathoffile
+ * @return 	string		File size
+ */
+function dol_filesize($pathoffile)
+{
+	$newpathoffile=check_utf8($pathoffile)?utf8_decode($pathoffile):$pathoffile;
+	return filesize($pathoffile);
+}
+
+/**
+ * Return time of a file
+ *
+ * @param 	$pathoffile
+ * @return 	timestamp	Time of file
+ */
+function dol_filetime($pathoffile)
+{
+	$newpathoffile=check_utf8($pathoffile)?utf8_decode($pathoffile):$pathoffile;
+	return filemtime($nrwpathoffile);
+}
+
+/**
+ * Return if path is a file
+ *
+ * @param 	$pathoffile
+ * @return 	boolean			True or false
+ */
+function dol_is_file($pathoffile)
+{
+	$newpathoffile=utf8_check($pathoffile)?utf8_decode($pathoffile):$pathoffile;
+	return is_file($newpathoffile);
+}
+
 ?>
diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php
index 858b518715e..ee43cb2e8ab 100644
--- a/htdocs/lib/functions.lib.php
+++ b/htdocs/lib/functions.lib.php
@@ -2124,19 +2124,29 @@ function print_fleche_navigation($page,$file,$options='',$nextpage,$betweenarrow
 
 
 /**
- *	\brief  	Remove a file
- *	\param		file			Fichier a effacer ou masque de fichier a effacer
- *	\param		boolean			true if file deleted, false if error
+ *	\brief  	Remove a file or several files with a mask
+ *	\param		file			File to delete or mask of file to delete
+ * 	\param		disableglob		Disable usage of globa like *
+ *	\param		boolean			True if file deleted, False if error
  */
-function dol_delete_file($file)
+function dol_delete_file($file,$disableglob=0)
 {
 	$ok=true;
 	$newfile=utf8_check($file)?utf8_decode($file):$file;	// glob function accepts only ISO string
-	foreach (glob($newfile) as $filename)
+	if (empty($disableglob))
 	{
-		$ok=unlink($filename);
-		if ($ok) dol_syslog("Removed file ".$filename,LOG_DEBUG);
-		else dol_syslog("Failed to remove file ".$filename,LOG_ERR);
+		foreach (glob($newfile) as $filename)
+		{
+			$ok=unlink($filename);	// The unlink encapsulated by dolibarr
+			if ($ok) dol_syslog("Removed file ".$filename,LOG_DEBUG);
+			else dol_syslog("Failed to remove file ".$filename,LOG_ERR);
+		}
+	}
+	else
+	{
+		$ok=unlink($newfile);		// The unlink encapsulated by dolibarr
+		if ($ok) dol_syslog("Removed file ".$newfile,LOG_DEBUG);
+		else dol_syslog("Failed to remove file ".$newfile,LOG_ERR);
 	}
 	return $ok;
 }
@@ -3006,5 +3016,4 @@ function utf8_check($Str)
 	return true;
 }
 
-
 ?>
\ No newline at end of file
diff --git a/htdocs/product.class.php b/htdocs/product.class.php
index 3155600d843..4729c4897dd 100644
--- a/htdocs/product.class.php
+++ b/htdocs/product.class.php
@@ -538,26 +538,26 @@ class Product extends CommonObject
 				$sqlz.= " WHERE rowid = ".$id;
 				$resultz = $this->db->query($sqlz);
 
-                if ( !$resultz )
-                {
-                    dol_syslog('Product::delete error sqlz='.$sqlz, LOG_ERR);
-                }
-
-                // Appel des triggers
-                include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
-                $interface=new Interfaces($this->db);
-                $result=$interface->run_triggers('PRODUCT_DELETE',$this,$user,$langs,$conf);
-                if ($result < 0) { $error++; $this->errors=$interface->errors; }
-                // Fin appel triggers
-
-                if ($error)
-                {
-                	return -$error;
-                }
-                else
-                {
-                	return 0;
-                }
+				if ( !$resultz )
+				{
+					dol_syslog('Product::delete error sqlz='.$sqlz, LOG_ERR);
+				}
+
+				// Appel des triggers
+				include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
+				$interface=new Interfaces($this->db);
+				$result=$interface->run_triggers('PRODUCT_DELETE',$this,$user,$langs,$conf);
+				if ($result < 0) { $error++; $this->errors=$interface->errors; }
+				// Fin appel triggers
+
+				if ($error)
+				{
+					return -$error;
+				}
+				else
+				{
+					return 0;
+				}
 			}
 			else
 			{
@@ -1619,17 +1619,17 @@ class Product extends CommonObject
 
 		if ($result = $this->db->query($sql))
 		{
-	  while ($row = $this->db->fetch_row($result) )
-	  {
-	  	$this->subproducts_id[$i] = $row[0];
-	  	$i++;
-	  }
-	  $this->db->free($result);
-	  return 0;
+			while ($row = $this->db->fetch_row($result) )
+			{
+				$this->subproducts_id[$i] = $row[0];
+				$i++;
+			}
+			$this->db->free($result);
+			return 0;
 		}
 		else
 		{
-	  return -1;
+	 		return -1;
 		}
 	}
 
@@ -2487,33 +2487,38 @@ class Product extends CommonObject
 	 */
 	function liste_photos($dir,$nbmax=0)
 	{
+		include_once(DOL_DOCUMENT_ROOT.'/lib/files.lib.php');
+
 		$nbphoto=0;
 		$tabobj=array();
 
-		$dirthumb = $dir.'thumbs/';
+		$newdir=utf8_check($dir)?utf8_decode($dir):$dir;
 
-		if (file_exists($dir))
+		$handle=@opendir($newdir);
+		if ($handle)
 		{
-			$handle=opendir($dir);
-
 			while (($file = readdir($handle)) != false)
 			{
-				if (is_file($dir.$file))
+				if (! utf8_check($file)) $file=utf8_encode($file);	// readdir returns ISO
+
+				if (dol_is_file($dir.$file))
 				{
 					$nbphoto++;
-					$photo = $file;
 
 					// On determine nom du fichier vignette
+					$photo=$file;
 					$photo_vignette='';
 					if (eregi('(\.jpg|\.bmp|\.gif|\.png|\.tiff)$',$photo,$regs))
 					{
 						$photo_vignette=eregi_replace($regs[0],'',$photo).'_small'.$regs[0];
 					}
 
+					$dirthumb = $dir.'thumbs/';
+
 					// Objet
 					$obj=array();
 					$obj['photo']=$photo;
-					if ($photo_vignette && is_file($dirthumb.$photo_vignette)) $obj['photo_vignette']=$photo_vignette;
+					if ($photo_vignette && dol_is_file($dirthumb.$photo_vignette)) $obj['photo_vignette']=$photo_vignette;
 					else $obj['photo_vignette']="";
 
 					$tabobj[$nbphoto-1]=$obj;
@@ -2540,7 +2545,7 @@ class Product extends CommonObject
 		$filename = eregi_replace($dir,'',$file); // Nom du fichier
 
 		// On efface l'image d'origine
-		unlink($file);
+		dol_delete_file($file);
 
 		// Si elle existe, on efface la vignette
 		if (eregi('(\.jpg|\.bmp|\.gif|\.png|\.tiff)$',$filename,$regs))
@@ -2548,7 +2553,7 @@ class Product extends CommonObject
 			$photo_vignette=eregi_replace($regs[0],'',$filename).'_small'.$regs[0];
 			if (file_exists($dirthumb.$photo_vignette))
 			{
-				unlink($dirthumb.$photo_vignette);
+				dol_delete_file($dirthumb.$photo_vignette);
 			}
 		}
 	}
@@ -2559,7 +2564,8 @@ class Product extends CommonObject
 	 */
 	function get_image_size($file)
 	{
-		$infoImg = getimagesize($file); // Get information on image
+		$newfile=utf8_check($file)?utf8_decode($file):$file;
+		$infoImg = getimagesize($newfile); // Get information on image
 		$this->imgWidth = $infoImg[0]; // Largeur de l'image
 		$this->imgHeight = $infoImg[1]; // Hauteur de l'image
 	}
diff --git a/htdocs/product/photos.php b/htdocs/product/photos.php
index f187b75e801..f637886d052 100644
--- a/htdocs/product/photos.php
+++ b/htdocs/product/photos.php
@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2004-2009 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005      Eric Seigne          <eric.seigne@ryxeo.com>
  * Copyright (C) 2005-2009 Regis Houssin        <regis@dolibarr.fr>
  *
@@ -171,7 +171,7 @@ if ($_GET["id"] || $_GET["ref"])
 		print "\n</div>\n";
 
 		/*
-		 * Ajouter une photo
+		 * Add a photo
 		 */
 		if ($_GET["action"] == 'ajout_photo' && ($user->rights->produit->creer || $user->rights->service->creer) && ! empty($conf->global->MAIN_UPLOAD_DOC))
 		{
@@ -204,7 +204,7 @@ if ($_GET["id"] || $_GET["ref"])
 				if ($nbbyrow && ($nbphoto % $nbbyrow == 1)) print '<tr align=center valign=middle border=1>';
 				if ($nbbyrow) print '<td width="'.ceil(100/$nbbyrow).'%" class="photo">';
 
-				print '<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart=product&file='.urlencode($pdir.$obj['photo']).'" alt="Taille origine" target="_blank">';
+				print '<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart=product&file='.urlencode($pdir.$obj['photo']).'" alt="'.dol_escape_htmltag($langs->trans("OriginalSize")).'" target="_blank">';
 
 				// Si fichier vignette disponible, on l'utilise, sinon on utilise photo origine
 				if ($obj['photo_vignette'])
diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php
index 649308d25f1..f64a5526326 100644
--- a/htdocs/viewimage.php
+++ b/htdocs/viewimage.php
@@ -376,17 +376,16 @@ if ($modulepart == 'barcode')
 		$result=$module->buildBarCode($code,$encoding,$readable);
 	}
 }
-else
+else					// Open and return file
 {
-	// Ouvre et renvoi fichier
 	clearstatcache();
 
-	// Output files on disk
-	$filename = basename($original_file);
-
-	dol_syslog("viewimage.php return file $original_file $filename content-type=$type");
+	// Output files on browser
+	dol_syslog("viewimage.php return file $original_file content-type=$type");
+	$neworiginal_file=utf8_check($original_file)?utf8_decode($original_file):$original_file;
 
-	if (! file_exists($original_file))
+	// This test if file exists should be useless. We keep it to find bug more easily
+	if (! file_exists($neworiginal_file))
 	{
 		$langs->load("main");
 		dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$_GET["file"]));
@@ -403,7 +402,7 @@ else
 		header('Content-type: image/png');
 	}
 
-	readfile($original_file);
+	readfile($neworiginal_file);	// Need a path in ISO
 }
 
 ?>
-- 
GitLab