Select Git revision
IndexController.php
functions.inc.php 125.33 KiB
<?php
/* Copyright (C) 2000-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
* Copyright (C) 2004-2007 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
* Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
* Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
* Copyright (C) 2005-2007 Regis Houssin <regis@dolibarr.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* or see http://www.gnu.org/
*
* $Id$
*/
/**
\file htdocs/lib/functions.inc.php
\brief Ensemble de fonctions de base de dolibarr sous forme d'include
\author Rodolphe Quiedeville
\author Jean-Louis Bergamo
\author Laurent Destailleur
\author Sebastien Di Cintio
\author Benoit Mortier
\version $Revision$
Ensemble de fonctions de base de dolibarr sous forme d'include
*/
// Pour compatibilit lors de l'upgrade
if (! defined('DOL_DOCUMENT_ROOT'))
{
define('DOL_DOCUMENT_ROOT', '..');
}
include_once(DOL_DOCUMENT_ROOT."/includes/adodbtime/adodb-time.inc.php");
/**
\brief Renvoi une version en chaine depuis une version en tableau
\param versionarray Tableau de version (vermajeur,vermineur,autre)
\return string Chaine version
*/
function versiontostring($versionarray)
{
$string='?';
if (isset($versionarray[0])) $string=$versionarray[0];
if (isset($versionarray[1])) $string.='.'.$versionarray[1];
if (isset($versionarray[2])) $string.='.'.$versionarray[2];
return $string;
}
/**
\brief Compare 2 versions
\param versionarray1 Tableau de version (vermajeur,vermineur,autre)
\param versionarray2 Tableau de version (vermajeur,vermineur,autre)
\return int <0 si versionarray1<versionarray2, 0 si =, >0 si versionarray1>versionarray2
*/
function versioncompare($versionarray1,$versionarray2)
{
$ret=0;
$i=0;
while ($i < max(sizeof($versionarray1),sizeof($versionarray1)))
{
$operande1=isset($versionarray1[$i])?$versionarray1[$i]:0;
$operande2=isset($versionarray2[$i])?$versionarray2[$i]:0;
if ($operande1 < $operande2) { $ret = -1; break; }
if ($operande1 > $operande2) { $ret = 1; break; }
$i++;
}
return $ret;
}
/**
\brief Renvoie version PHP
\return array Tableau de version (vermajeur,vermineur,autre)
*/
function versionphp()
{
return split('\.',PHP_VERSION);
}
/**
\brief Renvoi vrai si l'email est syntaxiquement valide
\param address adresse email (Ex: "toto@titi.com", "John Do <johndo@titi.com>")
\return boolean true si email valide, false sinon
*/
function ValidEmail($address)
{
if (ereg( ".*<(.+)>", $address, $regs)) {
$address = $regs[1];
}
if (ereg( "^[^@ ]+@([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9\-]{2}|coop|aero|biz|com|edu|gov|info|int|mil|name|net|org)\$",$address))
{
return true;
}
else
{
return false;
}
}
/**
\brief Renvoi vrai si l'email a un nom de domaine qui rsoud via dns
\param mail adresse email (Ex: "toto@titi.com", "John Do <johndo@titi.com>")
\return boolean true si email valide, false sinon
*/
function check_mail ($mail)
{
list($user, $domain) = split("@", $mail, 2);
if (checkdnsrr($domain, "MX"))
{
return true;
}
else
{
return false;
}
}
/**
\brief Nettoie chaine de caractere iso des accents
\param str Chaine a nettoyer
\return string Chaine nettoyee
*/
function unaccent_isostring($str)
{
$translation = array(
"\xE0" => "a",
"\xE1" => "a",
"\xE2" => "a",
"\xE8" => "e",
"\xE9" => "e",
"\xEA" => "e",
"\xEB" => "e",
"\xEE" => "i",
"\xEF" => "i",
"\xF4" => "o",
"\xF6" => "o",
"\xFB" => "u",
"\xFC" => "u"
);
return str_replace(array_keys($translation), array_values($translation), $str);
}
/**
\brief Nettoie chaine de caractere de caracteres speciaux
\remarks Fonction appelee par exemple pour definir un nom de fichier depuis un identifiant chaine libre
\param str Chaine a nettoyer
\return string Chaine nettoyee (A-Z_)
*/
function sanitize_string($str)
{
$forbidden_chars_to_underscore=array(" ","'","/","\\",":","*","?","\"","<",">","|","[","]",",",";","=");
//$forbidden_chars_to_remove=array("(",")");
$forbidden_chars_to_remove=array();
return str_replace($forbidden_chars_to_underscore,"_",str_replace($forbidden_chars_to_remove,"",$str));
}
/**
\brief Envoi des messages dolibarr dans un fichier ou dans syslog
Pour fichier: fichier dfini par SYSLOG_FILE
Pour syslog: facility dfini par SYSLOG_FACILITY
\param message Message a tracer. Ne doit pas etre traduit si level = LOG_ERR
\param level Niveau de l'erreur
\remarks Cette fonction n'a un effet que si le module syslog est activ.
Warning, les fonctions syslog sont buggus sous Windows et gnrent des
fautes de protection mmoire. Pour rsoudre, utiliser le loggage fichier,
au lieu du loggage syslog (configuration du module).
Si SYSLOG_FILE_NO_ERROR dfini, on ne gre pas erreur ecriture log
\remarks On Windows LOG_ERR=4, LOG_WARNING=5, LOG_NOTICE=LOG_INFO=LOG_DEBUG=6
On Linux LOG_ERR=3, LOG_WARNING=4, LOG_INFO=6, LOG_DEBUG=7
*/
function dolibarr_syslog($message, $level=LOG_INFO)
{
global $conf,$user,$langs;
if (isset($conf->syslog->enabled) && $conf->syslog->enabled)
{
//print $level.' - '.$conf->global->SYSLOG_LEVEL.' - '.$conf->syslog->enabled." \n";
if ($level > $conf->global->SYSLOG_LEVEL) return;
// Traduction du message
if ($level == LOG_ERR)
{
$langs->load("errors");
if ($message != $langs->trans($message)) $message = $langs->trans($message);
}
// Ajout user a la log
$login='???';
if (is_object($user) && $user->id) $login=$user->login;
$message=sprintf("%-8s",$login)." ".$message;
if (defined("SYSLOG_FILE") && SYSLOG_FILE)
{
if (defined("SYSLOG_FILE_NO_ERROR")) $file=@fopen(SYSLOG_FILE,"a+");
else $file=fopen(SYSLOG_FILE,"a+");
if ($file)
{
$liblevelarray=array(LOG_ERR=>'ERROR',LOG_WARNING=>'WARN',LOG_INFO=>'INFO',LOG_DEBUG=>'DEBUG');
$liblevel=$liblevelarray[$level];
if (! $liblevel) $liblevel='UNDEF';
$message=strftime("%Y-%m-%d %H:%M:%S",time())." ".sprintf("%-5s",$liblevel)." ".$message;
fwrite($file,$message."\n");
fclose($file);
// If enable html log tag enabled and url parameter log defined, we show output log on HTML comments
if (! empty($conf->global->MAIN_ENABLE_LOG_HTML) && ! empty($_GET["log"]))
{
print "\n\n<!-- Log start\n";
print $message."\n";
print "Log end -->\n";
}
}
elseif (! defined("SYSLOG_FILE_NO_ERROR"))
{
$langs->load("main");
print $langs->trans("ErrorFailedToOpenFile",SYSLOG_FILE);
}
}
else
{
//define_syslog_variables(); dja dfinit dans master.inc.php
if (defined("MAIN_SYSLOG_FACILITY") && MAIN_SYSLOG_FACILITY)
{
$facility = MAIN_SYSLOG_FACILITY;
}
elseif (defined("SYSLOG_FACILITY") && SYSLOG_FACILITY && defined(SYSLOG_FACILITY))
{
// Exemple: SYSLOG_FACILITY vaut LOG_USER qui vaut 8. On a besoin de 8 dans $facility.
$facility = constant(SYSLOG_FACILITY);
}
else
{
$facility = LOG_USER;
}
openlog("dolibarr", LOG_PID | LOG_PERROR, $facility);
if (! $level)
{
syslog(LOG_ERR, $message);
}
else
{
syslog($level, $message);
}
closelog();
}
}
}
/**
\brief Affiche le header d'une fiche
\param links Tableau de titre d'onglets
\param active 0=onglet non actif, 1=onglet actif
\param title Titre tabelau ("" par defaut)
\param notab 0=Add tab header, 1=no tab header
*/
function dolibarr_fiche_head($links, $active='0', $title='', $notab=0)
{
print "\n".'<div class="tabs">'."\n";
// Affichage titre
if ($title)
{
$limittitle=30;
print '<a class="tabTitle">';
print
((!defined('MAIN_USE_SHORT_TITLE')) || (defined('MAIN_USE_SHORT_TITLE') && MAIN_USE_SHORT_TITLE))
? dolibarr_trunc($title,$limittitle)
: $title;
print '</a>';
}
// Affichage onglets
for ($i = 0 ; $i < sizeof($links) ; $i++)
{
if ($links[$i][2] == 'image')
{
print '<a class="tabimage" href="'.$links[$i][0].'">'.$links[$i][1].'</a>'."\n";
}
else
{
//print "x $i $active ".$links[$i][2]." z";
if ((is_numeric($active) && $i == $active)
|| (! is_numeric($active) && $active == $links[$i][2]))
{
print '<a id="active" class="tab" href="'.$links[$i][0].'">'.$links[$i][1].'</a>'."\n";
}
else
{
print '<a class="tab" href="'.$links[$i][0].'">'.$links[$i][1].'</a>'."\n";
}
}
}
print "</div>\n";
if (! $notab) print '<div class="tabBar">'."\n\n";
}
/**
\brief Rcupre une constante depuis la base de donnes.
\see dolibarr_del_const, dolibarr_set_const
\param db Handler d'accs base
\param name Nom de la constante
\return string Valeur de la constante
*/
function dolibarr_get_const($db, $name)
{
$value='';
$sql ="SELECT value";
$sql.=" FROM llx_const";
$sql.=" WHERE name = '".addslashes($name)."'";
$resql=$db->query($sql);
if ($resql)
{
$obj=$db->fetch_object($resql);
$value=$obj->value;
}
return $value;
}
/**
\brief Insertion d'une constante dans la base de donnes.
\see dolibarr_del_const, dolibarr_get_const
\param db Handler d'accs base
\param name Nom de la constante
\param value Valeur de la constante
\param type Type de constante (chaine par dfaut)
\param visible La constante est elle visible (0 par dfaut)
\param note Explication de la constante
\return int <0 si ko, >0 si ok
*/
function dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='')
{
global $conf;
$db->begin();
if (! $name)
{
dolibarr_print_error("Error: Call to function dolibarr_set_const with wrong parameters");
exit;
}
//dolibarr_syslog("dolibarr_set_const name=$name, value=$value");
$sql = "DELETE FROM llx_const WHERE name = '".addslashes($name)."';";
$resql=$db->query($sql);
$sql = "INSERT INTO llx_const(name,value,type,visible,note)";
$sql.= " VALUES ('$name','".addslashes($value)."','$type',$visible,'".addslashes($note)."');";
$resql=$db->query($sql);
if ($resql)
{
$db->commit();
$conf->global->$name=$value;
return 1;
}
else
{
$db->rollback();
return -1;
}
}
/**
\brief Effacement d'une constante dans la base de donnes
\see dolibarr_get_const, dolibarr_sel_const
\param db Handler d'accs base
\param name Nom ou rowid de la constante
\return int <0 si ko, >0 si ok
*/
function dolibarr_del_const($db, $name)
{
global $conf;
$sql = "DELETE FROM llx_const";
$sql.=" WHERE name='".addslashes($name)."' or rowid='".addslashes($name)."'";
$resql=$db->query($sql);
if ($resql)
{
$conf->global->$name='';
return 1;
}
else
{
return -1;
}
}
/**
\brief Sauvegarde parametrage personnel
\param db Handler d'accs base
\param user Objet utilisateur
\param url Si defini, on sauve parametre du tableau tab dont cl = (url avec sortfield, sortorder, begin et page)
Si non defini on sauve tous parametres du tableau tab
\param tab Tableau (cl=>valeur) des paramtres a sauvegarder
\return int <0 si ko, >0 si ok
*/
function dolibarr_set_user_page_param($db, &$user, $url='', $tab)
{
// Verification parametres
if (sizeof($tab) < 1) return -1;
$db->begin();
// On efface anciens paramtres pour toutes les cl dans $tab
$sql = "DELETE FROM ".MAIN_DB_PREFIX."user_param";
$sql.= " WHERE fk_user = ".$user->id;
if ($url) $sql.=" AND page='".$url."'";
else $sql.=" AND page=''"; // Page ne peut etre null
$sql.= " AND param in (";
$i=0;
foreach ($tab as $key => $value)
{
if ($i > 0) $sql.=',';
$sql.="'".$key."'";
$i++;
}
$sql.= ")";
dolibarr_syslog("functions.inc.php::dolibarr_set_user_page_param $sql");
$resql=$db->query($sql);
if (! $resql)
{
dolibarr_print_error($db);
$db->rollback();
exit;
}
foreach ($tab as $key => $value)
{
// On positionne nouveaux paramtres
if ($value && (! $url || in_array($key,array('sortfield','sortorder','begin','page'))))
{
$sql = "INSERT INTO ".MAIN_DB_PREFIX."user_param(fk_user,page,param,value)";
$sql.= " VALUES (".$user->id.",";
if ($url) $sql.= " '".urlencode($url)."',";
else $sql.= " '',";
$sql.= " '".$key."','".addslashes($value)."');";
dolibarr_syslog("functions.inc.php::dolibarr_set_user_page_param $sql");
$result=$db->query($sql);
if (! $result)
{
dolibarr_print_error($db);
$db->rollback();
exit;
}
$user->page_param[$key] = $value;
}
}
$db->commit();
return 1;
}
/**
\brief Formattage des nombres
\param ca valeur a formater
\return int valeur formate
*/
function dolibarr_print_ca($ca)
{
global $langs,$conf;
if ($ca > 1000)
{
$cat = round(($ca / 1000),2);
$cat = "$cat K".$langs->trans("Currency".$conf->monnaie);
}
else
{
$cat = round($ca,2);
$cat = "$cat ".$langs->trans("Currency".$conf->monnaie);
}
if ($ca > 1000000)
{
$cat = round(($ca / 1000000),2);
$cat = "$cat M".$langs->trans("Currency".$conf->monnaie);
}
return $cat;
}
/**
\brief Effectue un dcalage de date par rapport a une dure
\param time Date timestamp ou au format YYYY-MM-DD
\param duration_value Valeur de la dure a ajouter
\param duration_unit Unit de la dure a ajouter (d, m, y)
\return int Nouveau timestamp
*/
function dolibarr_time_plus_duree($time,$duration_value,$duration_unit)
{
if ($duration_value == 0) return $time;
if ($duration_value > 0) $deltastring="+".abs($duration_value);
if ($duration_value < 0) $deltastring="-".abs($duration_value);
if ($duration_unit == 'd') { $deltastring.=" day"; }
if ($duration_unit == 'm') { $deltastring.=" month"; }
if ($duration_unit == 'y') { $deltastring.=" year"; }
return strtotime($deltastring,$time);
}
/**
\brief Formattage de la date en fonction de la langue $conf->langage
\param time Date 'timestamp' ou format 'YYYY-MM-DD' ou 'YYYY-MM-DD HH:MM:SS'
\param format Format d'affichage de la date
"%d %b %Y",
"%d/%m/%Y %H:%M",
"%d/%m/%Y %H:%M:%S",
"day", "daytext", "dayhour", "dayhourldap", "dayhourtext"
\return string Date formate ou '' si time null
*/
function dolibarr_print_date($time,$format='')
{
global $conf;
// Si format non dfini, on prend $conf->format_date_text_short sinon %Y-%m-%d %H:%M:%S
if (! $format) $format=(isset($conf->format_date_text_short) ? $conf->format_date_text_short : '%Y-%m-%d %H:%M:%S');
if ($format == 'day') $format=$conf->format_date_short;
if ($format == 'hour') $format=$conf->format_hour_short;
if ($format == 'daytext') $format=$conf->format_date_text_short;
if ($format == 'dayhour') $format=$conf->format_date_hour_short;
if ($format == 'dayhourtext') $format=$conf->format_date_hour_text_short;
if ($format == 'dayhourldap') $format='%Y%m%d%H%M%SZ';
// Si date non definie, on renvoie ''
if ($time == '') return ''; // $time=0 permis car signifie 01/01/1970 00:00:00
// Analyse de la date
if (eregi('^([0-9]+)\-([0-9]+)\-([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?',$time,$reg))
{
// Date est au format 'YYYY-MM-DD' ou 'YYYY-MM-DD HH:MM:SS'
$syear = $reg[1];
$smonth = $reg[2];
$sday = $reg[3];
$shour = $reg[4];
$smin = $reg[5];
$ssec = $reg[6];
return strftime($format,dolibarr_mktime($shour,$smin,$ssec,$smonth,$sday,$syear));
}
else
{
// Date est un timestamps
return strftime($format,$time);
}
}
/**
\brief Retourne une date fabrique depuis une chaine
\param string Date formate en chaine
YYYYMMDD
YYYYMMDDHHMMSS
DD/MM/YY ou DD/MM/YYYY
DD/MM/YY HH:MM:SS ou DD/MM/YYYY HH:MM:SS
\return date Date
*/
function dolibarr_stringtotime($string)
{
if (eregi('^([0-9]+)\/([0-9]+)\/([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?',$string,$reg))
{
// Date est au format 'DD/MM/YY' ou 'DD/MM/YY HH:MM:SS'
// Date est au format 'DD/MM/YYYY' ou 'DD/MM/YYYY HH:MM:SS'
$sday = $reg[1];
$smonth = $reg[2];
$syear = $reg[3];
$shour = $reg[4];
$smin = $reg[5];
$ssec = $reg[6];
if ($syear < 50) $syear+=1900;
if ($syear >= 50 && $syear < 100) $syear+=2000;
$string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
}
$string=eregi_replace('[^0-9]','',$string);
$tmp=$string.'000000';
$date=dolibarr_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4));
return $date;
}
/**
\brief Return an array with date info
\param timestamp Timestamp
\param fast Fast mode
\return array Array of informations
If no fast mode:
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'wday' => $dow,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'weekday' => gmdate('l',$_day_power*(3+$dow)),
'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
0 => $origd
If fast mode:
'seconds' => $secs,
'minutes' => $min,
'hours' => $hour,
'mday' => $day,
'mon' => $month,
'year' => $year,
'yday' => floor($secsInYear/$_day_power),
'leap' => $leaf,
'ndays' => $ndays
\remarks PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows
*/
function dolibarr_getdate($timestamp,$fast=false)
{
$usealternatemethod=false;
if ($timestamp <= 0) $usealternatemethod=true; // <= 1970
if ($timestamp >= 2145913200) $usealternatemethod=true; // >= 2038
if ($usealternatemethod)
{
$arrayinfo=adodb_getdate($timestamp,$fast);
}
else
{
$arrayinfo=getdate($timestamp);
}
return $arrayinfo;
}
/**
\brief Retourne une date fabrique depuis infos.
Remplace la fonction mktime non implmente sous Windows si anne < 1970
\param hour Heure
\param minute Minute
\param second Seconde
\param month Mois
\param day Jour
\param year Anne
\return timestamp Date en timestamp, '' if error
\remarks PHP mktime is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows
*/
function dolibarr_mktime($hour,$minute,$second,$month,$day,$year,$gm=0)
{
//print "- ".$hour.",".$minute.",".$second.",".$month.",".$day.",".$year.",".$_SERVER["WINDIR"]." -";
// Check parameters
if (! $month || ! $day) return '';
if ($day > 31) return '';
if ($month > 12) return '';
if ($min < 0 || $min > 60) return '';
if ($hour < 0 || $hour > 24) return '';
if ($min < 0 || $min > 60) return '';
$usealternatemethod=false;
if ($year <= 1970) $usealternatemethod=true; // <= 1970
if ($year >= 2038) $usealternatemethod=true; // >= 2038
if ($usealternatemethod || $gm) // Si time gm, seule adodb peut convertir
{
/*
// On peut utiliser strtotime pour obtenir la traduction.
// strtotime is ok for range: Vendredi 13 Dcembre 1901 20:45:54 GMT au Mardi 19 Janvier 2038 03:14:07 GMT.
$montharray=array(1=>'january',2=>'february',3=>'march',4=>'april',5=>'may',6=>'june',
7=>'july',8=>'august',9=>'september',10=>'october',11=>'november',12=>'december');
$string=$day." ".$montharray[0+$month]." ".$year." ".$hour.":".$minute.":".$second." GMT";
$date=strtotime($string);
print "- ".$string." ".$date." -";
*/
$date=adodb_mktime($hour,$minute,$second,$month,$day,$year,0,$gm);
}
else
{
$date=mktime($hour,$minute,$second,$month,$day,$year);
}
return $date;
}
/**
\brief Returns formated date
\param fmt Format (Exemple: 'Y-m-d H:i:s')
\param timestamp Date. Exemple: Si timestamp=0 et gm=1, renvoi 01/01/1970 00:00:00
\param gm 1 if timestamp was built with gmmktime, 0 if timestamp was build with mktime
\return string Formated date
*/
function dolibarr_date($fmt, $timestamp, $gm=0)
{
$usealternatemethod=false;
if ($timestamp <= 0) $usealternatemethod=true;
if ($timestamp >= 2145913200) $usealternatemethod=true;
if ($usealternatemethod || $gm) // Si time gm, seule adodb peut convertir
{
$string=adodb_date($fmt,$timestamp,$gm);
}
else
{
$string=date($fmt,$timestamp);
}
return $string;
}
/**
\brief Affiche les informations d'un objet
\param object objet a afficher
*/
function dolibarr_print_object_info($object)
{
global $langs;
$langs->load("other");
if (isset($object->user_creation) && $object->user_creation->fullname)
print $langs->trans("CreatedBy")." : " . $object->user_creation->fullname . '<br>';
if (isset($object->date_creation))
print $langs->trans("DateCreation")." : " . dolibarr_print_date($object->date_creation,"dayhourtext") . '<br>';
if (isset($object->user_modification) && $object->user_modification->fullname)
print $langs->trans("ModifiedBy")." : " . $object->user_modification->fullname . '<br>';
if (isset($object->date_modification))
print $langs->trans("DateLastModification")." : " . dolibarr_print_date($object->date_modification,"dayhourtext") . '<br>';
if (isset($object->user_validation) && $object->user_validation->fullname)
print $langs->trans("ValidatedBy")." : " . $object->user_validation->fullname . '<br>';
if (isset($object->date_validation))
print $langs->trans("DateValidation")." : " . dolibarr_print_date($object->date_validation,"dayhourtext") . '<br>';
if (isset($object->user_cloture) && $object->user_cloture->fullname )
print $langs->trans("ClosedBy")." : " . $object->user_cloture->fullname . '<br>';
if (isset($object->date_cloture))
print $langs->trans("DateClosing")." : " . dolibarr_print_date($object->date_cloture,"dayhourtext") . '<br>';
if (isset($object->user_rappro) && $object->user_rappro->fullname )
print $langs->trans("ConciliatedBy")." : " . $object->user_rappro->fullname . '<br>';
if (isset($object->date_rappro))
print $langs->trans("DateConciliating")." : " . dolibarr_print_date($object->date_rappro,"dayhourtext") . '<br>';
}
/**
\brief Formatage des numros de telephone en fonction du format d'un pays
\param phone Numro de telephone a formater
\param country Pays selon lequel formatter
\return string Numro de tlphone format
*/
function dolibarr_print_phone($phone,$country="FR")
{
$phone=trim($phone);
if (strstr($phone, ' ')) { return $phone; }
if (strtoupper($country) == "FR") {
// France
if (strlen($phone) == 10) {
return substr($phone,0,2)." ".substr($phone,2,2)." ".substr($phone,4,2)." ".substr($phone,6,2)." ".substr($phone,8,2);
}
elseif (strlen($phone) == 7)
{
return substr($phone,0,3)." ".substr($phone,3,2)." ".substr($phone,5,2);
}
elseif (strlen($phone) == 9)
{
return substr($phone,0,2)." ".substr($phone,2,3)." ".substr($phone,5,2)." ".substr($phone,7,2);
}
elseif (strlen($phone) == 11)
{
return substr($phone,0,3)." ".substr($phone,3,2)." ".substr($phone,5,2)." ".substr($phone,7,2)." ".substr($phone,9,2);
}
elseif (strlen($phone) == 12)
{
return substr($phone,0,4)." ".substr($phone,4,2)." ".substr($phone,6,2)." ".substr($phone,8,2)." ".substr($phone,10,2);
}
}
return $phone;
}
/**
\brief Tronque une chaine a une taille donne en ajoutant les points de suspension si cela dpasse
\param string String to truncate
\param size Max string size. 0 for no limit.
\param trunc Where to trunc: right, left, middle
\return string Truncated string
\remarks USE_SHORT_TITLE=0 can disable all truncings
*/
function dolibarr_trunc($string,$size=40,$trunc='right')
{
if ($size==0) return $string;
if (! defined('USE_SHORT_TITLE') || (defined('USE_SHORT_TITLE') && USE_SHORT_TITLE))
{
// We go always here
if ($trunc == 'right')
{
if (strlen($string) > $size)
return substr($string,0,$size).'...';
else
return $string;
}
if ($trunc == 'middle')
{
if (strlen($string) > 2 && strlen($string) > $size)
{
$size1=round($size/2);
$size2=round($size/2);
return substr($string,0,$size1).'...'.substr($string,strlen($string) - $size2,$size2);
}
else
return $string;
}
if ($trunc == 'left')
{
if (strlen($string) > $size)
return '...'.substr($string,strlen($string) - $size,$size);
else
return $string;
}
}
else
{
return $string;
}
}
/**
\brief Complte une chaine a une taille donne par des espaces
\param string Chaine a complter
\param size Longueur de la chaine.
\param side 0=Compltion a droite, 1=Compltion a gauche
\param char Chaine de compltion
\return string Chaine complte
*/
function dolibarr_pad($string,$size,$side,$char=' ')
{
$taille=sizeof($string);
$i=0;
while($i < ($size - $taille))
{
if ($side > 0) $string.=$char;
else $string=$char.$string;
$i++;
}
return $string;
}
/**
\brief Affiche picto propre a une notion/module (fonction gnrique)
\param alt Texte sur le alt de l'image
\param object Objet pour lequel il faut afficher le logo (exemple: user, group, action, bill, contract, propal, product, ...)
\return string Retourne tag img
*/
function img_object($alt, $object)
{
global $conf,$langs;
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/object_'.$object.'.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche picto (fonction gnrique)
\param alt Texte sur le alt de l'image
\param picto Nom de l'image a afficher (Si pas d'extension, on met '.png')
\param options Attribut supplmentaire a la balise img
\return string Retourne tag img
*/
function img_picto($alt, $picto, $options='')
{
global $conf;
if (! eregi('(\.png|\.gif)$',$picto)) $picto.='.png';
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/'.$picto.'" border="0" alt="'.$alt.'" title="'.$alt.'"'.($options?' '.$options:'').'>';
}
/**
\brief Affiche logo action
\param alt Texte sur le alt de l'image
\param numaction Determine image action
\return string Retourne tag img
*/
function img_action($alt = "default", $numaction)
{
global $conf,$langs;
if ($alt=="default") {
if ($numaction == -1) $alt=$langs->trans("ChangeDoNotContact");
if ($numaction == 0) $alt=$langs->trans("ChangeNeverContacted");
if ($numaction == 1) $alt=$langs->trans("ChangeToContact");
if ($numaction == 2) $alt=$langs->trans("ChangeContactInProcess");
if ($numaction == 3) $alt=$langs->trans("ChangeContactDone");
}
return '<img align="absmiddle" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/stcomm'.$numaction.'.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo fichier
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_file($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Show");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/file.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo refresh
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_refresh($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Refresh");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/refresh.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo dossier
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_folder($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Dossier");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/folder.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo nouveau fichier
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_file_new($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Show");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/filenew.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo pdf
\param alt Texte sur le alt de l'image
\param $size Taille de l'icone : 3 = 16x16px , 2 = 14x14px
\return string Retourne tag img
*/
function img_pdf($alt = "default",$size=3)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Show");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/pdf'.$size.'.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo vcard
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_vcard($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("VCard");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/vcard.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo +
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_edit_add($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Add");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/edit_add.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo -
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_edit_remove($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Remove");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/edit_remove.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo editer/modifier fiche
\param alt Texte sur le alt de l'image
\param float Si il faut y mettre le style "float: right"
\return string Retourne tag img
*/
function img_edit($alt = "default",$float=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Modify");
$img='<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/edit.png" border="0" alt="'.$alt.'" title="'.$alt.'"';
if ($float) $img.=' style="float: right"';
$img.='>';
return $img;
}
/**
\brief Affiche logo effacer
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_delete($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Delete");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo dsactiver
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_disable($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Disable");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/disable.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo help avec curseur "?"
\return string Retourne tag img
*/
function img_help($usehelpcursor=1,$usealttitle=1)
{
global $conf,$langs;
$s ='<img ';
if ($usehelpcursor) $s.='style="cursor: help;" ';
$s.='src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/info.png" border="0"';
if ($usealttitle) $s.=' alt="'.$langs->trans("Info").'" title="'.$langs->trans("Info").'"';
$s.='>';
return $s;
}
/**
\brief Affiche picto calendrier "?"
\return string Retourne tag img
*/
function img_cal()
{
global $conf,$langs;
return '<img style="vertical-align:middle" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/calendar.png" border="0" alt="" title="">';
}
/**
\brief Affiche logo info
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_info($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Informations");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/info.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo calculatrice
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_calc($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Calculate");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/calc.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo warning
\param alt Texte sur le alt de l'image
\param float Si il faut afficher le style "float: right"
\return string Retourne tag img
*/
function img_warning($alt = "default",$float=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Warning");
$img='<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/warning.png" border="0" alt="'.$alt.'" title="'.$alt.'"';
if ($float) $img.=' style="float: right"';
$img.='>';
return $img;
}
/**
\brief Affiche logo warning
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_error($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Error");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/error.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo alerte
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_alerte($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Alert");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/alerte.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo tlphone in
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_phone_in($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Modify");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/call.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo tlphone out
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_phone_out($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Modify");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/call.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo suivant
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_next($alt = "default")
{
global $conf,$langs;
if ($alt=="default") {
$alt=$langs->trans("Next");
}
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/next.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo prcdent
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_previous($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Previous");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/previous.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo bas
\param alt Texte sur le alt de l'image
\param selected Affiche version "selected" du logo
\return string Retourne tag img
*/
function img_down($alt = "default", $selected=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Down");
if ($selected) return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1downarrow_selected.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
else return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1downarrow.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo haut
\param alt Texte sur le alt de l'image
\param selected Affiche version "selected" du logo
\return string Retourne tag img
*/
function img_up($alt = "default", $selected=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Up");
if ($selected) return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1uparrow_selected.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
else return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1uparrow.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo gauche
\param alt Texte sur le alt de l'image
\param selected Affiche version "selected" du logo
\return string Retourne tag img
*/
function img_left($alt = "default", $selected=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Left");
if ($selected) return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1leftarrow_selected.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
else return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1leftarrow.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo droite
\param alt Texte sur le alt de l'image
\param selected Affiche version "selected" du logo
\return string Retourne tag img
*/
function img_right($alt = "default", $selected=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Right");
if ($selected) return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1rightarrow_selected.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
else return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1rightarrow.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche logo tick
\param alt Texte sur le alt de l'image
\return string Retourne tag img
*/
function img_tick($alt = "default")
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Active");
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/tick.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\brief Affiche le logo tick si allow
\param allow Authorise ou non
\return string Retourne tag img
*/
function img_allow($allow)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Active");
if ($allow == 1)
{
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/tick.png" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
else
{
return "-";
}
}
/**
\brief Return if a filename is file name of a supported image format
\param file Filename
\return int -1=Not image filename, 0=Image filename but format not supported by PHP, 1=Image filename with format supported
*/
function image_format_supported($file)
{
// Case filename is not a format image
if (! eregi('(\.gif|\.jpg|\.jpeg|\.png|\.bmp)$',$file,$reg)) return -1;
// Case filename is a format image but not supported by this PHP
$imgfonction='';
if (strtolower($reg[1]) == '.gif') $imgfonction = 'imagecreatefromgif';
if (strtolower($reg[1]) == '.png') $imgfonction = 'imagecreatefrompng';
if (strtolower($reg[1]) == '.jpg') $imgfonction = 'imagecreatefromjpeg';
if (strtolower($reg[1]) == '.jpeg') $imgfonction = 'imagecreatefromjpeg';
if (strtolower($reg[1]) == '.bmp') $imgfonction = 'imagecreatefromwbmp';
if ($imgfonction)
{
if (! function_exists($imgfonction))
{
// Fonctions de conversion non presente dans ce PHP
return 0;
}
}
// Filename is a format image and supported by this PHP
return 1;
}
/**
\brief Affiche info admin
\param text Texte info
*/
function info_admin($texte)
{
global $conf,$langs;
$s='<div class="info">';
$s.=img_picto($langs->trans("InfoAdmin"),'star');
$s.=' ';
$s.=$texte;
$s.='</div>';
return $s;
}
/**
\brief Affiche formulaire de login PEAR
\remarks Il faut changer le code html dans cette fonction pour changer le design de la logon
*/
function dol_loginfunction($notused,$pearstatus)
{
global $langs,$conf,$mysoc;
$langs->load("main");
$langs->load("other");
$conf->css = "theme/".$conf->theme."/".$conf->theme.".css";
// Si feuille de style en php existe
if (file_exists(DOL_DOCUMENT_ROOT.'/'.$conf->css.".php")) $conf->css.=".php";
header('Cache-Control: Public, must-revalidate');
// Ce DTD est KO car inhibe document.body.scrollTop
//print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
// Ce DTD est OK
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'."\n";
// En tete html
print "<html>\n";
print "<head>\n";
print '<meta name="robots" content="noindex,nofollow">'."\n"; // Evite indexation par robots
print "<title>Dolibarr login</title>\n";
print '<link rel="stylesheet" type="text/css" href="'.DOL_URL_ROOT.'/'.$conf->css.'">'."\n";
print '<style type="text/css">'."\n";
print '<!--'."\n";
print '#login {';
print ' margin-top: 70px;';
print ' margin-bottom: 30px;';
print ' text-align: center;';
print ' font: 12px arial,helvetica;';
print '}'."\n";
print '#login table {';
print ' border: 1px solid #C0C0C0;';
if (file_exists(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/login_background.png'))
{
print 'background: #F0F0F0 url('.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/login_background.png) repeat-x;';
}
else
{
print 'background: #F0F0F0 url('.DOL_URL_ROOT.'/theme/login_background.png) repeat-x;';
}
print 'font-size: 12px;';
print '}'."\n";
print '-->'."\n";
print '</style>'."\n";
print '<script language="javascript" type="text/javascript">'."\n";
print "function donnefocus() {\n";
if (! $_REQUEST["username"]) print "document.getElementsByTagName('INPUT')[0].focus();";
else print "document.getElementsByTagName('INPUT')[1].focus();";
print "}\n";
print '</script>'."\n";
print '</head>'."\n";
// Body
print '<body class="body" onload="donnefocus();">';
// Start Form
print '<form id="login" name="login" method="post" action="';
print $_SERVER['PHP_SELF'];
print $_SERVER["QUERY_STRING"]?'?'.$_SERVER["QUERY_STRING"]:'';
print '">';
// Table 1
print '<table cellpadding="0" cellspacing="0" border="0" align="center" width="450">';
if (file_exists(DOL_DOCUMENT_ROOT.'/logo.png'))
{
// TODO A virer Cas qui ne devrait pas arriver (pour compatibilit)
print '<tr><td colspan="3" style="text-align:center;">';
print '<img src="/logo.png"></td></tr>';
}
else
{
print '<tr class="vmenu"><td align="center">Dolibarr '.DOL_VERSION.'</td></tr>';
}
print '</table>';
print '<br>';
// Table 2
print '<table cellpadding="2" align="center" width="450">';
print '<tr><td colspan="3"> </td></tr>';
print '<tr>';
print '<td align="left"><br> <b>'.$langs->trans("Login").'</b> </td>';
print '<td><input name="username" class="flat" size="15" maxlength="25" value="'.(isset($_REQUEST["username"])?$_REQUEST["username"]:'').'" tabindex="1" /></td>';
if ($conf->main_authentication) $title.=$langs->trans("AuthenticationMode").': '.$conf->main_authentication;
// Show logo (search in order: small company logo, large company logo, theme logo, common logo)
$width=0;
$urllogo=DOL_URL_ROOT.'/theme/login_logo.png';
if (! empty($mysoc->logo_small) && is_readable($conf->societe->dir_logos.'/thumbs/'.$mysoc->logo_small))
{
$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=companylogo&file='.urlencode('/thumbs/'.$mysoc->logo_small);
}
elseif (! empty($mysoc->logo_small) && is_readable($conf->societe->dir_logos.'/'.$mysoc->logo))
{
$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=companylogo&file='.urlencode($mysoc->logo);
$width=96;
}
elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/login_logo.png'))
{
$urllogo=DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/login_logo.png';
}
print '<td rowspan="2" align="center"><img title="'.$title.'" src="'.$urllogo.'"';
if ($width) print ' width="'.$width.'"';
print '></td>';
print '</tr>';
print '<tr><td align="left" valign="top"> <b>'.$langs->trans("Password").'</b> </td>';
print '<td valign="top" nowrap="nowrap"><input name="password" class="flat" type="password" size="15" maxlength="30" tabindex="2">';
print '</td></tr>';
print '<tr><td colspan="3"> </td></tr>'."\n";
// Code de scurit
if ($conf->global->MAIN_SECURITY_ENABLECAPTCHA)
{
//print "Info session: ".session_name().session_id();print_r($_SESSION);
include_once(DOL_DOCUMENT_ROOT.'/includes/cryptographp/cryptographp.fct.php');
$cryptinstall = DOL_URL_ROOT.'/includes/cryptographp';
print '<tr><td align="left"> <b>'.$langs->trans("SecurityCode").'</b></td>';
print '<td><input type="text" size="15" maxlength="10" name="code" tabindex="3"></td>';
print '<td align="center">';
dsp_crypt('dolibarr.cfg.php',1);
print '</td>';
print '</tr>';
}
print '<tr><td colspan="3" style="text-align:center;"><br>';
print '<input type="submit" class="button" value=" '.$langs->trans("Connection").' " tabindex="4" />';
print '</td></tr>';
if (! $conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK)
{
print '<tr><td colspan="3" align="center"><a style="color: #888888; font-size: 10px" href="'.DOL_URL_ROOT.'/user/passwordforgotten.php">('.$langs->trans("PasswordForgotten").')</a></td></tr>';
}
print '</table>';
print '<input type="hidden" name="loginfunction" value="loginfunction" />';
print '</form>';
// Message
if ($_SESSION["loginmesg"] || ! empty($pearstatus))
{
print '<center><table width="60%"><tr><td align="center" class="small"><div class="error">';
if ($pearstatus == AUTH_EXPIRED) print "<i>Your session expired. Please login again!</i>\n";
elseif ($pearstatus == AUTH_IDLED) print "<i>You have been idle for too long. Please login again!</i>\n";
elseif ($pearstatus == AUTH_WRONG_LOGIN) print $langs->trans("ErrorBadLoginPassword");
elseif ($_SESSION["loginmesg"])
{
print $_SESSION["loginmesg"];
$_SESSION["loginmesg"]="";
}
print '</div></td></tr></table></center>';
}
if ($conf->global->MAIN_HOME)
{
print '<center><table cellpadding="0" cellspacing="0" border="0" align="center" width="750"><tr><td align="center">';
print nl2br($conf->global->MAIN_HOME);
print '</td></tr></table></center><br>';
}
// Fin entete html
print "\n</body>\n</html>";
}
/**
\brief Vrifie les droits de l'utilisateur
\param user Utilisateur courant
\param module Module a vrifier
\param objectid ID du document
\param dbtable Table de la base correspondant au module (optionnel)
\param list Dfini si la page sert de liste et donc ne fonctionne pas avec un id
*/
function restrictedArea($user, $modulename, $objectid='', $dbtablename='', $list=0)
{
global $db;
if (!$modulename)
{
$modulename = 'societe';
$list = 1;
}
$user->getrights($modulename);
$user->getrights('commercial');
$socid = 0;
$nocreate = 0;
//si dbtable non dfini, mme nom que le module
if (!$dbtablename) $dbtablename = $modulename;
if (!$user->rights->$modulename->lire)
{
accessforbidden();
}
else if (!$user->rights->$modulename->creer)
{
$nocreate = 1;
if ($_GET["action"] == 'create' || $_POST["action"] == 'create')
{
accessforbidden();
}
}
if ($user->societe_id > 0)
{
$_GET["action"] = '';
$_POST["action"] = '';
$socid = $user->societe_id;
if (!$objectid) $objectid = $socid;
if ($modulename == 'societe' && $socid <> $objectid) accessforbidden();
}
if ($objectid)
{
if ($modulename == 'societe' && !$user->rights->commercial->client->voir && !$socid > 0)
{
$sql = "SELECT sc.fk_soc";
$sql .= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE sc.fk_soc = ".$objectid." AND sc.fk_user = ".$user->id;
}
else if (!$user->rights->commercial->client->voir || $socid > 0)
{
$sql = "SELECT sc.fk_soc, dbt.fk_soc";
$sql .= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc, ".MAIN_DB_PREFIX.$dbtablename." as dbt";
$sql .= " WHERE dbt.rowid = ".$objectid;
if (!$user->rights->commercial->client->voir && !$socid > 0)
{
$sql .= " AND sc.fk_soc = dbt.fk_soc AND sc.fk_user = ".$user->id;
}
if ($socid > 0) $sql .= " AND dbt.fk_soc = ".$socid;
}
//print $sql;
if ($sql && $db->query($sql))
{
if ($db->num_rows() == 0)
{
accessforbidden();
}
}
}
else if ((!$objectid && $list==0) && $nocreate == 1)
{
accessforbidden();
}
return $objectid;
}
/**
\brief Affiche message erreur de type acces interdit et arrete le programme
\param message Force error message
\param printheader Affiche avant le header
\remarks L'appel a cette fonction termine le code.
*/
function accessforbidden($message='',$printheader=1)
{
global $user, $langs;
$langs->load("other");
if ($printheader && function_exists("llxHeader")) llxHeader();
print '<div class="error">';
if (! $message) print $langs->trans("ErrorForbidden");
else print $message;
print '</div>';
print '<br>';
if ($user->login)
{
print $langs->trans("CurrentLogin").': <font class="error">'.$user->login.'</font><br>';
print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users"));
}
elseif (! empty($_SERVER["REMOTE_USER"]))
{
print $langs->trans("CurrentLogin").': <font class="error">'.$_SERVER["REMOTE_USER"]."</font><br>";
print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users"));
}
else
{
print $langs->trans("ErrorForbidden3");
}
if (function_exists("llxFooter")) llxFooter();
exit(0);
}
/**
\brief Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte des bugs.
On doit appeler cette fonction quand une erreur technique bloquante est rencontre.
Toutefois, il faut essayer de ne l'appeler qu'au sein de pages php, les classes devant
renvoyer leur erreur par l'intermdiaire de leur proprit "error".
\param db Handler de base utilis
\param error Chaine erreur ou tableau de chaines erreur complmentaires a afficher
*/
function dolibarr_print_error($db='',$error='')
{
global $conf,$langs,$argv;
$syslog = '';
// Si erreur intervenue avant chargement langue
if (! $langs)
{
require_once(DOL_DOCUMENT_ROOT ."/translate.class.php");
$langs = new Translate(DOL_DOCUMENT_ROOT ."/langs", $conf);
}
$langs->load("main");
if ($_SERVER['DOCUMENT_ROOT']) // Mode web
{
print $langs->trans("DolibarrHasDetectedError").".<br>\n";
print $langs->trans("InformationToHelpDiagnose").":<br><br>\n";
print "<b>".$langs->trans("Server").":</b> ".$_SERVER["SERVER_SOFTWARE"]."<br>\n";;
print "<b>".$langs->trans("Dolibarr").":</b> ".DOL_VERSION."<br>\n";;
print "<b>".$langs->trans("RequestedUrl").":</b> ".$_SERVER["REQUEST_URI"]."<br>\n";;
print "<b>QUERY_STRING:</b> ".$_SERVER["QUERY_STRING"]."<br>\n";;
print "<b>".$langs->trans("Referer").":</b> ".$_SERVER["HTTP_REFERER"]."<br>\n";;
$syslog.="url=".$_SERVER["REQUEST_URI"];
$syslog.=", query_string=".$_SERVER["QUERY_STRING"];
}
else // Mode CLI
{
print $langs->transnoentities("ErrorInternalErrorDetected").": ".$argv[0]."\n";
$syslog.="pid=".getmypid();
}
if (is_object($db))
{
if ($_SERVER['DOCUMENT_ROOT']) // Mode web
{
print "<br>\n";
print "<b>".$langs->trans("DatabaseTypeManager").":</b> ".$db->type."<br>\n";
print "<b>".$langs->trans("RequestLastAccessInError").":</b> ".($db->lastqueryerror()?$db->lastqueryerror():$langs->trans("ErrorNoRequestInError"))."<br>\n";
print "<b>".$langs->trans("ReturnCodeLastAccess").":</b> ".$db->errno()."<br>\n";
print "<b>".$langs->trans("InformationLastAccess").":</b> ".$db->error()."<br>\n";
}
else // Mode CLI
{
print $langs->transnoentities("DatabaseTypeManager").":\n".$db->type."\n";
print $langs->transnoentities("RequestLastAccessInError").":\n".($db->lastqueryerror()?$db->lastqueryerror():$langs->trans("ErrorNoRequestInError"))."\n";
print $langs->transnoentities("ReturnCodeLastAccess").":\n".$db->errno()."\n";
print $langs->transnoentities("InformationLastAccess").":\n".$db->error()."\n";
}
$syslog.=", sql=".$db->lastquery();
$syslog.=", db_error=".$db->error();
}
if ($error)
{
$langs->load("errors");
if (is_array($error)) $errors=$error;
else $errors=array($error);
foreach($errors as $msg)
{
$msg=$langs->trans($msg);
if ($_SERVER['DOCUMENT_ROOT']) // Mode web
{
print "<b>".$langs->trans("Message").":</b> ".$msg."<br>\n" ;
}
else // Mode CLI
{
print $langs->transnoentities("Message").":\n".$msg."\n" ;
}
$syslog.=", msg=".$msg;
}
}
dolibarr_syslog("Error $syslog",LOG_ERROR);
}
/**
\brief Deplacer les fichiers telechargs, apres quelques controles divers
\param src_file fichier source
\param dest_file fichier de destination
\return int true=Deplacement OK, false=Pas de deplacement ou KO
*/
function doliMoveFileUpload($src_file, $dest_file)
{
global $conf;
$file_name = $dest_file;
if ($conf->global->MAIN_USE_AVSCAN)
{
$malware = dol_avscan_file($src_file);
if ($malware) return $malware;
}
// Security:
// On renomme les fichiers avec extention executable car si on a mis le rep
// documents dans un rep de la racine web (pas bien), cela permet d'executer
// du code a la demande.
if (eregi('\.htm|\.html|\.php|\.pl|\.cgi$',$file_name))
{
$file_name.= '.txt';
}
// Security:
// On interdit les remontes de repertoire ainsi que les pipe dans
// les noms de fichiers.
if (eregi('\.\.',$src_file) || eregi('[<>|]',$src_file))
{
dolibarr_syslog("Refused to deliver file ".$src_file);
return false;
}
// Security:
// On interdit les remontes de repertoire ainsi que les pipe dans
// les noms de fichiers.
if (eregi('\.\.',$dest_file) || eregi('[<>|]',$dest_file))
{
dolibarr_syslog("Refused to deliver file ".$dest_file);
return false;
}
$return=move_uploaded_file($src_file, $file_name);
return $return;
}
/**
\brief Transcodage de francs en euros
\param zonein zone de depart
\param devise type de devise
\return r resultat transcod
*/
function transcoS2L($zonein,$devise)
{
// Open source offert par <A HREF="mailto:alainfloch@free.fr?subject=chif2let">alainfloch@free.fr</A> 28/10/2001, sans garantie.
// dbut de la fonction de transcodification de somme en toutes lettres
/* $zonein = "123,56";
* $devise = "E"; // prciser F si francs , sinon ce sera de l'euro
* $r = transcoS2L($zonein,$devise); // appeler la fonction
* echo "rsultat vaut $r<br>";
* $zonelettresM = strtoupper($r); // si vous voulez la mme zone mais tout en majuscules
* echo "rsultat en Majuscules vaut $zonelettresM<br>";
* $zonein = "1,01";
* $r = transcoS2L($zonein,$devise);
* echo "rsultat vaut $r<br>";
*/
if ($devise == "F")
{
$unite_singulier = " franc ";
$unite_pluriel = " francs ";
$cent_singulier = " centime";
}
else
{
$unite_singulier = " euro ";
$unite_pluriel = " euros ";
$cent_singulier = " centime";
}
$arr1_99 = array("zro","un","deux","trois",
"quatre","cinq","six","sept",
"huit","neuf","dix","onze","douze",
"treize","quatorze","quinze","seize",
"dix-sept","dix-huit","dix-neuf","vingt ");
$arr1_99[30] = "trente ";
$arr1_99[40] = "quarante ";
$arr1_99[50] = "cinquante ";
$arr1_99[60] = "soixante ";
$arr1_99[70] = "soixante-dix ";
$arr1_99[71] = "soixante et onze";
$arr1_99[80] = "quatre-vingts ";
$i = 22;
while ($i < 63) {// initialise la table
$arr1_99[$i - 1] = $arr1_99[$i - 2]." et un";
$j = 0;
while ($j < 8) {
$k = $i + $j;
$arr1_99[$k] = $arr1_99[$i - 2].$arr1_99[$j + 2];
$j++;
}
$i = $i + 10;
} // fin initialise la table
$i = 12;
while ($i < 20) {// initialise la table (suite)
$j = 60 + $i;
$arr1_99[$j] = "soixante-".$arr1_99[$i];
$i++;
} // fin initialise la table (suite)
$i = 1;
while ($i < 20) {// initialise la table (fin)
$j = 80 + $i;
$arr1_99[$j] = "quatre-vingt-".$arr1_99[$i];
$i++;
} // fin initialise la table (fin)
// echo "Pour une valeur en entre = $zonein<br>"; //pour ceux qui ne croient que ce qu'ils voient !
// quelques petits controles s'imposent !!
$valid = "[a-zA-Z\&\\"\'\(\-\\_\\\)\=\;\:\!\*\$\^\<\>]";
if (ereg($valid,$zonein))
{
$r = "<b>la chane ".$zonein." n'est pas valide</b>";
return($r);
}
$zone = explode(" ",$zonein); // supprimer les blancs sparateurs
$zonein = implode("",$zone); // reconcatne la zone input
$zone = explode(".",$zonein); // supprimer les points sparateurs
$zonein = implode("",$zone); // reconcatne la zone input, a c'est fort ! merci PHP
$virg = strpos($zonein,",",1); // a la poursuite de la virgule
$i = strlen($zonein); // et de la longueur de la zone input
if ($virg == 0) { // ya pas de virgule
if ($i > 7)
{
$r = "<b>la chane ".$zonein." est trop longue (maxi = 9 millions)</b>";
return($r);
}
$deb = 7 - $i;
$zoneanaly = substr($zonechiffres,0,$deb).$zonein.",00";
}
else
{ //ya une virgule
$ti = explode(",",$zonein); // mettre de ct ce qu'il y a devant la virgule
$i = strlen($ti[0]); // en controler la longueur
$zonechiffres = "0000000,00";
if ($i > 7)
{
$r = "<b>la chane ".$zonein." est trop longue (maxi = 9 millions,00)</b>";
return($r);
}
$deb = 7 - $i;
$zoneanaly = substr($zonechiffres,0,$deb).$zonein;
}
$M= substr($zoneanaly,0,1);
if ($M != 0)
{ // qui veut gagner des millions
$r = $arr1_99[$M]." million";
if ($M ==1) $r = $r." ";
else $r = $r."s ";
if (substr($zoneanaly,1,6)==0)
{
if ($devise == 'F') $r = $r." de ";
else $r = $r."d'";
}
}
$CM= substr($zoneanaly,1,1);
if ($CM == 1)
{ // qui veut gagner des centaines de mille
$r = $r." cent ";
}
else
{ // ya des centaines de mille
if ($CM > 1)
{
$r = $r. $arr1_99[$CM]." cent ";
}
} // fin du else ya des centaines de mille
$MM= substr($zoneanaly,2,2);
if (substr($zoneanaly,2,1)==0){ $MM = substr($zoneanaly,3,1);} // enlever le zro des milliers cause indexation
if ($MM ==0 && $CM > 0)
{
$r = $r."mille ";
}
if ($MM != 0)
{
if ($MM == 80)
{
$r = $r."quatre-vingt mille ";
}
else
{
if ($MM > 1 )
{
$r = $r.$arr1_99[$MM]." mille ";
}
else
{
if ($CM == 0) $r = $r." mille ";
else
{
$r = $r.$arr1_99[$MM]." mille ";
}
}
}
}
$C2= substr($zoneanaly,5,2);
if (substr($zoneanaly,5,1)==0){ $C2 = substr($zoneanaly,6,1);} // enlever le zro des centaines cause indexation
$C1= substr($zoneanaly,4,1);
if ($C2 ==0 && $C1 > 1)
{
$r = $r.$arr1_99[$C1]." cents ";
}
else
{
if ($C1 == 1) $r = $r." cent ";
else
{
if ($C1 > 1) $r = $r.$arr1_99[$C1]." cent ";
}
}
if ($C2 != 0)
{
$r = $r.$arr1_99[$C2];
}
if ($virg !=0)
{
if ($ti[0] > 1) $r = $r. $unite_pluriel; else $r = "un ".$unite_singulier;
}
else
{
if ($zonein > 1) $r = $r.$unite_pluriel; else $r = "un ".$unite_singulier;
}
$UN= substr($zoneanaly,8,2);
if ($UN != "00")
{
$cts = $UN;
if (substr($UN,0,1)==0){ $cts = substr($UN,1,1);} // enlever le zro des centimes cause indexation
$r = $r." et ". $arr1_99[$cts].$cent_singulier;
if ($UN > 1) $r =$r."s"; // accorde au pluriel
}
$r1 = ltrim($r); // enleve quelques blancs possibles en dbut de zone
$r = ucfirst($r1); // met le 1er caractre en Majuscule, c'est + zoli
return($r); // retourne le rsultat
} // fin fonction transcoS2L
/**
\brief Affichage de la ligne de titre d'un tabelau
\param name libelle champ
\param file url pour clic sur tri
\param field champ de tri
\param begin ("" par defaut)
\param options ("" par defaut)
\param td options de l'attribut td ("" par defaut)
\param sortfield nom du champ sur lequel est effectu le tri du tableau
\param sortorder ordre du tri
*/
function print_liste_field_titre($name, $file, $field, $begin="", $options="", $td="", $sortfield="", $sortorder="")
{
global $conf;
//print "$name, $file, $field, $begin, $options, $td, $sortfield, $sortorder<br>\n";
// Le champ de tri est mis en vidence.
// Exemple si (sortfield,field)=("nom","xxx.nom") ou (sortfield,field)=("nom","nom")
if ($sortfield == $field || $sortfield == ereg_replace("^[^\.]+\.","",$field))
{
print '<td class="liste_titre_sel" '. $td.'>';
}
else
{
print '<td class="liste_titre" '. $td.'>';
}
print $name." ";
if (! $sortorder)
{
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",0).'</a>';
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",0).'</a>';
}
else
{
if ($field != $sortfield)
{
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",0).'</a>';
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",0).'</a>';
}
else {
$sortorder=strtoupper($sortorder);
if ($sortorder == 'DESC' ) {
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",0).'</a>';
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",1).'</a>';
}
if ($sortorder == 'ASC' ) {
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",1).'</a>';
print '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",0).'</a>';
}
}
}
print "</td>";
}
/**
\brief Affichage d'un titre
\param titre Le titre a afficher
*/
function print_titre($titre)
{
print '<div class="titre">'.$titre.'</div>';
}
/**
\brief Affichage d'un titre d'une fiche, align a gauche
\param titre Le titre a afficher
\param mesg Message suplmentaire a afficher a droite
\param picto Picto pour ligne de titre
*/
function print_fiche_titre($titre, $mesg='', $picto='')
{
print "\n";
print '<table width="100%" border="0" class="notopnoleftnoright"><tr>';
if ($picto) print '<td width="24" align="left" valign="middle">'.img_picto('',$picto).'</td>';
print '<td class="notopnoleftnoright" valign="middle">';
print '<div class="titre">'.$titre.'</div>';
print '</td>';
if (strlen($mesg))
{
print '<td align="right" valign="middle"><b>'.$mesg.'</b></td>';
}
print '</tr></table>'."\n";
}
/**
\brief Effacement d'un fichier
\param file Fichier a effacer ou masque de fichier a effacer
\param boolean true if file deleted, false if error
*/
function dol_delete_file($file)
{
$ok=true;
foreach (glob($file) as $filename)
{
$ok=unlink($filename);
if ($ok) dolibarr_syslog("Removed file $filename",LOG_DEBUG);
else dolibarr_syslog("Failed to remove file $filename",LOG_ERROR);
}
return $ok;
}
/**
\brief Effacement d'un rpertoire
\param file Rpertoire a effacer
*/
function dol_delete_dir($dir)
{
return rmdir($dir);
}
/**
\brief Effacement d'un rpertoire $dir et de son arborescence
\param file Rpertoire a effacer
\param count Compteur pour comptage nb elements supprims
\return int Nombre de fichier+reprtoires supprims
*/
function dol_delete_dir_recursive($dir,$count=0)
{
if ($handle = opendir("$dir"))
{
while (false !== ($item = readdir($handle)))
{
if ($item != "." && $item != "..")
{
if (is_dir("$dir/$item"))
{
$count=dol_delete_dir_recursive("$dir/$item",$count);
}
else
{
unlink("$dir/$item");
$count++;
//echo " removing $dir/$item<br>\n";
}
}
}
closedir($handle);
rmdir($dir);
$count++;
//echo "removing $dir<br>\n";
}
//echo "return=".$count;
return $count;
}
/**
\brief Scan les fichiers avec un anti-virus
\param file Fichier a scanner
\return malware Nom du virus si infect sinon retourne "null"
*/
function dol_avscan_file($file)
{
$malware = '';
// Clamav
if (function_exists("cl_scanfile"))
{
$maxreclevel = 5 ; // maximal recursion level
$maxfiles = 1000; // maximal number of files to be scanned within archive
$maxratio = 200; // maximal compression ratio
$archivememlim = 0; // limit memory usage for bzip2 (0/1)
$maxfilesize = 10485760; // archived files larger than this value (in bytes) will not be scanned
cl_setlimits($maxreclevel, $maxfiles, $maxratio, $archivememlim, $maxfilesize);
$malware = cl_scanfile($file);
}
return $malware;
}
/**
\brief Fonction print_barre_liste
\param titre titre de la page
\param page numro de la page
\param file lien
\param options parametres complementaires lien ('' par defaut)
\param sortfield champ de tri ('' par defaut)
\param sortorder ordre de tri ('' par defaut)
\param center chaine du centre ('' par defaut)
\param num nombre d'lment total
*/
function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1)
{
global $conf,$langs;
if ($num > $conf->liste_limit or $num == -1)
{
$nextpage = 1;
}
else
{
$nextpage = 0;
}
print '<table width="100%" border="0" class="notopnoleftnoright">';
if ($page > 0 || $num > $conf->liste_limit)
{
print '<tr><td class="notopnoleftnoright"><div class="titre">'.$titre.($titre?' - ':'').$langs->trans('page').' '.($page+1);
print '</div></td>';
}
else
{
print '<tr><td class="notopnoleftnoright"><div class="titre">'.$titre.'</div></td>';
}
if ($center)
{
print '<td align="left">'.$center.'</td>';
}
print '<td align="right">';
if ($sortfield) $options .= "&sortfield=$sortfield";
if ($sortorder) $options .= "&sortorder=$sortorder";
// Affichage des fleches de navigation
print_fleche_navigation($page,$file,$options,$nextpage);
print '</td></tr></table>';
}
/**
\brief Fonction servant a afficher les fleches de navigation dans les pages de listes
\param page numro de la page
\param file lien
\param options autres parametres d'url a propager dans les liens ("" par defaut)
\param nextpage faut-il une page suivante
*/
function print_fleche_navigation($page,$file,$options='',$nextpage)
{
global $conf, $langs;
if ($page > 0)
{
print '<a href="'.$file.'?page='.($page-1).$options.'">'.img_previous($langs->trans("Previous")).'</a>';
}
if ($nextpage > 0)
{
print '<a href="'.$file.'?page='.($page+1).$options.'">'.img_next($langs->trans("Next")).'</a>';
}
}
/**
* \brief Fonction qui retourne un taux de tva format pour visualisation
* \remarks Fonction utilise dans les pdf et les pages html
* \param rate Taux a formater (19.6 19,6 19.6% 19,6%...)
* \return string Chaine avec montant format (19,6 ou 19,6%)
*/
function vatrate($rate)
{
$foundpercent=false;
if (eregi('%',$rate))
{
$rate=eregi_replace('%','',$rate);
$foundpercent=true;
}
return price($rate,0,'',0,0).($foundpercent?'%':'');
}
/**
* \brief Fonction qui retourne un montant montaire format pour visualisation
* \remarks Fonction utilise dans les pdf et les pages html
* \param amount Montant a formater
* \param html Formatage html ou pas (0 par defaut)
* \param outlangs Objet langs pour formatage text
* \param trunc 1=Tronque affichage si trop de dcimales,0=Force le non troncage
* \param nbdecimal Nbre decimals minimum.
* \return string Chaine avec montant format
* \seealso price2num Fonction inverse de price
*/
function price($amount, $html=0, $outlangs='', $trunc=1, $nbdecimal=2)
{
global $langs,$conf;
// Separateurs par defaut
$dec='.'; $thousand=' ';
// Si $outlangs non force, on prend langue utilisateur
if (! is_object($outlangs)) $outlangs=$langs;
if ($outlangs->trans("SeparatorDecimal") != "SeparatorDecimal") $dec=$outlangs->trans("SeparatorDecimal");
if ($outlangs->trans("SeparatorThousand")!= "SeparatorThousand") $thousand=$outlangs->trans("SeparatorThousand");
//print "amount=".$amount." html=".$html." trunc=".$trunc." nbdecimal=".$nbdecimal." dec=".$dec." thousand=".$thousand;
//print "amount=".$amount."-";
$amount = ereg_replace(',','.',$amount);
//print $amount."-";
$datas = split('\.',$amount);
$decpart = $datas[1];
$decpart = eregi_replace('0+$','',$decpart); // Supprime les 0 de fin de partie dcimale
//print "decpart=".$decpart."<br>";
$end='';
// On augmente au besoin si il y a plus de 2 dcimales
if (strlen($decpart) > $nbdecimal) $nbdecimal=strlen($decpart);
// Si on depasse max
if ($trunc && $nbdecimal > $conf->global->MAIN_MAX_DECIMALS_SHOWN)
{
$nbdecimal=$conf->global->MAIN_MAX_DECIMALS_SHOWN;
if (eregi('\.\.\.',$conf->global->MAIN_MAX_DECIMALS_SHOWN))
{
// Si un affichage est tronqu, on montre des ...
$end='...';
}
}
// Formate nombre
if ($html)
{
$output=ereg_replace(' ',' ',number_format($amount, $nbdecimal, $dec, $thousand));
}
else
{
$output=number_format($amount, $nbdecimal, $dec, $thousand);
}
$output.=$end;
return $output;
}
/**
\brief Fonction qui retourne un numrique conforme PHP et SQL, depuis un montant au
format utilisateur.
\remarks Fonction a appeler sur montants saisis avant un insert en base
\param amount Montant a formater
\param rounding 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
'MT'=Round to Max with Tax (MAIN_MAX_DECIMALS_TOT)
'MS'=Round to Max Shown (MAIN_MAX_DECIMALS_SHOWN)
''=No rounding
\return string Montant au format numrique PHP et SQL (Exemple: '99.99999')
\seealso price Fonction inverse de price2num
*/
function price2num($amount,$rounding='')
{
global $conf;
// Round PHP function does not allow number like '1,234.5'.
// Numbers must be '1234.5'
$amount=ereg_replace(',','.',$amount);
$amount=ereg_replace(' ','',$amount);
if ($rounding)
{
if ($rounding == 'MU') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_UNIT);
elseif ($rounding == 'MT') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_TOT);
elseif ($rounding == 'MS') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_SHOWN);
else $amount='ErrorBadParameterProvidedToFunction';
$amount=ereg_replace(',','.',$amount);
$amount=ereg_replace(' ','',$amount);
}
return $amount;
}
/**
\brief Fonction qui renvoie la tva d'une ligne (en fonction du vendeur, acheteur et taux du produit)
\remarks Si vendeur non assujeti a TVA, TVA par dfaut=0. Fin de rgle.
Si le (pays vendeur = pays acheteur) alors TVA par dfaut=TVA du produit vendu. Fin de rgle.
Si (vendeur et acheteur dans Communaut europenne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par dfaut=0 (La TVA doit tre pay par acheteur au centre d'impots de son pays et non au vendeur). Fin de rgle.
Si (vendeur et acheteur dans Communaut europenne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par dfaut=TVA du produit vendu. Fin de rgle.
Si (vendeur et acheteur dans Communaut europenne) et (acheteur = entreprise avec num TVA) intra alors TVA par dfaut=0. Fin de rgle.
Sinon TVA propose par dfaut=0. Fin de rgle.
\param societe_vendeuse Objet socit vendeuse
\param societe_acheteuse Objet socit acheteuse
\param taux_produit Taux par defaut du produit vendu
\return float Taux de tva a appliquer, -1 si ne peut etre dtermin
*/
function get_default_tva($societe_vendeuse, $societe_acheteuse, $taux_produit)
{
dolibarr_syslog("get_default_tva vendeur_assujeti=".$societe_vendeuse->tva_assuj." pays_vendeur=".$societe_vendeuse->pays_id.", pays_acheteur=".$societe_acheteuse->pays_id.", taux_produit=".$taux_produit);
if (!is_object($societe_vendeuse)) return -1;
if (!is_object($societe_acheteuse)) return -1;
// Si vendeur non assujeti a TVA (tva_assuj vaut 0/1 ou franchise/reel)
if (is_numeric($societe_vendeuse->tva_assuj) && ! $societe_vendeuse->tva_assuj) return 0;
if (! is_numeric($societe_vendeuse->tva_assuj) && $societe_vendeuse->tva_assuj=='franchise') return 0;
// Si le (pays vendeur = pays acheteur) alors la TVA par dfaut=TVA du produit vendu. Fin de rgle.
//if (is_object($societe_acheteuse) && ($societe_vendeuse->pays_id == $societe_acheteuse->pays_id) && ($societe_acheteuse->tva_assuj == 1 || $societe_acheteuse->tva_assuj == 'reel'))
// Le test ci-dessus ne devrait pas etre necessaire. Me signaler l'exemple du cas juridique concercn si le test suivant n'est pas suffisant.
if ($societe_vendeuse->pays_id == $societe_acheteuse->pays_id)
{
if (strlen($taux_produit) == 0) return -1; // Si taux produit = '', on ne peut dterminer taux tva
return $taux_produit;
}
// Si (vendeur et acheteur dans Communaut europenne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par dfaut=0 (La TVA doit tre pay par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de rgle.
// Non gr
// Si (vendeur et acheteur dans Communaut europenne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par dfaut=TVA du produit vendu. Fin de rgle.
if (($societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC()) && ! $societe_acheteuse->tva_intra)
{
if (strlen($taux_produit) == 0) return -1; // Si taux produit = '', on ne peut dterminer taux tva
return $taux_produit;
}
// Si (vendeur et acheteur dans Communaut europenne) et (acheteur = entreprise avec num TVA intra) alors TVA par dfaut=0. Fin de rgle.
if (($societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC()) && $societe_acheteuse->tva_intra)
{
return 0;
}
// Sinon la TVA propose par dfaut=0. Fin de rgle.
// Rem: Cela signifie qu'au moins un des 2 est hors Communaut europenne et que le pays diffre
return 0;
}
/**
\brief Renvoie oui ou non dans la langue choisie
\param yesno Variable pour test si oui ou non
\param case 1=Yes/No, 0=yes/no
\param color 0=texte only, 1=Text is format with a color font style
*/
function yn($yesno, $case=1, $color=0)
{
global $langs;
$result='unknown';
if ($yesno == 1 || strtolower($yesno) == 'yes' || strtolower($yesno) == 'true') // A mettre avant test sur no a cause du == 0
{
$result=($case?$langs->trans("Yes"):$langs->trans("yes"));
$class='ok';
}
elseif ($yesno == 0 || strtolower($yesno) == 'no' || strtolower($yesno) == 'false')
{
$result=($case?$langs->trans("No"):$langs->trans("no"));
$class='error';
}
if ($color) return '<font class="'.$class.'">'.$result.'</font>';
return $result;
}
/**
\brief Fonction pour initialiser un salt pour la fonction crypt
\param $type 2=>renvoi un salt pour cryptage DES
12=>renvoi un salt pour cryptage MD5
non defini=>renvoi un salt pour cryptage par defaut
\return string Chaine salt
*/
function makesalt($type=CRYPT_SALT_LENGTH)
{
dolibarr_syslog("functions.inc::makesalt type=".$type);
switch($type)
{
case 12: // 8 + 4
$saltlen=8; $saltprefix='$1$'; $saltsuffix='$'; break;
case 8: // 8 + 4 (Pour compatibilite, ne devrait pas etre utilis)
$saltlen=8; $saltprefix='$1$'; $saltsuffix='$'; break;
case 2: // 2
default: // by default, fall back on Standard DES (should work everywhere)
$saltlen=2; $saltprefix=''; $saltsuffix=''; break;
}
$salt='';
while(strlen($salt) < $saltlen) $salt.=chr(rand(64,126));
$result=$saltprefix.$salt.$saltsuffix;
dolibarr_syslog("functions.inc::makesalt return=".$result);
return $result;
}
/**
\brief Fonction pour qui retourne le rowid d'un departement par son code
\param db handler d'accs base
\param code Code rgion
\param pays_id Id du pays
*/
function departement_rowid($db,$code, $pays_id)
{
$sql = "SELECT c.rowid FROM ".MAIN_DB_PREFIX."c_departements as c,".MAIN_DB_PREFIX."c_regions as r";
$sql .= " WHERE c.code_departement=". $code;
$sql .= " AND c.fk_region = r.code_region";
$sql .= " AND r.fk_pays =".$pays_id;
if ($db->query($sql))
{
$num = $db->num_rows();
if ($num)
{
$obj = $db->fetch_object();
return $obj->rowid;
}
else
{
return 0;
}
$db->free();
}
else
{
return 0;
}
}
/**
\brief Renvoi un chemin de classement rpertoire en fonction d'un id
\remarks Examples: 1->"0/0/1/", 15->"0/1/5/"
\param $num Id a dcomposer
\param $level Niveau de decoupage (1, 2 ou 3 niveaux)
*/
function get_exdir($num,$level=3)
{
$num = eregi_replace('[^0-9]','',$num);
$num = substr("000".$num, -$level);
if ($level == 1) return substr($num,0,1).'/';
if ($level == 2) return substr($num,1,1).'/'.substr($num,0,1).'/';
if ($level == 3) return substr($num,2,1).'/'.substr($num,1,1).'/'.substr($num,0,1).'/';
return '';
}
/**
\brief Cration de rpertoire recursive
\param $dir Rpertoire a crer
\return int < 0 si erreur, >= 0 si succs
*/
function create_exdir($dir)
{
dolibarr_syslog("functions.inc.php::create_exdir: dir=$dir",LOG_INFO);
if (@is_dir($dir)) return 0;
$nberr=0;
$nbcreated=0;
$ccdir = '';
$cdir = explode("/",$dir);
for ($i = 0 ; $i < sizeof($cdir) ; $i++)
{
if ($i > 0) $ccdir .= '/'.$cdir[$i];
else $ccdir = $cdir[$i];
if (eregi("^.:$",$ccdir,$regs)) continue; // Si chemin Windows incomplet, on poursuit par rep suivant
// Attention, le is_dir() peut chouer bien que le rep existe.
// (ex selon config de open_basedir)
if ($ccdir)
{
if (! @is_dir($ccdir))
{
dolibarr_syslog("functions.inc.php::create_exdir: Directory '".$ccdir."' does not exists or is outside open_basedir PHP setting.",LOG_DEBUG);
umask(0);
if (! @mkdir($ccdir, 0755))
{
// Si le is_dir a renvoy une fausse info, alors on passe ici.
dolibarr_syslog("functions.inc.php::create_exdir: Fails to create directory '".$ccdir."' or directory already exists.",LOG_WARNING);
$nberr++;
}
else
{
dolibarr_syslog("functions.inc.php::create_exdir: Directory '".$ccdir."' created",LOG_DEBUG);
$nberr=0; // On remet a zro car si on arrive ici, cela veut dire que les checs prcdents peuvent etre ignors
$nbcreated++;
}
}
else
{
$nberr=0; // On remet a zro car si on arrive ici, cela veut dire que les checs prcdents peuvent etre ignors
}
}
}
return ($nberr ? -$nberr : $nbcreated);
}
/**
\brief Scan a directory and return a list of files/directories
\param $path Starting path from which to search
\param $types Can be "directories", "files", or "all"
\param $recursive Determines whether subdirectories are searched
\param $filter Regex for filter
\param $exludefilter Regex for exclude filter
\param $sortcriteria Sort criteria ("date","size")
\param $sortorder Sort order (SORT_ASC, SORT_DESC)
\return array Array of array('name'=>xxx,'date'=>yyy,'size'=>zzz)
*/
function dolibarr_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter="", $sortcriteria="", $sortorder=SORT_ASC)
{
dolibarr_syslog("functions.inc.php::dolibarr_dir_list $path");
if (! is_dir($path)) return array();
if ($dir = opendir($path))
{
$file_list = array();
while (false !== ($file = readdir($dir)))
{
$qualified=1;
// Check if file is qualified
if (eregi('^\.',$file)) $qualified=0;
if ($excludefilter && eregi($excludefilter,$file)) $qualified=0;
if ($qualified)
{
// Check whether this is a file or directory and whether we're interested in that type
if ((is_dir($path."/".$file)) && (($types=="directories") || ($types=="all")))
{
// Add entry into file_list array
if ($sortcriteria == 'date') $filedate=filemtime($path."/".$file);
if ($sortcriteria == 'size') $filesize=filesize($path."/".$file);
if (! $filter || eregi($filter,$path.'/'.$file))
{
$file_list[] = array(
"name" => $file,
"fullname" => $path.'/'.$file,
"date" => $filedate,
"size" => $filesize
);
}
// if we're in a directory and we want recursive behavior, call this function again
if ($recursive)
{
$file_list = array_merge($file_list, dolibarr_dir_list($path."/".$file."/", $types, $recursive, $filter, $excludefilter, $sortcriteria, $sortorder));
}
}
else if (($types == "files") || ($types == "all"))
{
// Add file into file_list array
if ($sortcriteria == 'date') $filedate=filemtime($path."/".$file);
if ($sortcriteria == 'size') $filesize=filesize($path."/".$file);
if (! $filter || eregi($filter,$path.'/'.$file))
{
$file_list[] = array(
"name" => $file,
"fullname" => $path.'/'.$file,
"date" => $filedate,
"size" => $filesize
);
}
}
}
}
closedir($dir);
// Obtain a list of columns
$myarray=array();
foreach ($file_list as $key => $row)
{
$myarray[$key] = $row[$sortcriteria];
}
// Sort the data
array_multisort($myarray, $sortorder, $file_list);
return $file_list;
}
else
{
return false;
}
}
/**
\brief Retourne le numro de la semaine par rapport a une date
\param time Date au format 'timestamp'
\return int Numro de semaine
*/
function numero_semaine($time)
{
$stime = strftime( '%Y-%m-%d',$time);
if (eregi('^([0-9]+)\-([0-9]+)\-([0-9]+) ?([0-9]+)?:?([0-9]+)?',$stime,$reg))
{
// Date est au format 'YYYY-MM-DD' ou 'YYYY-MM-DD HH:MM:SS'
$annee = $reg[1];
$mois = $reg[2];
$jour = $reg[3];
}
/*
* Norme ISO-8601:
* - La semaine 1 de toute anne est celle qui contient le 4 janvier ou que la semaine 1 de toute anne est celle qui contient le 1er jeudi de janvier.
* - La majorit des annes ont 52 semaines mais les annes qui commence un jeudi et les annes bissextiles commenant un mercredi en possde 53.
* - Le 1er jour de la semaine est le Lundi
*/
// Dfinition du Jeudi de la semaine
if (date("w",mktime(12,0,0,$mois,$jour,$annee))==0) // Dimanche
$jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)-3*24*60*60;
else if (date("w",mktime(12,0,0,$mois,$jour,$annee))<4) // du Lundi au Mercredi
$jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)+(4-date("w",mktime(12,0,0,$mois,$jour,$annee)))*24*60*60;
else if (date("w",mktime(12,0,0,$mois,$jour,$annee))>4) // du Vendredi au Samedi
$jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)-(date("w",mktime(12,0,0,$mois,$jour,$annee))-4)*24*60*60;
else // Jeudi
$jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee);
// Dfinition du premier Jeudi de l'anne
if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==0) // Dimanche
{
$premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+4*24*60*60;
}
else if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))<4) // du Lundi au Mercredi
{
$premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+(4-date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine))))*24*60*60;
}
else if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))>4) // du Vendredi au Samedi
{
$premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+(7-(date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))-4))*24*60*60;
}
else // Jeudi
{
$premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine));
}
// Dfinition du numro de semaine: nb de jours entre "premier Jeudi de l'anne" et "Jeudi de la semaine";
$numeroSemaine = (
(
date("z",mktime(12,0,0,date("m",$jeudiSemaine),date("d",$jeudiSemaine),date("Y",$jeudiSemaine)))
-
date("z",mktime(12,0,0,date("m",$premierJeudiAnnee),date("d",$premierJeudiAnnee),date("Y",$premierJeudiAnnee)))
) / 7
) + 1;
// Cas particulier de la semaine 53
if ($numeroSemaine==53)
{
// Les annes qui commence un Jeudi et les annes bissextiles commenant un Mercredi en possde 53
if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==4 || (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==3 && date("z",mktime(12,0,0,12,31,date("Y",$jeudiSemaine)))==365))
{
$numeroSemaine = 53;
}
else
{
$numeroSemaine = 1;
}
}
//echo $jour."-".$mois."-".$annee." (".date("d-m-Y",$premierJeudiAnnee)." - ".date("d-m-Y",$jeudiSemaine).") -> ".$numeroSemaine."<BR>";
return sprintf("%02d",$numeroSemaine);
}
/**
\brief Retourne le picto champ obligatoire
\return string Chaine avec picto obligatoire
*/
function picto_required()
{
return '<b>*</b>';
}
/**
\brief Convertit une masse d'une unite vers une autre unite
\param weight float Masse a convertir
\param from_unit int Unite originale en puissance de 10
\param to_unit int Nouvelle unite en puissance de 10
\return float Masse convertie
*/
function weight_convert($weight,&$from_unit,$to_unit)
{
/* Pour convertire 320 gr en Kg appeler
* $f = -3
* weigh_convert(320, $f, 0) retournera 0.32
*
*/
while ($from_unit <> $to_unit)
{
if ($from_unit > $to_unit)
{
$weight = $weight * 10;
$from_unit = $from_unit - 1;
$weight = weight_convert($weight,$from_unit, $to_unit);
}
if ($from_unit < $to_unit)
{
$weight = $weight / 10;
$from_unit = $from_unit + 1;
$weight = weight_convert($weight,$from_unit, $to_unit);
}
}
return $weight;
}
/**
\brief Renvoi le texte d'une unite
\param int Unit
\param measuring_style Le style de mesure : weight, volume,...
\return string Unite
\todo gerer les autres units de mesure comme la livre, le gallon, le litre, ...
*/
function measuring_units_string($unit,$measuring_style='')
{
/* Note Rodo aux dev :)
* Ne pas insrer dans la base de donnes ces valeurs
* cela surchagerait inutilement d'une requete supplmentaire
* pour quelque chose qui est somme toute peu variable
*/
global $langs;
if ($measuring_style == 'weight')
{
$measuring_units[3] = $langs->trans("WeightUnitton");
$measuring_units[0] = $langs->trans("WeightUnitkg");
$measuring_units[-3] = $langs->trans("WeightUnitg");
$measuring_units[-6] = $langs->trans("WeightUnitmg");
}
else if ($measuring_style == 'volume')
{
$measuring_units[0] = $langs->trans("VolumeUnitm3");
$measuring_units[-3] = $langs->trans("VolumeUnitcm3");
$measuring_units[-6] = $langs->trans("VolumeUnitmm3");
}
return $measuring_units[$unit];
}
/**
\brief Decode le code html
\param string StringHtml
\return string DecodeString
*/
function dol_entity_decode($StringHtml)
{
$DecodeString = html_entity_decode($StringHtml);
return $DecodeString;
}
/**
\brief Nettoie une url
\param string url
\param string http (1: avec http, 0: sans http)
\return string CleanUrl
*/
function clean_url($url,$http=1)
{
if (eregi('^(https?:[\\\/]+)?([0-9A-Z\-\.]+\.[A-Z]{2,4})(:[0-9]+)?',$url,$regs))
{
$proto=$regs[1];
$domain=$regs[2];
$port=$regs[3];
//print $url." -> ".$proto." - ".$domain." - ".$port;
$url = unaccent_isostring(trim($url));
// Si http: defini on supprime le http (Si https on ne supprime pas)
if ($http==0)
{
if (eregi('^http:[\\\/]+',$url))
{
$url = eregi_replace('^http:[\\\/]+','',$url);
$proto = '';
}
}
// On passe le nom de domaine en minuscule
$url = eregi_replace('^(https?:[\\\/]+)?'.$domain,$proto.strtolower($domain),$url);
return $url;
}
}
/**
\brief Supprime le code html
\param string StringHtml
\return string CleanString
*/
function clean_html($StringHtml)
{
$pattern = "<[^>]+>";
$temp = dol_entity_decode($StringHtml);
$temp = ereg_replace($pattern,"",$temp);
// Supprime aussi les retours
$temp=str_replace("\n"," ",$temp);
// et les espaces doubles
while(STRPOS($temp," "))
{
$temp = STR_REPLACE(" "," ",$temp);
}
$CleanString = $temp;
return $CleanString;
}
/**
\brief Convertir du binaire en hxadcimal
\param string bin
\return string x
*/
function binhex($bin, $pad=false, $upper=false){
$last = strlen($bin)-1;
for($i=0; $i<=$last; $i++){ $x += $bin[$last-$i] * pow(2,$i); }
$x = dechex($x);
if($pad){ while(strlen($x) < intval(strlen($bin))/4){ $x = "0$x"; } }
if($upper){ $x = strtoupper($x); }
return $x;
}
/**
\brief Convertir de l'hxadcimal en binaire
\param string hexa
\return string bin
*/
function hexbin($hexa){
$bin='';
for($i=0;$i<strlen($hexa);$i++)
{
$bin.=str_pad(decbin(hexdec($hexa{$i})),4,'0',STR_PAD_LEFT);
}
return $bin;
}
/*
* \brief Cette fonction est appele pour coder ou non une chaine en html.
* \param stringtoencode String to encode
* \param htmlinfo 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
* \remarks Selon qu'on compte l'afficher dans le PDF avec:
* writeHTMLCell -> a besoin d'etre encod en HTML
* MultiCell -> ne doit pas etre encod en HTML
*/
function dol_htmlentities($stringtoencode,$htmlinfo=-1)
{
if ($htmlinfo == 1) return $stringtoencode;
if ($htmlinfo == 0) return htmlentities($stringtoencode);
if ($htmlinfo == -1)
{
if (dol_textishtml($stringtoencode)) return $stringtoencode;
else return htmlentities($stringtoencode);
}
return $stringtoencode;
}
/**
\brief Encode\decode le mot de passe de la base de donnes dans le fichier de conf
\param level niveau d'encodage : 0 non encod, 1 encod
*/
function encodedecode_dbpassconf($level=0)
{
$config = '';
if ($fp = fopen(DOL_DOCUMENT_ROOT.'/conf/conf.php','r'))
{
while(!feof($fp))
{
$buffer = fgets($fp,4096);
if (strstr($buffer,"\$dolibarr_main_db_encrypted_pass") && $level == 0)
{
$passwd = strstr($buffer,"$dolibarr_main_db_encrypted_pass=");
$passwd = substr(substr($passwd,2),0,-3);
$passwd = dolibarr_decode($passwd);
$config .= "\$dolibarr_main_db_pass=\"$passwd\";\n";
}
else if (strstr($buffer,"\$dolibarr_main_db_pass") && $level == 1)
{
$passwd = strstr($buffer,"$dolibarr_main_db_pass=");
$passwd = substr(substr($passwd,2),0,-3);
$passwd = dolibarr_encode($passwd);
$config .= "\$dolibarr_main_db_encrypted_pass=\"$passwd\";\n";
}
else
{
$config .= $buffer;
}
}
fclose($fp);
if ($fp = @fopen(DOL_DOCUMENT_ROOT.'/conf/conf.php','w'))
{
fputs($fp, $config, strlen($config));
fclose($fp);
return 1;
}
else
{
return -1;
}
}
else
{
return -2;
}
}
/**
\brief Encode une chaine de caractre
\param chain chaine de caractres a encoder
\return string_coded chaine de caractres encode
*/
function dolibarr_encode($chain)
{
for($i=0;$i<strlen($chain);$i++)
{
$output_tab[$i] = chr(ord(substr($chain,$i,1))+17);
}
$string_coded = base64_encode(implode ("",$output_tab));
return $string_coded;
}
/**
\brief Decode une chaine de caractre
\param chain chaine de caractres a decoder
\return string_coded chaine de caractres decode
*/
function dolibarr_decode($chain)
{
$chain = base64_decode($chain);
for($i=0;$i<strlen($chain);$i++)
{
$output_tab[$i] = chr(ord(substr($chain,$i,1))-17);
}
$string_decoded = implode ("",$output_tab);
return $string_decoded;
}
/**
\brief Fonction retournant le nombre de jour fieries samedis et dimanches entre 2 dates entrees en timestamp
\remarks SERVANT AU CALCUL DES JOURS OUVRABLES
\param timestampStart Timestamp de debut
\param timestampEnd Timestamp de fin
\return nbFerie Nombre de jours feries
*/
function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR')
{
$nbFerie = 0;
while ($timestampStart != $timestampEnd)
{
$ferie=false;
$countryfound=0;
$jour = date("d", $timestampStart);
$mois = date("m", $timestampStart);
$annee = date("Y", $timestampStart);
if ($countrycode == 'FR')
{
$countryfound=1;
// Definition des dates feriees fixes
if($jour == 1 && $mois == 1) $ferie=true; // 1er janvier
if($jour == 1 && $mois == 5) $ferie=true; // 1er mai
if($jour == 8 && $mois == 5) $ferie=true; // 5 mai
if($jour == 14 && $mois == 7) $ferie=true; // 14 juillet
if($jour == 15 && $mois == 8) $ferie=true; // 15 aout
if($jour == 1 && $mois == 11) $ferie=true; // 1 novembre
if($jour == 11 && $mois == 11) $ferie=true; // 11 novembre
if($jour == 25 && $mois == 12) $ferie=true; // 25 decembre
// Calcul du jour de paques
$date_paques = easter_date($annee);
$jour_paques = date("d", $date_paques);
$mois_paques = date("m", $date_paques);
if($jour_paques == $jour && $mois_paques == $mois) $ferie=true;
// Paques
// Calcul du jour de l ascension (38 jours apres Paques)
$date_ascension = mktime(date("H", $date_paques),
date("i", $date_paques),
date("s", $date_paques),
date("m", $date_paques),
date("d", $date_paques) + 38,
date("Y", $date_paques)
);
$jour_ascension = date("d", $date_ascension);
$mois_ascension = date("m", $date_ascension);
if($jour_ascension == $jour && $mois_ascension == $mois) $ferie=true;
//Ascension
// Calcul de Pentecote (11 jours apres Paques)
$date_pentecote = mktime(date("H", $date_ascension),
date("i", $date_ascension),
date("s", $date_ascension),
date("m", $date_ascension),
date("d", $date_ascension) + 11,
date("Y", $date_ascension)
);
$jour_pentecote = date("d", $date_pentecote);
$mois_pentecote = date("m", $date_pentecote);
if($jour_pentecote == $jour && $mois_pentecote == $mois) $ferie=true;
//Pentecote
// Calul des samedis et dimanches
$jour_julien = unixtojd($timestampStart);
$jour_semaine = jddayofweek($jour_julien, 0);
if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
//Samedi (6) et dimanche (0)
}
// Mettre ici cas des autres pays
// Cas pays non defini
if (! $countryfound)
{
// Calul des samedis et dimanches
$jour_julien = unixtojd($timestampStart);
$jour_semaine = jddayofweek($jour_julien, 0);
if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
//Samedi (6) et dimanche (0)
}
// On incremente compteur
if ($ferie) $nbFerie++;
// Incrementation du nombre de jour (on avance dans la boucle)
$jour++;
$timestampStart=mktime(0,0,0,$mois,$jour,$annee);
}
return $nbFerie;
}
/**
\brief Fonction retournant le nombre de jour entre deux dates
\param timestampStart Timestamp de dbut
\param timestampEnd Timestamp de fin
\param lastday On prend en compte le dernier jour, 0: non, 1:oui
\return nbjours Nombre de jours
*/
function num_between_day($timestampStart, $timestampEnd, $lastday=0)
{
if ($timestampStart < $timestampEnd)
{
if ($lastday == 1)
{
$bit = 0;
}
else
{
$bit = 1;
}
$nbjours = round(($timestampEnd - $timestampStart)/(60*60*24)-$bit);
}
return $nbjours;
}
/**
\brief Fonction retournant le nombre de jour entre deux dates sans les jours fris (jours ouvrs)
\param timestampStart Timestamp de dbut
\param timestampEnd Timestamp de fin
\param inhour 0: sort le nombre de jour , 1: sort le nombre d'heure (72 max)
\param lastday On prend en compte le dernier jour, 0: non, 1:oui
\return nbjours Nombre de jours ou d'heures
*/
function num_open_day($timestampStart, $timestampEnd,$inhour=0,$lastday=0)
{
global $langs;
if ($timestampStart < $timestampEnd)
{
$bit = 0;
if ($lastday == 1) $bit = 1;
$nbOpenDay = num_between_day($timestampStart, $timestampEnd, $bit) - num_public_holiday($timestampStart, $timestampEnd);
$nbOpenDay.= " ".$langs->trans("Days");
if ($inhour == 1 && $nbOpenDay <= 3) $nbOpenDay = $nbOpenDay*24 . $langs->trans("HourShort");
return $nbOpenDay;
}
else
{
return $langs->trans("Error");
}
}
/**
\brief Fonction retournant le nombre de lignes dans un texte format
\param texte Texte
\return nblines Nombre de lignes
*/
function num_lines($texte)
{
$repTable = array("\t" => " ", "\n" => "<br>", "\r" => " ", "\0" => " ", "\x0B" => " ");
$texte = strtr($texte, $repTable);
$pattern = '/(<[^>]+>)/Uu';
$a = preg_split($pattern, $texte, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$nblines = ((count($a)+1)/2);
return $nblines;
}
function ajax_indicator($htmlname,$indicator='working')
{
$script.='<span id="indicator'.$htmlname.'" style="display: none">'.img_picto('Working...',$indicator.'.gif').'</span>';
return $script;
}
/**
\brief Rcupre la valeur d'un champ, effectue un traitement Ajax et affiche le rsultat
\param htmlname nom et id du champ
\param keysearch nom et id complmentaire du champ de collecte
\param url chemin du fichier de rponse : /chemin/fichier.php
\param option champ supplmentaire de recherche dans les paramtres
\param indicator Nom de l'image gif sans l'extension
\return script script complet
*/
function ajax_updater($htmlname,$keysearch,$url,$option='',$indicator='working')
{
$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="">';
if ($indicator) $script.=ajax_indicator($htmlname,$indicator);
$script.='<script type="text/javascript">';
$script.='var myIndicator'.$htmlname.' = {
onCreate: function(){
if($F("'.$keysearch.$htmlname.'")){
Element.show(\'indicator'.$htmlname.'\');
}
},
onComplete: function() {
if(Ajax.activeRequestCount == 0){
Element.hide(\'indicator'.$htmlname.'\');
}
}
};';
$script.='Ajax.Responders.register(myIndicator'.$htmlname.');';
$script.='new Form.Element.Observer($("'.$keysearch.$htmlname.'"), 1,
function(){
var myAjax = new Ajax.Updater( {
success: \'ajdynfield'.$htmlname.'\'},
\''.DOL_URL_ROOT.$url.'\', {
method: \'get\',
parameters: "'.$keysearch.'="+$F("'.$keysearch.$htmlname.'")+"&htmlname='.$htmlname.$option.'"
});
});';
$script.='</script>';
$script.='<div class="nocellnopadd" id="ajdynfield'.$htmlname.'"></div>';
return $script;
}
/**
\brief Rcupre la valeur d'un champ, effectue un traitement Ajax et affiche le rsultat
\param htmlname nom et id du champ
\param keysearch nom et id complmentaire du champ de collecte
\param id ID du champ a modifier
\param url chemin du fichier de rponse : /chemin/fichier.php
\param option champ supplmentaire de recherche dans les paramtres
\param indicator Nom de l'image gif sans l'extension
\return script script complet
*/
function ajax_updaterWithID($htmlname,$keysearch,$id,$url,$option='',$indicator='working')
{
$script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="">';
if ($indicator) $script.=ajax_indicator($htmlname,$indicator);
$script.='<script type="text/javascript">';
$script.='var myIndicator'.$htmlname.' = {
onCreate: function(){
if($F("'.$keysearch.$htmlname.'")){
Element.show(\'indicator'.$htmlname.'\');
}
},
onComplete: function() {
if(Ajax.activeRequestCount == 0){
Element.hide(\'indicator'.$htmlname.'\');
}
}
};';
$script.='Ajax.Responders.register(myIndicator'.$htmlname.');';
$script.='new Form.Element.DelayedObserver($("'.$keysearch.$htmlname.'"), 1,
function(){
var elementHTML = $(\''.$id.'\');
var url = \''.DOL_URL_ROOT.$url.'\';
o_options = new Object();
o_options = {method: \'get\',parameters: "'.$keysearch.'="+$F("'.$keysearch.$htmlname.'")+"'.$option.'"};
var myAjax = new Ajax.Updater(elementHTML,url,o_options);
});';
$script.='</script>';
return $script;
}
/**
\brief Rcupre la valeur d'un champ, effectue un traitement Ajax et affiche le rsultat
\param htmlname nom et id du champ
\param url chemin du fichier de rponse : /chemin/fichier.php
\param indicator nom de l'image gif sans l'extension
\return script script complet
*/
function ajax_autocompleter($selected='',$htmlname,$url,$indicator='working')
{
if ($indicator) $script.= ajax_indicator($htmlname,$indicator);
$script.= '<input type="hidden" name="'.$htmlname.'_id" id="'.$htmlname.'_id" value="'.$selected.'" />';
$script.= '</div>';
$script.= '<div id="result'.$htmlname.'" class="autocomplete"></div>';
$script.= '<script type="text/javascript">';
$script.= 'new Ajax.Autocompleter(\''.$htmlname.'\',\'result'.$htmlname.'\',\''.DOL_URL_ROOT.$url.'\',{
method: \'post\',
paramName: \''.$htmlname.'\',
indicator: \'indicator'.$htmlname.'\',
afterUpdateElement: ac_return
});';
$script.= '</script>';
return $script;
}
/**
* \brief Fonction simple identique a microtime de PHP 5 mais compatible PHP 4
* \return float Time en millisecondes avec decimal pour microsecondes
*/
function dol_microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
/*
* \brief Return if a text is a html content
* \param msg Content to check
* \param option 0=Full detection, 1=Fast check
* \return boolean true/false
*/
function dol_textishtml($msg,$option=0)
{
if ($option == 1)
{
if (eregi('<html',$msg)) return true;
elseif (eregi('<body',$msg)) return true;
elseif (eregi('<br',$msg)) return true;
return false;
}
else
{
if (eregi('<html',$msg)) return true;
elseif (eregi('<body',$msg)) return true;
elseif (eregi('<br',$msg)) return true;
elseif (eregi('<table',$msg)) return true;
elseif (eregi('<font',$msg)) return true;
elseif (eregi('<strong',$msg)) return true;
elseif (eregi('<img',$msg)) return true;
elseif (eregi('<i>',$msg)) return true;
elseif (eregi('<b>',$msg)) return true;
elseif (eregi('&[A-Z0-9]{1,6};',$msg)) return true;
return false;
}
}
/*
* \brief Effectue les substitutions des mots cls par les donnes en fonction du tableau
* \param chaine Chaine dans laquelle faire les substitutions
* \param substitutionarray Tableau cl substitution => valeur a mettre
* \return string Chaine avec les substitutions effectues
*/
function make_substitutions($chaine,$substitutionarray)
{
foreach ($substitutionarray as $key => $value)
{
$chaine=ereg_replace($key,$value,$chaine);
}
return $chaine;
}
/*
* \brief Convertit une variable php en variable javascript
* \param var variable php
* \return result variable javascript
*/
function php2js($var)
{
if (is_array($var))
{
$array = array();
foreach ($var as $a_var)
{
$array[] = php2js($a_var);
}
$result = "[" . join(",", $array) . "]";
return $result;
}
else if (is_bool($var))
{
$result = $var ? "true" : "false";
return $result;
}
else if (is_int($var) || is_integer($var) || is_double($var) || is_float($var))
{
$result = $var;
return $result;
}
else if (is_string($var))
{
$result = "\"" . addslashes(stripslashes($var)) . "\"";
return $result;
}
// autres cas: objets, on ne les gre pas
$result = FALSE;
return $result;
}
/*
* \brief Formate l'affichage de date de dbut et de fin
* \param date_start date de dbut
* \param date_end date de fin
*/
function print_date_range($date_start,$date_end)
{
global $langs;
if ($date_start && $date_end)
{
print ' ('.$langs->trans('DateFromTo',dolibarr_print_date($date_start),dolibarr_print_date($date_end)).')';
}
if ($date_start && ! $date_end)
{
print ' ('.$langs->trans('DateFrom',dolibarr_print_date($date_start)).')';
}
if (! $date_start && $date_end)
{
print ' ('.$langs->trans('DateUntil',dolibarr_print_date($date_end)).')';
}
}
/*
* \brief Cration de 2 vignettes a partir d'un fichier image (une small et un mini)
* \brief Les extension prise en compte sont jpg et png
* \param file Chemin du fichier image a redimensionner
* \param maxWidth Largeur maximum que dois faire la miniature (160 par dfaut)
* \param maxHeight Hauteur maximum que dois faire l'image (120 par dfaut)
* \param extName Extension pour diffrencier le nom de la vignette
* \param quality Qualit de compression (0=worst, 100=best)
* \return string Chemin de la vignette
*/
function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName='_small', $quality=50)
{
global $langs;
dolibarr_syslog("functions.inc::vignette file=".$file." extName=".$extName." maxWidth=".$maxWidth." maxHeight=".$maxHeight." quality=".$quality);
// Nettoyage parametres
$file=trim($file);
// Vrification des paramtres
if (! $file)
{
// Si le fichier n'a pas t indiqu
return 'Bad parameter file';
}
elseif (! file_exists($file))
{
// Si le fichier pass en paramtre n'existe pas
return $langs->trans("ErrorFileNotFound",$file);
}
elseif(image_format_supported($file) < 0)
{
return 'This file '.$file.' does not seem to be an image format file name.';
}
elseif(!is_numeric($maxWidth) || empty($maxWidth) || $maxWidth < 0){
// Si la largeur max est incorrecte (n'est pas numrique, est vide, ou est infrieure a 0)
return 'Valeur de la largeur incorrecte.';
}
elseif(!is_numeric($maxHeight) || empty($maxHeight) || $maxHeight < 0){
// Si la hauteur max est incorrecte (n'est pas numrique, est vide, ou est infrieure a 0)
return 'Valeur de la hauteur incorrecte.';
}
$fichier = realpath($file); // Chemin canonique absolu de l'image
$dir = dirname($file).'/'; // Chemin du dossier contenant l'image
$dirthumb = $dir.'thumbs/'; // Chemin du dossier contenant les vignettes
$infoImg = getimagesize($fichier); // Rcupration des infos de l'image
$imgWidth = $infoImg[0]; // Largeur de l'image
$imgHeight = $infoImg[1]; // Hauteur de l'image
// Si l'image est plus petite que la largeur et la hauteur max, on ne cre pas de vignette
if ($infoImg[0] < $maxWidth && $infoImg[1] < $maxHeight)
{
// On cree toujours les vignettes
dolibarr_syslog("File size is smaller than thumb size",LOG_DEBUG);
//return 'Le fichier '.$file.' ne ncessite pas de cration de vignette';
}
$imgfonction='';
switch($infoImg[2])
{
case 1: // IMG_GIF
$imgfonction = 'imagecreatefromgif';
break;
case 2: // IMG_JPG
$imgfonction = 'imagecreatefromjpeg';
break;
case 3: // IMG_PNG
$imgfonction = 'imagecreatefrompng';
break;
case 4: // IMG_WBMP
$imgfonction = 'imagecreatefromwbmp';
break;
}
if ($imgfonction)
{
if (! function_exists($imgfonction))
{
// Fonctions de conversion non presente dans ce PHP
return 'Creation de vignette impossible. Ce PHP ne supporte pas les fonctions du module GD '.$imgfonction;
}
}
// On cre le rpertoire contenant les vignettes
if (! file_exists($dirthumb))
{
create_exdir($dirthumb);
}
// Initialisation des variables selon l'extension de l'image
switch($infoImg[2])
{
case 1: // Gif
$img = imagecreatefromgif($fichier);
$extImg = '.gif'; // Extension de l'image
$newquality='NU';
break;
case 2: // Jpg
$img = imagecreatefromjpeg($fichier);
$extImg = '.jpg'; // Extension de l'image
$newquality=$quality;
break;
case 3: // Png
$img = imagecreatefrompng($fichier);
$extImg = '.png';
$newquality=$quality-100;
$newquality=round(abs($quality-100)*9/100);
break;
case 4: // Bmp
$img = imagecreatefromwbmp($fichier);
$extImg = '.bmp';
$newquality='NU';
break;
}
// Initialisation des dimensions de la vignette si elles sont suprieures a l'original
if($maxWidth > $imgWidth){ $maxWidth = $imgWidth; }
if($maxHeight > $imgHeight){ $maxHeight = $imgHeight; }
$whFact = $maxWidth/$maxHeight; // Facteur largeur/hauteur des dimensions max de la vignette
$imgWhFact = $imgWidth/$imgHeight; // Facteur largeur/hauteur de l'original
// Fixe les dimensions de la vignette
if($whFact < $imgWhFact){
// Si largeur dterminante
$thumbWidth = $maxWidth;
$thumbHeight = $thumbWidth / $imgWhFact;
} else {
// Si hauteur dterminante
$thumbHeight = $maxHeight;
$thumbWidth = $thumbHeight * $imgWhFact;
}
$thumbHeight=round($thumbHeight);
$thumbWidth=round($thumbWidth);
// Create empty image
if ($infoImg[2] == 1)
{
// Compatibilit image GIF
$imgThumb = imagecreate($thumbWidth, $thumbHeight);
}
else
{
$imgThumb = imagecreatetruecolor($thumbWidth, $thumbHeight);
}
// Activate antialiasing for better quality
if (function_exists('imageantialias'))
{
imageantialias($imgThumb, true);
}
// This is to keep transparent alpha channel if exists (PHP >= 4.2)
if (function_exists('imagesavealpha'))
{
imagesavealpha($imgThumb, true);
}
// Initialisation des variables selon l'extension de l'image
switch($infoImg[2])
{
case 1: // Gif
$trans_colour = imagecolorallocate($imgThumb, 255, 255, 255); // On procde autrement pour le format GIF
imagecolortransparent($imgThumb,$trans_colour);
break;
case 2: // Jpg
$trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0);
break;
case 3: // Png
imagealphablending($imgThumb,false); // Pour compatibilit sur certain systme
$trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 127); // Keep transparent channel
break;
case 4: // Bmp
$trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0);
break;
}
if (function_exists("imagefill")) imagefill($imgThumb, 0, 0, $trans_colour);
dolibarr_syslog("vignette: convert image from ($imgWidth x $imgHeight) to ($thumbWidth x $thumbHeight) as $extImg, newquality=$newquality");
//imagecopyresized($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insre l'image de base redimensionne
imagecopyresampled($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insre l'image de base redimensionne
$fileName = eregi_replace('(\.gif|\.jpeg|\.jpg|\.png|\.bmp)$','',$file); // On enleve extension quelquesoit la casse
$fileName = basename($fileName);
$imgThumbName = $dirthumb.$fileName.$extName.$extImg; // Chemin complet du fichier de la vignette
// Check if permission are ok
//$fp = fopen($imgThumbName, "w");
//fclose($fp);
// Create image on disk
switch($infoImg[2])
{
case 1: // Gif
imagegif($imgThumb, $imgThumbName);
break;
case 2: // Jpg
imagejpeg($imgThumb, $imgThumbName, $newquality);
break;
case 3: // Png
imagepng($imgThumb, $imgThumbName, $newquality);
break;
case 4: // Bmp
image2wmp($imgThumb, $imgThumbName);
break;
}
// Free memory
imagedestroy($imgThumb);
return $imgThumbName;
}
/*
* \brief Converti les heures et minutes en secondes
* \param iHours Heures
* \param iMinutes Minutes
* \param iSeconds Secondes
* \return iResult Temps en secondes
*/
function ConvertTime2Seconds($iHours=0,$iMinutes=0,$iSeconds=0)
{
$iResult=($iHours*3600)+($iMinutes*60)+$iSeconds;
return $iResult;
}
/*
* \brief Converti les secondes en heures et minutes
* \param iSecond Nombre de secondes
* \param format Choix de l'affichage (all:affichage complet, hour: n'affiche que les heures, min: n'affiche que les minutes)
* \return sTime Temps format
*/
function ConvertSecondToTime($iSecond,$format='all'){
if ($format == 'all'){
$sTime=date("H",$iSecond)-1;
$sTime.='h'.date("i",$iSecond);
}else if ($format == 'hour'){
$sTime=date("H",$iSecond)-1;
}else if ($format == 'min'){
$sTime=date("i",$iSecond);
}
return $sTime;
}
/*
*
*/
function make_alpha_from_numbers($number)
{
$numeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if($number<strlen($numeric))
{
return $numeric[$number];
}
else
{
$dev_by = floor($number/strlen($numeric));
return "" . make_alpha_from_numbers($dev_by-1) . make_alpha_from_numbers($number-($dev_by*strlen($numeric)));
}
}
/*
* \brief Affiche le contenu d'un fichier CSV sous forme de tableau
* \param file_to_include Fichier CSV a afficher
* \param max_rows Nombre max de lignes a afficher (0 = illimit)
*/
function viewCsvFileContent($file_to_include='',$max_rows=0)
{
$fic = fopen($file_to_include, 'rb');
$count = 0;
print '<table border="1">';
for ($ligne = fgetcsv($fic, 1024); (!feof($fic) && (($max_rows > 0)?($count<=$max_rows):1==1)); $ligne = fgetcsv($fic, 1024))
{
print '<tr>';
$j = sizeof($ligne);
for ($i = 0; $i < $j; $i++)
{
print '<td>'.$ligne[$i].'</td>';
}
print '</tr>';
$count++;
}
print '</table>';
}
/*
* \brief Affiche le contenu d'un fichier Excel (avec les feuilles de calcul) sous forme de tableau
* \param file_to_include Fichier Excel a afficher
* \param max_rows Nombre max de lignes a afficher (0 = illimit)
* \param max_cols Nombre max de colonnes a afficher (0 = illimit)
*/
function viewExcelFileContent($file_to_include='',$max_rows=0,$max_cols=0)
{
$debug = 0; //1 for on 0 for off
$force_nobr = 0; //Force the info in cells not to wrap unless stated explicitly (newline)
require_once(DOL_DOCUMENT_ROOT.'/includes/phpexcelreader/excelreader.php');
$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('CPa25a');
$data->read($file_to_include);
error_reporting(E_ALL ^ E_NOTICE);
echo "<script language='Javascript'>
var sheet_HTML = Array();\n";
for($sheet=0;$sheet<count($data->sheets);$sheet++)
{
$table_output[$sheet] .= "<TABLE CLASS='table_body'>
<TR>
<TD> </TD>";
for($i=0;$i < $data->sheets[$sheet]['numCols'] && (($i < $max_cols) || ($max_cols == 0));$i++)
{
$table_output[$sheet] .= "<TD CLASS='table_sub_heading' ALIGN=CENTER>" . make_alpha_from_numbers($i) . "</TD>";
}
for($row=1;$row<=$data->sheets[$sheet]['numRows']&&($row<=$max_rows||$max_rows==0);$row++)
{
$table_output[$sheet] .= "<TR><TD CLASS='table_sub_heading'>" . $row . "</TD>";
for($col=1;$col<=$data->sheets[$sheet]['numCols']&&($col<=$max_cols||$max_cols==0);$col++)
{
if($data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'] >=1 && $data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'] >=1)
{
$this_cell_colspan = " COLSPAN=" . $data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'];
$this_cell_rowspan = " ROWSPAN=" . $data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'];
for($i=1;$i<$data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'];$i++)
{
$data->sheets[$sheet]['cellsInfo'][$row][$col+$i]['dontprint']=1;
}
for($i=1;$i<$data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'];$i++)
{
for($j=0;$j<$data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'];$j++)
{
$data->sheets[$sheet]['cellsInfo'][$row+$i][$col+$j]['dontprint']=1;
}
}
}
else if($data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'] >=1)
{
$this_cell_colspan = " COLSPAN=" . $data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'];
$this_cell_rowspan = "";
for($i=1;$i<$data->sheets[$sheet]['cellsInfo'][$row][$col]['colspan'];$i++)
{
$data->sheets[$sheet]['cellsInfo'][$row][$col+$i]['dontprint']=1;
}
}
else if($data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'] >=1)
{
$this_cell_colspan = "";
$this_cell_rowspan = " ROWSPAN=" . $data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'];
for($i=1;$i<$data->sheets[$sheet]['cellsInfo'][$row][$col]['rowspan'];$i++)
{
$data->sheets[$sheet]['cellsInfo'][$row+$i][$col]['dontprint']=1;
}
}
else
{
$this_cell_colspan = "";
$this_cell_rowspan = "";
}
if(!($data->sheets[$sheet]['cellsInfo'][$row][$col]['dontprint']))
{
$table_output[$sheet] .= "<TD CLASS='table_data' $this_cell_colspan $this_cell_rowspan> ";
if($force_nobr)
{
$table_output[$sheet] .= "<NOBR>";
}
$table_output[$sheet] .= nl2br(htmlentities($data->sheets[$sheet]['cells'][$row][$col]));
if($force_nobr)
{
$table_output[$sheet] .= "</NOBR>";
}
$table_output[$sheet] .= "</TD>";
}
}
$table_output[$sheet] .= "</TR>";
}
$table_output[$sheet] .= "</TABLE>";
$table_output[$sheet] = str_replace("\n","",$table_output[$sheet]);
$table_output[$sheet] = str_replace("\r","",$table_output[$sheet]);
$table_output[$sheet] = str_replace("\t"," ",$table_output[$sheet]);
if($debug)
{
$debug_output = print_r($data->sheets[$sheet],true);
$debug_output = str_replace("\n","\\n",$debug_output);
$debug_output = str_replace("\r","\\r",$debug_output);
$table_output[$sheet] .= "<PRE>$debug_output</PRE>";
}
echo "sheet_HTML[$sheet] = \"$table_output[$sheet]\";\n";
}
echo "
function change_tabs(sheet)
{
//alert('sheet_tab_' + sheet);
for(i=0;i<", count($data->sheets) , ";i++)
{
document.getElementById('sheet_tab_' + i).className = 'tab_base';
}
document.getElementById('table_loader_div').innerHTML=sheet_HTML[sheet];
document.getElementById('sheet_tab_' + sheet).className = 'tab_loaded';
}
</SCRIPT>";
echo "
<TABLE CLASS='table_body' NAME='tab_table'>
<TR>";
for($sheet=0;$sheet<count($data->sheets);$sheet++)
{
echo "<TD CLASS='tab_base' ID='sheet_tab_$sheet' ALIGN=CENTER
ONMOUSEDOWN=\"change_tabs($sheet);\">", $data->boundsheets[$sheet]['name'] , "</TD>";
}
echo
"<TR>";
echo "</TABLE>
<DIV ID=table_loader_div></DIV>
<SCRIPT LANGUAGE='JavaScript'>
change_tabs(0);
</SCRIPT>";
}
/**
\brief Gnrateur de codes barres
\param $code Valeur numrique a coder
\param $encoding Mode de codage
\param $generator Gnrateur utilis (1=php-barcode, 2=pi_barcode)
\param $readable Code lisible
\return url
*/
function dol_genbarcode($code,$encoding,$generator=1,$readable='Y')
{
$url='';
if ($encoding == 'EAN8' || $encoding == 'EAN13') $encoding = 'EAN';
if ($generator == 1)
{
if ($encoding == 'C39' || $encoding == 'C128') $encoding = substr($encoding,1);
$url = DOL_URL_ROOT.'/includes/barcode/php-barcode/genbarcode.php?code='.$code.'&encoding='.$encoding.'&scale=1';
}
else if ($generator == 2)
{
$url = DOL_URL_ROOT.'/includes/barcode/pi_barcode/pi_barcode.php?code='.$code.'&type='.$encoding.'&height=50&readable='.$readable;
}
return $url;
}
/**
\brief Retourne un tableau des mois ou le mois slectionn
\param selected Mois slectionner ou -1
\return string or array Month string or array if selected < 0
*/
function monthArrayOrSelected($selected=0)
{
global $langs;
$langs->load("main");
$month = array (1 => $langs->trans("January"),
2 => $langs->trans("February"),
3 => $langs->trans("March"),
4 => $langs->trans("April"),
5 => $langs->trans("May"),
6 => $langs->trans("June"),
7 => $langs->trans("July"),
8 => $langs->trans("August"),
9 => $langs->trans("September"),
10 => $langs->trans("October"),
11 => $langs->trans("November"),
12 => $langs->trans("December")
);
if ($selected >=0)
{
$return='';
foreach ($month as $key => $val)
{
if ($selected == $key)
{
$return = $val;
}
}
return $return;
}
else
{
return $month;
}
}
/**
\brief Returns formated reduction
\param reduction Reduction percentage
\return string Formated reduction
*/
function dolibarr_print_reduction($reduction=0)
{
global $langs;
$langs->load("main");
$string = '';
if ($reduction == 100)
{
$string = $langs->trans("Offered");
}
else
{
$string = $reduction.'%';
}
return $string;
}
/**
\brief Returns formated reduction
\param reduction Reduction percentage
\return int Return number of error messages shown
*/
function dol_htmloutput_errors($mesgstring='',$mesgarray='')
{
global $langs;
$ret = 0;
$langs->load("errors");
if (is_array($mesgarray) && sizeof($mesgarray))
{
print '<div class="error">';
foreach($mesgarray as $message)
{
$ret++;
print $langs->trans($message)."<br>\n";
}
print '</div>';
}
if ($mesgstring)
{
$ret++;
print '<div class="error">';
print $mesgstring;
print '</div>';
}
return $ret;
}
?>