Select Git revision
functions.lib.php
functions.lib.php 94.36 KiB
<?php
/* Copyright (C) 2000-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
* Copyright (C) 2004-2008 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>
* Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.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/
*/
/**
* \file htdocs/lib/functions.lib.php
* \brief Ensemble de fonctions de base de dolibarr sous forme d'include
* \version $Id$
*/
// For compatibility during upgrade
if (! defined('DOL_DOCUMENT_ROOT')) define('DOL_DOCUMENT_ROOT', '..');
if (! defined('ADODB_DATE_VERSION')) include_once(DOL_DOCUMENT_ROOT."/includes/adodbtime/adodb-time.inc.php");
/**
\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 r�soud 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 String to clean
* \param newstr String to replace bad chars by
* \return string String cleaned (a-zA-Z_)
*/
function sanitize_string($str,$newstr='_')
{
$forbidden_chars_to_underscore=array(" ","'","/","\\",":","*","?","\"","<",">","|","[","]",",",";","=");
//$forbidden_chars_to_remove=array("(",")");
$forbidden_chars_to_remove=array();
return str_replace($forbidden_chars_to_underscore,$newstr,str_replace($forbidden_chars_to_remove,"",$str));
}
/**
* \brief Returns text escaped for inclusion in javascript code
* \param $stringtoescape String to escape
* \return string Escaped string
*/
function dol_escape_js($stringtoescape)
{
// escape quotes and backslashes, newlines, etc.
return strtr($stringtoescape, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
}
/**
\brief Envoi des messages dolibarr dans un fichier ou dans syslog
Pour fichier: fichier defini par SYSLOG_FILE
Pour syslog: facility defini 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 buggu�s sous Windows et g�n�rent des
fautes de protection m�moire. Pour r�soudre, utiliser le loggage fichier,
au lieu du loggage syslog (configuration du module).
Si SYSLOG_FILE_NO_ERROR d�fini, on ne g�re 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)
{
$filelog=SYSLOG_FILE;
$filelog=eregi_replace('DOL_DATA_ROOT',DOL_DATA_ROOT,$filelog);
if (defined("SYSLOG_FILE_NO_ERROR")) $file=@fopen($filelog,"a+");
else $file=fopen($filelog,"a+");
if ($file)
{
$ip='unknown_ip';
if (! empty($_SERVER["REMOTE_ADDR"])) $ip=$_SERVER["REMOTE_ADDR"];
$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)." ".$ip." ".$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",$filelog);
}
}
else
{
//define_syslog_variables(); d�ja d�finit 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 Sauvegarde parametrage personnel
\param db Handler d'acc�s 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 param�tres 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 param�tres 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.lib.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 param�tres
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.lib.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 format�e
*/
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 d�calage de date par rapport a une dur�e
\param time Date timestamp ou au format YYYY-MM-DD
\param duration_value Valeur de la dur�e a ajouter
\param duration_unit Unit� de la dur�e 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 GM Timestamps date (or 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' in server TZ)
* \param format Output date format
* "%d %b %Y",
* "%d/%m/%Y %H:%M",
* "%d/%m/%Y %H:%M:%S",
* "day", "daytext", "dayhour", "dayhourldap", "dayhourtext"
* \param to_gmt false=output string if for local server TZ users, true=output string is for GMT users
* \return string Formated date or '' if time is null
*/
function dolibarr_print_date($time,$format='',$to_gmt=false)
{
global $conf;
// Si format non defini, 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;
if ($format == 'daytextshort') $format=$conf->format_date_text_short;
if ($format == 'dayhour') $format=$conf->format_date_hour_short;
if ($format == 'dayhourtext') $format=$conf->format_date_hour_text;
if ($format == 'dayhourtextshort') $format=$conf->format_date_hour_text_short;
if ($format == 'dayhourlog') $format='%Y%m%d%H%M%S';
if ($format == 'dayhourldap') $format='%Y%m%d%H%M%SZ';
if ($format == 'dayhourxcard') $format='%Y%m%dT%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))
{
// This part of code should not be used.
dolibarr_syslog("Functions.lib::dolibarr_print_date call to function with deprecated parameter", LOG_WARN);
// 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 adodb_strftime($format,dolibarr_mktime($shour,$smin,$ssec,$smonth,$sday,$syear),$to_gmt);
}
else
{
// Date is a timestamps
return adodb_strftime($format,$time,$to_gmt);
}
}
/**
* \brief Convert a GM string date into a GM Timestamps date
* \param string Date in a string
* 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
* \example 19700101020000 -> 7200
*/
function dolibarr_stringtotime($string)
{
if (eregi('^([0-9]+)\/([0-9]+)\/([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?',$string,$reg))
{
// This part of code should not be used.
dolibarr_syslog("Functions.lib::dolibarr_stringtotime call to function with deprecated parameter", LOG_WARN);
// 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),1);
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;
}
/**
* Retourne une date fabriquee depuis infos.
* Remplace la fonction mktime non implementee sous Windows si annee < 1970
* @param hour Hour (can be -1 for undefined)
* @param minute Minute (can be -1 for undefined)
* @param second Second (can be -1 for undefined)
* @param month Month
* @param day Day
* @param year Year
* @param gm Time gm
* @param check No check on parameters (Can use day 32, etc...)
* @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,$check=1)
{
//print "- ".$hour.",".$minute.",".$second.",".$month.",".$day.",".$year.",".$_SERVER["WINDIR"]." -";
// Clean parameters
if ($hour == -1) $hour=0;
if ($minute == -1) $minute=0;
if ($second == -1) $second=0;
// Check parameters
if ($check)
{
if (! $month || ! $day) return '';
if ($day > 31) return '';
if ($month > 12) return '';
if ($hour < 0 || $hour > 24) return '';
if ($minute< 0 || $minute > 60) return '';
if ($second< 0 || $second > 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 D�cembre 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 num�ros de telephone en fonction du format d'un pays
\param phone Num�ro de telephone a formater
\param country Pays selon lequel formatter
\return string Num�ro de t�l�phone format�
*/
function dolibarr_print_phone($phone,$country="FR")
{
$phone=trim($phone);
if (! $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 Return string with formated size
* \param size Size to print
* \return string Link
*/
function dol_print_size($size)
{
global $langs;
return $size.' '.$langs->trans("Bytes");
}
/**
* \brief Show click to dial link
* \param phone Phone to call
* \param option Type of picto
* \return string Link
*/
function dol_phone_link($phone,$option=0)
{
global $conf,$user;
$link='';
//if (! empty($conf->global->CLICKTODIAL_URL))
if ($conf->clicktodial->enabled)
{
$phone=trim($phone);
$url = $conf->global->CLICKTODIAL_URL;
$url.= "?login=".urlencode($user->clicktodial_login)."&password=".urlencode($user->clicktodial_password);
$url.= "&caller=".urlencode($user->clicktodial_poste)."&called=".urlencode(trim($phone));
$link.='<a href="URL_DEFINED_IN_CLICKTODIAL_MODULE" onclick="newpopup(\''.$url.'\',\'\'); return false;">'.img_phone("default",0).'</a>';
}
return $link;
}
/**
* \brief Truncate a string to a particular length adding '...' if string larger than length
* \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 Compl�te une chaine a une taille donn�e par des espaces
\param string Chaine a compl�ter
\param size Longueur de la chaine.
\param side 0=Compl�tion a droite, 1=Compl�tion a gauche
\param char Chaine de compl�tion
\return string Chaine compl�t�e
*/
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 g�n�rique)
\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 g�n�rique)
\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 supplementaire a la balise img
\param pictoisfullpath If 1, image path is a full path
\return string Retourne tag img
*/
function img_picto($alt, $picto, $options='', $pictoisfullpath=0)
{
global $conf;
if (! eregi('(\.png|\.gif)$',$picto)) $picto.='.png';
if ($pictoisfullpath) return '<img src="'.$picto.'" border="0" alt="'.$alt.'" title="'.$alt.'"'.($options?' '.$options:'').'>';
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/'.$picto.'" border="0" alt="'.$alt.'" title="'.$alt.'"'.($options?' '.$options:'').'>';
}
/**
\brief Affiche picto (fonction g�n�rique)
\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 supplementaire a la balise img
\param pictoisfullpath If 1, image path is a full path
\return string Retourne tag img
*/
function img_picto_common($alt, $picto, $options='', $pictoisfullpath=0)
{
global $conf;
if (! eregi('(\.png|\.gif)$',$picto)) $picto.='.png';
if ($pictoisfullpath) return '<img src="'.$picto.'" border="0" alt="'.$alt.'" title="'.$alt.'"'.($options?' '.$options:'').'>';
return '<img src="'.DOL_URL_ROOT.'/theme/common/'.$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, $other='')
{
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"';
if ($other) $img.=' '.$other;
$img.='>';
return $img;
}
/**
\brief Affiche logo voir 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_view($alt = "default", $float=0, $other='')
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("View");
$img='<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/view.png" border="0" alt="'.$alt.'" title="'.$alt.'"';
if ($float) $img.=' style="float: right"';
if ($other) $img.=' '.$other;
$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 d�sactiver
\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 t�l�phone
\param alt Texte sur le alt de l'image
\param option Choose of logo
\return string Retourne tag img
*/
function img_phone($alt = "default",$option=0)
{
global $conf,$langs;
if ($alt=="default") $alt=$langs->trans("Call");
$img='call_out';
if ($option == 1) $img='call';
$img='object_commercial';
return '<img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/'.$img.'.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 pr�c�dent
\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 Show mime picto
* \param file Filename
* \param alt Alternate text
* \return string Return img tag
*/
function img_mime($file,$alt='')
{
$mime='other';
if (eregi('\.pdf',$file)) { $mime='pdf'; }
if (eregi('\.(html|htm)',$file)) { $mime='html'; }
if (eregi('\.txt',$file)) { $mime='other'; }
if (eregi('\.php',$file)) { $mime='php'; }
if (eregi('\.pl',$file)) { $mime='pl'; }
if (eregi('\.js',$file)) { $mime='jscript'; }
if (eregi('\.(png|bmp|jpg|jpeg|gif)',$file)) $mime='image';
if (eregi('\.(mp3|ogg|au)',$file)) $mime='audio';
if (eregi('\.(avi|mvw|divx|xvid)',$file)) $mime='video';
if (eregi('\.(zip|rar|gz|tgz|z|cab|bz2)',$file)) $mime='archive';
if (empty($alt)) $alt='Mime type: '.$mime;
$mime.='.png';
return '<img src="'.DOL_URL_ROOT.'/theme/common/mime/'.$mime.'" border="0" alt="'.$alt.'" title="'.$alt.'">';
}
/**
\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 Text info
\param infoonimgalt Info is shown on alt of star picto
\return string String with info text
*/
function info_admin($texte,$infoonimgalt=0)
{
global $conf,$langs;
$s='';
if ($infoonimgalt)
{
$s.=img_picto($texte,'star');
}
else
{
$s.='<div class="info">';
$s.=img_picto($langs->trans("InfoAdmin"),'star');
$s.=' ';
$s.=$texte;
$s.='</div>';
}
return $s;
}
/**
\brief Check permissions of a user to show a page and an object.
\param user User to check
\param feature Feature to check (in most cases, it's module name)
\param objectid Object ID if we want to check permission on on object (optionnal)
\param dbtablename Table name where object is stored. Not used if objectid is null (optionnel)
\param feature2 Feature to check (second level of permission)
*/
function restrictedArea($user, $feature='societe', $objectid=0, $dbtablename='',$feature2='')
{
global $db;
//print "$user->id, $feature, $objectid, $dbtablename, $list ".$user->rights->societe->contact->lire;
// Check read permission from module
// TODO Replace "feature" param by permission for reading
$readok=1;
if ($feature == 'societe')
{
if (! $user->rights->societe->lire && ! $user->rights->fournisseur->lire) $readok=0;
}
else if ($feature == 'contact')
{
if (! $user->rights->societe->contact->lire) $readok=0;
}
else if ($feature == 'prelevement')
{
if (! $user->rights->prelevement->bons->lire) $readok=0;
}
else if ($feature == 'commande_fournisseur')
{
if (! $user->rights->fournisseur->commande->lire) $readok=0;
}
else if ($feature == 'cheque')
{
if (! $user->rights->banque->cheque) $readok=0;
}
else if (! empty($feature2)) // This should be used for future changes
{
if (! $user->rights->$feature->$feature2->read) $readok=0;
}
else if (! empty($feature)) // This is for old permissions
{
if (! $user->rights->$feature->lire) $readok=0;
}
if (! $readok) accessforbidden();
//print "Read access is ok";
// Check write permission from module
$createok=1;
if ($_GET["action"] == 'create' || $_POST["action"] == 'create')
{
if ($feature == 'societe')
{
if (! $user->rights->societe->creer && ! $user->rights->fournisseur->creer) $createok=0;
}
else if ($feature == 'contact')
{
if (! $user->rights->societe->contact->creer) $createok=0;
}
else if ($feature == 'prelevement')
{
if (! $user->rights->prelevement->bons->creer) $createok=0;
}
else if ($feature == 'commande_fournisseur')
{
if (! $user->rights->fournisseur->commande->creer) $createok=0;
}
else if ($feature == 'banque')
{
if (! $user->rights->banque->modifier) $createok=0;
}
else if ($feature == 'cheque')
{
if (! $user->rights->banque->cheque) $createok=0;
}
else if (! empty($feature2)) // This should be used for future changes
{
if (! $user->rights->$feature->$feature2->write) $createok=0;
}
else if (! empty($feature)) // This is for old permissions
{
if (! $user->rights->$feature->creer) $createok=0;
}
if (! $createok) accessforbidden();
//print "Write access is ok";
}
// If we have a particular object to check permissions on
if ($objectid)
{
$sql='';
// Check permission for external users
if ($user->societe_id > 0)
{
if ($feature == 'societe')
{
if ($user->societe_id <> $objectid) accessforbidden();
}
else
{
if (!$dbtablename) $dbtablename = $feature; // Si dbtable non d�fini, meme nom que le module
$sql = "SELECT dbt.fk_soc";
$sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
$sql.= " WHERE dbt.rowid = ".$objectid;
$sql.= " AND dbt.fk_soc = ".$user->societe_id;
}
}
// Check permission for internal users that are restricted on their objects
else if (! $user->rights->societe->client->voir)
{
if ($feature == 'societe')
{
$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 (!$dbtablename) $dbtablename = $feature; // Si dbtable non defini, meme nom que le module
$sql = "SELECT sc.fk_soc";
$sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.fk_soc";
$sql.= " WHERE dbt.rowid = ".$objectid;
$sql.= " AND IFNULL(sc.fk_user, ".$user->id.") = ".$user->id;
}
}
//print $sql;
if ($sql)
{
$resql=$db->query($sql);
if ($resql)
{
if ($db->num_rows($resql) == 0) accessforbidden();
}
else
{
dolibarr_syslog("functions.lib.php::restrictedArea sql=".$sql, LOG_ERR);
accessforbidden();
}
}
}
return 1;
}
/**
\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 remont�e des bugs.
* On doit appeler cette fonction quand une erreur technique bloquante est rencontree.
* Toutefois, il faut essayer de ne l'appeler qu'au sein de pages php, les classes devant
* renvoyer leur erreur par l'intermediaire de leur propriete "error".
* \param db Database handler
* \param error Chaine erreur ou tableau de chaines erreur complementaires 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("", $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("Dolibarr").":</b> ".DOL_VERSION."<br>\n";;
if (isset($conf->global->MAIN_FEATURES_LEVEL)) print "<b>".$langs->trans("LevelOfFeature").":</b> ".$conf->global->MAIN_FEATURES_LEVEL."<br>\n";;
print "<b>".$langs->trans("Server").":</b> ".$_SERVER["SERVER_SOFTWARE"]."<br>\n";;
print "<b>".$langs->trans("RequestedUrl").":</b> ".$_SERVER["REQUEST_URI"]."<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").":\n".$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("ReturnCodeLastAccessInError").":</b> ".($db->lasterrno()?$db->lasterrno():$langs->trans("ErrorNoRequestInError"))."<br>\n";
print "<b>".$langs->trans("InformationLastAccessInError").":</b> ".($db->lasterror()?$db->lasterror():$langs->trans("ErrorNoRequestInError"))."<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("ReturnCodeLastAccessInError").":\n".($db->lasterrno()?$db->lasterrno():$langs->trans("ErrorNoRequestInError"))."\n";
print '> '.$langs->transnoentities("InformationLastAccessInError").":\n".($db->lasterror()?$db->lasterror():$langs->trans("ErrorNoRequestInError"))."\n";
}
$syslog.=", sql=".$db->lastquery();
$syslog.=", db_error=".$db->lasterror();
}
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_ERR);
}
/**
* \brief Deplacer les fichiers telecharg�s, apres quelques controles divers
* \param src_file Source filename
* \param dest_file Target filename
* \param allowoverwrite Overwrite if exists
* \return int >0 if OK, <0 if KO, Name of virus if virus found
*/
function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite)
{
global $conf;
$file_name = $dest_file;
// If we need to make a virus scan
if ($conf->global->MAIN_USE_AVSCAN)
{
$malware = dol_avscan_file($src_file);
if ($malware) return $malware;
}
// Security:
// On renomme les fichiers avec extention script web 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.= '.noexe';
}
// Security:
// On interdit les remont�es de repertoire ainsi que les pipes dans
// les noms de fichiers.
if (eregi('\.\.',$src_file) || eregi('[<>|]',$src_file))
{
dolibarr_syslog("Refused to deliver file ".$src_file);
return -1;
}
// Security:
// On interdit les remont�es 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 -1;
}
// Check if destination file already exists
if (! $allowoverwrite)
{
if (file_exists($file_name))
{
dolibarr_syslog("Functions.lib::dol_move_uploaded_file File ".$file_name." already exists", LOG_WARNING);
return -2;
}
}
// Move file
$return=move_uploaded_file($src_file, $file_name);
if ($return)
{
dolibarr_syslog("Functions.lib::dol_move_uploaded_file Success to move ".$src_file." to ".$file_name, LOG_DEBUG);
return 1;
}
else
{
dolibarr_syslog("Functions.lib::dol_move_uploaded_file Failed to move ".$src_file." to ".$file_name, LOG_ERR);
return -3;
}
}
/**
\brief Show title line of an array
\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 this is a sort field
if ($field)
{
//print " ";
print '<img width="2" src="'.DOL_URL_ROOT.'/theme/common/transparent.png">';
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 supl�mentaire a afficher a droite
\param picto Picto pour ligne de titre
\param pictoisfullpath 1=Picto is a full absolute url of image
*/
function print_fiche_titre($titre, $mesg='', $picto='', $pictoisfullpath=0)
{
print "\n";
print '<table width="100%" border="0" class="notopnoleftnoright"><tr>';
if ($picto) print '<td width="24" align="left" valign="middle">'.img_picto('',$picto, '', $pictoisfullpath).'</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_ERR);
}
return $ok;
}
/**
\brief Effacement d'un r�pertoire
\param file R�pertoire a effacer
*/
function dol_delete_dir($dir)
{
return rmdir($dir);
}
/**
\brief Effacement d'un r�pertoire $dir et de son arborescence
\param file R�pertoire a effacer
\param count Compteur pour comptage nb elements supprim�s
\return int Nombre de fichier+rep�rtoires supprim�s
*/
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 numero 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 number of records found by select with limit+1
\param totalnboflines Total number of records/lines for all pages (if known)
*/
function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=0)
{
global $conf,$langs;
if ($num > $conf->liste_limit or $num == -1)
{
$nextpage = 1;
}
else
{
$nextpage = 0;
}
print '<table width="100%" border="0" class="notopnoleftnoright">';
$pagelist = '';
if ($page > 0 || $num > $conf->liste_limit)
{
if ($totalnboflines)
{
print '<tr><td class="notopnoleftnoright">';
print '<div class="titre">'.$titre.'</div>';
print '</td>';
$maxnbofpage=10;
$nbpages=ceil($totalnboflines/$conf->liste_limit);
$cpt=($page-$maxnbofpage);
if ($cpt < 0) { $cpt=0; }
$pagelist.=$langs->trans('Page');
if ($cpt>=1)
{
$pagelist.=' <a href="'.$file.'?page=0'.$options.'&sortfield='.$sortfield.'&sortorder='.$sortorder.'">1</a>';
if ($cpt >= 2) $pagelist.=' ...';
}
do
{
if($cpt==$page)
{
$pagelist.= ' <u>'.($page+1).'</u>';
}
else
{
$pagelist.= ' <a href="'.$file.'?page='.$cpt.$options.'&sortfield='.$sortfield.'&sortorder='.$sortorder.'">'.($cpt+1).'</a>';
}
$cpt++;
}
while ($cpt < $nbpages && $cpt<=$page+$maxnbofpage);
if ($cpt<$nbpages)
{
if ($cpt<$nbpages-1) $pagelist.= ' ...';
$pagelist.= ' <a href="'.$file.'?page='.($nbpages-1).$options.'&sortfield='.$sortfield.'&sortorder='.$sortorder.'">'.$nbpages.'</a>';
}
}
else
{
print '<tr><td class="notopnoleftnoright">';
print '<div class="titre">'.$titre.'</div>';
$pagelist.= $langs->trans('Page').' '.($page+1);
print '</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,$pagelist);
print '</td></tr></table>';
}
/**
\brief Fonction servant a afficher les fleches de navigation dans les pages de listes
\param page Num�ro 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
\param betweenarraows HTML Content to show between arrows
*/
function print_fleche_navigation($page,$file,$options='',$nextpage,$betweenarrows='')
{
global $conf, $langs;
if ($page > 0)
{
print '<a href="'.$file.'?page='.($page-1).$options.'">'.img_previous($langs->trans("Previous")).'</a>';
}
if ($betweenarrows) print ($page > 0?' ':'').$betweenarrows.($nextpage>0?' ':'');
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 utilis�e dans les pdf et les pages html
* \param rate Rate value to format (19.6 19,6 19.6% 19,6%,...)
* \param foundpercent Add a percent % sign in output
* \param info_bits Miscellanous information on vat
* \return string Chaine avec montant format� (19,6 ou 19,6% ou 8.5% *)
*/
function vatrate($rate,$addpercent=false,$info_bits=0)
{
// Test for compatibility
if (eregi('%',$rate))
{
$rate=eregi_replace('%','',$rate);
$addpercent=true;
}
if (eregi('\*',$rate) || eregi(MAIN_LABEL_MENTION_NPR,$rate))
{
$rate=eregi_replace('\*','',$rate);
$info_bits |= 1;
}
$ret=price($rate,0,'',0,0).($addpercent?'%':'');
if ($info_bits & 1) $ret.=' '.MAIN_LABEL_MENTION_NPR;
return $ret;
}
/**
* \brief Fonction qui formate un montant pour visualisation
* \remarks Fonction utilisee dans les pdf et les pages html
* \param amount Montant a formater
* \param html Type de formatage, html ou pas (par defaut)
* \param outlangs Objet langs pour formatage text
* \param trunc 1=Tronque affichage si trop de decimales,0=Force le non troncage
* \param rounding Nbre decimals minimum.
* \return string Chaine avec montant formate
* \seealso price2num Revert function of price
*/
function price($amount, $html=0, $outlangs='', $trunc=1, $rounding=2)
{
global $langs,$conf;
$nbdecimal=$rounding;
// Output separators by default (french)
$dec=','; $thousand=' ';
// If $outlangs not forced, we use use language
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); // should be useless
//print $amount."-";
$datas = split('\.',$amount);
$decpart = $datas[1];
$decpart = eregi_replace('0+$','',$decpart); // Supprime les 0 de fin de partie decimale
//print "decpart=".$decpart."<br>";
$end='';
// We increase nbdecimal if there is more decimal than asked (to not loose information)
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 tronque, on montre des ...
$end='...';
}
}
// Format number
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 numerique conforme 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 for totals with Tax (MAIN_MAX_DECIMALS_TOT)
* 'MS'=Round to Max Shown (MAIN_MAX_DECIMALS_SHOWN)
* ''=No rounding
* \return string Montant au format numerique PHP et SQL (Exemple: '99.99999')
* \seealso price Fonction inverse de price2num
*/
function price2num($amount,$rounding='',$alreadysqlnb=-1)
{
global $langs,$conf;
// Round PHP function does not allow number like '1,234.5' nor '1.234,5' nor '1 234,5'
// Numbers must be '1234.5'
// Decimal delimiter for database SQL request must be '.'
$dec=','; $thousand=' ';
if ($langs->trans("SeparatorDecimal") != "SeparatorDecimal") $dec=$langs->trans("SeparatorDecimal");
if ($langs->trans("SeparatorThousand")!= "SeparatorThousand") $thousand=$langs->trans("SeparatorThousand");
if ($alreadysqlnb != 1) // If not a PHP number or unknown, we change format
{
if ($thousand != ',' && $thousand != '.') $amount=str_replace(',','.',$amount); // To accept 2 notations for french users
$amount=str_replace(' ','',$amount); // To avoid spaces
$amount=str_replace($thousand,'',$amount); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount=str_replace($dec,'.',$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';
// Always make replace because each math function (like round) replace
// with local values and we want a number that has a SQL string format x.y
if ($thousand != ',' && $thousand != '.') $amount=str_replace(',','.',$amount); // To accept 2 notations for french users
$amount=str_replace(' ','',$amount); // To avoid spaces
$amount=str_replace($thousand,'',$amount); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount=str_replace($dec,'.',$amount);
}
return $amount;
}
/**
* \brief Return vat rate of a product in a particular selling country
*/
function get_product_vat_for_country($idprod, $countrycode)
{
global $db;
$product=new Product($db);
$product->fetch($idprod);
// \TODO Read rate according to countrycode
// For the moment only one rate supported
return $product->tva_tx;
}
/**
\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 d�faut=0. Fin de r�gle.
Si le (pays vendeur = pays acheteur) alors TVA par d�faut=TVA du produit vendu. Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par d�faut=0 (La TVA doit �tre pay� par acheteur au centre d'impots de son pays et non au vendeur). Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par d�faut=TVA du produit vendu. Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = entreprise avec num TVA) intra alors TVA par d�faut=0. Fin de r�gle.
Sinon TVA propos�e par d�faut=0. Fin de r�gle.
\param societe_vendeuse Objet soci�t� vendeuse
\param societe_acheteuse Objet soci�t� acheteuse
\param taux_produit Taux par defaut du produit vendu (old way to get product vat rate)
\param idprod Id product (new way to get product vat rate)
\return float Taux de tva a appliquer, -1 si ne peut etre d�termin�
*/
function get_default_tva($societe_vendeuse, $societe_acheteuse, $taux_produit, $idprod=0)
{
if (!is_object($societe_vendeuse)) return -1;
if (!is_object($societe_acheteuse)) return -1;
dolibarr_syslog("get_default_tva vendeur_assujeti=".$societe_vendeuse->tva_assuj." pays_vendeur=".$societe_vendeuse->pays_code.", seller in cee=".$societe_vendeuse->isInEEC().", pays_acheteur=".$societe_acheteuse->pays_code.", buyer in cee=".$societe_acheteuse->isInEEC().", taux_produit(deprecated)=".$taux_produit.", idprod=".$idprod);
// 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 d�faut=TVA du produit vendu. Fin de r�gle.
//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 ($idprod) return get_product_vat_for_country($idprod,$societe_vendeuse->pays_code);
if (strlen($taux_produit) == 0) return -1; // Si taux produit = '', on ne peut d�terminer taux tva
return $taux_produit;
}
// Si (vendeur et acheteur dans Communaut� europ�enne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par d�faut=0 (La TVA doit �tre pay� par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de r�gle.
// Non g�r�
// Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par d�faut=TVA du produit vendu. Fin de r�gle.
if (($societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC()) && ! $societe_acheteuse->tva_intra)
{
if ($idprod) return get_product_vat_for_country($idprod,$societe_vendeuse->pays_code);
if (strlen($taux_produit) == 0) return -1; // Si taux produit = '', on ne peut d�terminer taux tva
return $taux_produit;
}
// Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = entreprise avec num TVA intra) alors TVA par d�faut=0. Fin de r�gle.
if (($societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC()) && $societe_acheteuse->tva_intra)
{
return 0;
}
// Sinon la TVA propos�e par d�faut=0. Fin de r�gle.
// Rem: Cela signifie qu'au moins un des 2 est hors Communaut� europ�enne et que le pays diff�re
return 0;
}
/**
\brief Fonction qui renvoie si tva doit etre tva percue r�cup�rable
\remarks Si vendeur non assujeti a TVA, TVA par d�faut=0. Fin de r�gle.
Si le (pays vendeur = pays acheteur) alors TVA par d�faut=TVA du produit vendu. Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par d�faut=0 (La TVA doit �tre pay� par acheteur au centre d'impots de son pays et non au vendeur). Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = particulier ou entreprise sans num TVA intra) alors TVA par d�faut=TVA du produit vendu. Fin de r�gle.
Si (vendeur et acheteur dans Communaut� europ�enne) et (acheteur = entreprise avec num TVA) intra alors TVA par d�faut=0. Fin de r�gle.
Sinon TVA propos�e par d�faut=0. Fin de r�gle.
\param societe_vendeuse Objet soci�t� vendeuse
\param societe_acheteuse Objet soci�t� acheteuse
\param taux_produit Taux par defaut du produit vendu
\return float 0 or 1
*/
function get_default_npr($societe_vendeuse, $societe_acheteuse, $taux_produit)
{
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 qui retourne le rowid d'un departement par son code
\param db handler d'acc�s base
\param code Code r�gion
\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 r�pertoire en fonction d'un id
\remarks Examples: 1->"0/0/1/", 15->"0/1/5/"
\param $num Id a d�composer
\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 Creation of a directory (recursive)
* \param $dir Directory to create
* \return int < 0 if KO, >= 0 if OK
*/
function create_exdir($dir)
{
dolibarr_syslog("functions.lib.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 echouer bien que le rep existe.
// (ex selon config de open_basedir)
if ($ccdir)
{
if (! @is_dir($ccdir))
{
dolibarr_syslog("functions.lib.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 renvoye une fausse info, alors on passe ici.
dolibarr_syslog("functions.lib.php::create_exdir: Fails to create directory '".$ccdir."' or directory already exists.",LOG_WARNING);
$nberr++;
}
else
{
dolibarr_syslog("functions.lib.php::create_exdir: Directory '".$ccdir."' created",LOG_DEBUG);
$nberr=0; // On remet a zero car si on arrive ici, cela veut dire que les �checs pr�c�dents peuvent etre ignor�s
$nbcreated++;
}
}
else
{
$nberr=0; // On remet a zero car si on arrive ici, cela veut dire que les �checs pr�c�dents peuvent etre ignor�s
}
}
}
return ($nberr ? -$nberr : $nbcreated);
}
/**
\brief Retourne le num�ro de la semaine par rapport a une date
\param time Date au format 'timestamp'
\return int Num�ro 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 ann�e est celle qui contient le 4 janvier ou que la semaine 1 de toute ann�e est celle qui contient le 1er jeudi de janvier.
* - La majorit� des ann�es ont 52 semaines mais les ann�es qui commence un jeudi et les ann�es bissextiles commen�ant un mercredi en poss�de 53.
* - Le 1er jour de la semaine est le Lundi
*/
// D�finition 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);
// D�finition du premier Jeudi de l'ann�e
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));
}
// D�finition du num�ro de semaine: nb de jours entre "premier Jeudi de l'ann�e" 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 ann�es qui commence un Jeudi et les ann�es bissextiles commen�ant un Mercredi en poss�de 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 unit�s de mesure comme la livre, le gallon, le litre, ...
*/
function measuring_units_string($unit,$measuring_style='')
{
/* Note Rodo aux dev :)
* Ne pas ins�rer dans la base de donn�es ces valeurs
* cela surchagerait inutilement d'une requete suppl�mentaire
* 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("VolumeUnitdm3");
$measuring_units[-6] = $langs->trans("VolumeUnitcm3");
$measuring_units[-9] = $langs->trans("VolumeUnitmm3");
}
return $measuring_units[$unit];
}
/**
\brief Clean an url
\param url Url
\param http 1: keep http, 0: remove also http
\return string CleanUrl
*/
function clean_url($url,$http=1)
{
// Fixed by Matelli (see http://matelli.fr/showcases/patchs-dolibarr/fix-cleaning-url.html)
// To include the minus sign in a char class, we must not escape it but put it at the end of the class
// Also, there's no need of escape a dot sign in a class
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 Clean a string from all html tags
* \param StringHtml String to clean
* \param removelinefeed Replace also all lines feeds by a space
* \return string String cleaned
*/
function clean_html($StringHtml,$removelinefeed=1)
{
$pattern = "<[^>]+>";
$temp = dol_entity_decode($StringHtml);
$temp = ereg_replace($pattern,"",$temp);
// Supprime aussi les retours
if ($removelinefeed) $temp=str_replace("\n"," ",$temp);
// et les espaces doubles
while(strpos($temp," "))
{
$temp = str_replace(" "," ",$temp);
}
$CleanString = $temp;
return $CleanString;
}
/**
\brief Convert a binaray data to string that represent hexadecimal value
\param bin Value to convert
\param pad Add 0
\param upper Convert to tupper
\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'h�xad�cimal 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 Replace CRLF in string with a HTML BR tag.
* \param string2encode String to encode
* \param nl2brmode 0=Adding br before \n, 1=Replacing \n by br
* \return string String encoded
*/
function dol_nl2br($stringtoencode,$nl2brmode=0)
{
if (! $nl2brmode) return nl2br($stringtoencode);
else
{
$ret=ereg_replace("\r","",$stringtoencode);
$ret=ereg_replace("\n","<br>",$ret);
return $ret;
}
}
/**
* \brief This function is called to encode a string into a HTML string
* \param stringtoencode String to encode
* \param nl2brmode 0=Adding br before \n, 1=Replacing \n by br (for use with FPDF writeHTMLCell function for example)
* \remarks For PDF usage, you can show text by 2 ways:
* - writeHTMLCell -> param must be encoded into HTML.
* - MultiCell -> param must not be encoded into HTML.
* Because writeHTMLCell convert also \n into <br>, if function
* is used to build PDF, nl2brmode must be 1.
*/
function dol_htmlentitiesbr($stringtoencode,$nl2brmode=0)
{
if (dol_textishtml($stringtoencode))
{
// Replace "<br type="_moz" />" by "<br>". It's same and avoid pb with FPDF.
$stringtoencode=eregi_replace('<br( [ a-zA-Z_="]*)?/?>','<br>',$stringtoencode);
return $stringtoencode;
}
else {
$newstring=dol_nl2br(htmlentities($stringtoencode),$nl2brmode);
// Other substitutions that htmlentities does not do
$newstring=str_replace(chr(128),'€',$newstring); // 128 = 0x80
return $newstring;
}
}
/*
* \brief This function is called to decode a HTML string
* \param stringtodecode String to decode
*/
function dol_htmlentitiesbr_decode($stringtodecode)
{
$ret=html_entity_decode($stringtodecode);
$ret=eregi_replace("\r\n".'<br( [ a-zA-Z_="]*)?/?>',"<br>",$ret);
$ret=eregi_replace('<br( [ a-zA-Z_="]*)?/?>'."\r\n","\r\n",$ret);
$ret=eregi_replace('<br( [ a-zA-Z_="]*)?/?>'."\n","\n",$ret);
$ret=eregi_replace('<br( [ a-zA-Z_="]*)?/?>',"\n",$ret);
return $ret;
}
/**
* \brief Decode le code html
* \param string stringhtml
* \return string decodestring
*/
function dol_entity_decode($stringhtml)
{
$decodedstring = html_entity_decode($stringhtml);
return $decodedstring;
}
/**
\brief Check if a string is a correct iso string
If not, it will we considered not HTML encoded even if it is by FPDF.
\remarks Example, if string contains euro symbol that has ascii code 128.
\param s String to check
\return int 0 if bad iso, 1 if good iso
*/
function dol_string_is_good_iso($s)
{
$len=strlen($s);
$ok=1;
for($scursor=0;$scursor<$len;$scursor++)
{
$ordchar=ord($s{$scursor});
//print $scursor.'-'.$ordchar.'<br>';
if ($ordchar < 32 && $ordchar != 13 && $ordchar != 10) { $ok=0; break; }
if ($ordchar > 126 && $ordchar < 160) { $ok=0; break; }
}
return $ok;
}
/**
* \brief Return nb of lines of a text
* \param s String to check
* \param maxchar Not yet used
* \return int 0 if bad iso, 1 if good iso
*/
function dol_nboflines($s,$maxchar=0)
{
$arraystring=split("\n",$s);
$nb=sizeof($arraystring);
return $nb;
}
/**
* \brief Fonction retournant le nombre de lignes dans un texte formate
* \param texte Texte
* \param maxlinesize Largeur de ligne en caracteres(ou 0 si pas de limite - defaut)
* \return nblines Nombre de lignes
*/
function num_lines($texte,$maxlinesize=0)
{
$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);
// count possible auto line breaks
if($maxlinesize)
{
foreach ($a as $line)
{
if (strlen($line)>$maxlinesize)
{
//$line_dec = html_entity_decode(strip_tags($line));
$line_dec = html_entity_decode($line);
if(strlen($line_dec)>$maxlinesize)
{
$line_dec=wordwrap($line_dec,$maxlinesize,'\n',true);
$nblines+=substr_count($line_dec,'\n');
}
}
}
}
return $nblines;
}
/**
* \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('<span',$msg)) return true;
elseif (eregi('<div',$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 cl�s par les donn�es 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 effectu�es
*/
function make_substitutions($chaine,$substitutionarray)
{
foreach ($substitutionarray as $key => $value)
{
$chaine=ereg_replace($key,$value,$chaine);
}
return $chaine;
}
/*
* \brief Formate l'affichage de date de d�but et de fin
* \param date_start date de d�but
* \param date_end date de fin
* \param format format de l'affichage
* \remarks Updated by Matelli : added format paramter
* \remarks See http://matelli.fr/showcases/patchs-dolibarr/update-date-range-format.html for details
*/
function print_date_range($date_start,$date_end,$format = '')
{
global $langs;
if ($date_start && $date_end)
{
print ' ('.$langs->trans('DateFromTo',dolibarr_print_date($date_start, $format),dolibarr_print_date($date_end, $format)).')';
}
if ($date_start && ! $date_end)
{
print ' ('.$langs->trans('DateFrom',dolibarr_print_date($date_start), $format).')';
}
if (! $date_start && $date_end)
{
print ' ('.$langs->trans('DateUntil',dolibarr_print_date($date_end), $format).')';
}
}
/*
*
*/
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 Retourne un tableau des mois ou le mois s�lectionn�
\param selected Mois � s�lectionner 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;
}
/**
* \brief This function output memory used by PHP and exit everything. Used for debugging purpose.
*/
function stopwithmem()
{
print memory_get_usage();
llxFooter();
exit;
}
/**
* \brief Advanced sort array by second index function, which produces
* ascending (default) or descending output and uses optionally
* natural case insensitive sorting (which can be optionally case
* sensitive as well).
*/
function dol_sort_array($array, $index, $order='asc', $natsort, $case_sensitive)
{
// Clean parameters
$order=strtolower($order);
if (is_array($array) && count($array)>0)
{
foreach(array_keys($array) as $key) $temp[$key]=$array[$key][$index];
if (!$natsort) ($order=='asc') ? asort($temp) : arsort($temp);
else
{
($case_sensitive) ? natsort($temp) : natcasesort($temp);
if($order!='asc') $temp=array_reverse($temp,TRUE);
}
foreach(array_keys($temp) as $key) (is_numeric($key))? $sorted[]=$array[$key] : $sorted[$key]=$array[$key];
return $sorted;
}
return $array;
}
/**
* \brief Test if a folder is empty
* \return true is empty or non-existing, false if it contains files
*/
function is_emtpy_folder($folder){
if(is_dir($folder) ){
$handle = opendir($folder);
while( (gettype( $name = readdir($handle)) != "boolean")){
$name_array[] = $name;
}
foreach($name_array as $temp)
$folder_content .= $temp;
if($folder_content == "...")
return true;
else
return false;
closedir($handle);
}
else
return true; // Le rpertoire n'existe pas
}
/**
* \brief Return an html table from an array
*/
function array2table($data,$tableMarkup=1,$tableoptions='',$troptions='',$tdoptions=''){
$text='' ;
if($tableMarkup) $text = '<table '.$tableoptions.'>' ;
foreach($data as $key => $item){
if(is_array($item)){
$text.=array2tr($item,$troptions,$tdoptions) ;
} else {
$text.= '<tr '.$troptions.'>' ;
$text.= '<td '.$tdoptions.'>'.$key.'</td>' ;
$text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
$text.= '</tr>' ;
}
}
if($tableMarkup) $text.= '</table>' ;
return $text ;
}
/**
* \brief Return lines of an html table from an array
*/
function array2tr($data,$troptions='',$tdoptions=''){
$text = '<tr '.$troptions.'>' ;
foreach($data as $key => $item){
$text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
}
$text.= '</tr>' ;
return $text ;
}
/**
* \brief Check if a string is in UTF8
* \param $Str String to check
* \return boolean True if string is UTF8, false if not
*/
function utf8_check($Str)
{
for ($i=0; $i<strlen($Str); $i++)
{
if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
else return false; # Does not match any model
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
return false;
}
}
return true;
}
?>