diff --git a/htdocs/contact/fiche.php b/htdocs/contact/fiche.php index 5e6d61e0352..dd4f1a41a83 100644 --- a/htdocs/contact/fiche.php +++ b/htdocs/contact/fiche.php @@ -31,6 +31,7 @@ require("./pre.inc.php"); require_once(DOL_DOCUMENT_ROOT."/actioncomm.class.php"); require_once(DOL_DOCUMENT_ROOT."/contact.class.php"); require_once(DOL_DOCUMENT_ROOT."/lib/contact.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/lib/company.lib.php"); $langs->load("companies"); $langs->load("users"); @@ -475,6 +476,8 @@ if ($user->rights->societe->contact->creer) if ($_GET["id"] && $_GET["action"] != 'edit') { + $objsoc = new Societe($db); + /* * Fiche en mode visualisation * @@ -495,7 +498,6 @@ if ($_GET["id"] && $_GET["action"] != 'edit') // Company if ($contact->socid > 0) { - $objsoc = new Societe($db); $objsoc->fetch($contact->socid); print '
| '.$langs->trans("Date").' | '; - print ''.$langs->trans("Actions").' | '; - print ''.$langs->trans("Comments").' | '; - print ''.$langs->trans("Author").' | '; - print ''.$langs->trans("Status").' | '; - print '
| ". dolibarr_print_date($histo[$key]['date'],"dayhour") ." | "; - - // Action - print ''; - if ($histo[$key]['type']=='action') - { - print ''.img_object($langs->trans("ShowTask"),"task").' '; - $transcode=$langs->trans("Action".$histo[$key]['acode']); - $libelle=($transcode!="Action".$histo[$key]['acode']?$transcode:$histo[$key]['libelle']); - print dolibarr_trunc($libelle,30); - print ''; - } - if ($histo[$key]['type']=='mailing') - { - print ''.img_object($langs->trans("ShowEMailing"),"email").' '; - $transcode=$langs->trans("Action".$histo[$key]['acode']); - $libelle=($transcode!="Action".$histo[$key]['acode']?$transcode:'Send mass mailing'); - print dolibarr_trunc($libelle,30); - print ''; - } - print ' | '; - - // Note - print ''.dolibarr_trunc($histo[$key]['note'], 30).' | '; - - // Author - print ''; - if ($histo[$key]['login']) - { - print ''.img_object($langs->trans("ShowUser"),'user').' '.$histo[$key]['login'].''; - } - else print " "; - print " | "; - - // Status/Percent - print ''; - $actionstatic=new ActionComm($db); - print $actionstatic->LibStatut($histo[$key]['percent'],5); - print ' | '; - - print "
| '.$langs->trans("ActionsToDoShort").' | '; + print ' | '.$langs->trans("ActionsToDoShort").' | '; print ' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '.strftime("%Y",$obj->dp)." | \n"; - $oldyear = strftime("%Y",$obj->dp); - - print '' .strftime("%b",$obj->dp)." | \n"; - $oldmonth = strftime("%Y%b",$obj->dp); - - print ''.strftime("%d",$obj->dp)." | \n"; - print ''.strftime("%H:%M",$obj->dp).' | '; + print ''.dolibarr_print_date($obj->dp,'dayhour')." | \n"; // Picto warning print ''; @@ -402,12 +412,9 @@ function show_actions_todo($conf,$langs,$db,$objsoc) else print ' '; print ' | '; - // Status/Percent - print ''; - if ($obj->propalrowid) { - print ' | '.img_object($langs->trans("ShowAction"),"task"); + print ' | '.img_object($langs->trans("ShowAction"),"task"); $transcode=$langs->trans("Action".$obj->acode); $libelle=($transcode!="Action".$obj->acode?$transcode:$obj->libelle); print $libelle; @@ -418,23 +425,24 @@ function show_actions_todo($conf,$langs,$db,$objsoc) $actionstatic->code=$obj->acode; $actionstatic->libelle=$obj->libelle; $actionstatic->id=$obj->id; - print ' | '.$actionstatic->getNomUrl(1,16).' | '; + print ''.$actionstatic->getNomUrl(1,16).' | '; } + print ''.$obj->label.' | '; // Contact pour cette action - if ($obj->fk_contact > 0) + if (! $objcon->id && $obj->fk_contact > 0) { $contactstatic->name=$obj->name; $contactstatic->firstname=$obj->firstname; $contactstatic->id=$obj->fk_contact; - print ''.$contactstatic->getNomUrl(1).' | '; + print ''.$contactstatic->getNomUrl(1,'',10).' | '; } else { print ''; } - + print ' | ';
$userstatic->id=$obj->fk_user_author;
$userstatic->login=$obj->login;
@@ -466,141 +474,220 @@ function show_actions_todo($conf,$langs,$db,$objsoc)
}
/**
- * \brief Show html area with actions done
+ * \brief Show html area with actions done
+ * \param conf Object conf
+ * \param langs Object langs
+ * \param db Object db
+ * \param objsoc Object third party
+ * \param objcon Object contact
*/
-function show_actions_done($conf,$langs,$db,$objsoc)
+function show_actions_done($conf,$langs,$db,$objsoc,$objcon='')
{
global $bc;
+ $histo=array();
+ $numaction = 0 ;
+
if ($conf->agenda->enabled)
{
- require_once(DOL_DOCUMENT_ROOT."/actioncomm.class.php");
- require_once(DOL_DOCUMENT_ROOT."/facture.class.php");
- $actionstatic=new ActionComm($db);
- $userstatic=new User($db);
- $contactstatic = new Contact($db);
- $facturestatic=new Facture($db);
-
- print '
\n"; } + + if ($conf->mailing->enabled && $objcon->email) + { + $langs->load("mails"); + + // Recherche histo sur mailing + $sql = "SELECT m.rowid as id, ".$db->pdate("mc.date_envoi")." as da, m.titre as note, '100' as percentage,"; + $sql.= " 'AC_EMAILING' as acode,"; + $sql.= " u.rowid as user_id, u.login"; // User that valid action + $sql.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u"; + $sql.= " WHERE mc.email = '".addslashes($objcon->email)."'"; // Search is done on email. + $sql.= " AND mc.statut = 1"; + $sql.= " AND u.rowid = m.fk_user_valid"; + $sql.= " AND mc.fk_mailing=m.rowid"; + $sql.= " ORDER BY mc.date_envoi DESC, m.rowid DESC"; + + dolibarr_syslog("compan.lib::show_actions_done sql=".$sql, LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $i = 0 ; + $num = $db->num_rows($resql); + $var=true; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + $histo[$numaction]=array('type'=>'mailing','id'=>$obj->id,'date'=>$obj->da,'note'=>$obj->note,'percent'=>$obj->percentage, + 'acode'=>$obj->acode,'libelle'=>$obj->libelle, + 'userid'=>$obj->user_id,'login'=>$obj->login, + 'contact_id'=>$obj->contact_id); + $numaction++; + $i++; + } + } + else + { + dolibarr_print_error($db); + } + } + + + if ($conf->agenda->enabled || ($conf->mailing->enabled && $objcon->email)) + { + require_once(DOL_DOCUMENT_ROOT."/actioncomm.class.php"); + require_once(DOL_DOCUMENT_ROOT."/propal.class.php"); + require_once(DOL_DOCUMENT_ROOT."/commande/commande.class.php"); + require_once(DOL_DOCUMENT_ROOT."/facture.class.php"); + $actionstatic=new ActionComm($db); + $userstatic=new User($db); + $contactstatic = new Contact($db); + $propalstatic=new Propal($db); + $orderstatic=new Commande($db); + $facturestatic=new Facture($db); + + print '
\n"; } + /** * \brief Show footer of page for PDF generation * \param pdf Object PDF diff --git a/htdocs/lib/contact.lib.php b/htdocs/lib/contact.lib.php index 324f7fb3ec0..6f9cd091846 100644 --- a/htdocs/lib/contact.lib.php +++ b/htdocs/lib/contact.lib.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2006-2008 Laurent Destailleur '."\n";
-
- // Affichage titre
- if ($title)
- {
- $limittitle=30;
- print '';
- print
- ((!defined('MAIN_USE_SHORT_TITLE')) || (defined('MAIN_USE_SHORT_TITLE') && MAIN_USE_SHORT_TITLE))
- ? dolibarr_trunc($title,$limittitle)
- : $title;
- print '';
- }
-
- // Affichage onglets
- for ($i = 0 ; $i < sizeof($links) ; $i++)
- {
- if ($links[$i][2] == 'image')
- {
- print ''.$links[$i][1].''."\n";
- }
- else
- {
- //print "x $i $active ".$links[$i][2]." z";
- if ((is_numeric($active) && $i == $active)
- || (! is_numeric($active) && $active == $links[$i][2]))
- {
- print ''.$links[$i][1].''."\n";
- }
- else
- {
- print ''.$links[$i][1].''."\n";
- }
- }
- }
-
- print " \n";
-
- if (! $notab) print ''."\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 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 formatee ou '' si time 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_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';
- 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))
- {
- // 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 est un timestamps
- return adodb_strftime($format,$time,$to_gmt);
- }
-}
-
-
-/**
- * \brief Convert a string date into a TMS 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
- */
-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 fabriquee depuis infos.
- Remplace la fonction mktime non implementee sous Windows si annee < 1970
- \param hour Hour
- \param minute Minute
- \param second Second
- \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"]." -";
-
- // Check parameters
- if ($check)
- {
- 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 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 . ' '; - - if (isset($object->date_creation)) - print $langs->trans("DateCreation")." : " . dolibarr_print_date($object->date_creation,"dayhourtext") . ' '; - - if (isset($object->user_modification) && $object->user_modification->fullname) - print $langs->trans("ModifiedBy")." : " . $object->user_modification->fullname . ' '; - - if (isset($object->date_modification)) - print $langs->trans("DateLastModification")." : " . dolibarr_print_date($object->date_modification,"dayhourtext") . ' '; - - if (isset($object->user_validation) && $object->user_validation->fullname) - print $langs->trans("ValidatedBy")." : " . $object->user_validation->fullname . ' '; - - if (isset($object->date_validation)) - print $langs->trans("DateValidation")." : " . dolibarr_print_date($object->date_validation,"dayhourtext") . ' '; - - if (isset($object->user_cloture) && $object->user_cloture->fullname ) - print $langs->trans("ClosedBy")." : " . $object->user_cloture->fullname . ' '; - - if (isset($object->date_cloture)) - print $langs->trans("DateClosing")." : " . dolibarr_print_date($object->date_cloture,"dayhourtext") . ' '; - - if (isset($object->user_rappro) && $object->user_rappro->fullname ) - print $langs->trans("ConciliatedBy")." : " . $object->user_rappro->fullname . ' '; - - if (isset($object->date_rappro)) - print $langs->trans("DateConciliating")." : " . dolibarr_print_date($object->date_rappro,"dayhourtext") . ' '; -} - -/** - \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.=''.img_phone("default",0).''; - } - 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 ' ';
-}
-
-/**
- \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 suppl�mentaire 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 ' ';
-}
-
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-/**
- \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 ' ';
-}
-
-/**
- \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=' ';
- 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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-
-/**
- \brief Affiche logo help avec curseur "?"
- \return string Retourne tag img
- */
-function img_help($usehelpcursor=1,$usealttitle=1)
-{
- global $conf,$langs;
- $s =' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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=' ';
-
- 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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
- else return ' ';
-}
-
-/**
- \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 ' ';
- else return ' ';
-}
-
-/**
- \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 ' ';
- else return ' ';
-}
-
-/**
- \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 ' ';
- else return ' ';
-}
-
-/**
- \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 ' ';
-}
-
-/**
- \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 ' ';
- }
- 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 '';
- $s.=img_picto($langs->trans("InfoAdmin"),'star');
- $s.=' ';
- $s.=$texte;
- $s.=' ';
- }
- 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 dbtable Table name where object is stored. Not used if objectid is null (optionnel)
- \param feature 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
- // TODO Add after "feature" a param for permission for writing
- $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 (! $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 d�fini, 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 '';
- if (! $message) print $langs->trans("ErrorForbidden");
- else print $message;
- print ' ';
- print ''; - if ($user->login) - { - print $langs->trans("CurrentLogin").': '.$user->login.' '; - print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users")); - } - elseif (! empty($_SERVER["REMOTE_USER"])) - { - print $langs->trans("CurrentLogin").': '.$_SERVER["REMOTE_USER"]." "; - 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").". \n"; - print $langs->trans("InformationToHelpDiagnose").": \n"; - - print "".$langs->trans("Dolibarr").": ".DOL_VERSION." \n";; - if (isset($conf->global->MAIN_FEATURES_LEVEL)) print "".$langs->trans("LevelOfFeature").": ".$conf->global->MAIN_FEATURES_LEVEL." \n";; - print "".$langs->trans("Server").": ".$_SERVER["SERVER_SOFTWARE"]." \n";; - print "".$langs->trans("RequestedUrl").": ".$_SERVER["REQUEST_URI"]." \n";; - print "".$langs->trans("Referer").": ".$_SERVER["HTTP_REFERER"]." \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 " \n"; - print "".$langs->trans("DatabaseTypeManager").": ".$db->type." \n"; - print "".$langs->trans("RequestLastAccessInError").": ".($db->lastqueryerror()?$db->lastqueryerror():$langs->trans("ErrorNoRequestInError"))." \n"; - print "".$langs->trans("ReturnCodeLastAccessInError").": ".($db->lasterrno()?$db->lasterrno():$langs->trans("ErrorNoRequestInError"))." \n"; - print "".$langs->trans("InformationLastAccessInError").": ".($db->lasterror()?$db->lasterror():$langs->trans("ErrorNoRequestInError"))." \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 "".$langs->trans("Message").": ".$msg." \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 \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 ' ';
- }
- else
- {
- print ' | ';
- }
- print $name;
-
- // If this is a sort field
- if ($field)
- {
- //print " ";
- print ' | ";
-}
-
-/**
- \brief Affichage d'un titre
- \param titre Le titre a afficher
- */
-function print_titre($titre)
-{
- print ''.$titre.' ';
-}
-
-/**
- \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 '
\n"; - } - } - } - closedir($handle); - rmdir($dir); - $count++; - //echo "removing $dir \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 num�ro 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 '
"; - $end=''; - - // On augmente au besoin si il y a plus de 2 d�cimales - 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 numerique 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 num�rique 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' - // \TODO If there is already a ".", we remove ",", otherwise replace by "." - $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 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 ''.$result.''; - 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 Cr�ation de r�pertoire recursive - \param $dir R�pertoire a cr�er - \return int < 0 si erreur, >= 0 si succ�s - */ -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 �chouer 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 renvoy� 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 z�ro 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 z�ro 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." "; - - return sprintf("%02d",$numeroSemaine); -} - - -/** - \brief Retourne le picto champ obligatoire - \return string Chaine avec picto obligatoire - */ -function picto_required() -{ - return '*'; -} -/** - \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) -{ - 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 , if function - * is used to build PDF, nl2brmode must be 1. - */ -function dol_htmlentitiesbr($stringtoencode,$nl2brmode=0) -{ - if (dol_textishtml($stringtoencode)) - { - // Replace " " by " ". It's same and avoid pb with FPDF. - $stringtoencode=eregi_replace(' ",$ret); - $ret=eregi_replace(' '; - 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 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 d�but - \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 f�ri�s (jours ouvr�s) - \param timestampStart Timestamp de d�but - \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,$maxlinesize=0) -{ - $repTable = array("\t" => " ", "\n" => " ", "\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('',$msg)) return true; - elseif (eregi('',$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 - */ -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)).')'; - } -} - - -/* - * - */ -function make_alpha_from_numbers($number) -{ - $numeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if($number ';
- foreach($mesgarray as $message)
- {
- $ret++;
- print $langs->trans($message)." ';
- }
- if ($mesgstring)
- {
- $ret++;
- print '\n"; - } - print ' ';
- print $mesgstring;
- print ' ';
- }
-
- 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;
-}
-
-?>
+
+ * Copyright (C) 2003 Jean-Louis Bergamo '."\n";
+
+ // Affichage titre
+ if ($title)
+ {
+ $limittitle=30;
+ print '';
+ print
+ ((!defined('MAIN_USE_SHORT_TITLE')) || (defined('MAIN_USE_SHORT_TITLE') && MAIN_USE_SHORT_TITLE))
+ ? dolibarr_trunc($title,$limittitle)
+ : $title;
+ print '';
+ }
+
+ // Affichage onglets
+ for ($i = 0 ; $i < sizeof($links) ; $i++)
+ {
+ if ($links[$i][2] == 'image')
+ {
+ print ''.$links[$i][1].''."\n";
+ }
+ else
+ {
+ //print "x $i $active ".$links[$i][2]." z";
+ if ((is_numeric($active) && $i == $active)
+ || (! is_numeric($active) && $active == $links[$i][2]))
+ {
+ print ''.$links[$i][1].''."\n";
+ }
+ else
+ {
+ print ''.$links[$i][1].''."\n";
+ }
+ }
+ }
+
+ print " \n";
+
+ if (! $notab) print ''."\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 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 formatee ou '' si time 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_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';
+ 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))
+ {
+ // 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 est un timestamps
+ return adodb_strftime($format,$time,$to_gmt);
+ }
+}
+
+
+/**
+ * \brief Convert a string date into a TMS 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
+ */
+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 fabriquee depuis infos.
+ Remplace la fonction mktime non implementee sous Windows si annee < 1970
+ \param hour Hour
+ \param minute Minute
+ \param second Second
+ \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"]." -";
+
+ // Check parameters
+ if ($check)
+ {
+ 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 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 . ' '; + + if (isset($object->date_creation)) + print $langs->trans("DateCreation")." : " . dolibarr_print_date($object->date_creation,"dayhourtext") . ' '; + + if (isset($object->user_modification) && $object->user_modification->fullname) + print $langs->trans("ModifiedBy")." : " . $object->user_modification->fullname . ' '; + + if (isset($object->date_modification)) + print $langs->trans("DateLastModification")." : " . dolibarr_print_date($object->date_modification,"dayhourtext") . ' '; + + if (isset($object->user_validation) && $object->user_validation->fullname) + print $langs->trans("ValidatedBy")." : " . $object->user_validation->fullname . ' '; + + if (isset($object->date_validation)) + print $langs->trans("DateValidation")." : " . dolibarr_print_date($object->date_validation,"dayhourtext") . ' '; + + if (isset($object->user_cloture) && $object->user_cloture->fullname ) + print $langs->trans("ClosedBy")." : " . $object->user_cloture->fullname . ' '; + + if (isset($object->date_cloture)) + print $langs->trans("DateClosing")." : " . dolibarr_print_date($object->date_cloture,"dayhourtext") . ' '; + + if (isset($object->user_rappro) && $object->user_rappro->fullname ) + print $langs->trans("ConciliatedBy")." : " . $object->user_rappro->fullname . ' '; + + if (isset($object->date_rappro)) + print $langs->trans("DateConciliating")." : " . dolibarr_print_date($object->date_rappro,"dayhourtext") . ' '; +} + +/** + \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.=''.img_phone("default",0).''; + } + 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 ' ';
+}
+
+/**
+ \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 suppl�mentaire 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 ' ';
+}
+
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+/**
+ \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 ' ';
+}
+
+/**
+ \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=' ';
+ 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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+
+/**
+ \brief Affiche logo help avec curseur "?"
+ \return string Retourne tag img
+ */
+function img_help($usehelpcursor=1,$usealttitle=1)
+{
+ global $conf,$langs;
+ $s =' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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=' ';
+
+ 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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+ else return ' ';
+}
+
+/**
+ \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 ' ';
+ else return ' ';
+}
+
+/**
+ \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 ' ';
+ else return ' ';
+}
+
+/**
+ \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 ' ';
+ else return ' ';
+}
+
+/**
+ \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 ' ';
+}
+
+/**
+ \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 ' ';
+ }
+ 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 '';
+ $s.=img_picto($langs->trans("InfoAdmin"),'star');
+ $s.=' ';
+ $s.=$texte;
+ $s.=' ';
+ }
+ 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 dbtable Table name where object is stored. Not used if objectid is null (optionnel)
+ \param feature 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
+ // TODO Add after "feature" a param for permission for writing
+ $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 (! $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 d�fini, 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 '';
+ if (! $message) print $langs->trans("ErrorForbidden");
+ else print $message;
+ print ' ';
+ print ''; + if ($user->login) + { + print $langs->trans("CurrentLogin").': '.$user->login.' '; + print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users")); + } + elseif (! empty($_SERVER["REMOTE_USER"])) + { + print $langs->trans("CurrentLogin").': '.$_SERVER["REMOTE_USER"]." "; + 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").". \n"; + print $langs->trans("InformationToHelpDiagnose").": \n"; + + print "".$langs->trans("Dolibarr").": ".DOL_VERSION." \n";; + if (isset($conf->global->MAIN_FEATURES_LEVEL)) print "".$langs->trans("LevelOfFeature").": ".$conf->global->MAIN_FEATURES_LEVEL." \n";; + print "".$langs->trans("Server").": ".$_SERVER["SERVER_SOFTWARE"]." \n";; + print "".$langs->trans("RequestedUrl").": ".$_SERVER["REQUEST_URI"]." \n";; + print "".$langs->trans("Referer").": ".$_SERVER["HTTP_REFERER"]." \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 " \n"; + print "".$langs->trans("DatabaseTypeManager").": ".$db->type." \n"; + print "".$langs->trans("RequestLastAccessInError").": ".($db->lastqueryerror()?$db->lastqueryerror():$langs->trans("ErrorNoRequestInError"))." \n"; + print "".$langs->trans("ReturnCodeLastAccessInError").": ".($db->lasterrno()?$db->lasterrno():$langs->trans("ErrorNoRequestInError"))." \n"; + print "".$langs->trans("InformationLastAccessInError").": ".($db->lasterror()?$db->lasterror():$langs->trans("ErrorNoRequestInError"))." \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 "".$langs->trans("Message").": ".$msg." \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 \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 ' ';
+ }
+ else
+ {
+ print ' | ';
+ }
+ print $name;
+
+ // If this is a sort field
+ if ($field)
+ {
+ //print " ";
+ print ' | ";
+}
+
+/**
+ \brief Affichage d'un titre
+ \param titre Le titre a afficher
+ */
+function print_titre($titre)
+{
+ print ''.$titre.' ';
+}
+
+/**
+ \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 '
\n"; + } + } + } + closedir($handle); + rmdir($dir); + $count++; + //echo "removing $dir \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 num�ro 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 '
"; + $end=''; + + // On augmente au besoin si il y a plus de 2 d�cimales + 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 numerique 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 num�rique 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' + // \TODO If there is already a ".", we remove ",", otherwise replace by "." + $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 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 ''.$result.''; + 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 Cr�ation de r�pertoire recursive + \param $dir R�pertoire a cr�er + \return int < 0 si erreur, >= 0 si succ�s + */ +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 �chouer 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 renvoy� 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 z�ro 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 z�ro 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." "; + + return sprintf("%02d",$numeroSemaine); +} + + +/** + \brief Retourne le picto champ obligatoire + \return string Chaine avec picto obligatoire + */ +function picto_required() +{ + return '*'; +} +/** + \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) +{ + 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 , if function + * is used to build PDF, nl2brmode must be 1. + */ +function dol_htmlentitiesbr($stringtoencode,$nl2brmode=0) +{ + if (dol_textishtml($stringtoencode)) + { + // Replace " " by " ". It's same and avoid pb with FPDF. + $stringtoencode=eregi_replace(' ",$ret); + $ret=eregi_replace(' '; + 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 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 d�but + \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 f�ri�s (jours ouvr�s) + \param timestampStart Timestamp de d�but + \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" => " ", "\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; +} + +/** + * \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('',$msg)) return true; + elseif (eregi('',$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 + */ +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)).')'; + } +} + + +/* + * + */ +function make_alpha_from_numbers($number) +{ + $numeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if($number ';
+ foreach($mesgarray as $message)
+ {
+ $ret++;
+ print $langs->trans($message)." ';
+ }
+ if ($mesgstring)
+ {
+ $ret++;
+ print '\n"; + } + print ' ';
+ print $mesgstring;
+ print ' ';
+ }
+
+ 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;
+}
+
+?>
\ No newline at end of file
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||