2008-08-06 16:50:06 +02:00
< ? php
2020-04-12 18:03:51 +02:00
/* Copyright ( C ) 2000 - 2007 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2017-02-09 05:58:39 +01:00
* Copyright ( C ) 2003 Jean - Louis Bergamo < jlb @ j1b . org >
2018-04-14 12:45:40 +02:00
* Copyright ( C ) 2004 - 2018 Laurent Destailleur < eldy @ users . sourceforge . net >
2017-02-09 05:58:39 +01:00
* Copyright ( C ) 2004 Sebastien Di Cintio < sdicintio @ ressource - toi . org >
* Copyright ( C ) 2004 Benoit Mortier < benoit . mortier @ opensides . be >
2020-04-12 18:03:51 +02:00
* Copyright ( C ) 2004 Christophe Combelles < ccomb @ free . fr >
2019-07-19 09:47:05 +02:00
* Copyright ( C ) 2005 - 2019 Regis Houssin < regis . houssin @ inodbox . com >
2017-02-09 05:58:39 +01:00
* Copyright ( C ) 2008 Raphael Bertrand ( Resultic ) < raphael . bertrand @ resultic . fr >
2018-04-14 12:45:40 +02:00
* Copyright ( C ) 2010 - 2018 Juanjo Menent < jmenent @ 2 byte . es >
2017-02-09 05:58:39 +01:00
* Copyright ( C ) 2013 Cédric Salvador < csalvador @ gpcsolutions . fr >
2021-03-21 22:58:21 +01:00
* Copyright ( C ) 2013 - 2021 Alexandre Spangaro < aspangaro @ open - dsi . fr >
2020-04-12 18:03:51 +02:00
* Copyright ( C ) 2014 Cédric GROSS < c . gross @ kreiz - it . fr >
2017-02-09 05:58:39 +01:00
* Copyright ( C ) 2014 - 2015 Marcos García < marcosgdf @ gmail . com >
* Copyright ( C ) 2015 Jean - François Ferry < jfefe @ aternatik . fr >
2021-02-14 21:30:54 +01:00
* Copyright ( C ) 2018 - 2021 Frédéric France < frederic . france @ netlogic . fr >
2019-03-27 11:05:43 +01:00
* Copyright ( C ) 2019 Thibault Foucart < support @ ptibogxiv . net >
2020-04-27 17:35:14 +02:00
* Copyright ( C ) 2020 Open - Dsi < support @ open - dsi . fr >
2021-03-24 14:09:46 +01:00
* Copyright ( C ) 2021 Gauthier VERDOL < gauthier . verdol @ atm - consulting . fr >
2022-01-19 11:37:38 +01:00
* Copyright ( C ) 2022 Anthony Berton < anthony . berton @ bb2a . fr >
2008-08-06 16:50:06 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2008-08-06 16:50:06 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2008-08-06 16:50:06 +02:00
*/
/**
2011-10-24 12:59:44 +02:00
* \file htdocs / core / lib / functions . lib . php
2008-11-16 02:09:04 +01:00
* \brief A set of functions for Dolibarr
* This file contains all frequently used functions .
2008-08-06 16:50:06 +02:00
*/
2019-11-11 23:59:36 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/json.lib.php' ;
2011-11-05 03:15:35 +01:00
2021-03-19 17:58:01 +01:00
/**
* Return dolibarr global constant string value
* @ param string $key key to return value , return '' if not set
2021-10-23 21:06:37 +02:00
* @ param string $default value to return
2021-03-19 17:58:01 +01:00
* @ return string
*/
2021-10-23 21:06:37 +02:00
function getDolGlobalString ( $key , $default = '' )
2021-03-19 17:58:01 +01:00
{
global $conf ;
2021-10-23 21:10:43 +02:00
// return $conf->global->$key ?? $default;
2021-10-23 21:06:37 +02:00
return ( string ) ( empty ( $conf -> global -> $key ) ? $default : $conf -> global -> $key );
2021-03-19 17:58:01 +01:00
}
/**
* Return dolibarr global constant int value
* @ param string $key key to return value , return 0 if not set
2021-10-23 21:06:37 +02:00
* @ param int $default value to return
2021-03-19 17:58:01 +01:00
* @ return int
*/
2021-10-23 21:06:37 +02:00
function getDolGlobalInt ( $key , $default = 0 )
2021-03-19 17:58:01 +01:00
{
global $conf ;
2021-10-23 21:06:37 +02:00
// return $conf->global->$key ?? $default;
return ( int ) ( empty ( $conf -> global -> $key ) ? $default : $conf -> global -> $key );
2021-03-19 17:58:01 +01:00
}
2017-12-19 00:15:22 +01:00
2011-09-28 16:26:49 +02:00
/**
* Return a DoliDB instance ( database handler ) .
*
* @ param string $type Type of database ( mysql , pgsql ... )
* @ param string $host Address of database server
2019-10-18 19:55:21 +02:00
* @ param string $user Authorized username
* @ param string $pass Password
* @ param string $name Name of database
2011-09-28 16:26:49 +02:00
* @ param int $port Port of database server
* @ return DoliDB A DoliDB instance
*/
function getDoliDBInstance ( $type , $host , $user , $pass , $name , $port )
{
2019-11-11 23:59:36 +01:00
require_once DOL_DOCUMENT_ROOT . " /core/db/ " . $type . '.class.php' ;
2011-09-28 16:26:49 +02:00
2019-11-11 23:59:36 +01:00
$class = 'DoliDB' . ucfirst ( $type );
$dolidb = new $class ( $type , $host , $user , $pass , $name , $port );
2012-08-03 23:29:08 +02:00
return $dolidb ;
2011-09-28 16:26:49 +02:00
}
2012-01-11 14:14:14 +01:00
/**
2017-05-31 19:20:33 +02:00
* Get list of entity id to use .
2012-01-15 02:39:43 +01:00
*
2017-06-08 10:24:16 +02:00
* @ param string $element Current element
* 'societe' , 'socpeople' , 'actioncomm' , 'agenda' , 'resource' ,
2020-02-28 19:26:52 +01:00
* 'product' , 'productprice' , 'stock' , 'bom' , 'mo' ,
2020-03-23 15:33:52 +01:00
* 'propal' , 'supplier_proposal' , 'invoice' , 'supplier_invoice' , 'payment_various' ,
2017-06-08 10:24:16 +02:00
* 'categorie' , 'bank_account' , 'bank_account' , 'adherent' , 'user' ,
2020-03-23 15:33:52 +01:00
* 'commande' , 'supplier_order' , 'expedition' , 'intervention' , 'survey' ,
2017-06-08 10:24:16 +02:00
* 'contract' , 'tax' , 'expensereport' , 'holiday' , 'multicurrency' , 'project' ,
2017-11-12 12:39:23 +01:00
* 'email_template' , 'event' , 'donation'
2018-01-30 15:48:09 +01:00
* 'c_paiement' , 'c_payment_term' , ...
2017-06-08 10:24:16 +02:00
* @ param int $shared 0 = Return id of current entity only ,
2017-09-27 17:40:02 +02:00
* 1 = Return id of current entity + shared entities ( default )
2018-10-26 18:23:48 +02:00
* @ param object $currentobject Current object if needed
2019-06-03 12:04:17 +02:00
* @ return mixed Entity id ( s ) to use ( eg . entity IN ( '.getEntity(elementname).' ) ' )
2012-01-11 14:14:14 +01:00
*/
2019-01-27 15:20:16 +01:00
function getEntity ( $element , $shared = 1 , $currentobject = null )
2012-01-11 14:14:14 +01:00
{
2021-11-07 17:44:34 +01:00
global $conf , $mc , $hookmanager , $object , $action , $db ;
2012-01-15 02:39:43 +01:00
2021-10-31 15:59:03 +01:00
if ( ! is_object ( $hookmanager )) {
$hookmanager = new HookManager ( $db );
}
2020-09-16 10:51:19 +02:00
// fix different element names (France to English)
2020-09-16 14:03:41 +02:00
switch ( $element ) {
2021-02-23 22:03:23 +01:00
case 'contrat' :
$element = 'contract' ;
break ; // "/contrat/class/contrat.class.php"
case 'order_supplier' :
$element = 'supplier_order' ;
break ; // "/fourn/class/fournisseur.commande.class.php"
2020-09-16 10:51:19 +02:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $mc )) {
2021-08-26 15:04:59 +02:00
$out = $mc -> getEntity ( $element , $shared , $currentobject );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$out = '' ;
2017-09-22 20:18:11 +02:00
$addzero = array ( 'user' , 'usergroup' , 'c_email_templates' , 'email_template' , 'default_values' );
2021-02-23 22:03:23 +01:00
if ( in_array ( $element , $addzero )) {
$out .= '0,' ;
}
2020-09-18 17:24:31 +02:00
$out .= (( int ) $conf -> entity );
2012-01-11 14:14:14 +01:00
}
2021-08-26 15:04:59 +02:00
// Manipulate entities to query on the fly
$parameters = array (
'element' => $element ,
'shared' => $shared ,
2021-08-28 14:51:49 +02:00
'object' => $object ,
'currentobject' => $currentobject ,
'out' => $out
2021-08-26 15:04:59 +02:00
);
2021-08-28 14:51:49 +02:00
$reshook = $hookmanager -> executeHooks ( 'hookGetEntity' , $parameters , $currentobject , $action ); // Note that $action and $object may have been modified by some hooks
2021-08-26 15:04:59 +02:00
if ( is_numeric ( $reshook )) {
2021-11-07 17:46:08 +01:00
if ( $reshook == 0 && ! empty ( $hookmanager -> resPrint )) {
$out .= ',' . $hookmanager -> resPrint ; // add
2021-08-26 15:04:59 +02:00
} elseif ( $reshook == 1 ) {
2021-11-07 17:46:08 +01:00
$out = $hookmanager -> resPrint ; // replace
2021-08-26 15:04:59 +02:00
}
}
return $out ;
2012-01-11 14:14:14 +01:00
}
2011-09-28 16:26:49 +02:00
2019-06-03 11:13:26 +02:00
/**
2019-06-03 12:04:17 +02:00
* Set entity id to use when to create an object
2019-06-03 11:13:26 +02:00
*
* @ param object $currentobject Current object
2019-06-03 12:05:58 +02:00
* @ return mixed Entity id to use ( eg . entity = ' . setEntity ( $object ) )
2019-06-03 11:13:26 +02:00
*/
function setEntity ( $currentobject )
{
global $conf , $mc ;
2021-02-23 22:03:23 +01:00
if ( is_object ( $mc ) && method_exists ( $mc , 'setEntity' )) {
2019-06-03 11:13:26 +02:00
return $mc -> setEntity ( $currentobject );
2020-05-21 15:05:19 +02:00
} else {
2019-07-19 09:47:05 +02:00
return (( is_object ( $currentobject ) && $currentobject -> id > 0 && $currentobject -> entity > 0 ) ? $currentobject -> entity : $conf -> entity );
2019-06-03 11:13:26 +02:00
}
}
2020-10-05 12:13:06 +02:00
/**
* Return if string has a name dedicated to store a secret
*
* @ param string $keyname Name of key to test
* @ return boolean True if key is used to store a secret
*/
function isASecretKey ( $keyname )
{
return preg_match ( '/(_pass|password|_pw|_key|securekey|serverkey|secret\d?|p12key|exportkey|_PW_[a-z]+|token)$/i' , $keyname );
}
2012-02-29 19:41:12 +01:00
/**
* Return information about user browser
*
2015-02-25 16:45:14 +01:00
* Returns array with the following format :
* array (
* 'browsername' => Browser name ( firefox | chrome | iceweasel | epiphany | safari | opera | ie | unknown )
* 'browserversion' => Browser version . Empty if unknown
* 'browseros' => Set with mobile OS ( android | blackberry | ios | palm | symbian | webos | maemo | windows | unknown )
* 'layout' => ( tablet | phone | classic )
* 'phone' => empty if not mobile , ( android | blackberry | ios | palm | unknown ) if mobile
* 'tablet' => true / false
* )
*
2015-02-22 12:35:51 +01:00
* @ param string $user_agent Content of $_SERVER [ " HTTP_USER_AGENT " ] variable
2015-02-25 16:45:14 +01:00
* @ return array Check function documentation
2012-02-29 19:41:12 +01:00
*/
2015-02-22 12:35:51 +01:00
function getBrowserInfo ( $user_agent )
2012-02-29 19:41:12 +01:00
{
2015-08-06 16:43:30 +02:00
include_once DOL_DOCUMENT_ROOT . '/includes/mobiledetect/mobiledetectlib/Mobile_Detect.php' ;
2015-02-22 13:17:57 +01:00
2019-11-11 23:59:36 +01:00
$name = 'unknown' ;
$version = '' ;
$os = 'unknown' ;
2015-02-25 16:41:51 +01:00
$phone = '' ;
2015-02-22 13:17:57 +01:00
2020-12-04 21:38:33 +01:00
$user_agent = substr ( $user_agent , 0 , 512 ); // Avoid to process too large user agent
2015-08-06 18:38:50 +02:00
$detectmobile = new Mobile_Detect ( null , $user_agent );
2015-02-22 13:17:57 +01:00
$tablet = $detectmobile -> isTablet ();
if ( $detectmobile -> isMobile ()) {
2015-02-25 16:41:51 +01:00
$phone = 'unknown' ;
2015-02-22 13:17:57 +01:00
// If phone/smartphone, we set phone os name.
2015-02-23 10:51:43 +01:00
if ( $detectmobile -> is ( 'AndroidOS' )) {
$os = $phone = 'android' ;
} elseif ( $detectmobile -> is ( 'BlackBerryOS' )) {
$os = $phone = 'blackberry' ;
} elseif ( $detectmobile -> is ( 'iOS' )) {
$os = 'ios' ;
$phone = 'iphone' ;
} elseif ( $detectmobile -> is ( 'PalmOS' )) {
$os = $phone = 'palm' ;
} elseif ( $detectmobile -> is ( 'SymbianOS' )) {
$os = 'symbian' ;
} elseif ( $detectmobile -> is ( 'webOS' )) {
$os = 'webos' ;
} elseif ( $detectmobile -> is ( 'MaemoOS' )) {
$os = 'maemo' ;
} elseif ( $detectmobile -> is ( 'WindowsMobileOS' ) || $detectmobile -> is ( 'WindowsPhoneOS' )) {
$os = 'windows' ;
2015-02-22 13:17:57 +01:00
}
}
2014-07-27 14:13:25 +02:00
// OS
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/linux/i' , $user_agent )) {
$os = 'linux' ;
} elseif ( preg_match ( '/macintosh/i' , $user_agent )) {
$os = 'macintosh' ;
} elseif ( preg_match ( '/windows/i' , $user_agent )) {
$os = 'windows' ;
}
2014-07-27 14:13:25 +02:00
2012-08-03 23:29:08 +02:00
// Name
2020-10-30 05:45:36 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/firefox(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) {
2021-03-01 20:37:16 +01:00
$name = 'firefox' ;
$version = $reg [ 2 ];
2021-02-23 22:03:23 +01:00
} elseif ( preg_match ( '/edge(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) {
2021-03-01 20:37:16 +01:00
$name = 'edge' ;
$version = $reg [ 2 ];
2021-02-23 22:03:23 +01:00
} elseif ( preg_match ( '/chrome(\/|\s)([\d\.]+)/i' , $user_agent , $reg )) {
2021-03-01 20:37:16 +01:00
$name = 'chrome' ;
$version = $reg [ 2 ];
} elseif ( preg_match ( '/chrome/i' , $user_agent , $reg )) {
// we can have 'chrome (Mozilla...) chrome x.y' in one string
2021-02-23 22:03:23 +01:00
$name = 'chrome' ;
} elseif ( preg_match ( '/iceweasel/i' , $user_agent )) {
$name = 'iceweasel' ;
} elseif ( preg_match ( '/epiphany/i' , $user_agent )) {
$name = 'epiphany' ;
} elseif ( preg_match ( '/safari(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) {
2021-03-01 20:37:16 +01:00
$name = 'safari' ;
$version = $reg [ 2 ];
} elseif ( preg_match ( '/opera(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) {
// Safari is often present in string for mobile but its not.
$name = 'opera' ;
$version = $reg [ 2 ];
2021-02-23 22:03:23 +01:00
} elseif ( preg_match ( '/(MSIE\s([0-9]+\.[0-9]))|.*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i' , $user_agent , $reg )) {
2021-03-01 20:37:16 +01:00
$name = 'ie' ;
$version = end ( $reg );
} elseif ( preg_match ( '/(Windows NT\s([0-9]+\.[0-9])).*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i' , $user_agent , $reg )) {
// MS products at end
$name = 'ie' ;
$version = end ( $reg );
} elseif ( preg_match ( '/l(i|y)n(x|ks)(\(|\/|\s)*([\d\.]+)/i' , $user_agent , $reg )) {
// MS products at end
$name = 'lynxlinks' ;
$version = $reg [ 4 ];
2021-02-23 22:03:23 +01:00
}
2016-11-16 09:40:29 +01:00
2015-02-22 13:17:57 +01:00
if ( $tablet ) {
$layout = 'tablet' ;
} elseif ( $phone ) {
$layout = 'phone' ;
} else {
$layout = 'classic' ;
}
2014-07-27 20:56:26 +02:00
2015-02-22 12:35:51 +01:00
return array (
'browsername' => $name ,
'browserversion' => $version ,
'browseros' => $os ,
2015-02-22 13:17:57 +01:00
'layout' => $layout ,
2015-02-22 12:35:51 +01:00
'phone' => $phone ,
'tablet' => $tablet
);
2012-02-29 19:41:12 +01:00
}
2011-03-09 16:02:52 +01:00
/**
* Function called at end of web php process
2011-09-20 13:43:14 +02:00
*
2011-09-17 02:47:01 +02:00
* @ return void
2011-03-09 16:02:52 +01:00
*/
function dol_shutdown ()
{
2019-11-11 23:59:36 +01:00
global $conf , $user , $langs , $db ;
2021-03-01 20:37:16 +01:00
$disconnectdone = false ;
$depth = 0 ;
2021-02-23 22:03:23 +01:00
if ( is_object ( $db ) && ! empty ( $db -> connected )) {
2021-03-01 20:37:16 +01:00
$depth = $db -> transaction_opened ;
$disconnectdone = $db -> close ();
2021-02-23 22:03:23 +01:00
}
2019-11-11 23:59:36 +01:00
dol_syslog ( " --- End access to " . $_SERVER [ " PHP_SELF " ] . (( $disconnectdone && $depth ) ? ' (Warn: db disconnection forced, transaction depth was ' . $depth . ')' : '' ), (( $disconnectdone && $depth ) ? LOG_WARNING : LOG_INFO ));
2011-03-09 16:02:52 +01:00
}
2009-08-12 01:42:21 +02:00
2017-10-09 10:43:19 +02:00
/**
2021-05-11 21:31:43 +02:00
* Return true if we are in a context of submitting the parameter $paramname from a POST of a form .
2017-10-09 10:43:19 +02:00
*
* @ param string $paramname Name or parameter to test
* @ return boolean True if we have just submit a POST or GET request with the parameter provided ( even if param is empty )
*/
function GETPOSTISSET ( $paramname )
{
2020-11-30 14:47:07 +01:00
$isset = false ;
2020-01-31 19:46:03 +01:00
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
2021-02-23 22:03:23 +01:00
if ( constant ( 'DOL_URL_ROOT' )) {
$relativepathstring = preg_replace ( '/^' . preg_quote ( constant ( 'DOL_URL_ROOT' ), '/' ) . '/' , '' , $relativepathstring );
}
2020-01-31 19:46:03 +01:00
$relativepathstring = preg_replace ( '/^\//' , '' , $relativepathstring );
$relativepathstring = preg_replace ( '/^custom\//' , '' , $relativepathstring );
//var_dump($relativepathstring);
//var_dump($user->default_values);
// Code for search criteria persistence.
// Retrieve values if restore_lastsearch_values
2021-02-23 22:03:23 +01:00
if ( ! empty ( $_GET [ 'restore_lastsearch_values' ])) { // Use $_GET here and not GETPOST
if ( ! empty ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ])) { // If there is saved values
2020-01-31 19:46:03 +01:00
$tmp = json_decode ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ], true );
2021-02-23 22:03:23 +01:00
if ( is_array ( $tmp )) {
foreach ( $tmp as $key => $val ) {
if ( $key == $paramname ) { // We are on the requested parameter
2020-11-30 14:47:07 +01:00
$isset = true ;
2020-01-31 19:46:03 +01:00
break ;
}
}
}
}
2022-02-09 15:21:25 +01:00
// If there is saved contextpage, limit, page or mode
2021-02-23 22:03:23 +01:00
if ( $paramname == 'contextpage' && ! empty ( $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ])) {
2020-11-30 14:47:07 +01:00
$isset = true ;
2022-02-09 15:21:25 +01:00
} elseif ( $paramname == 'limit' && ! empty ( $_SESSION [ 'lastsearch_limit_' . $relativepathstring ])) {
$isset = true ;
2021-02-23 22:03:23 +01:00
} elseif ( $paramname == 'page' && ! empty ( $_SESSION [ 'lastsearch_page_' . $relativepathstring ])) {
2020-11-30 14:47:07 +01:00
$isset = true ;
2022-02-09 15:21:25 +01:00
} elseif ( $paramname == 'mode' && ! empty ( $_SESSION [ 'lastsearch_mode_' . $relativepathstring ])) {
2020-11-30 14:47:07 +01:00
$isset = true ;
2020-01-31 19:46:03 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2020-12-01 02:41:19 +01:00
$isset = ( isset ( $_POST [ $paramname ]) || isset ( $_GET [ $paramname ])); // We must keep $_POST and $_GET here
2020-01-31 19:46:03 +01:00
}
return $isset ;
2017-10-09 10:43:19 +02:00
}
2011-11-05 03:15:35 +01:00
2010-08-29 20:29:19 +02:00
/**
2017-05-16 23:38:23 +02:00
* Return value of a param into GET or POST supervariable .
2021-03-01 20:58:02 +01:00
* Use the property $user -> default_values [ path ][ 'createform' ] and / or $user -> default_values [ path ][ 'filters' ] and / or $user -> default_values [ path ][ 'sortorder' ]
2017-06-01 13:32:20 +02:00
* Note : The property $user -> default_values is loaded by main . php when loading the user .
2017-05-25 08:48:59 +02:00
*
2018-08-09 11:50:07 +02:00
* @ param string $paramname Name of parameter to found
* @ param string $check Type of check
* '' = no check ( deprecated )
2022-03-29 14:27:22 +02:00
* 'none' = no check ( only for param that should have very rich content like passwords )
2020-11-30 14:47:07 +01:00
* 'array' , 'array:restricthtml' or 'array:aZ09' to check it ' s an array
2018-08-09 11:50:07 +02:00
* 'int' = check it ' s numeric ( integer or float )
* 'intcomma' = check it 's integer+comma (' 1 , 2 , 3 , 4. .. ' )
2020-09-17 12:53:58 +02:00
* 'alpha' = Same than alphanohtml since v13
2021-03-24 19:53:31 +01:00
* 'alphawithlgt' = alpha with lgt
2020-09-17 12:53:58 +02:00
* 'alphanohtml' = check there is no html content and no " and no ../
2018-08-09 11:50:07 +02:00
* 'aZ' = check it ' s a - z only
* 'aZ09' = check it ' s simple alpha string ( recommended for keys )
* 'san_alpha' = Use filter_var with FILTER_SANITIZE_STRING ( do not use this for free text string )
2020-09-17 12:53:58 +02:00
* 'nohtml' = check there is no html content and no " and no ../
2020-02-16 19:33:58 +01:00
* 'restricthtml' = check html content is restricted to some tags only
2018-08-09 11:50:07 +02:00
* 'custom' = custom filter specify $filter and $options )
2019-04-08 14:55:31 +02:00
* @ param int $method Type of method ( 0 = get then post , 1 = only get , 2 = only post , 3 = post then get )
2017-05-10 13:46:02 +02:00
* @ param int $filter Filter to apply when $check is set to 'custom' . ( See http :// php . net / manual / en / filter . filters . php for détails )
2017-11-06 17:54:18 +01:00
* @ param mixed $options Options to pass to filter_var when $check is set to 'custom'
* @ param string $noreplace Force disable of replacement of __xxx__ strings .
2020-02-20 01:26:40 +01:00
* @ return string | array Value found ( string or array ), or '' if check fails
2010-08-29 20:29:19 +02:00
*/
2020-02-16 19:33:58 +01:00
function GETPOST ( $paramname , $check = 'alphanohtml' , $method = 0 , $filter = null , $options = null , $noreplace = 0 )
2010-08-29 20:29:19 +02:00
{
2019-11-11 23:59:36 +01:00
global $mysoc , $user , $conf ;
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $paramname )) {
return 'BadFirstParameterForGETPOST' ;
}
if ( empty ( $check )) {
2017-10-13 13:28:26 +02:00
dol_syslog ( " Deprecated use of GETPOST, called with 1st param = " . $paramname . " and 2nd param is '', when calling page " . $_SERVER [ " PHP_SELF " ], LOG_WARNING );
// Enable this line to know who call the GETPOST with '' $check parameter.
//var_dump(debug_backtrace()[0]);
}
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $method )) {
$out = isset ( $_GET [ $paramname ]) ? $_GET [ $paramname ] : ( isset ( $_POST [ $paramname ]) ? $_POST [ $paramname ] : '' );
} elseif ( $method == 1 ) {
$out = isset ( $_GET [ $paramname ]) ? $_GET [ $paramname ] : '' ;
} elseif ( $method == 2 ) {
$out = isset ( $_POST [ $paramname ]) ? $_POST [ $paramname ] : '' ;
} elseif ( $method == 3 ) {
$out = isset ( $_POST [ $paramname ]) ? $_POST [ $paramname ] : ( isset ( $_GET [ $paramname ]) ? $_GET [ $paramname ] : '' );
} else {
return 'BadThirdParameterForGETPOST' ;
}
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $method ) || $method == 3 || $method == 4 ) {
2017-10-13 13:28:26 +02:00
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
2021-02-23 22:03:23 +01:00
if ( constant ( 'DOL_URL_ROOT' )) {
$relativepathstring = preg_replace ( '/^' . preg_quote ( constant ( 'DOL_URL_ROOT' ), '/' ) . '/' , '' , $relativepathstring );
}
2017-10-13 13:28:26 +02:00
$relativepathstring = preg_replace ( '/^\//' , '' , $relativepathstring );
$relativepathstring = preg_replace ( '/^custom\//' , '' , $relativepathstring );
2017-09-11 00:02:52 +02:00
//var_dump($relativepathstring);
//var_dump($user->default_values);
2017-05-25 08:48:59 +02:00
2017-10-13 13:28:26 +02:00
// Code for search criteria persistence.
2018-06-23 11:55:04 +02:00
// Retrieve values if restore_lastsearch_values
2021-02-23 22:03:23 +01:00
if ( ! empty ( $_GET [ 'restore_lastsearch_values' ])) { // Use $_GET here and not GETPOST
if ( ! empty ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ])) { // If there is saved values
2019-11-11 23:59:36 +01:00
$tmp = json_decode ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ], true );
2021-02-23 22:03:23 +01:00
if ( is_array ( $tmp )) {
foreach ( $tmp as $key => $val ) {
if ( $key == $paramname ) { // We are on the requested parameter
2019-11-11 23:59:36 +01:00
$out = $val ;
2018-06-23 11:55:04 +02:00
break ;
}
2017-10-13 13:28:26 +02:00
}
}
}
2018-12-14 10:31:09 +01:00
// If there is saved contextpage, page or limit
2021-02-23 22:03:23 +01:00
if ( $paramname == 'contextpage' && ! empty ( $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ])) {
2018-12-14 10:31:09 +01:00
$out = $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ];
2021-02-23 22:03:23 +01:00
} elseif ( $paramname == 'limit' && ! empty ( $_SESSION [ 'lastsearch_limit_' . $relativepathstring ])) {
2018-12-14 10:31:09 +01:00
$out = $_SESSION [ 'lastsearch_limit_' . $relativepathstring ];
2022-02-09 15:21:25 +01:00
} elseif ( $paramname == 'page' && ! empty ( $_SESSION [ 'lastsearch_page_' . $relativepathstring ])) {
$out = $_SESSION [ 'lastsearch_page_' . $relativepathstring ];
} elseif ( $paramname == 'mode' && ! empty ( $_SESSION [ 'lastsearch_mode_' . $relativepathstring ])) {
$out = $_SESSION [ 'lastsearch_mode_' . $relativepathstring ];
2018-06-23 11:55:04 +02:00
}
2021-03-01 20:37:16 +01:00
} elseif ( ! isset ( $_GET [ 'sortfield' ])) {
// Else, retrieve default values if we are not doing a sort
// If we did a click on a field to sort, we do no apply default values. Same if option MAIN_ENABLE_DEFAULT_VALUES is not set
2021-02-23 22:03:23 +01:00
if ( ! empty ( $_GET [ 'action' ]) && $_GET [ 'action' ] == 'create' && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ])) {
2017-10-25 22:02:07 +02:00
// Search default value from $object->field
global $object ;
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && isset ( $object -> fields [ $paramname ][ 'default' ])) {
2017-10-25 22:02:07 +02:00
$out = $object -> fields [ $paramname ][ 'default' ];
2017-10-01 14:54:17 +02:00
}
2017-10-13 13:28:26 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_ENABLE_DEFAULT_VALUES )) {
if ( ! empty ( $_GET [ 'action' ]) && ( preg_match ( '/^create/' , $_GET [ 'action' ]) || preg_match ( '/^presend/' , $_GET [ 'action' ])) && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ])) {
2017-10-25 22:02:07 +02:00
// Now search in setup to overwrite default values
2021-02-23 22:03:23 +01:00
if ( ! empty ( $user -> default_values )) { // $user->default_values defined from menu 'Setup - Default values'
if ( isset ( $user -> default_values [ $relativepathstring ][ 'createform' ])) {
foreach ( $user -> default_values [ $relativepathstring ][ 'createform' ] as $defkey => $defval ) {
2017-10-13 13:28:26 +02:00
$qualified = 0 ;
2021-02-23 22:03:23 +01:00
if ( $defkey != '_noquery_' ) {
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpqueryarraytohave as $tmpquerytohave ) {
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) {
$foundintru = 1 ;
}
}
if ( ! $foundintru ) {
$qualified = 1 ;
2017-10-13 13:28:26 +02:00
}
//var_dump($defkey.'-'.$qualified);
2021-02-23 22:03:23 +01:00
} else {
$qualified = 1 ;
}
2017-10-13 13:28:26 +02:00
2021-02-23 22:03:23 +01:00
if ( $qualified ) {
if ( isset ( $user -> default_values [ $relativepathstring ][ 'createform' ][ $defkey ][ $paramname ])) {
2017-10-25 22:02:07 +02:00
$out = $user -> default_values [ $relativepathstring ][ 'createform' ][ $defkey ][ $paramname ];
break ;
}
}
}
}
}
2021-03-01 20:37:16 +01:00
} elseif ( ! empty ( $paramname ) && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ])) {
// Management of default search_filters and sort order
if ( ! empty ( $user -> default_values )) {
// $user->default_values defined from menu 'Setup - Default values'
2017-10-25 22:02:07 +02:00
//var_dump($user->default_values[$relativepathstring]);
2021-03-01 20:37:16 +01:00
if ( $paramname == 'sortfield' || $paramname == 'sortorder' ) {
// Sorted on which fields ? ASC or DESC ?
if ( isset ( $user -> default_values [ $relativepathstring ][ 'sortorder' ])) {
// Even if paramname is sortfield, data are stored into ['sortorder...']
2021-02-23 22:03:23 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'sortorder' ] as $defkey => $defval ) {
2017-10-25 22:02:07 +02:00
$qualified = 0 ;
2021-02-23 22:03:23 +01:00
if ( $defkey != '_noquery_' ) {
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpqueryarraytohave as $tmpquerytohave ) {
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) {
$foundintru = 1 ;
}
}
if ( ! $foundintru ) {
$qualified = 1 ;
2017-10-13 13:28:26 +02:00
}
2017-10-25 22:02:07 +02:00
//var_dump($defkey.'-'.$qualified);
2021-02-23 22:03:23 +01:00
} else {
$qualified = 1 ;
}
2017-10-25 22:02:07 +02:00
2021-02-23 22:03:23 +01:00
if ( $qualified ) {
2019-11-11 23:59:36 +01:00
$forbidden_chars_to_replace = array ( " " , " ' " , " / " , " \\ " , " : " , " * " , " ? " , " \" " , " < " , " > " , " | " , " [ " , " ] " , " ; " , " = " ); // we accept _, -, . and ,
2021-02-23 22:03:23 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'sortorder' ][ $defkey ] as $key => $val ) {
if ( $out ) {
$out .= ', ' ;
}
if ( $paramname == 'sortfield' ) {
2019-11-11 23:59:36 +01:00
$out .= dol_string_nospecial ( $key , '' , $forbidden_chars_to_replace );
2017-10-25 22:02:07 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $paramname == 'sortorder' ) {
2019-11-11 23:59:36 +01:00
$out .= dol_string_nospecial ( $val , '' , $forbidden_chars_to_replace );
2017-10-25 22:02:07 +02:00
}
2017-10-13 13:28:26 +02:00
}
2017-10-25 22:02:07 +02:00
//break; // No break for sortfield and sortorder so we can cumulate fields (is it realy usefull ?)
2017-10-13 13:28:26 +02:00
}
}
}
2021-02-23 22:03:23 +01:00
} elseif ( isset ( $user -> default_values [ $relativepathstring ][ 'filters' ])) {
foreach ( $user -> default_values [ $relativepathstring ][ 'filters' ] as $defkey => $defval ) { // $defkey is a querystring like 'a=b&c=d', $defval is key of user
2017-10-25 22:02:07 +02:00
$qualified = 0 ;
2021-02-23 22:03:23 +01:00
if ( $defkey != '_noquery_' ) {
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpqueryarraytohave as $tmpquerytohave ) {
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) {
$foundintru = 1 ;
}
}
if ( ! $foundintru ) {
$qualified = 1 ;
2017-10-25 22:02:07 +02:00
}
//var_dump($defkey.'-'.$qualified);
2021-02-23 22:03:23 +01:00
} else {
$qualified = 1 ;
}
2017-10-01 14:54:17 +02:00
2021-02-23 22:03:23 +01:00
if ( $qualified ) {
2020-11-30 14:47:07 +01:00
// We must keep $_POST and $_GET here
2021-02-23 22:03:23 +01:00
if ( isset ( $_POST [ 'sall' ]) || isset ( $_POST [ 'search_all' ]) || isset ( $_GET [ 'sall' ]) || isset ( $_GET [ 'search_all' ])) {
2017-10-25 22:02:07 +02:00
// We made a search from quick search menu, do we still use default filter ?
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> global -> MAIN_DISABLE_DEFAULT_FILTER_FOR_QUICK_SEARCH )) {
2019-11-11 23:59:36 +01:00
$forbidden_chars_to_replace = array ( " " , " ' " , " / " , " \\ " , " : " , " * " , " ? " , " \" " , " < " , " > " , " | " , " [ " , " ] " , " ; " , " = " ); // we accept _, -, . and ,
2017-10-25 22:02:07 +02:00
$out = dol_string_nospecial ( $user -> default_values [ $relativepathstring ][ 'filters' ][ $defkey ][ $paramname ], '' , $forbidden_chars_to_replace );
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$forbidden_chars_to_replace = array ( " " , " ' " , " / " , " \\ " , " : " , " * " , " ? " , " \" " , " < " , " > " , " | " , " [ " , " ] " , " ; " , " = " ); // we accept _, -, . and ,
2017-10-13 13:28:26 +02:00
$out = dol_string_nospecial ( $user -> default_values [ $relativepathstring ][ 'filters' ][ $defkey ][ $paramname ], '' , $forbidden_chars_to_replace );
}
2017-10-25 22:02:07 +02:00
break ;
2017-10-13 13:28:26 +02:00
}
2017-10-01 14:54:17 +02:00
}
2017-10-13 13:28:26 +02:00
}
}
}
}
}
2017-05-25 08:48:59 +02:00
}
2019-03-16 14:48:41 +01:00
// Substitution variables for GETPOST (used to get final url with variable parameters or final default value with variable parameters)
2017-12-09 15:35:01 +01:00
// Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOMPANY_COUNTRY_ID__, __USER_ID__, ...
2017-10-01 14:54:17 +02:00
// We do this only if var is a GET. If it is a POST, may be we want to post the text with vars as the setup text.
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $out ) && empty ( $_POST [ $paramname ]) && empty ( $noreplace )) {
2020-03-19 11:59:57 +01:00
$reg = array ();
2021-03-01 20:37:16 +01:00
$maxloop = 20 ;
$loopnb = 0 ; // Protection against infinite loop
2021-02-23 22:03:23 +01:00
while ( preg_match ( '/__([A-Z0-9]+_?[A-Z0-9]+)__/i' , $out , $reg ) && ( $loopnb < $maxloop )) { // Detect '__ABCDEF__' as key 'ABCDEF' and '__ABC_DEF__' as key 'ABC_DEF'. Detection is also correct when 2 vars are side by side.
2021-03-01 20:37:16 +01:00
$loopnb ++ ;
$newout = '' ;
2019-10-20 11:17:54 +02:00
2020-05-21 16:00:12 +02:00
if ( $reg [ 1 ] == 'DAY' ) {
$tmp = dol_getdate ( dol_now (), true );
$newout = $tmp [ 'mday' ];
} elseif ( $reg [ 1 ] == 'MONTH' ) {
$tmp = dol_getdate ( dol_now (), true );
$newout = $tmp [ 'mon' ];
} elseif ( $reg [ 1 ] == 'YEAR' ) {
$tmp = dol_getdate ( dol_now (), true );
$newout = $tmp [ 'year' ];
} elseif ( $reg [ 1 ] == 'PREVIOUS_DAY' ) {
$tmp = dol_getdate ( dol_now (), true );
$tmp2 = dol_get_prev_day ( $tmp [ 'mday' ], $tmp [ 'mon' ], $tmp [ 'year' ]);
$newout = $tmp2 [ 'day' ];
} elseif ( $reg [ 1 ] == 'PREVIOUS_MONTH' ) {
$tmp = dol_getdate ( dol_now (), true );
$tmp2 = dol_get_prev_month ( $tmp [ 'mon' ], $tmp [ 'year' ]);
$newout = $tmp2 [ 'month' ];
} elseif ( $reg [ 1 ] == 'PREVIOUS_YEAR' ) {
$tmp = dol_getdate ( dol_now (), true );
$newout = ( $tmp [ 'year' ] - 1 );
} elseif ( $reg [ 1 ] == 'NEXT_DAY' ) {
$tmp = dol_getdate ( dol_now (), true );
$tmp2 = dol_get_next_day ( $tmp [ 'mday' ], $tmp [ 'mon' ], $tmp [ 'year' ]);
$newout = $tmp2 [ 'day' ];
} elseif ( $reg [ 1 ] == 'NEXT_MONTH' ) {
$tmp = dol_getdate ( dol_now (), true );
$tmp2 = dol_get_next_month ( $tmp [ 'mon' ], $tmp [ 'year' ]);
$newout = $tmp2 [ 'month' ];
} elseif ( $reg [ 1 ] == 'NEXT_YEAR' ) {
$tmp = dol_getdate ( dol_now (), true );
$newout = ( $tmp [ 'year' ] + 1 );
} elseif ( $reg [ 1 ] == 'MYCOMPANY_COUNTRY_ID' || $reg [ 1 ] == 'MYCOUNTRY_ID' || $reg [ 1 ] == 'MYCOUNTRYID' ) {
2019-10-20 11:17:54 +02:00
$newout = $mysoc -> country_id ;
2020-05-21 16:00:12 +02:00
} elseif ( $reg [ 1 ] == 'USER_ID' || $reg [ 1 ] == 'USERID' ) {
2019-10-20 11:17:54 +02:00
$newout = $user -> id ;
2020-05-21 16:00:12 +02:00
} elseif ( $reg [ 1 ] == 'USER_SUPERVISOR_ID' || $reg [ 1 ] == 'SUPERVISOR_ID' || $reg [ 1 ] == 'SUPERVISORID' ) {
2019-10-20 11:17:54 +02:00
$newout = $user -> fk_user ;
2020-05-21 16:00:12 +02:00
} elseif ( $reg [ 1 ] == 'ENTITY_ID' || $reg [ 1 ] == 'ENTITYID' ) {
2019-10-20 11:17:54 +02:00
$newout = $conf -> entity ;
2020-05-21 16:00:12 +02:00
} else {
$newout = '' ; // Key not found, we replace with empty string
}
2019-10-20 11:17:54 +02:00
//var_dump('__'.$reg[1].'__ -> '.$newout);
$out = preg_replace ( '/__' . preg_quote ( $reg [ 1 ], '/' ) . '__/' , $newout , $out );
2017-10-13 13:28:26 +02:00
}
}
2020-09-19 04:14:49 +02:00
// Check rule
2022-01-19 15:20:10 +01:00
if ( preg_match ( '/^array/' , $check )) { // If 'array' or 'array:restricthtml' or 'array:aZ09' or 'array:intcomma'
2020-09-19 04:14:49 +02:00
if ( ! is_array ( $out ) || empty ( $out )) {
$out = array ();
} else {
2020-09-29 21:28:07 +02:00
$tmparray = explode ( ':' , $check );
if ( ! empty ( $tmparray [ 1 ])) {
$tmpcheck = $tmparray [ 1 ];
} else {
$tmpcheck = 'alphanohtml' ;
}
2020-09-19 23:30:29 +02:00
foreach ( $out as $outkey => $outval ) {
2020-09-29 21:28:07 +02:00
$out [ $outkey ] = checkVal ( $outval , $tmpcheck , $filter , $options );
2020-09-19 04:14:49 +02:00
}
}
2021-02-23 22:03:23 +01:00
} else {
2020-09-19 04:14:49 +02:00
$out = checkVal ( $out , $check , $filter , $options );
}
2021-05-17 23:47:16 +02:00
// Sanitizing for special parameters.
2022-02-21 21:45:28 +01:00
// Note: There is no reason to allow the backtopage, backtolist or backtourl parameter to contains an external URL. Only relative URLs are allowed.
2021-03-28 21:39:18 +02:00
if ( $paramname == 'backtopage' || $paramname == 'backtolist' || $paramname == 'backtourl' ) {
2022-02-21 21:45:28 +01:00
$out = str_replace ( '\\' , '/' , $out ); // Can be before the loop because only 1 char is replaced. No risk to get it after other replacements.
$out = str_replace ( array ( ':' , ';' , '@' , " \t " , ' ' ), '' , $out ); // Can be before the loop because only 1 char is replaced. No risk to retreive it after other replacements.
2021-03-14 18:57:18 +01:00
do {
$oldstringtoclean = $out ;
2021-03-14 20:31:53 +01:00
$out = str_ireplace ( array ( 'javascript' , 'vbscript' , '&colon' , '&#' ), '' , $out );
2022-02-21 21:45:28 +01:00
$out = preg_replace ( array ( '/^[^\?]*%/' ), '' , $out ); // We remove any % chars before the ?. Example in url: '/product/stock/card.php?action=create&backtopage=%2Fdolibarr_dev%2Fhtdocs%2Fpro%25duct%2Fcard.php%3Fid%3Dabc'
$out = preg_replace ( array ( '/^[a-z]*\/\s*\/+/i' ), '' , $out ); // We remove schema*// to remove external URL
2021-03-14 18:57:18 +01:00
} while ( $oldstringtoclean != $out );
2020-09-19 04:14:49 +02:00
}
// Code for search criteria persistence.
// Save data into session if key start with 'search_' or is 'smonth', 'syear', 'month', 'year'
2021-02-23 22:03:23 +01:00
if ( empty ( $method ) || $method == 3 || $method == 4 ) {
if ( preg_match ( '/^search_/' , $paramname ) || in_array ( $paramname , array ( 'sortorder' , 'sortfield' ))) {
2020-09-19 04:14:49 +02:00
//var_dump($paramname.' - '.$out.' '.$user->default_values[$relativepathstring]['filters'][$paramname]);
// We save search key only if $out not empty that means:
// - posted value not empty, or
// - if posted value is empty and a default value exists that is not empty (it means we did a filter to an empty value when default was not).
2021-02-23 22:03:23 +01:00
if ( $out != '' ) { // $out = '0' or 'abc', it is a search criteria to keep
2020-09-19 04:14:49 +02:00
$user -> lastsearch_values_tmp [ $relativepathstring ][ $paramname ] = $out ;
}
}
}
return $out ;
}
2020-11-30 15:44:29 +01:00
/**
* Return value of a param into GET or POST supervariable .
* Use the property $user -> default_values [ path ][ 'creatform' ] and / or $user -> default_values [ path ][ 'filters' ] and / or $user -> default_values [ path ][ 'sortorder' ]
* Note : The property $user -> default_values is loaded by main . php when loading the user .
*
* @ param string $paramname Name of parameter to found
* @ param int $method Type of method ( 0 = get then post , 1 = only get , 2 = only post , 3 = post then get )
* @ return int Value found ( int )
*/
2021-09-02 17:24:34 +02:00
function GETPOSTINT ( $paramname , $method = 0 )
2020-11-30 15:44:29 +01:00
{
2021-09-02 17:24:34 +02:00
return ( int ) GETPOST ( $paramname , 'int' , $method , null , null , 0 );
2020-11-30 15:44:29 +01:00
}
2020-09-19 04:14:49 +02:00
/**
2021-05-17 23:47:16 +02:00
* Return a value after checking on a rule . A sanitization may also have been done .
2020-09-19 04:14:49 +02:00
*
2022-02-22 23:44:56 +01:00
* @ param string | array $out Value to check / clear .
* @ param string $check Type of check / sanitizing
* @ param int $filter Filter to apply when $check is set to 'custom' . ( See http :// php . net / manual / en / filter . filters . php for détails )
* @ param mixed $options Options to pass to filter_var when $check is set to 'custom'
* @ return string | array Value sanitized ( string or array ) . It may be '' if format check fails .
2020-09-19 04:14:49 +02:00
*/
function checkVal ( $out = '' , $check = 'alphanohtml' , $filter = null , $options = null )
{
2021-03-17 21:36:20 +01:00
global $conf ;
2017-10-13 13:28:26 +02:00
// Check is done after replacement
2021-02-23 22:03:23 +01:00
switch ( $check ) {
2017-10-13 13:28:26 +02:00
case 'none' :
break ;
case 'int' : // Check param is a numeric value (integer but also float or hexadecimal)
2021-02-23 22:03:23 +01:00
if ( ! is_numeric ( $out )) {
$out = '' ;
}
2017-10-13 13:28:26 +02:00
break ;
case 'intcomma' :
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[^0-9,-]+/i' , $out )) {
$out = '' ;
}
2017-10-13 13:28:26 +02:00
break ;
case 'san_alpha' :
2019-11-11 23:59:36 +01:00
$out = filter_var ( $out , FILTER_SANITIZE_STRING );
2017-10-13 13:28:26 +02:00
break ;
2020-10-22 20:01:59 +02:00
case 'email' :
$out = filter_var ( $out , FILTER_SANITIZE_EMAIL );
break ;
2017-10-13 13:28:26 +02:00
case 'aZ' :
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $out )) {
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[^a-z]+/i' , $out )) {
$out = '' ;
}
2017-11-02 09:58:22 +01:00
}
2017-10-13 13:28:26 +02:00
break ;
case 'aZ09' :
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $out )) {
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[^a-z0-9_\-\.]+/i' , $out )) {
$out = '' ;
}
2017-11-02 09:58:22 +01:00
}
2017-10-13 13:28:26 +02:00
break ;
2018-04-25 15:47:42 +02:00
case 'aZ09comma' : // great to sanitize sortfield or sortorder params that can be t.abc,t.def_gh
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $out )) {
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[^a-z0-9_\-\.,]+/i' , $out )) {
$out = '' ;
}
2018-04-25 15:47:42 +02:00
}
break ;
2021-01-15 19:23:56 +01:00
case 'nohtml' : // No html
2019-11-11 23:59:36 +01:00
$out = dol_string_nohtmltag ( $out , 0 );
2017-10-01 14:54:17 +02:00
break ;
2021-01-15 19:23:56 +01:00
case 'alpha' : // No html and no ../ and "
2020-02-19 11:33:45 +01:00
case 'alphanohtml' : // Recommended for most scalar parameters and search parameters
2020-11-04 09:45:02 +01:00
if ( ! is_array ( $out )) {
2021-03-24 18:57:23 +01:00
$out = trim ( $out );
do {
$oldstringtoclean = $out ;
2021-03-29 14:11:51 +02:00
// Remove html tags
$out = dol_string_nohtmltag ( $out , 0 );
// Remove also other dangerous string sequences
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
2021-08-23 15:47:18 +02:00
// '../' or '..\' is dangerous because it allows dir transversals
2021-03-24 23:14:22 +01:00
// Note &, '&', '&'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
2021-08-23 15:47:18 +02:00
$out = str_ireplace ( array ( '&' , '&' , '&' , '"' , '"' , '"' , '"' , '"' , '/' , '/' , '\' , '\' , '/' , '../' , '..\\' ), '' , $out );
2021-03-24 18:57:23 +01:00
} while ( $oldstringtoclean != $out );
2020-11-04 09:45:02 +01:00
// keep lines feed
2017-11-02 09:58:22 +01:00
}
2017-10-01 14:54:17 +02:00
break ;
2022-01-26 13:00:48 +01:00
case 'alphawithlgt' : // No " and no ../ but we keep balanced < > tags with no special chars inside. Can be used for email string like "Name <email>". Less secured than 'alphanohtml'
2021-01-12 21:06:02 +01:00
if ( ! is_array ( $out )) {
2021-03-24 18:57:23 +01:00
$out = trim ( $out );
do {
$oldstringtoclean = $out ;
2021-03-29 14:11:51 +02:00
// Remove html tags
$out = dol_html_entity_decode ( $out , ENT_COMPAT | ENT_HTML5 , 'UTF-8' );
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
2021-08-23 15:47:18 +02:00
// '../' or '..\' is dangerous because it allows dir transversals
2021-03-24 23:14:22 +01:00
// Note &, '&', '&'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
2021-08-23 15:47:18 +02:00
$out = str_ireplace ( array ( '&' , '&' , '&' , '"' , '"' , '"' , '"' , '"' , '/' , '/' , '\' , '\' , '/' , '../' , '..\\' ), '' , $out );
2021-03-24 18:57:23 +01:00
} while ( $oldstringtoclean != $out );
2021-01-12 21:06:02 +01:00
}
break ;
2019-10-04 14:04:31 +02:00
case 'restricthtml' : // Recommended for most html textarea
2021-07-06 01:44:05 +02:00
case 'restricthtmlallowunvalid' :
2021-03-29 14:50:44 +02:00
do {
$oldstringtoclean = $out ;
2021-05-17 23:47:16 +02:00
2021-07-07 01:45:31 +02:00
if ( ! empty ( $out ) && ! empty ( $conf -> global -> MAIN_RESTRICTHTML_ONLY_VALID_HTML ) && $check != 'restricthtmlallowunvalid' ) {
2021-07-06 00:47:43 +02:00
try {
2021-07-06 01:44:05 +02:00
$dom = new DOMDocument ;
2021-07-08 13:59:04 +02:00
// Add a trick to solve pb with text without parent tag
// like '<h1>Foo</h1><p>bar</p>' that ends up with '<h1>Foo<p>bar</p></h1>'
// like 'abc' that ends up with '<p>abc</p>'
$out = '<div class="tricktoremove">' . $out . '</div>' ;
2021-07-06 00:47:43 +02:00
$dom -> loadHTML ( $out , LIBXML_ERR_NONE | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NONET | LIBXML_NOWARNING | LIBXML_NOXMLDECL );
2021-07-08 13:59:04 +02:00
$out = trim ( $dom -> saveHTML ());
// Remove the trick added to solve pb with text without parent tag
$out = preg_replace ( '/^<div class="tricktoremove">/' , '' , $out );
$out = preg_replace ( '/<\/div>$/' , '' , $out );
2021-07-06 02:11:28 +02:00
} catch ( Exception $e ) {
2021-07-06 01:44:05 +02:00
//print $e->getMessage();
2021-07-06 00:47:43 +02:00
return 'InvalidHTMLString' ;
}
}
2021-08-21 12:19:50 +02:00
// Ckeditor use the numeric entitic for apostrophe so we force it to text entity (all other special chars are
// encoded using text entities) so we can then exclude all numeric entities.
2021-07-05 16:08:47 +02:00
$out = preg_replace ( '/'/i' , ''' , $out );
2021-08-21 12:19:50 +02:00
// We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step (preg_replace).
2021-06-29 18:17:27 +02:00
// No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are
// using a non coventionnel way to be encoded, to not have them sanitized just after)
2022-01-17 09:12:09 +01:00
//$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $out);
$out = preg_replace_callback ( '/&#(x?[0-9][0-9a-f]+;?)/i' , function ( $m ) {
return realCharForNumericEntities ( $m ); }, $out );
2022-01-14 17:46:06 +01:00
2021-06-29 18:17:27 +02:00
2021-07-05 16:08:47 +02:00
// Now we remove all remaining HTML entities starting with a number. We don't want such entities.
2021-05-17 23:47:16 +02:00
$out = preg_replace ( '/&#x?[0-9]+/i' , '' , $out ); // For example if we have javascript with an entities without the ; to hide the 'a' of 'javascript'.
2021-03-29 14:50:44 +02:00
$out = dol_string_onlythesehtmltags ( $out , 0 , 1 , 1 );
2021-03-17 21:36:20 +01:00
2021-11-28 12:01:42 +01:00
// We should also exclude non expected HTML attributes and clean content of some attributes.
2021-03-29 14:50:44 +02:00
if ( ! empty ( $conf -> global -> MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES )) {
2021-07-06 00:47:43 +02:00
// Warning, the function may add a LF so we are forced to trim to compare with old $out without having always a difference and an infinit loop.
2021-12-17 12:01:25 +01:00
$out = dol_string_onlythesehtmlattributes ( $out );
2021-03-29 14:50:44 +02:00
}
2021-08-21 12:19:50 +02:00
// Restore entity ' into ' (restricthtml is for html content so we can use html entity)
$out = preg_replace ( '/'/i' , " ' " , $out );
2021-03-29 14:50:44 +02:00
} while ( $oldstringtoclean != $out );
2019-10-04 14:04:31 +02:00
break ;
2017-10-01 14:54:17 +02:00
case 'custom' :
2021-02-23 22:03:23 +01:00
if ( empty ( $filter )) {
return 'BadFourthParameterForGETPOST' ;
}
2019-11-11 23:59:36 +01:00
$out = filter_var ( $out , $filter , $options );
2017-10-13 13:28:26 +02:00
break ;
}
2011-11-27 02:23:55 +01:00
2011-11-25 16:47:57 +01:00
return $out ;
2010-08-29 20:29:19 +02:00
}
2010-12-27 20:13:06 +01:00
2021-02-23 22:03:23 +01:00
if ( ! function_exists ( 'dol_getprefix' )) {
2020-09-07 10:18:17 +02:00
/**
* Return a prefix to use for this Dolibarr instance , for session / cookie names or email id .
* The prefix is unique for instance and avoid conflict between multi - instances , even when having two instances with same root dir
* or two instances in same virtual servers .
2022-02-21 12:21:43 +01:00
* This function must not use dol_hash ( that is used for password hash ) and need to have all context $conf loaded .
2020-09-07 10:18:17 +02:00
*
* @ param string $mode '' ( prefix for session name ) or 'email' ( prefix for email id )
* @ return string A calculated prefix
*/
function dol_getprefix ( $mode = '' )
{
2022-02-21 12:21:43 +01:00
// If prefix is for email (we need to have $conf already loaded for this case)
2021-02-23 22:03:23 +01:00
if ( $mode == 'email' ) {
2020-12-05 13:26:58 +01:00
global $conf ;
2022-02-21 12:21:43 +01:00
if ( ! empty ( $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID )) { // If MAIL_PREFIX_FOR_EMAIL_ID is set
2021-02-23 22:03:23 +01:00
if ( $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME' ) {
return $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID ;
2022-02-21 12:21:43 +01:00
} elseif ( isset ( $_SERVER [ " SERVER_NAME " ])) { // If MAIL_PREFIX_FOR_EMAIL_ID is set to 'SERVER_NAME'
2021-02-23 22:03:23 +01:00
return $_SERVER [ " SERVER_NAME " ];
}
2018-11-16 16:43:13 +01:00
}
2019-04-07 15:44:17 +02:00
2022-02-21 12:21:43 +01:00
// The recommended value if MAIL_PREFIX_FOR_EMAIL_ID is not defined (may be not defined for old versions)
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> file -> instance_unique_id )) {
2022-02-21 12:21:43 +01:00
return sha1 ( 'dolibarr' . $conf -> file -> instance_unique_id );
2021-02-23 22:03:23 +01:00
}
2019-04-07 15:44:17 +02:00
2022-02-21 12:21:43 +01:00
// For backward compatibility when instance_unique_id is not set
return sha1 ( DOL_DOCUMENT_ROOT . DOL_URL_ROOT );
2017-12-19 00:15:22 +01:00
}
2020-12-05 13:26:58 +01:00
// If prefix is for session (no need to have $conf loaded)
global $dolibarr_main_instance_unique_id , $dolibarr_main_cookie_cryptkey ; // This is loaded by filefunc.inc.php
$tmp_instance_unique_id = empty ( $dolibarr_main_instance_unique_id ) ? ( empty ( $dolibarr_main_cookie_cryptkey ) ? '' : $dolibarr_main_cookie_cryptkey ) : $dolibarr_main_instance_unique_id ; // Unique id of instance
2019-04-07 15:44:17 +02:00
// The recommended value (may be not defined for old versions)
2020-12-05 13:26:58 +01:00
if ( ! empty ( $tmp_instance_unique_id )) {
2022-02-21 12:21:43 +01:00
return sha1 ( 'dolibarr' . $tmp_instance_unique_id );
2020-12-05 13:26:58 +01:00
}
2019-04-07 15:44:17 +02:00
2022-02-21 12:21:43 +01:00
// For backward compatibility when instance_unique_id is not set
2020-12-05 13:26:58 +01:00
if ( isset ( $_SERVER [ " SERVER_NAME " ]) && isset ( $_SERVER [ " DOCUMENT_ROOT " ])) {
2022-02-21 12:21:43 +01:00
return sha1 ( $_SERVER [ " SERVER_NAME " ] . $_SERVER [ " DOCUMENT_ROOT " ] . DOL_DOCUMENT_ROOT . DOL_URL_ROOT );
} else {
return sha1 ( DOL_DOCUMENT_ROOT . DOL_URL_ROOT );
2017-12-19 00:15:22 +01:00
}
2014-08-08 13:09:06 +02:00
}
2010-12-27 20:13:06 +01:00
}
2010-12-19 03:42:53 +01:00
/**
* Make an include_once using default root and alternate root if it fails .
2010-12-29 11:39:41 +01:00
* To link to a core file , use include ( DOL_DOCUMENT_ROOT . '/pathtofile' )
2012-08-23 02:04:35 +02:00
* To link to a module file from a module file , use include './mymodulefile' ;
2013-05-28 17:54:55 +02:00
* To link to a module file from a core file , then this function can be used ( call by hook / trigger / speciales pages )
2011-08-17 18:18:12 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param string $relpath Relative path to file ( Ie : mydir / myfile , ../ myfile , ... )
2016-01-31 14:58:04 +01:00
* @ param string $classname Class name ( deprecated )
2015-09-01 14:31:32 +02:00
* @ return bool True if load is a success , False if it fails
2010-12-19 03:42:53 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_include_once ( $relpath , $classname = '' )
2010-12-19 03:42:53 +01:00
{
2020-10-23 20:08:35 +02:00
global $conf , $langs , $user , $mysoc ; // Do not remove this. They must be defined for files we include. Other globals var must be retrieved with $GLOBALS['var']
2014-07-27 20:31:11 +02:00
2014-07-17 21:44:59 +02:00
$fullpath = dol_buildpath ( $relpath );
2014-07-15 17:18:41 +02:00
2014-07-17 21:44:59 +02:00
if ( ! file_exists ( $fullpath )) {
2019-02-12 16:34:52 +01:00
dol_syslog ( 'functions::dol_include_once Tried to load unexisting file: ' . $relpath , LOG_WARNING );
2014-07-15 17:18:41 +02:00
return false ;
}
2012-12-02 12:59:06 +01:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $classname ) && ! class_exists ( $classname )) {
2014-07-17 21:44:59 +02:00
return include $fullpath ;
2012-08-03 23:29:08 +02:00
} else {
2014-07-17 21:44:59 +02:00
return include_once $fullpath ;
2012-08-03 23:29:08 +02:00
}
2010-12-19 03:42:53 +01:00
}
2010-12-19 12:05:07 +01:00
/**
2018-11-05 15:31:41 +01:00
* Return path of url or filesystem . Can check into alternate dir or alternate dir + main dir depending on value of $returnemptyifnotfound .
2011-08-17 18:18:12 +02:00
*
2017-09-23 01:24:31 +02:00
* @ param string $path Relative path to file ( if mode = 0 ) or relative url ( if mode = 1 ) . Ie : mydir / myfile , ../ myfile
* @ param int $type 0 = Used for a Filesystem path , 1 = Used for an URL path ( output relative ), 2 = Used for an URL path ( output full path using same host that current url ), 3 = Used for an URL path ( output full path using host defined into $dolibarr_main_url_root of conf file )
2017-11-05 18:15:59 +01:00
* @ param int $returnemptyifnotfound 0 : If $type == 0 and if file was not found into alternate dir , return default path into main dir ( no test on it )
* 1 : If $type == 0 and if file was not found into alternate dir , return empty string
* 2 : If $type == 0 and if file was not found into alternate dir , test into main dir , return default path if found , empty string if not found
2019-05-29 12:21:51 +02:00
* @ return string Full filesystem path ( if path = 0 ) or '' if file not found , Full url path ( if mode = 1 )
2010-12-19 12:05:07 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_buildpath ( $path , $type = 0 , $returnemptyifnotfound = 0 )
2010-12-19 12:05:07 +01:00
{
2013-07-07 03:26:51 +02:00
global $conf ;
2019-11-11 23:59:36 +01:00
$path = preg_replace ( '/^\//' , '' , $path );
2013-07-07 03:26:51 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $type )) { // For a filesystem path
2019-11-11 23:59:36 +01:00
$res = DOL_DOCUMENT_ROOT . '/' . $path ; // Standard default path
2021-02-23 22:03:23 +01:00
if ( is_array ( $conf -> file -> dol_document_root )) {
foreach ( $conf -> file -> dol_document_root as $key => $dirroot ) { // ex: array("main"=>"/home/main/htdocs", "alt0"=>"/home/dirmod/htdocs", ...)
if ( $key == 'main' ) {
2019-05-15 18:59:46 +02:00
continue ;
}
2021-02-23 22:03:23 +01:00
if ( file_exists ( $dirroot . '/' . $path )) {
2019-11-11 23:59:36 +01:00
$res = $dirroot . '/' . $path ;
2019-05-15 18:59:46 +02:00
return $res ;
}
2013-07-07 13:17:48 +02:00
}
}
2021-03-01 20:37:16 +01:00
if ( $returnemptyifnotfound ) {
// Not found into alternate dir
2021-02-23 22:03:23 +01:00
if ( $returnemptyifnotfound == 1 || ! file_exists ( $res )) {
return '' ;
}
2017-09-23 01:24:31 +02:00
}
2021-03-01 20:37:16 +01:00
} else {
// For an url path
2012-08-03 23:29:08 +02:00
// We try to get local path of file on filesystem from url
// Note that trying to know if a file on disk exist by forging path on disk from url
// works only for some web server and some setup. This is bugged when
// using proxy, rewriting, virtual path, etc...
2019-11-11 23:59:36 +01:00
$res = '' ;
2021-02-23 22:03:23 +01:00
if ( $type == 1 ) {
$res = DOL_URL_ROOT . '/' . $path ; // Standard value
}
if ( $type == 2 ) {
$res = DOL_MAIN_URL_ROOT . '/' . $path ; // Standard value
}
if ( $type == 3 ) {
$res = DOL_URL_ROOT . '/' . $path ;
}
2016-11-16 09:40:29 +01:00
2021-02-23 22:03:23 +01:00
foreach ( $conf -> file -> dol_document_root as $key => $dirroot ) { // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
if ( $key == 'main' ) {
if ( $type == 3 ) {
2017-10-13 13:28:26 +02:00
global $dolibarr_main_url_root ;
// Define $urlwithroot
2019-11-11 23:59:36 +01:00
$urlwithouturlroot = preg_replace ( '/' . preg_quote ( DOL_URL_ROOT , '/' ) . '$/i' , '' , trim ( $dolibarr_main_url_root ));
$urlwithroot = $urlwithouturlroot . DOL_URL_ROOT ; // This is to use external domain name found into config file
2017-10-13 13:28:26 +02:00
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2019-11-11 23:59:36 +01:00
$res = ( preg_match ( '/^http/i' , $conf -> file -> dol_url_root [ $key ]) ? '' : $urlwithroot ) . '/' . $path ; // Test on start with http is for old conf syntax
2017-10-13 13:28:26 +02:00
}
continue ;
2016-10-31 10:37:58 +01:00
}
2019-11-11 23:59:36 +01:00
preg_match ( '/^([^\?]+(\.css\.php|\.css|\.js\.php|\.js|\.png|\.jpg|\.php)?)/i' , $path , $regs ); // Take part before '?'
2021-02-23 22:03:23 +01:00
if ( ! empty ( $regs [ 1 ])) {
2013-07-07 03:26:51 +02:00
//print $key.'-'.$dirroot.'/'.$path.'-'.$conf->file->dol_url_root[$type].'<br>'."\n";
2021-02-23 22:03:23 +01:00
if ( file_exists ( $dirroot . '/' . $regs [ 1 ])) {
if ( $type == 1 ) {
2019-11-11 23:59:36 +01:00
$res = ( preg_match ( '/^http/i' , $conf -> file -> dol_url_root [ $key ]) ? '' : DOL_URL_ROOT ) . $conf -> file -> dol_url_root [ $key ] . '/' . $path ;
2013-07-07 23:37:56 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $type == 2 ) {
2019-11-11 23:59:36 +01:00
$res = ( preg_match ( '/^http/i' , $conf -> file -> dol_url_root [ $key ]) ? '' : DOL_MAIN_URL_ROOT ) . $conf -> file -> dol_url_root [ $key ] . '/' . $path ;
2016-08-02 14:33:46 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $type == 3 ) {
2017-10-13 13:28:26 +02:00
global $dolibarr_main_url_root ;
2016-11-16 09:40:29 +01:00
2017-10-13 13:28:26 +02:00
// Define $urlwithroot
2019-11-11 23:59:36 +01:00
$urlwithouturlroot = preg_replace ( '/' . preg_quote ( DOL_URL_ROOT , '/' ) . '$/i' , '' , trim ( $dolibarr_main_url_root ));
$urlwithroot = $urlwithouturlroot . DOL_URL_ROOT ; // This is to use external domain name found into config file
2017-10-13 13:28:26 +02:00
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2016-11-16 09:40:29 +01:00
2019-11-11 23:59:36 +01:00
$res = ( preg_match ( '/^http/i' , $conf -> file -> dol_url_root [ $key ]) ? '' : $urlwithroot ) . $conf -> file -> dol_url_root [ $key ] . '/' . $path ; // Test on start with http is for old conf syntax
2013-07-07 23:37:56 +02:00
}
2013-07-07 13:17:48 +02:00
break ;
2012-08-03 23:29:08 +02:00
}
2013-07-07 13:17:48 +02:00
}
2012-08-03 23:29:08 +02:00
}
}
return $res ;
2010-12-19 12:05:07 +01:00
}
2009-08-12 01:42:21 +02:00
/**
2017-05-22 01:19:16 +02:00
* Create a clone of instance of object ( new instance with same value for properties )
2019-04-12 12:12:08 +02:00
* With native = 0 : Property that are reference are also new object ( full isolation clone ) . This means $this -> db of new object is not valid .
* With native = 1 : Use PHP clone . Property that are reference are same pointer . This means $this -> db of new object is still valid but point to same this -> db than original object .
2011-08-17 18:18:12 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param object $object Object to clone
2020-02-17 11:51:49 +01:00
* @ param int $native 0 = Full isolation method , 1 = Native PHP method
2019-04-12 12:12:08 +02:00
* @ return object Clone object
2015-04-23 23:21:06 +02:00
* @ see https :// php . net / manual / language . oop5 . cloning . php
2009-08-12 01:42:21 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_clone ( $object , $native = 0 )
2009-08-12 01:42:21 +02:00
{
2021-02-23 22:03:23 +01:00
if ( empty ( $native )) {
2021-06-30 17:14:19 +02:00
$myclone = unserialize ( serialize ( $object )); // serialize then unserialize is hack to be sure to have a new object for all fields
2020-05-21 15:05:19 +02:00
} else {
2020-10-22 21:31:34 +02:00
$myclone = clone $object ; // PHP clone is a shallow copy only, not a real clone, so properties of references will keep the reference (refering to the same target/variable)
2017-07-23 20:27:30 +02:00
}
2017-05-25 08:48:59 +02:00
2012-08-03 23:29:08 +02:00
return $myclone ;
2009-08-12 01:42:21 +02:00
}
2009-09-15 13:24:00 +02:00
/**
2011-03-09 16:02:52 +01:00
* Optimize a size for some browsers ( phone , smarphone , ... )
2011-08-17 18:18:12 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param int $size Size we want
* @ param string $type Type of optimizing :
2013-04-03 15:20:56 +02:00
* '' = function used to define a size for truncation
* 'width' = function is used to define a width
2011-09-17 02:47:01 +02:00
* @ return int New size after optimizing
2009-09-15 13:24:00 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_size ( $size , $type = '' )
2009-09-15 13:24:00 +02:00
{
2012-08-03 23:29:08 +02:00
global $conf ;
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> dol_optimize_smallscreen )) {
return $size ;
}
if ( $type == 'width' && $size > 250 ) {
return 250 ;
} else {
return 10 ;
}
2009-09-15 13:24:00 +02:00
}
2009-08-12 01:42:21 +02:00
2008-08-06 16:50:06 +02:00
/**
2021-07-05 22:26:38 +02:00
* Clean a string to use it as a file name .
2021-10-17 12:21:22 +02:00
* Replace also '--' and ' -' strings , they are used for parameters separation ( Note : ' - ' is allowed ) .
2011-08-17 18:18:12 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param string $str String to clean
2021-07-05 22:26:38 +02:00
* @ param string $newstr String to replace bad chars with .
2016-09-08 11:05:47 +02:00
* @ param int $unaccent 1 = Remove also accent ( default ), 0 do not remove them
2011-09-17 02:47:01 +02:00
* @ return string String cleaned ( a - zA - Z_ )
*
2019-03-11 01:01:15 +01:00
* @ see dol_string_nospecial (), dol_string_unaccent (), dol_sanitizePathName ()
2008-10-25 23:35:27 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_sanitizeFileName ( $str , $newstr = '_' , $unaccent = 1 )
2008-10-25 23:35:27 +02:00
{
2019-09-02 22:25:44 +02:00
// List of special chars for filenames in windows are defined on page https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
// Char '>' '<' '|' '$' and ';' are special chars for shells.
// Char '/' and '\' are file delimiters.
2021-08-23 12:18:04 +02:00
// Chars '--' can be used into filename to inject special paramaters like --use-compress-program to make command with file as parameter making remote execution of command
2021-07-05 22:26:38 +02:00
$filesystem_forbidden_chars = array ( '<' , '>' , '/' , '\\' , '?' , '*' , '|' , '"' , ':' , '°' , '$' , ';' );
$tmp = dol_string_nospecial ( $unaccent ? dol_string_unaccent ( $str ) : $str , $newstr , $filesystem_forbidden_chars );
$tmp = preg_replace ( '/\-\-+/' , '_' , $tmp );
2021-10-17 12:21:22 +02:00
$tmp = preg_replace ( '/\s+\-([^\s])/' , ' _$1' , $tmp );
2022-02-22 18:41:14 +01:00
$tmp = str_replace ( '..' , '' , $tmp );
2021-07-05 22:26:38 +02:00
return $tmp ;
2008-10-25 23:35:27 +02:00
}
2016-09-08 11:05:47 +02:00
/**
2021-07-08 18:12:15 +02:00
* Clean a string to use it as a path name .
2021-10-17 12:21:22 +02:00
* Replace also '--' and ' -' strings , they are used for parameters separation ( Note : ' - ' is allowed ) .
2016-09-08 11:05:47 +02:00
*
* @ param string $str String to clean
* @ param string $newstr String to replace bad chars with
* @ param int $unaccent 1 = Remove also accent ( default ), 0 do not remove them
* @ return string String cleaned ( a - zA - Z_ )
*
2019-03-11 01:01:15 +01:00
* @ see dol_string_nospecial (), dol_string_unaccent (), dol_sanitizeFileName ()
2016-09-08 11:05:47 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_sanitizePathName ( $str , $newstr = '_' , $unaccent = 1 )
2016-09-08 11:05:47 +02:00
{
2021-08-23 12:18:04 +02:00
// List of special chars for filenames in windows are defined on page https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
// Char '>' '<' '|' '$' and ';' are special chars for shells.
// Chars '--' can be used into filename to inject special paramaters like --use-compress-program to make command with file as parameter making remote execution of command
$filesystem_forbidden_chars = array ( '<' , '>' , '?' , '*' , '|' , '"' , '°' , '$' , ';' );
2021-07-08 18:12:15 +02:00
$tmp = dol_string_nospecial ( $unaccent ? dol_string_unaccent ( $str ) : $str , $newstr , $filesystem_forbidden_chars );
$tmp = preg_replace ( '/\-\-+/' , '_' , $tmp );
2021-10-17 12:21:22 +02:00
$tmp = preg_replace ( '/\s+\-([^\s])/' , ' _$1' , $tmp );
2022-02-22 18:41:14 +01:00
$tmp = str_replace ( '..' , '' , $tmp );
2021-07-08 18:12:15 +02:00
return $tmp ;
2016-09-08 11:05:47 +02:00
}
2021-03-14 15:06:40 +01:00
/**
2021-03-14 16:13:03 +01:00
* Clean a string to use it as an URL ( into a href or src attribute )
2021-03-14 15:06:40 +01:00
*
* @ param string $stringtoclean String to clean
2021-03-14 16:13:03 +01:00
* @ param int $type 0 = Accept all Url , 1 = Clean external Url ( keep only relative Url )
2021-03-14 15:06:40 +01:00
* @ return string Escaped string .
*/
2021-03-14 16:13:03 +01:00
function dol_sanitizeUrl ( $stringtoclean , $type = 1 )
2021-03-14 15:06:40 +01:00
{
2021-03-14 16:13:03 +01:00
// We clean string because some hacks try to obfuscate evil strings by inserting non printable chars. Example: 'java(ascci09)scr(ascii00)ipt' is processed like 'javascript' (whatever is place of evil ascii char)
2021-03-14 18:57:18 +01:00
// We should use dol_string_nounprintableascii but function may not be yet loaded/available
2021-03-14 16:13:03 +01:00
$stringtoclean = preg_replace ( '/[\x00-\x1F\x7F]/u' , '' , $stringtoclean ); // /u operator makes UTF8 valid characters being ignored so are not included into the replace
// We clean html comments because some hacks try to obfuscate evil strings by inserting HTML comments. Example: on<!-- -->error=alert(1)
2021-03-14 16:44:11 +01:00
$stringtoclean = preg_replace ( '/<!--[^>]*-->/' , '' , $stringtoclean );
2021-03-14 16:13:03 +01:00
$stringtoclean = str_replace ( '\\' , '/' , $stringtoclean );
2021-03-14 18:57:18 +01:00
if ( $type == 1 ) {
2021-03-15 10:08:02 +01:00
// removing : should disable links to external url like http:aaa)
// removing ';' should disable "named" html entities encode into an url (we should not have this into an url)
2021-03-14 18:57:18 +01:00
$stringtoclean = str_replace ( array ( ':' , ';' , '@' ), '' , $stringtoclean );
}
2021-03-14 16:13:03 +01:00
do {
$oldstringtoclean = $stringtoclean ;
2021-03-15 10:08:02 +01:00
// removing '&colon' should disable links to external url like http:aaa)
// removing '&#' should disable "numeric" html entities encode into an url (we should not have this into an url)
2021-03-14 20:31:53 +01:00
$stringtoclean = str_ireplace ( array ( 'javascript' , 'vbscript' , '&colon' , '&#' ), '' , $stringtoclean );
2021-03-14 16:13:03 +01:00
} while ( $oldstringtoclean != $stringtoclean );
if ( $type == 1 ) {
2021-03-15 10:08:02 +01:00
// removing '//' should disable links to external url like //aaa or http//)
2021-03-14 16:13:03 +01:00
$stringtoclean = preg_replace ( array ( '/^[a-z]*\/\/+/i' ), '' , $stringtoclean );
}
2021-03-14 15:06:40 +01:00
return $stringtoclean ;
}
2008-10-25 23:35:27 +02:00
/**
2011-08-17 18:18:12 +02:00
* Clean a string from all accent characters to be used as ref , login or by dol_sanitizeFileName
*
2011-09-17 02:47:01 +02:00
* @ param string $str String to clean
* @ return string Cleaned string
*
2019-03-11 01:01:15 +01:00
* @ see dol_sanitizeFilename (), dol_string_nospecial ()
2008-08-06 16:50:06 +02:00
*/
2008-10-25 23:35:27 +02:00
function dol_string_unaccent ( $str )
2008-08-06 16:50:06 +02:00
{
2021-12-08 15:49:52 +01:00
global $conf ;
2021-12-08 19:15:35 +01:00
2021-02-23 22:03:23 +01:00
if ( utf8_check ( $str )) {
2021-12-08 15:49:52 +01:00
if ( extension_loaded ( 'intl' ) && ! empty ( $conf -> global -> MAIN_UNACCENT_USE_TRANSLITERATOR )) {
2021-12-06 14:34:20 +01:00
$transliterator = \Transliterator :: createFromRules ( ':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;' , \Transliterator :: FORWARD );
return $transliterator -> transliterate ( $str );
}
2014-09-06 14:40:43 +02:00
// See http://www.utf8-chartable.de/
2012-08-03 23:29:08 +02:00
$string = rawurlencode ( $str );
$replacements = array (
2019-11-11 23:59:36 +01:00
'%C3%80' => 'A' , '%C3%81' => 'A' , '%C3%82' => 'A' , '%C3%83' => 'A' , '%C3%84' => 'A' , '%C3%85' => 'A' ,
2021-12-06 14:33:51 +01:00
'%C3%87' => 'C' ,
2019-11-11 23:59:36 +01:00
'%C3%88' => 'E' , '%C3%89' => 'E' , '%C3%8A' => 'E' , '%C3%8B' => 'E' ,
'%C3%8C' => 'I' , '%C3%8D' => 'I' , '%C3%8E' => 'I' , '%C3%8F' => 'I' ,
2021-12-06 14:33:51 +01:00
'%C3%91' => 'N' ,
2019-11-11 23:59:36 +01:00
'%C3%92' => 'O' , '%C3%93' => 'O' , '%C3%94' => 'O' , '%C3%95' => 'O' , '%C3%96' => 'O' ,
2021-12-06 14:33:51 +01:00
'%C5%A0' => 'S' ,
2019-11-11 23:59:36 +01:00
'%C3%99' => 'U' , '%C3%9A' => 'U' , '%C3%9B' => 'U' , '%C3%9C' => 'U' ,
2021-12-06 14:33:51 +01:00
'%C3%9D' => 'Y' , '%C5%B8' => 'y' ,
2019-11-11 23:59:36 +01:00
'%C3%A0' => 'a' , '%C3%A1' => 'a' , '%C3%A2' => 'a' , '%C3%A3' => 'a' , '%C3%A4' => 'a' , '%C3%A5' => 'a' ,
2014-09-06 14:40:43 +02:00
'%C3%A7' => 'c' ,
2019-11-11 23:59:36 +01:00
'%C3%A8' => 'e' , '%C3%A9' => 'e' , '%C3%AA' => 'e' , '%C3%AB' => 'e' ,
'%C3%AC' => 'i' , '%C3%AD' => 'i' , '%C3%AE' => 'i' , '%C3%AF' => 'i' ,
2014-09-06 14:40:43 +02:00
'%C3%B1' => 'n' ,
2019-11-11 23:59:36 +01:00
'%C3%B2' => 'o' , '%C3%B3' => 'o' , '%C3%B4' => 'o' , '%C3%B5' => 'o' , '%C3%B6' => 'o' ,
2021-12-06 14:33:51 +01:00
'%C5%A1' => 's' ,
2019-11-11 23:59:36 +01:00
'%C3%B9' => 'u' , '%C3%BA' => 'u' , '%C3%BB' => 'u' , '%C3%BC' => 'u' ,
2021-12-06 14:33:51 +01:00
'%C3%BD' => 'y' , '%C3%BF' => 'y'
2008-10-26 00:23:22 +02:00
);
2019-11-11 23:59:36 +01:00
$string = strtr ( $string , $replacements );
2008-10-26 00:54:31 +02:00
return rawurldecode ( $string );
2020-05-21 15:05:19 +02:00
} else {
2014-09-06 14:40:43 +02:00
// See http://www.ascii-code.com/
2020-09-07 10:18:17 +02:00
$string = strtr (
2012-08-03 23:29:08 +02:00
$str ,
2014-09-06 14:40:43 +02:00
" \xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC7
2012-08-03 23:29:08 +02:00
\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1
\xD2\xD3\xD4\xD5\xD8\xD9\xDA\xDB\xDD
2014-09-06 14:40:43 +02:00
\xE0\xE1\xE2\xE3\xE4\xE5\xE7\xE8\xE9\xEA\xEB
2012-08-03 23:29:08 +02:00
\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF8
2014-09-06 14:40:43 +02:00
\xF9\xFA\xFB\xFC\xFD\xFF " ,
" AAAAAAC
2012-08-03 23:29:08 +02:00
EEEEIIIIDN
OOOOOUUUY
2014-09-06 14:40:43 +02:00
aaaaaaceeee
2012-08-03 23:29:08 +02:00
iiiidnooooo
2014-09-06 14:40:43 +02:00
uuuuyy "
2012-08-03 23:29:08 +02:00
);
$string = strtr ( $string , array ( " \xC4 " => " Ae " , " \xC6 " => " AE " , " \xD6 " => " Oe " , " \xDC " => " Ue " , " \xDE " => " TH " , " \xDF " => " ss " , " \xE4 " => " ae " , " \xE6 " => " ae " , " \xF6 " => " oe " , " \xFC " => " ue " , " \xFE " => " th " ));
return $string ;
}
2008-08-06 16:50:06 +02:00
}
/**
2017-06-28 19:02:09 +02:00
* Clean a string from all punctuation characters to use it as a ref or login .
* This is a more complete function than dol_sanitizeFileName .
2011-08-17 18:18:12 +02:00
*
2021-07-05 22:26:38 +02:00
* @ param string $str String to clean
* @ param string $newstr String to replace forbidden chars with
2022-01-30 16:30:19 +01:00
* @ param array | string $badcharstoreplace Array of forbidden characters to replace . Use '' to keep default list .
* @ param array | string $badcharstoremove Array of forbidden characters to remove . Use '' to keep default list .
2021-07-05 22:26:38 +02:00
* @ return string Cleaned string
2011-09-20 13:43:14 +02:00
*
2020-09-20 04:56:45 +02:00
* @ see dol_sanitizeFilename (), dol_string_unaccent (), dol_string_nounprintableascii ()
2008-08-06 16:50:06 +02:00
*/
2021-07-05 22:26:38 +02:00
function dol_string_nospecial ( $str , $newstr = '_' , $badcharstoreplace = '' , $badcharstoremove = '' )
2008-08-06 16:50:06 +02:00
{
2019-11-11 23:59:36 +01:00
$forbidden_chars_to_replace = array ( " " , " ' " , " / " , " \\ " , " : " , " * " , " ? " , " \" " , " < " , " > " , " | " , " [ " , " ] " , " , " , " ; " , " = " , '°' ); // more complete than dol_sanitizeFileName
$forbidden_chars_to_remove = array ();
2021-07-05 22:26:38 +02:00
//$forbidden_chars_to_remove=array("(",")");
2021-02-23 22:03:23 +01:00
if ( is_array ( $badcharstoreplace )) {
$forbidden_chars_to_replace = $badcharstoreplace ;
}
2021-07-05 22:26:38 +02:00
if ( is_array ( $badcharstoremove )) {
$forbidden_chars_to_remove = $badcharstoremove ;
}
2008-10-09 19:29:32 +02:00
2019-01-27 11:55:16 +01:00
return str_replace ( $forbidden_chars_to_replace , $newstr , str_replace ( $forbidden_chars_to_remove , " " , $str ));
2008-08-06 16:50:06 +02:00
}
2014-10-16 01:01:30 +02:00
2020-09-20 04:56:45 +02:00
/**
2020-10-15 19:36:08 +02:00
* Clean a string from all non printable ASCII chars ( 0x00 - 0x1F and 0x7F ) . It can also removes also Tab - CR - LF . UTF8 chars remains .
2020-09-20 04:56:45 +02:00
* This can be used to sanitize a string and view its real content . Some hacks try to obfuscate attacks by inserting non printable chars .
2020-10-15 19:36:08 +02:00
* Note , for information : UTF8 on 1 byte are : \x00 - \7F
* 2 bytes are : byte 1 \xc0 - \xdf , byte 2 = \x80 - \xbf
* 3 bytes are : byte 1 \xe0 - \xef , byte 2 = \x80 - \xbf , byte 3 = \x80 - \xbf
* 4 bytes are : byte 1 \xf0 - \xf7 , byte 2 = \x80 - \xbf , byte 3 = \x80 - \xbf , byte 4 = \x80 - \xbf
2020-09-20 04:56:45 +02:00
* @ param string $str String to clean
2020-10-15 19:36:08 +02:00
* @ param int $removetabcrlf Remove also CR - LF
2020-09-20 04:56:45 +02:00
* @ return string Cleaned string
*
* @ see dol_sanitizeFilename (), dol_string_unaccent (), dol_string_nospecial ()
*/
2020-10-15 19:36:08 +02:00
function dol_string_nounprintableascii ( $str , $removetabcrlf = 1 )
2020-09-20 04:56:45 +02:00
{
2020-10-15 19:36:08 +02:00
if ( $removetabcrlf ) {
2020-10-31 14:32:18 +01:00
return preg_replace ( '/[\x00-\x1F\x7F]/u' , '' , $str ); // /u operator makes UTF8 valid characters being ignored so are not included into the replace
2020-10-15 19:36:08 +02:00
} else {
2020-10-31 14:32:18 +01:00
return preg_replace ( '/[\x00-\x08\x11-\x12\x14-\x1F\x7F]/u' , '' , $str ); // /u operator should make UTF8 valid characters being ignored so are not included into the replace
2020-10-15 19:36:08 +02:00
}
2020-09-20 04:56:45 +02:00
}
2008-08-06 16:50:06 +02:00
/**
2011-05-01 12:52:10 +02:00
* Returns text escaped for inclusion into javascript code
2011-08-17 18:18:12 +02:00
*
2014-02-13 23:40:39 +01:00
* @ param string $stringtoescape String to escape
2015-02-25 18:24:36 +01:00
* @ param int $mode 0 = Escape also ' and " into ' , 1 = Escape ' but not " for usage into ' string ', 2=Escape " but not ' for usage into " string " , 3 = Escape ' and " with \
* @ param int $noescapebackslashn 0 = Escape also \n . 1 = Do not escape \n .
2014-02-13 23:40:39 +01:00
* @ return string Escaped string . Both ' and " are escaped into ' if they are escaped .
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_escape_js ( $stringtoescape , $mode = 0 , $noescapebackslashn = 0 )
2008-08-06 16:50:06 +02:00
{
2012-08-03 23:29:08 +02:00
// escape quotes and backslashes, newlines, etc.
2019-11-11 23:59:36 +01:00
$substitjs = array ( " ' " => " \\ ' " , " \r " => '\\r' );
2014-02-13 23:40:39 +01:00
//$substitjs['</']='<\/'; // We removed this. Should be useless.
2021-02-23 22:03:23 +01:00
if ( empty ( $noescapebackslashn )) {
2021-03-01 20:37:16 +01:00
$substitjs [ " \n " ] = '\\n' ;
$substitjs [ '\\' ] = '\\\\' ;
2021-02-23 22:03:23 +01:00
}
if ( empty ( $mode )) {
2021-03-01 20:37:16 +01:00
$substitjs [ " ' " ] = " \\ ' " ;
$substitjs [ '"' ] = " \\ ' " ;
2021-02-23 22:03:23 +01:00
} elseif ( $mode == 1 ) {
$substitjs [ " ' " ] = " \\ ' " ;
} elseif ( $mode == 2 ) {
$substitjs [ '"' ] = '\\"' ;
} elseif ( $mode == 3 ) {
2021-03-01 20:37:16 +01:00
$substitjs [ " ' " ] = " \\ ' " ;
$substitjs [ '"' ] = " \\ \" " ;
2021-02-23 22:03:23 +01:00
}
2012-08-03 23:29:08 +02:00
return strtr ( $stringtoescape , $substitjs );
2008-08-06 16:50:06 +02:00
}
2020-03-20 17:10:35 +01:00
/**
* Returns text escaped for inclusion into javascript code
*
* @ param string $stringtoescape String to escape
* @ return string Escaped string for json content .
*/
function dol_escape_json ( $stringtoescape )
{
return str_replace ( '"' , '\"' , $stringtoescape );
}
2008-10-09 19:29:32 +02:00
2009-01-28 10:00:29 +01:00
/**
2015-06-28 23:32:38 +02:00
* Returns text escaped for inclusion in HTML alt or title tags , or into values of HTML input fields .
2011-08-17 18:18:12 +02:00
*
2020-03-12 16:15:48 +01:00
* @ param string $stringtoescape String to escape
2021-08-24 13:19:53 +02:00
* @ param int $keepb 1 = Keep b tags , 0 = remove them completely
2020-03-12 16:15:48 +01:00
* @ param int $keepn 1 = Preserve \r\n strings ( otherwise , replace them with escaped value ) . Set to 1 when escaping for a < textarea >.
2021-08-24 13:19:53 +02:00
* @ param string $noescapetags '' or 'common' or list of tags to not escape . TODO Does not works yet when there is attributes to tag .
2020-03-12 16:15:48 +01:00
* @ param int $escapeonlyhtmltags 1 = Escape only html tags , not the special chars like accents .
* @ return string Escaped string
2019-03-11 01:01:15 +01:00
* @ see dol_string_nohtmltag (), dol_string_nospecial (), dol_string_unaccent ()
2009-01-28 10:00:29 +01:00
*/
2021-08-21 13:27:25 +02:00
function dol_escape_htmltag ( $stringtoescape , $keepb = 0 , $keepn = 0 , $noescapetags = '' , $escapeonlyhtmltags = 0 )
2009-01-28 10:00:29 +01:00
{
2021-08-21 13:27:25 +02:00
if ( $noescapetags == 'common' ) {
2021-08-24 13:19:53 +02:00
$noescapetags = 'html,body,a,b,em,hr,i,u,ul,li,br,div,img,font,p,span,strong,table,tr,td,th,tbody' ;
2021-02-23 22:03:23 +01:00
}
2019-08-30 16:22:24 +02:00
2012-08-03 23:29:08 +02:00
// escape quotes and backslashes, newlines, etc.
2020-03-12 16:15:48 +01:00
if ( $escapeonlyhtmltags ) {
$tmp = htmlspecialchars_decode ( $stringtoescape , ENT_COMPAT );
} else {
$tmp = html_entity_decode ( $stringtoescape , ENT_COMPAT , 'UTF-8' );
}
2021-02-23 22:03:23 +01:00
if ( ! $keepb ) {
$tmp = strtr ( $tmp , array ( " <b> " => '' , '</b>' => '' ));
}
if ( ! $keepn ) {
$tmp = strtr ( $tmp , array ( " \r " => '\\r' , " \n " => '\\n' ));
}
2021-08-21 13:27:25 +02:00
2020-03-12 16:15:48 +01:00
if ( $escapeonlyhtmltags ) {
return htmlspecialchars ( $tmp , ENT_COMPAT , 'UTF-8' );
} else {
2021-08-21 13:27:25 +02:00
// Escape tags to keep
2021-08-24 13:19:53 +02:00
// TODO Does not works yet when there is attributes to tag
2021-08-21 13:27:25 +02:00
$tmparrayoftags = array ();
if ( $noescapetags ) {
$tmparrayoftags = explode ( ',' , $noescapetags );
}
if ( count ( $tmparrayoftags )) {
foreach ( $tmparrayoftags as $tagtoreplace ) {
2021-08-22 01:44:52 +02:00
$tmp = str_ireplace ( '<' . $tagtoreplace . '>' , '__BEGINTAGTOREPLACE' . $tagtoreplace . '__' , $tmp );
$tmp = str_ireplace ( '</' . $tagtoreplace . '>' , '__ENDTAGTOREPLACE' . $tagtoreplace . '__' , $tmp );
2021-08-24 13:19:53 +02:00
$tmp = str_ireplace ( '<' . $tagtoreplace . ' />' , '__BEGINENDTAGTOREPLACE' . $tagtoreplace . '__' , $tmp );
2021-08-21 13:27:25 +02:00
}
}
$result = htmlentities ( $tmp , ENT_COMPAT , 'UTF-8' );
if ( count ( $tmparrayoftags )) {
foreach ( $tmparrayoftags as $tagtoreplace ) {
2021-08-22 01:44:52 +02:00
$result = str_ireplace ( '__BEGINTAGTOREPLACE' . $tagtoreplace . '__' , '<' . $tagtoreplace . '>' , $result );
$result = str_ireplace ( '__ENDTAGTOREPLACE' . $tagtoreplace . '__' , '</' . $tagtoreplace . '>' , $result );
2021-08-24 13:19:53 +02:00
$result = str_ireplace ( '__BEGINENDTAGTOREPLACE' . $tagtoreplace . '__' , '<' . $tagtoreplace . ' />' , $result );
2021-08-21 13:27:25 +02:00
}
}
return $result ;
2020-03-12 16:15:48 +01:00
}
2009-01-28 10:00:29 +01:00
}
2012-10-23 09:30:48 +02:00
/**
2012-10-18 16:30:12 +02:00
* Convert a string to lower . Never use strtolower because it does not works with UTF8 strings .
2012-10-23 09:30:48 +02:00
*
2020-10-27 20:06:49 +01:00
* @ param string $string String to encode
* @ param string $encoding Character set encoding
2012-10-23 09:30:48 +02:00
* @ return string String converted
2012-10-18 16:30:12 +02:00
*/
2020-10-27 20:06:49 +01:00
function dol_strtolower ( $string , $encoding = " UTF-8 " )
2012-10-18 16:30:12 +02:00
{
2020-10-27 20:06:49 +01:00
if ( function_exists ( 'mb_strtolower' )) {
2020-10-31 14:32:18 +01:00
return mb_strtolower ( $string , $encoding );
} else {
return strtolower ( $string );
}
2012-10-18 16:30:12 +02:00
}
2012-10-23 09:30:48 +02:00
/**
2012-10-18 16:30:12 +02:00
* Convert a string to upper . Never use strtolower because it does not works with UTF8 strings .
2012-10-23 09:30:48 +02:00
*
2020-10-27 20:06:49 +01:00
* @ param string $string String to encode
* @ param string $encoding Character set encoding
2012-10-23 09:30:48 +02:00
* @ return string String converted
2012-10-18 16:30:12 +02:00
*/
2020-10-27 20:06:49 +01:00
function dol_strtoupper ( $string , $encoding = " UTF-8 " )
2012-10-28 13:57:21 +01:00
{
2020-10-27 20:06:49 +01:00
if ( function_exists ( 'mb_strtoupper' )) {
2020-10-31 14:32:18 +01:00
return mb_strtoupper ( $string , $encoding );
} else {
return strtoupper ( $string );
}
2012-10-28 13:57:21 +01:00
}
2012-10-18 16:30:12 +02:00
2020-10-27 20:44:17 +01:00
/**
* Convert first character of the first word of a string to upper . Never use ucfirst because it does not works with UTF8 strings .
*
* @ param string $string String to encode
* @ param string $encoding Character set encodign
* @ return string String converted
*/
function dol_ucfirst ( $string , $encoding = " UTF-8 " )
{
2020-10-31 14:32:18 +01:00
if ( function_exists ( 'mb_substr' )) {
2020-10-31 18:51:30 +01:00
return mb_strtoupper ( mb_substr ( $string , 0 , 1 , $encoding ), $encoding ) . mb_substr ( $string , 1 , null , $encoding );
2020-10-31 14:32:18 +01:00
} else {
return ucfirst ( $string );
}
2020-10-27 20:44:17 +01:00
}
/**
* Convert first character of all the words of a string to upper . Never use ucfirst because it does not works with UTF8 strings .
*
* @ param string $string String to encode
* @ param string $encoding Character set encodign
* @ return string String converted
*/
function dol_ucwords ( $string , $encoding = " UTF-8 " )
{
2020-10-31 14:32:18 +01:00
if ( function_exists ( 'mb_convert_case' )) {
return mb_convert_case ( $string , MB_CASE_TITLE , $encoding );
} else {
return ucwords ( $string );
}
2020-10-27 20:44:17 +01:00
}
2012-10-18 16:30:12 +02:00
2008-08-06 16:50:06 +02:00
/**
2011-10-03 17:19:39 +02:00
* Write log message into outputs . Possible outputs can be :
2013-01-14 17:12:13 +01:00
* SYSLOG_HANDLERS = [ " mod_syslog_file " ] file name is then defined by SYSLOG_FILE
* SYSLOG_HANDLERS = [ " mod_syslog_syslog " ] facility is then defined by SYSLOG_FACILITY
2012-04-02 18:37:37 +02:00
* Warning , syslog functions are bugged on Windows , generating memory protection faults . To solve
* this , use logging to files instead of syslog ( see setup of module ) .
2017-06-10 22:11:12 +02:00
* Note : If constant 'SYSLOG_FILE_NO_ERROR' defined , we never output any error message when writing to log fails .
2012-02-17 23:24:47 +01:00
* Note : You can get log message into html sources by adding parameter & logtohtml = 1 ( constant MAIN_LOGTOHTML must be set )
2012-04-02 18:37:37 +02:00
* This function works only if syslog module is enabled .
2011-10-03 17:19:39 +02:00
* This must not use any call to other function calling dol_syslog ( avoid infinite loop ) .
2011-08-28 18:22:09 +02:00
*
2016-07-28 14:11:41 +02:00
* @ param string $message Line to log . '' = Show nothing
2015-03-21 01:22:05 +01:00
* @ param int $level Log level
* On Windows LOG_ERR = 4 , LOG_WARNING = 5 , LOG_NOTICE = LOG_INFO = 6 , LOG_DEBUG = 6 si define_syslog_variables ou PHP 5.3 + , 7 si dolibarr
2021-04-07 12:43:28 +02:00
* On Linux LOG_ERR = 3 , LOG_WARNING = 4 , LOG_NOTICE = 5 , LOG_INFO = 6 , LOG_DEBUG = 7
2015-03-21 01:22:05 +01:00
* @ param int $ident 1 = Increase ident of 1 , - 1 = Decrease ident of 1
* @ param string $suffixinfilename When output is a file , append this suffix into default log filename .
2019-08-20 13:57:25 +02:00
* @ param string $restricttologhandler Force output of log only to this log handler
* @ param array | null $logcontext If defined , an array with extra informations ( can be used by some log handlers )
2012-04-02 18:37:37 +02:00
* @ return void
2008-08-06 16:50:06 +02:00
*/
2019-08-20 13:57:25 +02:00
function dol_syslog ( $message , $level = LOG_INFO , $ident = 0 , $suffixinfilename = '' , $restricttologhandler = '' , $logcontext = null )
2008-08-06 16:50:06 +02:00
{
2020-09-07 10:18:17 +02:00
global $conf , $user , $debugbar ;
2012-10-16 02:01:37 +02:00
// If syslog module enabled
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> syslog -> enabled )) {
return ;
}
2012-10-16 02:01:37 +02:00
2020-05-06 04:32:48 +02:00
// Check if we are into execution of code of a website
2020-09-08 21:27:28 +02:00
if ( defined ( 'USEEXTERNALSERVER' ) && ! defined ( 'USEDOLIBARRSERVER' ) && ! defined ( 'USEDOLIBARREDITOR' )) {
2020-05-06 04:32:48 +02:00
global $website , $websitekey ;
2021-02-23 22:03:23 +01:00
if ( is_object ( $website ) && ! empty ( $website -> ref )) {
$suffixinfilename .= '_website_' . $website -> ref ;
} elseif ( ! empty ( $websitekey )) {
$suffixinfilename .= '_website_' . $websitekey ;
}
2020-05-06 04:32:48 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $ident < 0 ) {
foreach ( $conf -> loghandlers as $loghandlerinstance ) {
2018-06-04 12:55:55 +02:00
$loghandlerinstance -> setIdent ( $ident );
}
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $message )) {
2017-10-13 13:28:26 +02:00
// Test log level
2019-03-23 14:37:54 +01:00
$logLevels = array ( LOG_EMERG => 'EMERG' , LOG_ALERT => 'ALERT' , LOG_CRIT => 'CRITICAL' , LOG_ERR => 'ERR' , LOG_WARNING => 'WARN' , LOG_NOTICE => 'NOTICE' , LOG_INFO => 'INFO' , LOG_DEBUG => 'DEBUG' );
2021-02-23 22:03:23 +01:00
if ( ! array_key_exists ( $level , $logLevels )) {
2017-10-13 13:28:26 +02:00
throw new Exception ( 'Incorrect log level' );
}
2021-02-23 22:03:23 +01:00
if ( $level > $conf -> global -> SYSLOG_LEVEL ) {
return ;
}
2017-10-13 13:28:26 +02:00
2021-05-09 22:07:08 +02:00
if ( empty ( $conf -> global -> MAIN_SHOW_PASSWORD_INTO_LOG )) {
$message = preg_replace ( '/password=\'[^\']*\'/' , 'password=\'hidden\'' , $message ); // protection to avoid to have value of password in log
}
2018-11-05 20:29:07 +01:00
2017-10-13 13:28:26 +02:00
// If adding log inside HTML page is required
2019-11-11 23:59:36 +01:00
if (( ! empty ( $_REQUEST [ 'logtohtml' ]) && ! empty ( $conf -> global -> MAIN_ENABLE_LOG_TO_HTML ))
2021-02-23 22:03:23 +01:00
|| ( ! empty ( $user -> rights -> debugbar -> read ) && is_object ( $debugbar ))) {
2020-09-07 10:18:17 +02:00
$conf -> logbuffer [] = dol_print_date ( time (), " %Y-%m-%d %H:%M:%S " ) . " " . $logLevels [ $level ] . " " . $message ;
2017-10-13 13:28:26 +02:00
}
//TODO: Remove this. MAIN_ENABLE_LOG_INLINE_HTML should be deprecated and use a log handler dedicated to HTML output
2018-11-05 20:29:07 +01:00
// If html log tag enabled and url parameter log defined, we show output log on HTML comments
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_ENABLE_LOG_INLINE_HTML ) && ! empty ( $_GET [ " log " ])) {
2017-10-13 13:28:26 +02:00
print " \n \n <!-- Log start \n " ;
2021-03-31 12:44:13 +02:00
print dol_escape_htmltag ( $message ) . " \n " ;
2017-10-13 13:28:26 +02:00
print " Log end --> \n " ;
}
$data = array (
'message' => $message ,
2019-11-11 23:59:36 +01:00
'script' => ( isset ( $_SERVER [ 'PHP_SELF' ]) ? basename ( $_SERVER [ 'PHP_SELF' ], '.php' ) : false ),
2017-10-13 13:28:26 +02:00
'level' => $level ,
'user' => (( is_object ( $user ) && $user -> id ) ? $user -> login : false ),
'ip' => false
);
2020-02-13 10:44:08 +01:00
$remoteip = getUserRemoteIP (); // Get ip when page run on a web server
if ( ! empty ( $remoteip )) {
2020-01-31 17:51:30 +01:00
$data [ 'ip' ] = $remoteip ;
// This is when server run behind a reverse proxy
2021-02-23 22:03:23 +01:00
if ( ! empty ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]) && $_SERVER [ 'HTTP_X_FORWARDED_FOR' ] != $remoteip ) {
$data [ 'ip' ] = $_SERVER [ 'HTTP_X_FORWARDED_FOR' ] . ' -> ' . $data [ 'ip' ];
} elseif ( ! empty ( $_SERVER [ 'HTTP_CLIENT_IP' ]) && $_SERVER [ 'HTTP_CLIENT_IP' ] != $remoteip ) {
$data [ 'ip' ] = $_SERVER [ 'HTTP_CLIENT_IP' ] . ' -> ' . $data [ 'ip' ];
}
2021-03-01 20:37:16 +01:00
} elseif ( ! empty ( $_SERVER [ 'SERVER_ADDR' ])) {
// This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache)
2021-02-23 22:03:23 +01:00
$data [ 'ip' ] = $_SERVER [ 'SERVER_ADDR' ];
2021-03-01 20:37:16 +01:00
} elseif ( ! empty ( $_SERVER [ 'COMPUTERNAME' ])) {
// This is when PHP session is ran outside a web server, like from Windows command line (Not always defined, but useful if OS defined it).
2021-02-23 22:03:23 +01:00
$data [ 'ip' ] = $_SERVER [ 'COMPUTERNAME' ] . ( empty ( $_SERVER [ 'USERNAME' ]) ? '' : '@' . $_SERVER [ 'USERNAME' ]);
2021-03-01 20:37:16 +01:00
} elseif ( ! empty ( $_SERVER [ 'LOGNAME' ])) {
// This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it).
2021-02-23 22:03:23 +01:00
$data [ 'ip' ] = '???@' . $_SERVER [ 'LOGNAME' ];
}
2022-01-24 12:43:42 +01:00
2017-10-13 13:28:26 +02:00
// Loop on each log handler and send output
2021-02-23 22:03:23 +01:00
foreach ( $conf -> loghandlers as $loghandlerinstance ) {
if ( $restricttologhandler && $loghandlerinstance -> code != $restricttologhandler ) {
continue ;
}
2019-01-27 11:55:16 +01:00
$loghandlerinstance -> export ( $data , $suffixinfilename );
2017-10-13 13:28:26 +02:00
}
unset ( $data );
2016-07-19 15:27:03 +02:00
}
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( $ident > 0 ) {
foreach ( $conf -> loghandlers as $loghandlerinstance ) {
2012-12-05 11:18:45 +01:00
$loghandlerinstance -> setIdent ( $ident );
}
2012-08-03 23:29:08 +02:00
}
2008-08-06 16:50:06 +02:00
}
2020-10-07 12:31:15 +02:00
/**
* Return HTML code to output a button to open a dialog popup box .
* Such buttons must be included inside a HTML form .
*
* @ param string $name A name for the html component
* @ param string $label Label of button
* @ param string $buttonstring button string
* @ param string $url Url to open
* @ param string $disabled Disabled text
* @ return string HTML component with button
*/
function dolButtonToOpenUrlInDialogPopup ( $name , $label , $buttonstring , $url , $disabled = '' )
{
2020-12-01 02:41:19 +01:00
if ( strpos ( $url , '?' ) > 0 ) {
$url .= '&dol_hide_topmenu=1&dol_hide_leftmenu=1&dol_openinpopup=1' ;
} else {
$url .= '?dol_hide_menuinpopup=1&dol_hide_leftmenu=1&dol_openinpopup=1' ;
}
2020-11-30 07:50:14 +01:00
2020-10-07 12:31:15 +02:00
//print '<input type="submit" class="button bordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("MediaFiles")).'" name="file_manager">';
$out = '<a class="button bordertransp button_' . $name . '"' . $disabled . ' title="' . dol_escape_htmltag ( $label ) . '">' . $buttonstring . '</a>' ;
2021-06-19 23:52:52 +02:00
$out .= '<!-- Add js code to open dialog popup on dialog -->' ;
2021-11-29 15:09:18 +01:00
$out .= ' < script type = " text/javascript " >
2021-06-19 23:52:52 +02:00
jQuery ( document ) . ready ( function () {
jQuery ( " .button_'. $name .' " ) . click ( function () {
console . log ( " Open popup with jQuery(...).dialog() on URL '.dol_escape_js(DOL_URL_ROOT. $url ).' " )
var $dialog = $ ( \ '<div></div>\').html(\'<iframe class="iframedialog" style="border: 0px;" src="' . DOL_URL_ROOT . $url . ' " width= " 100 % " height= " 98 % " ></iframe> \ ')
. dialog ({
autoOpen : false ,
modal : true ,
height : ( window . innerHeight - 150 ),
width : \ ' 80 % \ ' ,
title : " '.dol_escape_js( $label ).' "
});
$dialog . dialog ( \ ' open\ ' );
});
});
</ script > ' ;
2020-10-07 12:31:15 +02:00
return $out ;
}
2009-01-07 11:57:36 +01:00
2008-08-06 16:50:06 +02:00
/**
2010-12-28 01:10:13 +01:00
* Show tab header of a card
2011-09-03 01:57:26 +02:00
*
2016-10-07 17:53:41 +02:00
* @ param array $links Array of tabs . Currently initialized by calling a function xxx_admin_prepare_head
2013-03-10 13:23:55 +01:00
* @ param string $active Active tab name ( document ', ' info ', ' ldap ' , .... )
* @ param string $title Title
2020-10-27 18:19:31 +01:00
* @ param int $notab - 1 or 0 = Add tab header , 1 = no tab header ( if you set this to 1 , using print dol_get_fiche_end () to close tab is not required ), - 2 = Add tab header with no seaparation under tab ( to start a tab just after )
2013-03-10 13:23:55 +01:00
* @ param string $picto Add a picto on tab title
2013-11-30 16:57:11 +01:00
* @ param int $pictoisfullpath If 1 , image path is a full path . If you set this to 1 , you can use url returned by dol_buildpath ( '/mymodyle/img/myimg.png' , 1 ) for $picto .
2017-09-24 01:36:20 +02:00
* @ param string $morehtmlright Add more html content on right of tabs title
2018-03-06 21:51:43 +01:00
* @ param string $morecss More Css
2020-02-24 20:41:29 +01:00
* @ param int $limittoshow Limit number of tabs to show . Use 0 to use automatic default value .
2020-07-24 18:31:14 +02:00
* @ param string $moretabssuffix A suffix to use when you have several dol_get_fiche_head () in same page
2011-09-17 02:47:01 +02:00
* @ return void
2020-10-07 12:31:15 +02:00
* @ deprecated Use print dol_get_fiche_head () instead
2008-08-06 16:50:06 +02:00
*/
2020-07-24 18:31:14 +02:00
function dol_fiche_head ( $links = array (), $active = '0' , $title = '' , $notab = 0 , $picto = '' , $pictoisfullpath = 0 , $morehtmlright = '' , $morecss = '' , $limittoshow = 0 , $moretabssuffix = '' )
2008-08-06 16:50:06 +02:00
{
2020-07-24 18:31:14 +02:00
print dol_get_fiche_head ( $links , $active , $title , $notab , $picto , $pictoisfullpath , $morehtmlright , $morecss , $limittoshow , $moretabssuffix );
2011-07-08 15:07:44 +02:00
}
/**
2020-02-24 20:41:29 +01:00
* Show tabs of a record
2011-09-03 01:57:26 +02:00
*
2022-01-06 18:02:44 +01:00
* @ param array $links Array of tabs . Note that label into $links [ $i ][ 1 ] must be already HTML escaped .
2015-09-23 19:21:59 +02:00
* @ param string $active Active tab name
2013-03-10 13:23:55 +01:00
* @ param string $title Title
2020-10-27 18:19:31 +01:00
* @ param int $notab - 1 or 0 = Add tab header , 1 = no tab header ( if you set this to 1 , using print dol_get_fiche_end () to close tab is not required ), - 2 = Add tab header with no seaparation under tab ( to start a tab just after )
2013-03-10 13:23:55 +01:00
* @ param string $picto Add a picto on tab title
2013-11-30 16:57:11 +01:00
* @ param int $pictoisfullpath If 1 , image path is a full path . If you set this to 1 , you can use url returned by dol_buildpath ( '/mymodyle/img/myimg.png' , 1 ) for $picto .
2017-09-24 01:36:20 +02:00
* @ param string $morehtmlright Add more html content on right of tabs title
2021-10-12 23:50:23 +02:00
* @ param string $morecss More CSS on the link < a >
2020-02-24 20:41:29 +01:00
* @ param int $limittoshow Limit number of tabs to show . Use 0 to use automatic default value .
2020-07-24 18:31:14 +02:00
* @ param string $moretabssuffix A suffix to use when you have several dol_get_fiche_head () in same page
2015-02-10 10:45:48 +01:00
* @ return string
2011-07-08 15:07:44 +02:00
*/
2020-07-24 18:31:14 +02:00
function dol_get_fiche_head ( $links = array (), $active = '' , $title = '' , $notab = 0 , $picto = '' , $pictoisfullpath = 0 , $morehtmlright = '' , $morecss = '' , $limittoshow = 0 , $moretabssuffix = '' )
2011-07-08 15:07:44 +02:00
{
2016-11-12 14:36:52 +01:00
global $conf , $langs , $hookmanager ;
2015-11-01 17:27:41 +01:00
2019-11-01 23:16:08 +01:00
// Show title
2019-11-11 23:59:36 +01:00
$showtitle = 1 ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen )) {
$showtitle = 0 ;
}
2012-08-03 23:29:08 +02:00
2020-07-24 18:31:14 +02:00
$out = " \n " . '<!-- dol_fiche_head - dol_get_fiche_head -->' ;
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
if (( ! empty ( $title ) && $showtitle ) || $morehtmlright || ! empty ( $links )) {
2020-05-27 22:35:55 +02:00
$out .= '<div class="tabs' . ( $picto ? '' : ' nopaddingleft' ) . '" data-role="controlgroup" data-type="horizontal">' . " \n " ;
2019-11-01 23:16:08 +01:00
}
// Show right part
2021-02-23 22:03:23 +01:00
if ( $morehtmlright ) {
$out .= '<div class="inline-block floatright tabsElem">' . $morehtmlright . '</div>' ; // Output right area first so when space is missing, text is in front of tabs and not under.
}
2017-09-24 01:36:20 +02:00
2013-04-03 00:36:31 +02:00
// Show title
2021-02-23 22:03:23 +01:00
if ( ! empty ( $title ) && $showtitle && empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) {
2019-11-11 23:59:36 +01:00
$limittitle = 30 ;
$out .= '<a class="tabTitle">' ;
2021-02-23 22:03:23 +01:00
if ( $picto ) {
2021-10-26 17:23:51 +02:00
$noprefix = $pictoisfullpath ;
if ( strpos ( $picto , 'fontawesome_' ) !== false ) {
$noprefix = 1 ;
}
$out .= img_picto ( $title , ( $noprefix ? '' : 'object_' ) . $picto , '' , $pictoisfullpath , 0 , 0 , '' , 'imgTabTitle' ) . ' ' ;
2021-02-23 22:03:23 +01:00
}
2021-04-06 18:18:07 +02:00
$out .= '<span class="tabTitleText">' . dol_escape_htmltag ( dol_trunc ( $title , $limittitle )) . '</span>' ;
2019-11-11 23:59:36 +01:00
$out .= '</a>' ;
2012-08-03 23:29:08 +02:00
}
2019-11-01 23:16:08 +01:00
// Show tabs
2012-08-03 23:29:08 +02:00
// Define max of key (max may be higher than sizeof because of hole due to module disabling some tabs).
2019-11-11 23:59:36 +01:00
$maxkey = - 1 ;
2021-02-23 22:03:23 +01:00
if ( is_array ( $links ) && ! empty ( $links )) {
2019-11-11 23:59:36 +01:00
$keys = array_keys ( $links );
2021-02-23 22:03:23 +01:00
if ( count ( $keys )) {
$maxkey = max ( $keys );
}
2012-08-03 23:29:08 +02:00
}
// Show tabs
2014-12-22 12:26:04 +01:00
// if =0 we don't use the feature
2020-02-24 20:41:29 +01:00
if ( empty ( $limittoshow )) {
$limittoshow = ( empty ( $conf -> global -> MAIN_MAXTABS_IN_CARD ) ? 99 : $conf -> global -> MAIN_MAXTABS_IN_CARD );
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen )) {
$limittoshow = 2 ;
}
2020-02-24 20:41:29 +01:00
2019-11-11 23:59:36 +01:00
$displaytab = 0 ;
$nbintab = 0 ;
$popuptab = 0 ;
$outmore = '' ;
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i <= $maxkey ; $i ++ ) {
2019-11-11 23:59:36 +01:00
if (( is_numeric ( $active ) && $i == $active ) || ( ! empty ( $links [ $i ][ 2 ]) && ! is_numeric ( $active ) && $active == $links [ $i ][ 2 ])) {
2017-11-24 14:23:25 +01:00
// If active tab is already present
2021-02-23 22:03:23 +01:00
if ( $i >= $limittoshow ) {
$limittoshow -- ;
}
2015-11-17 14:42:34 +01:00
}
}
2015-11-01 17:27:41 +01:00
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i <= $maxkey ; $i ++ ) {
2019-11-11 23:59:36 +01:00
if (( is_numeric ( $active ) && $i == $active ) || ( ! empty ( $links [ $i ][ 2 ]) && ! is_numeric ( $active ) && $active == $links [ $i ][ 2 ])) {
$isactive = true ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$isactive = false ;
2017-11-24 14:23:25 +01:00
}
2013-12-19 20:57:13 +01:00
2021-02-23 22:03:23 +01:00
if ( $i < $limittoshow || $isactive ) {
2022-01-06 18:02:44 +01:00
// Output entry with a visible tab
$out .= '<div class="inline-block tabsElem' . ( $isactive ? ' tabsElemActive' : '' ) . (( ! $isactive && ! empty ( $conf -> global -> MAIN_HIDE_INACTIVETAB_ON_PRINT )) ? ' hideonprint' : '' ) . '"><!-- id tab = ' . ( empty ( $links [ $i ][ 2 ]) ? '' : dol_escape_htmltag ( $links [ $i ][ 2 ])) . ' -->' ;
2021-04-06 18:18:07 +02:00
2021-02-23 22:03:23 +01:00
if ( isset ( $links [ $i ][ 2 ]) && $links [ $i ][ 2 ] == 'image' ) {
if ( ! empty ( $links [ $i ][ 0 ])) {
2019-11-11 23:59:36 +01:00
$out .= '<a class="tabimage' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '">' . $links [ $i ][ 1 ] . '</a>' . " \n " ;
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$out .= '<span class="tabspan">' . $links [ $i ][ 1 ] . '</span>' . " \n " ;
2014-12-22 12:26:04 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( ! empty ( $links [ $i ][ 1 ])) {
2014-12-22 12:26:04 +01:00
//print "x $i $active ".$links[$i][2]." z";
2021-04-06 18:18:07 +02:00
$out .= '<div class="tab tab' . ( $isactive ? 'active' : 'unactive' ) . '" style="margin: 0 !important">' ;
if ( ! empty ( $links [ $i ][ 0 ])) {
2022-01-06 18:02:44 +01:00
$titletoshow = preg_replace ( '/<.*$/' , '' , $links [ $i ][ 1 ]);
$out .= '<a' . ( ! empty ( $links [ $i ][ 2 ]) ? ' id="' . $links [ $i ][ 2 ] . '"' : '' ) . ' class="tab inline-block' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '" title="' . dol_escape_htmltag ( $titletoshow ) . '">' ;
2021-04-06 18:18:07 +02:00
}
$out .= $links [ $i ][ 1 ];
if ( ! empty ( $links [ $i ][ 0 ])) {
2019-11-11 23:59:36 +01:00
$out .= '</a>' . " \n " ;
2014-12-22 12:26:04 +01:00
}
2021-04-06 18:18:07 +02:00
$out .= empty ( $links [ $i ][ 4 ]) ? '' : $links [ $i ][ 4 ];
$out .= '</div>' ;
2012-08-03 23:29:08 +02:00
}
2021-04-06 18:18:07 +02:00
2019-11-11 23:59:36 +01:00
$out .= '</div>' ;
2020-05-21 15:05:19 +02:00
} else {
2022-01-06 18:02:44 +01:00
// Add entry into the combo popup with the other tabs
2021-02-23 22:03:23 +01:00
if ( ! $popuptab ) {
2019-11-11 23:59:36 +01:00
$popuptab = 1 ;
$outmore .= '<div class="popuptabset wordwrap">' ; // The css used to hide/show popup
2015-10-15 13:31:44 +02:00
}
2019-11-11 23:59:36 +01:00
$outmore .= '<div class="popuptab wordwrap" style="display:inherit;">' ;
2021-02-23 22:03:23 +01:00
if ( isset ( $links [ $i ][ 2 ]) && $links [ $i ][ 2 ] == 'image' ) {
if ( ! empty ( $links [ $i ][ 0 ])) {
2019-11-11 23:59:36 +01:00
$outmore .= '<a class="tabimage' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '">' . $links [ $i ][ 1 ] . '</a>' . " \n " ;
2021-02-23 22:03:23 +01:00
} else {
$outmore .= '<span class="tabspan">' . $links [ $i ][ 1 ] . '</span>' . " \n " ;
}
} elseif ( ! empty ( $links [ $i ][ 1 ])) {
2019-11-11 23:59:36 +01:00
$outmore .= '<a' . ( ! empty ( $links [ $i ][ 2 ]) ? ' id="' . $links [ $i ][ 2 ] . '"' : '' ) . ' class="wordwrap inline-block' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '">' ;
$outmore .= preg_replace ( '/([a-z])\/([a-z])/i' , '\\1 / \\2' , $links [ $i ][ 1 ]); // Replace x/y with x / y to allow wrap on long composed texts.
$outmore .= '</a>' . " \n " ;
2017-11-24 14:23:25 +01:00
}
2019-11-11 23:59:36 +01:00
$outmore .= '</div>' ;
2015-11-01 17:27:41 +01:00
2015-09-15 03:33:27 +02:00
$nbintab ++ ;
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
$displaytab = $i ;
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $popuptab ) {
$outmore .= '</div>' ;
}
2015-11-01 17:27:41 +01:00
2021-02-23 22:03:23 +01:00
if ( $popuptab ) { // If there is some tabs not shown
2019-11-11 23:59:36 +01:00
$left = ( $langs -> trans ( " DIRECTION " ) == 'rtl' ? 'right' : 'left' );
$right = ( $langs -> trans ( " DIRECTION " ) == 'rtl' ? 'left' : 'right' );
2020-09-21 12:16:22 +02:00
$widthofpopup = 200 ;
2017-11-24 14:23:25 +01:00
2020-07-24 18:31:14 +02:00
$tabsname = $moretabssuffix ;
2021-02-23 22:03:23 +01:00
if ( empty ( $tabsname )) {
$tabsname = str_replace ( " @ " , " " , $picto );
}
2019-11-11 23:59:36 +01:00
$out .= '<div id="moretabs' . $tabsname . '" class="inline-block tabsElem">' ;
2022-01-06 18:02:44 +01:00
$out .= '<div class="tab"><a href="#" class="tab moretab inline-block tabunactive"><span class="hideonsmartphone">' . $langs -> trans ( " More " ) . '</span>... (' . $nbintab . ')</a></div>' ; // Do not use "reposition" class in the "More".
2020-09-21 12:16:22 +02:00
$out .= '<div id="moretabsList' . $tabsname . '" style="width: ' . $widthofpopup . 'px; position: absolute; ' . $left . ': -999em; text-align: ' . $left . '; margin:0px; padding:2px; z-index:10;">' ;
2019-11-11 23:59:36 +01:00
$out .= $outmore ;
$out .= '</div>' ;
$out .= '<div></div>' ;
$out .= " </div> \n " ;
2014-12-30 21:04:02 +01:00
2019-11-11 23:59:36 +01:00
$out .= " <script> " ;
2020-09-21 12:16:22 +02:00
$out .= " $ ('#moretabs " . $tabsname . " ').mouseenter( function() {
var x = this . offsetLeft , y = this . offsetTop ;
console . log ( 'mouseenter ".$left." x=' + x + ' y=' + y + ' window.innerWidth=' + window . innerWidth );
2020-10-07 15:01:28 +02:00
if (( window . innerWidth - x ) < " .( $widthofpopup + 10). " ) {
2020-09-21 12:16:22 +02:00
$ ( '#moretabsList".$tabsname."' ) . css ( '".$right."' , '8px' );
}
$ ( '#moretabsList".$tabsname."' ) . css ( '".$left."' , 'auto' );
});
" ;
2019-11-11 23:59:36 +01:00
$out .= " $ ('#moretabs " . $tabsname . " ').mouseleave( function() { console.log('mouseleave " . $left . " '); $ ('#moretabsList " . $tabsname . " ').css(' " . $left . " ','-999em');}); " ;
$out .= " </script> " ;
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
if (( ! empty ( $title ) && $showtitle ) || $morehtmlright || ! empty ( $links )) {
$out .= " </div> \n " ;
2019-11-01 23:16:08 +01:00
}
2015-11-01 17:27:41 +01:00
2021-02-23 22:03:23 +01:00
if ( ! $notab || $notab == - 1 || $notab == - 2 ) {
$out .= " \n " . '<div class="tabBar' . ( $notab == - 1 ? '' : ( $notab == - 2 ? ' tabBarNoTop' : ' tabBarWithBottom' )) . '">' . " \n " ;
}
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
$parameters = array ( 'tabname' => $active , 'out' => $out );
$reshook = $hookmanager -> executeHooks ( 'printTabsHead' , $parameters ); // This hook usage is called just before output the head of tabs. Take also a look at "completeTabsHead"
2021-02-23 22:03:23 +01:00
if ( $reshook > 0 ) {
2016-11-12 14:36:52 +01:00
$out = $hookmanager -> resPrint ;
}
2016-11-16 09:40:29 +01:00
2012-08-03 23:29:08 +02:00
return $out ;
2008-08-06 16:50:06 +02:00
}
2010-05-26 16:52:32 +02:00
/**
2011-07-08 15:07:44 +02:00
* Show tab footer of a card
2011-09-03 01:57:26 +02:00
*
2017-03-15 11:13:30 +01:00
* @ param int $notab - 1 or 0 = Add tab footer , 1 = no tab footer
2011-09-20 13:43:14 +02:00
* @ return void
2020-10-27 11:40:30 +01:00
* @ deprecated Use print dol_get_fiche_end () instead
2010-05-26 16:52:32 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_fiche_end ( $notab = 0 )
2010-05-26 16:52:32 +02:00
{
2012-08-03 23:29:08 +02:00
print dol_get_fiche_end ( $notab );
2011-07-08 15:07:44 +02:00
}
/**
* Return tab footer of a card
2011-09-03 01:57:26 +02:00
*
2017-03-15 11:13:30 +01:00
* @ param int $notab - 1 or 0 = Add tab footer , 1 = no tab footer
2015-02-10 10:45:48 +01:00
* @ return string
2011-07-08 15:07:44 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_get_fiche_end ( $notab = 0 )
2011-07-08 15:07:44 +02:00
{
2021-02-23 22:03:23 +01:00
if ( ! $notab || $notab == - 1 ) {
return " \n </div> \n " ;
} else {
return '' ;
}
2010-05-26 16:52:32 +02:00
}
2015-10-10 12:01:09 +02:00
/**
2017-06-09 10:12:01 +02:00
* Show tab footer of a card .
* Note : $object -> next_prev_filter can be set to restrict select to find next or previous record by $form -> showrefnav .
2015-10-10 12:01:09 +02:00
*
2017-12-22 14:19:12 +01:00
* @ param Object $object Object to show
2015-11-06 18:57:35 +01:00
* @ param string $paramid Name of parameter to use to name the id into the URL next / previous link
2015-10-10 12:01:09 +02:00
* @ param string $morehtml More html content to output just before the nav bar
* @ param int $shownav Show Condition ( navigation is shown if value is 1 )
2017-07-25 23:02:48 +02:00
* @ param string $fieldid Nom du champ en base a utiliser pour select next et previous ( we make the select max and min on this field ) . Use 'none' for no prev / next search .
2015-10-10 12:01:09 +02:00
* @ param string $fieldref Nom du champ objet ref ( object -> ref ) a utiliser pour select next et previous
2021-06-26 16:10:56 +02:00
* @ param string $morehtmlref More html to show after the ref ( see $morehtmlleft for before )
2015-10-10 12:01:09 +02:00
* @ param string $moreparam More param to add in nav link url .
* @ param int $nodbprefix Do not include DB prefix to forge table name
2021-06-26 16:10:56 +02:00
* @ param string $morehtmlleft More html code to show before the ref ( see $morehtmlref for after )
2016-11-11 23:17:37 +01:00
* @ param string $morehtmlstatus More html code to show under navigation arrows
2017-10-08 20:47:36 +02:00
* @ param int $onlybanner Put this to 1 , if the card will contains only a banner ( this add css 'arearefnobottom' on div )
2016-11-18 13:17:24 +01:00
* @ param string $morehtmlright More html code to show before navigation arrows
2015-10-10 12:01:09 +02:00
* @ return void
*/
2019-01-27 15:20:16 +01:00
function dol_banner_tab ( $object , $paramid , $morehtml = '' , $shownav = 1 , $fieldid = 'rowid' , $fieldref = 'ref' , $morehtmlref = '' , $moreparam = '' , $nodbprefix = 0 , $morehtmlleft = '' , $morehtmlstatus = '' , $onlybanner = 0 , $morehtmlright = '' )
2015-10-10 12:01:09 +02:00
{
2021-11-07 17:49:31 +01:00
global $conf , $form , $user , $langs , $hookmanager , $action ;
2015-10-10 12:01:09 +02:00
2017-04-15 03:05:04 +02:00
$error = 0 ;
2017-05-25 08:48:59 +02:00
2019-11-11 23:59:36 +01:00
$maxvisiblephotos = 1 ;
$showimage = 1 ;
$entity = ( empty ( $object -> entity ) ? $conf -> entity : $object -> entity );
2021-03-15 13:51:54 +01:00
$showbarcode = empty ( $conf -> barcode -> enabled ) ? 0 : ( empty ( $object -> barcode ) ? 0 : 1 );
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && empty ( $user -> rights -> barcode -> lire_advance )) {
$showbarcode = 0 ;
}
2019-11-11 23:59:36 +01:00
$modulepart = 'unknown' ;
2017-02-13 01:36:02 +01:00
2021-04-01 12:27:02 +02:00
if ( $object -> element == 'societe' || $object -> element == 'contact' || $object -> element == 'product' || $object -> element == 'ticket' ) {
$modulepart = $object -> element ;
} elseif ( $object -> element == 'member' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'memberphoto' ;
2021-04-01 12:27:02 +02:00
} elseif ( $object -> element == 'user' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'userphoto' ;
}
2017-05-05 12:33:49 +02:00
2021-02-23 22:03:23 +01:00
if ( class_exists ( " Imagick " )) {
2021-04-01 12:27:02 +02:00
if ( $object -> element == 'expensereport' || $object -> element == 'propal' || $object -> element == 'commande' || $object -> element == 'facture' || $object -> element == 'supplier_proposal' ) {
$modulepart = $object -> element ;
} elseif ( $object -> element == 'fichinter' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'ficheinter' ;
2021-04-01 12:27:02 +02:00
} elseif ( $object -> element == 'contrat' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'contract' ;
2021-04-01 12:27:02 +02:00
} elseif ( $object -> element == 'order_supplier' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'supplier_order' ;
2021-04-01 12:27:02 +02:00
} elseif ( $object -> element == 'invoice_supplier' ) {
2021-02-23 22:03:23 +01:00
$modulepart = 'supplier_invoice' ;
}
}
if ( $object -> element == 'product' ) {
2021-03-01 20:37:16 +01:00
$width = 80 ;
2022-01-20 18:09:30 +01:00
$cssclass = 'photowithmargin photoref' ;
2019-11-11 23:59:36 +01:00
$showimage = $object -> is_photo_available ( $conf -> product -> multidir_output [ $entity ]);
$maxvisiblephotos = ( isset ( $conf -> global -> PRODUCT_MAX_VISIBLE_PHOTO ) ? $conf -> global -> PRODUCT_MAX_VISIBLE_PHOTO : 5 );
2021-02-23 22:03:23 +01:00
if ( $conf -> browser -> layout == 'phone' ) {
$maxvisiblephotos = 1 ;
}
2020-10-13 10:51:51 +02:00
if ( $showimage ) {
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $object -> show_photos ( 'product' , $conf -> product -> multidir_output [ $entity ], 'small' , $maxvisiblephotos , 0 , 0 , 0 , $width , 0 ) . '</div>' ;
} else {
2016-06-04 16:34:26 +02:00
if ( ! empty ( $conf -> global -> PRODUCT_NODISPLAYIFNOPHOTO )) {
2019-11-11 23:59:36 +01:00
$nophoto = '' ;
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"></div>' ;
2020-05-21 15:05:19 +02:00
} else { // Show no photo link
2019-11-11 23:59:36 +01:00
$nophoto = '/public/theme/common/nophoto.png' ;
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photo' . $modulepart . ( $cssclass ? ' ' . $cssclass : '' ) . '" alt="No photo"' . ( $width ? ' style="width: ' . $width . 'px"' : '' ) . ' src="' . DOL_URL_ROOT . $nophoto . '"></div>' ;
2019-06-17 18:38:14 +02:00
}
2017-10-13 13:28:26 +02:00
}
2020-09-15 13:27:48 +02:00
} elseif ( $object -> element == 'ticket' ) {
2021-03-01 20:37:16 +01:00
$width = 80 ;
$cssclass = 'photoref' ;
2019-11-11 23:59:36 +01:00
$showimage = $object -> is_photo_available ( $conf -> ticket -> multidir_output [ $entity ] . '/' . $object -> ref );
$maxvisiblephotos = ( isset ( $conf -> global -> TICKET_MAX_VISIBLE_PHOTO ) ? $conf -> global -> TICKET_MAX_VISIBLE_PHOTO : 2 );
2021-02-23 22:03:23 +01:00
if ( $conf -> browser -> layout == 'phone' ) {
$maxvisiblephotos = 1 ;
}
2020-12-17 11:57:12 +01:00
2021-02-23 22:03:23 +01:00
if ( $showimage ) {
2019-10-01 12:02:28 +02:00
$showphoto = $object -> show_photos ( 'ticket' , $conf -> ticket -> multidir_output [ $entity ], 'small' , $maxvisiblephotos , 0 , 0 , 0 , $width , 0 );
2021-02-23 22:03:23 +01:00
if ( $object -> nbphoto > 0 ) {
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $showphoto . '</div>' ;
2020-05-21 15:05:19 +02:00
} else {
2019-10-01 12:02:28 +02:00
$showimage = 0 ;
}
}
2021-02-23 22:03:23 +01:00
if ( ! $showimage ) {
2019-10-01 11:28:10 +02:00
if ( ! empty ( $conf -> global -> TICKET_NODISPLAYIFNOPHOTO )) {
2019-11-11 23:59:36 +01:00
$nophoto = '' ;
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"></div>' ;
2020-05-21 15:05:19 +02:00
} else { // Show no photo link
2020-12-17 11:57:12 +01:00
$nophoto = img_picto ( 'No photo' , 'object_ticket' );
$morehtmlleft .= '<!-- No photo to show -->' ;
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref">' ;
$morehtmlleft .= $nophoto ;
$morehtmlleft .= '</div></div>' ;
2019-06-17 18:38:14 +02:00
}
2018-03-18 20:01:11 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $showimage ) {
if ( $modulepart != 'unknown' ) {
2019-11-11 23:59:36 +01:00
$phototoshow = '' ;
2017-10-13 13:28:26 +02:00
// Check if a preview file is available
2021-02-23 22:03:23 +01:00
if ( in_array ( $modulepart , array ( 'propal' , 'commande' , 'facture' , 'ficheinter' , 'contract' , 'supplier_order' , 'supplier_proposal' , 'supplier_invoice' , 'expensereport' )) && class_exists ( " Imagick " )) {
2017-10-13 13:28:26 +02:00
$objectref = dol_sanitizeFileName ( $object -> ref );
2019-11-11 23:59:36 +01:00
$dir_output = ( empty ( $conf -> $modulepart -> multidir_output [ $entity ]) ? $conf -> $modulepart -> dir_output : $conf -> $modulepart -> multidir_output [ $entity ]) . " / " ;
2021-02-23 22:03:23 +01:00
if ( in_array ( $modulepart , array ( 'invoice_supplier' , 'supplier_invoice' ))) {
2018-06-16 15:08:13 +02:00
$subdir = get_exdir ( $object -> id , 2 , 0 , 1 , $object , $modulepart );
2019-11-11 23:59:36 +01:00
$subdir .= (( ! empty ( $subdir ) && ! preg_match ( '/\/$/' , $subdir )) ? '/' : '' ) . $objectref ; // the objectref dir is not included into get_exdir when used with level=2, so we add it at end
2020-05-21 15:05:19 +02:00
} else {
2018-06-06 23:47:48 +02:00
$subdir = get_exdir ( $object -> id , 0 , 0 , 1 , $object , $modulepart );
2017-10-13 13:28:26 +02:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $subdir )) {
$subdir = 'errorgettingsubdirofobject' ; // Protection to avoid to return empty path
}
2018-01-13 16:09:05 +01:00
2019-11-11 23:59:36 +01:00
$filepath = $dir_output . $subdir . " / " ;
2018-06-16 15:08:13 +02:00
2019-11-11 23:59:36 +01:00
$filepdf = $filepath . $objectref . " .pdf " ;
2017-10-13 13:28:26 +02:00
$relativepath = $subdir . '/' . $objectref . '.pdf' ;
// Define path to preview pdf file (preview precompiled "file.ext" are "file.ext_preview.png")
2019-03-24 20:22:05 +01:00
$fileimage = $filepdf . '_preview.png' ;
2017-10-13 13:28:26 +02:00
$relativepathimage = $relativepath . '_preview.png' ;
2019-03-24 20:22:05 +01:00
$pdfexists = file_exists ( $filepdf );
2019-03-24 14:53:26 +01:00
2019-03-24 13:27:26 +01:00
// If PDF file exists
2021-02-23 22:03:23 +01:00
if ( $pdfexists ) {
2017-10-13 13:28:26 +02:00
// Conversion du PDF en image png si fichier png non existant
2021-02-23 22:03:23 +01:00
if ( ! file_exists ( $fileimage ) || ( filemtime ( $fileimage ) < filemtime ( $filepdf ))) {
if ( empty ( $conf -> global -> MAIN_DISABLE_PDF_THUMBS )) { // If you experience trouble with pdf thumb generation and imagick, you can disable here.
2018-12-17 13:57:30 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2019-11-11 23:59:36 +01:00
$ret = dol_convert_file ( $filepdf , 'png' , $fileimage , '0' ); // Convert first page of PDF into a file _preview.png
2021-02-23 22:03:23 +01:00
if ( $ret < 0 ) {
$error ++ ;
}
2017-10-13 13:28:26 +02:00
}
}
2019-03-24 14:53:26 +01:00
}
2017-10-13 13:28:26 +02:00
2021-02-23 22:03:23 +01:00
if ( $pdfexists && ! $error ) {
2020-10-09 18:43:24 +02:00
$heightforphotref = 80 ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen )) {
$heightforphotref = 60 ;
}
2019-03-24 14:54:04 +01:00
// If the preview file is found
2021-02-23 22:03:23 +01:00
if ( file_exists ( $fileimage )) {
2020-10-13 10:51:51 +02:00
$phototoshow = '<div class="photoref">' ;
2019-11-11 23:59:36 +01:00
$phototoshow .= '<img height="' . $heightforphotref . '" class="photo photowithmargin photowithborder" src="' . DOL_URL_ROOT . '/viewimage.php?modulepart=apercu' . $modulepart . '&file=' . urlencode ( $relativepathimage ) . '">' ;
2020-10-13 10:51:51 +02:00
$phototoshow .= '</div>' ;
2017-10-13 13:28:26 +02:00
}
}
2021-04-01 12:27:02 +02:00
} elseif ( ! $phototoshow ) { // example if modulepart = 'societe' or 'photo'
2022-01-17 19:18:48 +01:00
$phototoshow .= $form -> showphoto ( $modulepart , $object , 0 , 0 , 0 , 'photowithmargin photoref' , 'small' , 1 , 0 , $maxvisiblephotos );
2017-10-13 13:28:26 +02:00
}
2020-11-22 01:26:58 +01:00
if ( $phototoshow ) {
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' ;
$morehtmlleft .= $phototoshow ;
$morehtmlleft .= '</div>' ;
2017-10-13 13:28:26 +02:00
}
}
2021-03-17 20:13:20 +01:00
if ( empty ( $phototoshow )) { // Show No photo link (picto of object)
2021-02-23 22:03:23 +01:00
if ( $object -> element == 'action' ) {
2019-11-11 23:59:36 +01:00
$width = 80 ;
$cssclass = 'photorefcenter' ;
2020-04-13 04:14:28 +02:00
$nophoto = img_picto ( 'No photo' , 'title_agenda' );
2020-05-21 15:05:19 +02:00
} else {
2021-03-01 20:37:16 +01:00
$width = 14 ;
$cssclass = 'photorefcenter' ;
2017-10-13 13:28:26 +02:00
$picto = $object -> picto ;
2021-10-26 17:23:51 +02:00
$prefix = 'object_' ;
2021-02-23 22:03:23 +01:00
if ( $object -> element == 'project' && ! $object -> public ) {
$picto = 'project' ; // instead of projectpub
}
2021-10-26 17:23:51 +02:00
if ( strpos ( $picto , 'fontawesome_' ) !== false ) {
$prefix = '' ;
}
$nophoto = img_picto ( 'No photo' , $prefix . $picto );
2017-10-13 13:28:26 +02:00
}
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '<!-- No photo to show -->' ;
2020-04-13 04:14:28 +02:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref">' ;
$morehtmlleft .= $nophoto ;
$morehtmlleft .= '</div></div>' ;
2017-10-13 13:28:26 +02:00
}
}
2015-11-06 18:57:35 +01:00
}
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( $showbarcode ) {
2021-05-18 17:24:17 +02:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $form -> showbarcode ( $object , 100 , 'photoref' ) . '</div>' ;
2021-02-23 22:03:23 +01:00
}
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( $object -> element == 'societe' ) {
if ( ! empty ( $conf -> use_javascript_ajax ) && $user -> rights -> societe -> creer && ! empty ( $conf -> global -> MAIN_DIRECT_STATUS_UPDATE )) {
$morehtmlstatus .= ajax_object_onoff ( $object , 'status' , 'status' , 'InActivity' , 'ActivityCeased' );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= $object -> getLibStatut ( 6 );
2017-11-18 01:29:42 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( $object -> element == 'product' ) {
2017-10-13 13:28:26 +02:00
//$morehtmlstatus.=$langs->trans("Status").' ('.$langs->trans("Sell").') ';
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> use_javascript_ajax ) && $user -> rights -> produit -> creer && ! empty ( $conf -> global -> MAIN_DIRECT_STATUS_UPDATE )) {
$morehtmlstatus .= ajax_object_onoff ( $object , 'status' , 'tosell' , 'ProductStatusOnSell' , 'ProductStatusNotOnSell' );
2017-10-13 13:28:26 +02:00
} else {
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= '<span class="statusrefsell">' . $object -> getLibStatut ( 6 , 0 ) . '</span>' ;
2017-10-13 13:28:26 +02:00
}
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= ' ' ;
2017-10-13 13:28:26 +02:00
//$morehtmlstatus.=$langs->trans("Status").' ('.$langs->trans("Buy").') ';
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> use_javascript_ajax ) && $user -> rights -> produit -> creer && ! empty ( $conf -> global -> MAIN_DIRECT_STATUS_UPDATE )) {
$morehtmlstatus .= ajax_object_onoff ( $object , 'status_buy' , 'tobuy' , 'ProductStatusOnBuy' , 'ProductStatusNotOnBuy' );
2017-10-13 13:28:26 +02:00
} else {
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= '<span class="statusrefbuy">' . $object -> getLibStatut ( 6 , 1 ) . '</span>' ;
2017-10-13 13:28:26 +02:00
}
2021-02-09 09:50:46 +01:00
} elseif ( in_array ( $object -> element , array ( 'facture' , 'invoice' , 'invoice_supplier' , 'chargesociales' , 'loan' , 'tva' , 'salary' ))) {
2019-11-11 23:59:36 +01:00
$tmptxt = $object -> getLibStatut ( 6 , $object -> totalpaye );
2021-02-23 22:03:23 +01:00
if ( empty ( $tmptxt ) || $tmptxt == $object -> getLibStatut ( 3 )) {
$tmptxt = $object -> getLibStatut ( 5 , $object -> totalpaye );
}
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= $tmptxt ;
2020-12-12 21:27:56 +01:00
} elseif ( $object -> element == 'contrat' || $object -> element == 'contract' ) {
2021-02-23 22:03:23 +01:00
if ( $object -> statut == 0 ) {
$morehtmlstatus .= $object -> getLibStatut ( 5 );
} else {
$morehtmlstatus .= $object -> getLibStatut ( 4 );
}
2020-12-12 21:27:56 +01:00
} elseif ( $object -> element == 'facturerec' ) {
2021-02-23 22:03:23 +01:00
if ( $object -> frequency == 0 ) {
$morehtmlstatus .= $object -> getLibStatut ( 2 );
} else {
$morehtmlstatus .= $object -> getLibStatut ( 5 );
}
2020-12-12 21:27:56 +01:00
} elseif ( $object -> element == 'project_task' ) {
2018-03-06 21:51:43 +01:00
$object -> fk_statut = 1 ;
2021-02-23 22:03:23 +01:00
if ( $object -> progress > 0 ) {
$object -> fk_statut = 2 ;
}
if ( $object -> progress >= 100 ) {
$object -> fk_statut = 3 ;
}
2019-11-11 23:59:36 +01:00
$tmptxt = $object -> getLibStatut ( 5 );
$morehtmlstatus .= $tmptxt ; // No status on task
2020-05-21 15:05:19 +02:00
} else { // Generic case
2019-11-11 23:59:36 +01:00
$tmptxt = $object -> getLibStatut ( 6 );
2021-02-23 22:03:23 +01:00
if ( empty ( $tmptxt ) || $tmptxt == $object -> getLibStatut ( 3 )) {
$tmptxt = $object -> getLibStatut ( 5 );
}
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= $tmptxt ;
2015-10-10 12:01:09 +02:00
}
2018-01-22 03:07:11 +01:00
// Add if object was dispatched "into accountancy"
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> accounting -> enabled ) && in_array ( $object -> element , array ( 'bank' , 'paiementcharge' , 'facture' , 'invoice' , 'invoice_supplier' , 'expensereport' , 'payment_various' ))) {
2020-12-14 10:44:51 +01:00
// Note: For 'chargesociales', 'salaries'... this is the payments that are dispatched (so element = 'bank')
2021-02-23 22:03:23 +01:00
if ( method_exists ( $object , 'getVentilExportCompta' )) {
2018-01-22 03:07:11 +01:00
$accounted = $object -> getVentilExportCompta ();
$langs -> load ( " accountancy " );
2020-01-06 15:29:18 +01:00
$morehtmlstatus .= '</div><div class="statusref statusrefbis"><span class="opacitymedium">' . ( $accounted > 0 ? $langs -> trans ( " Accounted " ) : $langs -> trans ( " NotYetAccounted " )) . '</span>' ;
2018-01-22 03:07:11 +01:00
}
}
// Add alias for thirdparty
2021-02-23 22:03:23 +01:00
if ( ! empty ( $object -> name_alias )) {
$morehtmlref .= '<div class="refidno">' . $object -> name_alias . '</div>' ;
}
2017-05-25 08:48:59 +02:00
2017-04-05 14:48:24 +02:00
// Add label
2021-02-23 22:03:23 +01:00
if ( in_array ( $object -> element , array ( 'product' , 'bank_account' , 'project_task' ))) {
if ( ! empty ( $object -> label )) {
$morehtmlref .= '<div class="refidno">' . $object -> label . '</div>' ;
}
2017-02-09 05:58:39 +01:00
}
2017-05-25 08:48:59 +02:00
2021-02-23 22:03:23 +01:00
if ( method_exists ( $object , 'getBannerAddress' ) && ! in_array ( $object -> element , array ( 'product' , 'bookmark' , 'ecm_directories' , 'ecm_files' ))) {
2019-12-09 09:16:59 +01:00
$moreaddress = $object -> getBannerAddress ( 'refaddress' , $object );
if ( $moreaddress ) {
$morehtmlref .= '<div class="refidno">' ;
$morehtmlref .= $moreaddress ;
$morehtmlref .= '</div>' ;
}
2015-11-06 18:57:35 +01:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_SHOW_TECHNICAL_ID ) && ( $conf -> global -> MAIN_SHOW_TECHNICAL_ID == '1' || preg_match ( '/' . preg_quote ( $object -> element , '/' ) . '/i' , $conf -> global -> MAIN_SHOW_TECHNICAL_ID )) && ! empty ( $object -> id )) {
2020-09-16 20:09:40 +02:00
$morehtmlref .= '<div style="clear: both;"></div>' ;
$morehtmlref .= '<div class="refidno">' ;
2019-11-11 23:59:36 +01:00
$morehtmlref .= $langs -> trans ( " TechnicalID " ) . ': ' . $object -> id ;
$morehtmlref .= '</div>' ;
2015-10-11 12:27:04 +02:00
}
2017-05-25 08:48:59 +02:00
2021-11-03 16:18:03 +01:00
$parameters = array ( 'morehtmlref' => $morehtmlref );
2021-11-03 16:31:35 +01:00
$reshook = $hookmanager -> executeHooks ( 'formDolBanner' , $parameters , $object , $action );
2021-11-03 16:18:03 +01:00
if ( $reshook < 0 ) {
setEventMessages ( $hookmanager -> error , $hookmanager -> errors , 'errors' );
} elseif ( empty ( $reshook )) {
$morehtmlref .= $hookmanager -> resPrint ;
} elseif ( $reshook > 0 ) {
$morehtmlref = $hookmanager -> resPrint ;
}
2019-11-11 23:59:36 +01:00
print '<div class="' . ( $onlybanner ? 'arearefnobottom ' : 'arearef ' ) . 'heightref valignmiddle centpercent">' ;
2016-11-11 23:17:37 +01:00
print $form -> showrefnav ( $object , $paramid , $morehtml , $shownav , $fieldid , $fieldref , $morehtmlref , $moreparam , $nodbprefix , $morehtmlleft , $morehtmlstatus , $morehtmlright );
2015-10-10 12:01:09 +02:00
print '</div>' ;
print '<div class="underrefbanner clearboth"></div>' ;
}
2015-11-01 17:27:41 +01:00
2015-06-05 14:02:50 +02:00
/**
* Show a string with the label tag dedicated to the HTML edit field .
*
* @ param string $langkey Translation key
* @ param string $fieldkey Key of the html select field the text refers to
* @ param int $fieldrequired 1 = Field is mandatory
2018-08-14 12:23:10 +02:00
* @ return string
2016-03-25 14:49:48 +01:00
* @ deprecated Form :: editfieldkey
2015-06-05 14:02:50 +02:00
*/
2019-01-27 15:20:16 +01:00
function fieldLabel ( $langkey , $fieldkey , $fieldrequired = 0 )
2015-06-05 14:02:50 +02:00
{
2019-08-29 01:32:10 +02:00
global $langs ;
2019-11-11 23:59:36 +01:00
$ret = '' ;
2021-02-23 22:03:23 +01:00
if ( $fieldrequired ) {
$ret .= '<span class="fieldrequired">' ;
}
2019-11-11 23:59:36 +01:00
$ret .= '<label for="' . $fieldkey . '">' ;
$ret .= $langs -> trans ( $langkey );
$ret .= '</label>' ;
2021-02-23 22:03:23 +01:00
if ( $fieldrequired ) {
$ret .= '</span>' ;
}
2015-06-05 14:02:50 +02:00
return $ret ;
}
2013-04-09 01:27:41 +02:00
/**
* Return string to add class property on html element with pair / impair .
2013-04-14 02:09:41 +02:00
*
2013-04-09 01:27:41 +02:00
* @ param string $var 0 or 1
* @ param string $moreclass More class to add
* @ return string String to add class onto HTML element
*/
2019-01-27 15:20:16 +01:00
function dol_bc ( $var , $moreclass = '' )
2013-04-09 01:27:41 +02:00
{
global $bc ;
2019-11-11 23:59:36 +01:00
$ret = ' ' . $bc [ $var ];
2021-02-23 22:03:23 +01:00
if ( $moreclass ) {
$ret = preg_replace ( '/class=\"/' , 'class="' . $moreclass . ' ' , $ret );
}
2013-04-09 01:27:41 +02:00
return $ret ;
}
2011-10-12 19:24:27 +02:00
/**
2020-01-13 14:25:48 +01:00
* Return a formated address ( part address / zip / town / state ) according to country rules .
* See https :// en . wikipedia . org / wiki / Address
2011-10-12 19:24:27 +02:00
*
2017-11-22 09:51:46 +01:00
* @ param Object $object A company or contact object
2020-01-13 14:25:48 +01:00
* @ param int $withcountry 1 = Add country into address string
* @ param string $sep Separator to use to build string
* @ param Translate $outputlangs Object lang that contains language for text translation .
* @ param int $mode 0 = Standard output , 1 = Remove address
2020-04-01 18:11:28 +02:00
* @ param string $extralangcode User extralanguage $langcode as values for address , town
2017-11-22 09:51:46 +01:00
* @ return string Formated string
2019-03-11 01:01:15 +01:00
* @ see dol_print_address ()
2011-10-12 19:24:27 +02:00
*/
2020-04-01 18:11:28 +02:00
function dol_format_address ( $object , $withcountry = 0 , $sep = " \n " , $outputlangs = '' , $mode = 0 , $extralangcode = '' )
2011-10-12 19:24:27 +02:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs ;
2014-04-23 16:03:49 +02:00
2019-11-11 23:59:36 +01:00
$ret = '' ;
2021-08-18 16:30:28 +02:00
$countriesusingstate = array ( 'AU' , 'CA' , 'US' , 'IN' , 'GB' , 'ES' , 'UK' , 'TR' , 'CN' ); // See also MAIN_FORCE_STATE_INTO_ADDRESS
2011-10-12 19:24:27 +02:00
2020-01-13 14:25:48 +01:00
// See format of addresses on https://en.wikipedia.org/wiki/Address
2011-10-12 19:24:27 +02:00
// Address
2017-11-22 11:14:52 +01:00
if ( empty ( $mode )) {
2021-03-17 20:13:20 +01:00
$ret .= ( $extralangcode ? $object -> array_languages [ 'address' ][ $extralangcode ] : ( empty ( $object -> address ) ? '' : $object -> address ));
2017-11-22 09:51:46 +01:00
}
2011-10-12 19:24:27 +02:00
// Zip/Town/State
2021-08-18 16:30:28 +02:00
if ( isset ( $object -> country_code ) && in_array ( $object -> country_code , array ( 'AU' , 'CA' , 'US' , 'CN' )) || ! empty ( $conf -> global -> MAIN_FORCE_STATE_INTO_ADDRESS )) {
2021-03-01 20:37:16 +01:00
// US: title firstname name \n address lines \n town, state, zip \n country
2021-03-17 20:13:20 +01:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
2020-04-01 18:11:28 +02:00
$ret .= ( $ret ? $sep : '' ) . $town ;
2020-12-05 14:09:51 +01:00
if ( ! empty ( $object -> state )) {
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2011-10-12 19:24:27 +02:00
}
2021-03-17 20:13:20 +01:00
if ( ! empty ( $object -> zip )) {
2021-02-23 22:03:23 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> zip ;
}
2021-03-01 20:37:16 +01:00
} elseif ( isset ( $object -> country_code ) && in_array ( $object -> country_code , array ( 'GB' , 'UK' ))) {
// UK: title firstname name \n address lines \n town state \n zip \n country
2021-03-17 20:13:20 +01:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
2020-04-01 18:11:28 +02:00
$ret .= ( $ret ? $sep : '' ) . $town ;
2020-12-05 14:09:51 +01:00
if ( ! empty ( $object -> state )) {
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2012-09-15 09:02:20 +02:00
}
2021-03-17 20:13:20 +01:00
if ( ! empty ( $object -> zip )) {
2021-02-23 22:03:23 +01:00
$ret .= ( $ret ? $sep : '' ) . $object -> zip ;
}
2021-03-01 20:37:16 +01:00
} elseif ( isset ( $object -> country_code ) && in_array ( $object -> country_code , array ( 'ES' , 'TR' ))) {
// ES: title firstname name \n address lines \n zip town \n state \n country
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? $sep : '' ) . $object -> zip ;
2021-03-17 20:13:20 +01:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
2020-04-01 18:11:28 +02:00
$ret .= ( $town ? (( $object -> zip ? ' ' : '' ) . $town ) : '' );
2020-12-05 14:09:51 +01:00
if ( ! empty ( $object -> state )) {
2019-11-11 23:59:36 +01:00
$ret .= " \n " . $object -> state ;
2013-02-19 16:02:58 +01:00
}
2021-09-02 10:39:56 +02:00
} elseif ( isset ( $object -> country_code ) && in_array ( $object -> country_code , array ( 'JP' ))) {
// JP: In romaji, title firstname name\n address lines \n [state,] town zip \n country
// See https://www.sljfaq.org/afaq/addresses.html
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
$ret .= ( $ret ? $sep : '' ) . ( $object -> state ? $object -> state . ', ' : '' ) . $town . ( $object -> zip ? ' ' : '' ) . $object -> zip ;
2021-03-01 20:37:16 +01:00
} elseif ( isset ( $object -> country_code ) && in_array ( $object -> country_code , array ( 'IT' ))) {
2021-09-02 10:39:56 +02:00
// IT: title firstname name\n address lines \n zip town state_code \n country
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? $sep : '' ) . $object -> zip ;
2021-03-17 20:13:20 +01:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
2020-04-01 18:11:28 +02:00
$ret .= ( $town ? (( $object -> zip ? ' ' : '' ) . $town ) : '' );
2020-12-05 14:09:51 +01:00
$ret .= ( empty ( $object -> state_code ) ? '' : ( ' ' . $object -> state_code ));
2021-09-02 10:39:56 +02:00
} else {
// Other: title firstname name \n address lines \n zip town[, state] \n country
2021-03-17 20:13:20 +01:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : ( empty ( $object -> town ) ? '' : $object -> town ));
$ret .= ! empty ( $object -> zip ) ? (( $ret ? $sep : '' ) . $object -> zip ) : '' ;
2020-04-01 18:11:28 +02:00
$ret .= ( $town ? (( $object -> zip ? ' ' : ( $ret ? $sep : '' )) . $town ) : '' );
2020-12-05 14:09:51 +01:00
if ( ! empty ( $object -> state ) && in_array ( $object -> country_code , $countriesusingstate )) {
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2011-10-12 19:24:27 +02:00
}
}
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $outputlangs )) {
$outputlangs = $langs ;
}
2020-12-05 13:48:51 +01:00
if ( $withcountry ) {
2018-05-21 19:37:47 +02:00
$langs -> load ( " dict " );
2020-12-05 13:48:51 +01:00
$ret .= ( empty ( $object -> country_code ) ? '' : ( $ret ? $sep : '' ) . $outputlangs -> convToOutputCharset ( $outputlangs -> transnoentitiesnoconv ( " Country " . $object -> country_code )));
2018-05-21 19:37:47 +02:00
}
2013-04-07 17:39:08 +02:00
2011-10-12 19:24:27 +02:00
return $ret ;
}
2013-01-18 15:57:11 +01:00
2013-01-19 16:29:16 +01:00
/**
* Format a string .
2013-01-18 15:57:11 +01:00
*
* @ param string $fmt Format of strftime function ( http :// php . net / manual / fr / function . strftime . php )
* @ param int $ts Timesamp ( If is_gmt is true , timestamp is already includes timezone and daylight saving offset , if is_gmt is false , timestamp is a GMT timestamp and we must compensate with server PHP TZ )
* @ param int $is_gmt See comment of timestamp parameter
* @ return string A formatted string
2013-01-19 16:29:16 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_strftime ( $fmt , $ts = false , $is_gmt = false )
2013-01-19 16:29:16 +01:00
{
if (( abs ( $ts ) <= 0x7FFFFFFF )) { // check if number in 32-bit signed range
2019-11-11 23:59:36 +01:00
return ( $is_gmt ) ? @ gmstrftime ( $fmt , $ts ) : @ strftime ( $fmt , $ts );
2021-02-23 22:03:23 +01:00
} else {
return 'Error date into a not supported range' ;
}
2013-01-18 15:57:11 +01:00
}
2008-08-06 16:50:06 +02:00
/**
2010-11-21 17:11:52 +01:00
* Output date in a string format according to outputlangs ( or langs if not defined ) .
2012-01-22 02:12:11 +01:00
* Return charset is always UTF - 8 , except if encodetoouput is defined . In this case charset is output charset
2011-09-03 01:57:26 +02:00
*
2013-11-07 21:12:11 +01:00
* @ param int $time GM Timestamps date
2013-12-13 17:36:43 +01:00
* @ param string $format Output date format ( tag of strftime function )
2011-10-03 18:10:50 +02:00
* " %d %b %Y " ,
* " %d/%m/%Y %H:%M " ,
* " %d/%m/%Y %H:%M:%S " ,
2016-12-04 21:27:08 +01:00
* " %B " = Long text of month , " %A " = Long text of day , " %b " = Short text of month , " %a " = Short text of day
2021-02-19 22:00:44 +01:00
* " day " , " daytext " , " dayhour " , " dayhourldap " , " dayhourtext " , " dayrfc " , " dayhourrfc " , " ...inputnoreduce " , " ...reduceformat "
2013-01-18 15:57:11 +01:00
* @ param string $tzoutput true or 'gmt' => string is for Greenwich location
2011-10-03 18:10:50 +02:00
* false or 'tzserver' => output string is for local PHP server TZ usage
2017-10-29 17:49:24 +01:00
* 'tzuser' => output string is for user TZ ( current browser TZ with current dst ) => In a future , we should have same behaviour than 'tzuserrel'
2017-10-12 14:59:38 +02:00
* 'tzuserrel' => output string is for user TZ ( current browser TZ with dst or not , depending on date position ) ( TODO not implemented yet )
2014-09-18 15:38:07 +02:00
* @ param Translate $outputlangs Object lang that contains language for text translation .
2011-10-03 18:10:50 +02:00
* @ param boolean $encodetooutput false = no convert into output pagecode
* @ return string Formated date or '' if time is null
*
2019-03-11 01:01:15 +01:00
* @ see dol_mktime (), dol_stringtotime (), dol_getdate ()
2008-08-06 16:50:06 +02:00
*/
2021-01-03 18:42:45 +01:00
function dol_print_date ( $time , $format = '' , $tzoutput = 'auto' , $outputlangs = '' , $encodetooutput = false )
2008-08-06 16:50:06 +02:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs ;
2012-08-03 23:29:08 +02:00
2021-10-31 16:56:38 +01:00
// If date undefined or "", we return ""
if ( dol_strlen ( $time ) == 0 ) {
return '' ; // $time=0 allowed (it means 01/01/1970 00:00:00)
}
2021-01-28 10:30:09 +01:00
if ( $tzoutput === 'auto' ) {
2021-03-02 23:57:37 +01:00
$tzoutput = ( empty ( $conf ) ? 'tzserver' : ( isset ( $conf -> tzuserinputkey ) ? $conf -> tzuserinputkey : 'tzserver' ));
2021-01-03 18:42:45 +01:00
}
2013-04-03 15:20:56 +02:00
// Clean parameters
2019-11-11 23:59:36 +01:00
$to_gmt = false ;
$offsettz = $offsetdst = 0 ;
2021-02-23 22:03:23 +01:00
if ( $tzoutput ) {
2019-11-11 23:59:36 +01:00
$to_gmt = true ; // For backward compatibility
2021-02-23 22:03:23 +01:00
if ( is_string ( $tzoutput )) {
if ( $tzoutput == 'tzserver' ) {
2019-11-11 23:59:36 +01:00
$to_gmt = false ;
$offsettzstring = @ date_default_timezone_get (); // Example 'Europe/Berlin' or 'Indian/Reunion'
2021-04-28 20:44:22 +02:00
$offsettz = 0 ; // Timezone offset with server timezone, so 0
$offsetdst = 0 ; // Dst offset with server timezone, so 0
2021-02-23 22:03:23 +01:00
} elseif ( $tzoutput == 'tzuser' || $tzoutput == 'tzuserrel' ) {
2019-11-11 23:59:36 +01:00
$to_gmt = true ;
$offsettzstring = ( empty ( $_SESSION [ 'dol_tz_string' ]) ? 'UTC' : $_SESSION [ 'dol_tz_string' ]); // Example 'Europe/Berlin' or 'Indian/Reunion'
2021-10-14 16:06:22 +02:00
if ( class_exists ( 'DateTimeZone' )) {
$user_date_tz = new DateTimeZone ( $offsettzstring );
$user_dt = new DateTime ();
$user_dt -> setTimezone ( $user_date_tz );
2021-10-31 16:56:38 +01:00
$user_dt -> setTimestamp ( $tzoutput == 'tzuser' ? dol_now () : ( int ) $time );
2021-10-14 16:06:22 +02:00
$offsettz = $user_dt -> getOffset ();
2021-10-16 21:03:47 +02:00
} else { // old method (The 'tzuser' was processed like the 'tzuserrel')
2021-10-14 16:06:22 +02:00
$offsettz = ( empty ( $_SESSION [ 'dol_tz' ]) ? 0 : $_SESSION [ 'dol_tz' ]) * 60 * 60 ; // Will not be used anymore
$offsetdst = ( empty ( $_SESSION [ 'dol_dst' ]) ? 0 : $_SESSION [ 'dol_dst' ]) * 60 * 60 ; // Will not be used anymore
}
2012-08-03 23:29:08 +02:00
}
}
}
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $outputlangs )) {
$outputlangs = $langs ;
}
if ( ! $format ) {
$format = 'daytextshort' ;
}
2021-02-19 22:00:44 +01:00
// Do we have to reduce the length of date (year on 2 chars) to save space.
// Note: dayinputnoreduce is same than day but no reduction of year length will be done
$reduceformat = ( ! empty ( $conf -> dol_optimize_smallscreen ) && in_array ( $format , array ( 'day' , 'dayhour' ))) ? 1 : 0 ; // Test on original $format param.
$format = preg_replace ( '/inputnoreduce/' , '' , $format ); // so format 'dayinputnoreduce' is processed like day
2019-01-27 11:55:16 +01:00
$formatwithoutreduce = preg_replace ( '/reduceformat/' , '' , $format );
2021-02-23 22:03:23 +01:00
if ( $formatwithoutreduce != $format ) {
2021-03-01 20:37:16 +01:00
$format = $formatwithoutreduce ;
$reduceformat = 1 ;
2021-02-23 22:03:23 +01:00
} // so format 'dayreduceformat' is processed like day
2016-11-16 09:40:29 +01:00
2012-08-03 23:29:08 +02:00
// Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default.
2016-11-16 09:40:29 +01:00
// TODO Add format daysmallyear and dayhoursmallyear
2021-02-23 22:03:23 +01:00
if ( $format == 'day' ) {
$format = ( $outputlangs -> trans ( " FormatDateShort " ) != " FormatDateShort " ? $outputlangs -> trans ( " FormatDateShort " ) : $conf -> format_date_short );
} elseif ( $format == 'hour' ) {
$format = ( $outputlangs -> trans ( " FormatHourShort " ) != " FormatHourShort " ? $outputlangs -> trans ( " FormatHourShort " ) : $conf -> format_hour_short );
} elseif ( $format == 'hourduration' ) {
$format = ( $outputlangs -> trans ( " FormatHourShortDuration " ) != " FormatHourShortDuration " ? $outputlangs -> trans ( " FormatHourShortDuration " ) : $conf -> format_hour_short_duration );
} elseif ( $format == 'daytext' ) {
$format = ( $outputlangs -> trans ( " FormatDateText " ) != " FormatDateText " ? $outputlangs -> trans ( " FormatDateText " ) : $conf -> format_date_text );
} elseif ( $format == 'daytextshort' ) {
$format = ( $outputlangs -> trans ( " FormatDateTextShort " ) != " FormatDateTextShort " ? $outputlangs -> trans ( " FormatDateTextShort " ) : $conf -> format_date_text_short );
} elseif ( $format == 'dayhour' ) {
$format = ( $outputlangs -> trans ( " FormatDateHourShort " ) != " FormatDateHourShort " ? $outputlangs -> trans ( " FormatDateHourShort " ) : $conf -> format_date_hour_short );
} elseif ( $format == 'dayhoursec' ) {
$format = ( $outputlangs -> trans ( " FormatDateHourSecShort " ) != " FormatDateHourSecShort " ? $outputlangs -> trans ( " FormatDateHourSecShort " ) : $conf -> format_date_hour_sec_short );
} elseif ( $format == 'dayhourtext' ) {
$format = ( $outputlangs -> trans ( " FormatDateHourText " ) != " FormatDateHourText " ? $outputlangs -> trans ( " FormatDateHourText " ) : $conf -> format_date_hour_text );
} elseif ( $format == 'dayhourtextshort' ) {
$format = ( $outputlangs -> trans ( " FormatDateHourTextShort " ) != " FormatDateHourTextShort " ? $outputlangs -> trans ( " FormatDateHourTextShort " ) : $conf -> format_date_hour_text_short );
2021-03-01 20:37:16 +01:00
} elseif ( $format == 'dayhourlog' ) {
// Format not sensitive to language
2021-02-23 22:03:23 +01:00
$format = '%Y%m%d%H%M%S' ;
} elseif ( $format == 'dayhourldap' ) {
$format = '%Y%m%d%H%M%SZ' ;
} elseif ( $format == 'dayhourxcard' ) {
$format = '%Y%m%dT%H%M%SZ' ;
} elseif ( $format == 'dayxcard' ) {
$format = '%Y%m%d' ;
} elseif ( $format == 'dayrfc' ) {
$format = '%Y-%m-%d' ; // DATE_RFC3339
} elseif ( $format == 'dayhourrfc' ) {
$format = '%Y-%m-%dT%H:%M:%SZ' ; // DATETIME RFC3339
} elseif ( $format == 'standard' ) {
$format = '%Y-%m-%d %H:%M:%S' ;
}
if ( $reduceformat ) {
2019-11-11 23:59:36 +01:00
$format = str_replace ( '%Y' , '%y' , $format );
$format = str_replace ( 'yyyy' , 'yy' , $format );
2013-04-21 17:56:29 +02:00
}
2013-04-24 03:56:13 +02:00
2013-04-03 15:20:56 +02:00
// Clean format
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/%b/i' , $format )) { // There is some text to translate
2012-08-03 23:29:08 +02:00
// We inhibate translation to text made by strftime functions. We will use trans instead later.
2019-11-11 23:59:36 +01:00
$format = str_replace ( '%b' , '__b__' , $format );
$format = str_replace ( '%B' , '__B__' , $format );
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/%a/i' , $format )) { // There is some text to translate
2012-08-03 23:29:08 +02:00
// We inhibate translation to text made by strftime functions. We will use trans instead later.
2019-11-11 23:59:36 +01:00
$format = str_replace ( '%a' , '__a__' , $format );
$format = str_replace ( '%A' , '__A__' , $format );
2012-08-03 23:29:08 +02:00
}
2020-03-04 19:22:30 +01:00
2015-07-28 18:12:45 +02:00
// Analyze date
2019-11-11 23:59:36 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i' , $time , $reg )) { // Deprecated. Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000
2021-10-26 16:45:40 +02:00
dol_print_error ( '' , " Functions.lib::dol_print_date function called with a bad value from page " . $_SERVER [ " PHP_SELF " ]);
2020-09-07 10:18:17 +02:00
return '' ;
2021-02-23 22:03:23 +01:00
} elseif ( preg_match ( '/^([0-9]+)\-([0-9]+)\-([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i' , $time , $reg )) { // Still available to solve problems in extrafields of type date
2021-04-19 12:48:08 +02:00
// This part of code should not be used anymore.
2020-09-07 10:18:17 +02:00
dol_syslog ( " Functions.lib::dol_print_date function called with a bad value from page " . $_SERVER [ " PHP_SELF " ], LOG_WARNING );
//if (function_exists('debug_print_backtrace')) debug_print_backtrace();
// Date has format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'
$syear = ( ! empty ( $reg [ 1 ]) ? $reg [ 1 ] : '' );
$smonth = ( ! empty ( $reg [ 2 ]) ? $reg [ 2 ] : '' );
$sday = ( ! empty ( $reg [ 3 ]) ? $reg [ 3 ] : '' );
$shour = ( ! empty ( $reg [ 4 ]) ? $reg [ 4 ] : '' );
$smin = ( ! empty ( $reg [ 5 ]) ? $reg [ 5 ] : '' );
$ssec = ( ! empty ( $reg [ 6 ]) ? $reg [ 6 ] : '' );
$time = dol_mktime ( $shour , $smin , $ssec , $smonth , $sday , $syear , true );
$ret = adodb_strftime ( $format , $time + $offsettz + $offsetdst , $to_gmt );
2020-05-21 15:05:19 +02:00
} else {
2012-08-03 23:29:08 +02:00
// Date is a timestamps
2021-02-23 22:03:23 +01:00
if ( $time < 100000000000 ) { // Protection against bad date values
2019-11-11 23:59:36 +01:00
$timetouse = $time + $offsettz + $offsetdst ; // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring.
2017-10-29 17:49:24 +01:00
2021-04-28 20:44:22 +02:00
$ret = adodb_strftime ( $format , $timetouse , $to_gmt ); // If to_gmt = false then adodb_strftime use TZ of server
2021-02-23 22:03:23 +01:00
} else {
$ret = 'Bad value ' . $time . ' for date' ;
}
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/__b__/i' , $format )) {
2019-11-11 23:59:36 +01:00
$timetouse = $time + $offsettz + $offsetdst ; // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring.
2017-10-29 17:49:24 +01:00
2012-08-03 23:29:08 +02:00
// Here ret is string in PHP setup language (strftime was used). Now we convert to $outputlangs.
2021-04-28 20:44:22 +02:00
$month = adodb_strftime ( '%m' , $timetouse , $to_gmt ); // If to_gmt = false then adodb_strftime use TZ of server
2019-11-11 23:59:36 +01:00
$month = sprintf ( " %02d " , $month ); // $month may be return with format '06' on some installation and '6' on other, so we force it to '06'.
2021-02-23 22:03:23 +01:00
if ( $encodetooutput ) {
2019-11-11 23:59:36 +01:00
$monthtext = $outputlangs -> transnoentities ( 'Month' . $month );
$monthtextshort = $outputlangs -> transnoentities ( 'MonthShort' . $month );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$monthtext = $outputlangs -> transnoentitiesnoconv ( 'Month' . $month );
$monthtextshort = $outputlangs -> transnoentitiesnoconv ( 'MonthShort' . $month );
2012-08-03 23:29:08 +02:00
}
//print 'monthtext='.$monthtext.' monthtextshort='.$monthtextshort;
2019-11-11 23:59:36 +01:00
$ret = str_replace ( '__b__' , $monthtextshort , $ret );
$ret = str_replace ( '__B__' , $monthtext , $ret );
2012-08-03 23:29:08 +02:00
//print 'x'.$outputlangs->charset_output.'-'.$ret.'x';
//return $ret;
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/__a__/i' , $format )) {
2021-04-28 20:44:22 +02:00
//print "time=$time offsettz=$offsettz offsetdst=$offsetdst offsettzstring=$offsettzstring";
2019-11-11 23:59:36 +01:00
$timetouse = $time + $offsettz + $offsetdst ; // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring.
2017-10-29 17:49:24 +01:00
2021-04-28 20:44:22 +02:00
$w = adodb_strftime ( '%w' , $timetouse , $to_gmt ); // If to_gmt = false then adodb_strftime use TZ of server
2019-11-11 23:59:36 +01:00
$dayweek = $outputlangs -> transnoentitiesnoconv ( 'Day' . $w );
$ret = str_replace ( '__A__' , $dayweek , $ret );
$ret = str_replace ( '__a__' , dol_substr ( $dayweek , 0 , 3 ), $ret );
2012-08-03 23:29:08 +02:00
}
return $ret ;
2008-08-06 16:50:06 +02:00
}
/**
2019-10-17 20:24:04 +02:00
* Return an array with locale date info .
2020-10-14 17:11:22 +02:00
* WARNING : This function use PHP server timezone by default to return locale informations .
* Be aware to add the third parameter to " UTC " if you need to work on UTC .
2012-01-22 02:12:11 +01:00
*
2013-11-07 21:12:11 +01:00
* @ param int $timestamp Timestamp
2020-10-14 17:11:22 +02:00
* @ param boolean $fast Fast mode . deprecated .
2021-04-19 12:48:08 +02:00
* @ param string $forcetimezone '' to use the PHP server timezone . Or use a form like 'gmt' , 'Europe/Paris' or '+0200' to force timezone .
2011-10-03 18:10:50 +02:00
* @ return array Array of informations
* 'seconds' => $secs ,
* 'minutes' => $min ,
* 'hours' => $hour ,
* 'mday' => $day ,
2015-02-03 11:25:51 +01:00
* 'wday' => $dow , 0 = sunday , 6 = saturday
2011-10-03 18:10:50 +02:00
* 'mon' => $month ,
* 'year' => $year ,
2020-10-14 17:11:22 +02:00
* 'yday' => floor ( $secsInYear / $_day_power )
2020-10-14 19:42:17 +02:00
* '0' => original timestamp
2019-03-11 01:01:15 +01:00
* @ see dol_print_date (), dol_stringtotime (), dol_mktime ()
2008-08-06 16:50:06 +02:00
*/
2020-10-14 17:11:22 +02:00
function dol_getdate ( $timestamp , $fast = false , $forcetimezone = '' )
2008-08-06 16:50:06 +02:00
{
2021-05-04 13:33:18 +02:00
//$datetimeobj = new DateTime('@'.$timestamp);
$datetimeobj = new DateTime ();
$datetimeobj -> setTimestamp ( $timestamp ); // Use local PHP server timezone
if ( $forcetimezone ) {
$datetimeobj -> setTimezone ( new DateTimeZone ( $forcetimezone == 'gmt' ? 'UTC' : $forcetimezone )); // (add timezone relative to the date entered)
}
$arrayinfo = array (
'year' => (( int ) date_format ( $datetimeobj , 'Y' )),
'mon' => (( int ) date_format ( $datetimeobj , 'm' )),
'mday' => (( int ) date_format ( $datetimeobj , 'd' )),
'wday' => (( int ) date_format ( $datetimeobj , 'w' )),
'yday' => (( int ) date_format ( $datetimeobj , 'z' )),
'hours' => (( int ) date_format ( $datetimeobj , 'H' )),
'minutes' => (( int ) date_format ( $datetimeobj , 'i' )),
'seconds' => (( int ) date_format ( $datetimeobj , 's' )),
'0' => $timestamp
);
2012-08-03 23:29:08 +02:00
return $arrayinfo ;
2008-08-06 16:50:06 +02:00
}
/**
2010-02-03 03:22:15 +01:00
* Return a timestamp date built from detailed informations ( by default a local PHP server timestamp )
2009-01-04 23:09:02 +01:00
* Replace function mktime not available under Windows if year < 1970
2008-10-11 00:27:11 +02:00
* PHP mktime is restricted to the years 1901 - 2038 on Unix and 1970 - 2038 on Windows
2011-09-03 01:57:26 +02:00
*
2012-01-22 02:12:11 +01:00
* @ param int $hour Hour ( can be - 1 for undefined )
* @ param int $minute Minute ( can be - 1 for undefined )
* @ param int $second Second ( can be - 1 for undefined )
* @ param int $month Month ( 1 to 12 )
* @ param int $day Day ( 1 to 31 )
* @ param int $year Year
2016-02-22 22:00:59 +01:00
* @ param mixed $gm True or 1 or 'gmt' = Input informations are GMT values
2021-01-03 15:26:31 +01:00
* False or 0 or 'tzserver' = local to server TZ
2021-01-03 18:42:45 +01:00
* 'auto'
* 'tzuser' = local to user TZ taking dst into account at the current date . Not yet implemented .
2021-09-23 02:10:39 +02:00
* 'tzuserrel' = local to user TZ taking dst into account at the given date . Use this one to convert date input from user into a GMT date .
2016-02-22 22:00:59 +01:00
* 'tz,TimeZone' = use specified timezone
2012-01-22 02:12:11 +01:00
* @ param int $check 0 = No check on parameters ( Can use day 32 , etc ... )
2015-03-10 14:09:29 +01:00
* @ return int | string Date as a timestamp , '' or false if error
2019-03-11 01:01:15 +01:00
* @ see dol_print_date (), dol_stringtotime (), dol_getdate ()
2008-08-06 16:50:06 +02:00
*/
2021-01-03 18:42:45 +01:00
function dol_mktime ( $hour , $minute , $second , $month , $day , $year , $gm = 'auto' , $check = 1 )
2008-08-06 16:50:06 +02:00
{
2012-08-03 23:29:08 +02:00
global $conf ;
//print "- ".$hour.",".$minute.",".$second.",".$month.",".$day.",".$year.",".$_SERVER["WINDIR"]." -";
2021-02-02 00:19:41 +01:00
if ( $gm === 'auto' ) {
$gm = ( empty ( $conf ) ? 'tzserver' : $conf -> tzuserinputkey );
2021-01-03 18:42:45 +01:00
}
2022-02-11 11:20:36 +01:00
//print 'gm:'.$gm.' gm === auto:'.($gm === 'auto').'<br>';exit;
2021-01-03 18:42:45 +01:00
2012-08-03 23:29:08 +02:00
// Clean parameters
2021-02-23 22:03:23 +01:00
if ( $hour == - 1 || empty ( $hour )) {
$hour = 0 ;
}
if ( $minute == - 1 || empty ( $minute )) {
$minute = 0 ;
}
if ( $second == - 1 || empty ( $second )) {
$second = 0 ;
}
2012-08-03 23:29:08 +02:00
// Check parameters
2021-02-23 22:03:23 +01:00
if ( $check ) {
if ( ! $month || ! $day ) {
return '' ;
}
if ( $day > 31 ) {
return '' ;
}
if ( $month > 12 ) {
return '' ;
}
if ( $hour < 0 || $hour > 24 ) {
return '' ;
}
if ( $minute < 0 || $minute > 60 ) {
return '' ;
}
if ( $second < 0 || $second > 60 ) {
return '' ;
}
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $gm ) || ( $gm === 'server' || $gm === 'tzserver' )) {
2019-11-11 23:59:36 +01:00
$default_timezone = @ date_default_timezone_get (); // Example 'Europe/Berlin'
2019-11-01 15:21:21 +01:00
$localtz = new DateTimeZone ( $default_timezone );
2021-02-23 22:03:23 +01:00
} elseif ( $gm === 'user' || $gm === 'tzuser' || $gm === 'tzuserrel' ) {
2019-11-01 15:21:21 +01:00
// We use dol_tz_string first because it is more reliable.
2019-11-11 23:59:36 +01:00
$default_timezone = ( empty ( $_SESSION [ " dol_tz_string " ]) ? @ date_default_timezone_get () : $_SESSION [ " dol_tz_string " ]); // Example 'Europe/Berlin'
2019-11-01 15:21:21 +01:00
try {
2014-03-21 10:13:29 +01:00
$localtz = new DateTimeZone ( $default_timezone );
2021-02-23 22:03:23 +01:00
} catch ( Exception $e ) {
2019-11-01 15:21:21 +01:00
dol_syslog ( " Warning dol_tz_string contains an invalid value " . $_SESSION [ " dol_tz_string " ], LOG_WARNING );
2019-11-11 23:59:36 +01:00
$default_timezone = @ date_default_timezone_get ();
2014-03-21 09:49:10 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strrpos ( $gm , " tz, " ) !== false ) {
2019-11-11 23:59:36 +01:00
$timezone = str_replace ( " tz, " , " " , $gm ); // Example 'tz,Europe/Berlin'
2020-05-21 01:41:27 +02:00
try {
2019-11-01 15:21:21 +01:00
$localtz = new DateTimeZone ( $timezone );
2021-02-23 22:03:23 +01:00
} catch ( Exception $e ) {
2019-11-01 15:21:21 +01:00
dol_syslog ( " Warning passed timezone contains an invalid value " . $timezone , LOG_WARNING );
2014-11-12 22:53:23 +01:00
}
2012-08-03 23:29:08 +02:00
}
2019-11-01 15:21:21 +01:00
if ( empty ( $localtz )) {
$localtz = new DateTimeZone ( 'UTC' );
2012-08-03 23:29:08 +02:00
}
2019-11-01 15:21:21 +01:00
//var_dump($localtz);
//var_dump($year.'-'.$month.'-'.$day.'-'.$hour.'-'.$minute);
$dt = new DateTime ( null , $localtz );
$dt -> setDate (( int ) $year , ( int ) $month , ( int ) $day );
$dt -> setTime (( int ) $hour , ( int ) $minute , ( int ) $second );
2019-11-11 23:59:36 +01:00
$date = $dt -> getTimestamp (); // should include daylight saving time
2019-11-01 15:21:21 +01:00
//var_dump($date);
return $date ;
2008-08-06 16:50:06 +02:00
}
2012-02-06 05:31:19 +01:00
/**
2019-10-17 20:24:04 +02:00
* Return date for now . In most cases , we use this function without parameters ( that means GMT time ) .
2012-02-06 05:31:19 +01:00
*
2021-02-02 00:19:41 +01:00
* @ param string $mode 'auto' => for backward compatibility ( avoid this ),
2021-01-03 18:42:45 +01:00
* 'gmt' => we return GMT timestamp ,
2012-02-06 05:31:19 +01:00
* 'tzserver' => we add the PHP server timezone
2021-01-03 18:42:45 +01:00
* 'tzref' => we add the company timezone . Not implemented .
* 'tzuser' or 'tzuserrel' => we add the user timezone
2013-11-07 21:12:11 +01:00
* @ return int $date Timestamp
2012-02-06 05:31:19 +01:00
*/
2021-01-03 18:42:45 +01:00
function dol_now ( $mode = 'auto' )
2012-02-06 05:31:19 +01:00
{
2019-11-11 23:59:36 +01:00
$ret = 0 ;
2017-11-25 12:11:02 +01:00
2021-02-02 00:19:41 +01:00
if ( $mode === 'auto' ) {
$mode = 'gmt' ;
2021-01-03 18:42:45 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $mode == 'gmt' ) {
$ret = time (); // Time for now at greenwich.
} elseif ( $mode == 'tzserver' ) { // Time for now with PHP server timezone added
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2019-11-11 23:59:36 +01:00
$tzsecond = getServerTimeZoneInt ( 'now' ); // Contains tz+dayling saving time
$ret = ( int ) ( dol_now ( 'gmt' ) + ( $tzsecond * 3600 ));
2021-03-01 20:37:16 +01:00
//} elseif ($mode == 'tzref') {// Time for now with parent company timezone is added
// require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
// $tzsecond=getParentCompanyTimeZoneInt(); // Contains tz+dayling saving time
// $ret=dol_now('gmt')+($tzsecond*3600);
//}
} elseif ( $mode == 'tzuser' || $mode == 'tzuserrel' ) {
// Time for now with user timezone added
2020-02-19 11:59:27 +01:00
//print 'time: '.time();
2019-11-11 23:59:36 +01:00
$offsettz = ( empty ( $_SESSION [ 'dol_tz' ]) ? 0 : $_SESSION [ 'dol_tz' ]) * 60 * 60 ;
$offsetdst = ( empty ( $_SESSION [ 'dol_dst' ]) ? 0 : $_SESSION [ 'dol_dst' ]) * 60 * 60 ;
$ret = ( int ) ( dol_now ( 'gmt' ) + ( $offsettz + $offsetdst ));
2012-08-03 23:29:08 +02:00
}
2017-11-25 12:11:02 +01:00
2012-08-03 23:29:08 +02:00
return $ret ;
2012-02-06 05:31:19 +01:00
}
2009-01-07 13:39:40 +01:00
/**
2011-02-02 16:51:18 +01:00
* Return string with formated size
2011-09-03 01:57:26 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param int $size Size to print
* @ param int $shortvalue Tell if we want long value to use another unit ( Ex : 1.5 Kb instead of 1500 b )
2018-04-15 17:58:13 +02:00
* @ param int $shortunit Use short label of size unit ( for example 'b' instead of 'bytes' )
2011-09-17 02:47:01 +02:00
* @ return string Link
2009-01-07 13:39:40 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_size ( $size , $shortvalue = 0 , $shortunit = 0 )
2009-01-07 13:39:40 +01:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs ;
$level = 1024 ;
2013-04-24 03:56:13 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen )) {
$shortunit = 1 ;
}
2013-04-24 03:56:13 +02:00
2012-08-03 23:29:08 +02:00
// Set value text
2021-02-23 22:03:23 +01:00
if ( empty ( $shortvalue ) || $size < ( $level * 10 )) {
2019-11-11 23:59:36 +01:00
$ret = $size ;
$textunitshort = $langs -> trans ( " b " );
$textunitlong = $langs -> trans ( " Bytes " );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$ret = round ( $size / $level , 0 );
$textunitshort = $langs -> trans ( " Kb " );
$textunitlong = $langs -> trans ( " KiloBytes " );
2012-08-03 23:29:08 +02:00
}
// Use long or short text unit
2021-02-23 22:03:23 +01:00
if ( empty ( $shortunit )) {
$ret .= ' ' . $textunitlong ;
} else {
$ret .= ' ' . $textunitshort ;
}
2012-08-03 23:29:08 +02:00
return $ret ;
2009-01-07 13:39:40 +01:00
}
/**
2011-07-04 10:38:51 +02:00
* Show Url link
2011-09-03 01:57:26 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param string $url Url to show
* @ param string $target Target for link
* @ param int $max Max number of characters to show
2015-10-10 01:51:12 +02:00
* @ param int $withpicto With picto
2011-09-17 02:47:01 +02:00
* @ return string HTML Link
2009-01-07 13:39:40 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_url ( $url , $target = '_blank' , $max = 32 , $withpicto = 0 )
2009-01-07 13:39:40 +01:00
{
2015-10-10 01:51:12 +02:00
global $langs ;
2015-11-01 17:27:41 +01:00
2021-02-23 22:03:23 +01:00
if ( empty ( $url )) {
return '' ;
}
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
$link = '<a href="' ;
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/^http/i' , $url )) {
$link .= 'http://' ;
}
2019-11-11 23:59:36 +01:00
$link .= $url ;
$link .= '"' ;
2021-02-23 22:03:23 +01:00
if ( $target ) {
$link .= ' target="' . $target . '"' ;
}
2019-11-11 23:59:36 +01:00
$link .= '>' ;
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/^http/i' , $url )) {
$link .= 'http://' ;
}
2019-11-11 23:59:36 +01:00
$link .= dol_trunc ( $url , $max );
$link .= '</a>' ;
return '<div class="nospan float" style="margin-right: 10px">' . ( $withpicto ? img_picto ( $langs -> trans ( " Url " ), 'globe' ) . ' ' : '' ) . $link . '</div>' ;
2009-01-07 13:39:40 +01:00
}
/**
2020-10-22 20:01:59 +02:00
* Show EMail link formatted for HTML output .
2011-09-03 01:57:26 +02:00
*
2011-09-17 02:47:01 +02:00
* @ param string $email EMail to show ( only email , without 'Name of recipient' before )
* @ param int $cid Id of contact if known
* @ param int $socid Id of third party if known
2014-03-26 16:02:22 +01:00
* @ param int $addlink 0 = no link , 1 = email has a html email link ( + link to create action if constant AGENDA_ADDACTIONFOREMAIL is on )
2011-09-17 02:47:01 +02:00
* @ param int $max Max number of characters to show
2019-12-13 15:52:08 +01:00
* @ param int $showinvalid 1 = Show warning if syntax email is wrong
2014-12-30 21:24:57 +01:00
* @ param int $withpicto Show picto
2011-09-17 02:47:01 +02:00
* @ return string HTML Link
2009-01-07 13:39:40 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_email ( $email , $cid = 0 , $socid = 0 , $addlink = 0 , $max = 64 , $showinvalid = 1 , $withpicto = 0 )
2009-01-07 13:39:40 +01:00
{
2019-11-11 23:59:36 +01:00
global $conf , $user , $langs , $hookmanager ;
2012-08-03 23:29:08 +02:00
2020-10-22 20:01:59 +02:00
$newemail = dol_escape_htmltag ( $email );
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER ) && $withpicto ) {
$withpicto = 0 ;
}
2020-06-10 12:35:39 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $email )) {
return ' ' ;
}
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $addlink )) {
2019-11-11 23:59:36 +01:00
$newemail = '<a style="text-overflow: ellipsis;" href="' ;
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/^mailto:/i' , $email )) {
$newemail .= 'mailto:' ;
}
2019-11-11 23:59:36 +01:00
$newemail .= $email ;
$newemail .= '">' ;
$newemail .= dol_trunc ( $email , $max );
$newemail .= '</a>' ;
2021-02-23 22:03:23 +01:00
if ( $showinvalid && ! isValidEmail ( $email )) {
2012-08-03 23:29:08 +02:00
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$newemail .= img_warning ( $langs -> trans ( " ErrorBadEMail " , $email ));
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if (( $cid || $socid ) && ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create ) {
2021-03-01 20:37:16 +01:00
$type = 'AC_EMAIL' ;
$link = '' ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> AGENDA_ADDACTIONFOREMAIL )) {
$link = '<a href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $type . '&contactid=' . $cid . '&socid=' . $socid . '">' . img_object ( $langs -> trans ( " AddAction " ), " calendar " ) . '</a>' ;
}
if ( $link ) {
$newemail = '<div>' . $newemail . ' ' . $link . '</div>' ;
}
2012-08-03 23:29:08 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $showinvalid && ! isValidEmail ( $email )) {
2012-08-03 23:29:08 +02:00
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$newemail .= img_warning ( $langs -> trans ( " ErrorBadEMail " , $email ));
2012-08-03 23:29:08 +02:00
}
}
2018-03-15 22:22:42 +01:00
2020-04-12 15:29:13 +02:00
//$rep = '<div class="nospan" style="margin-right: 10px">';
2020-06-10 12:35:39 +02:00
$rep = ( $withpicto ? img_picto ( $langs -> trans ( " EMail " ) . ' : ' . $email , 'object_email.png' ) . ' ' : '' ) . $newemail ;
2020-04-12 15:29:13 +02:00
//$rep .= '</div>';
2018-03-15 22:22:42 +01:00
if ( $hookmanager ) {
2019-11-11 23:59:36 +01:00
$parameters = array ( 'cid' => $cid , 'socid' => $socid , 'addlink' => $addlink , 'picto' => $withpicto );
2018-03-15 22:22:42 +01:00
$reshook = $hookmanager -> executeHooks ( 'printEmail' , $parameters , $email );
2020-04-12 15:29:13 +02:00
if ( $reshook > 0 ) {
$rep = '' ;
}
2019-11-11 23:59:36 +01:00
$rep .= $hookmanager -> resPrint ;
2018-03-15 22:22:42 +01:00
}
return $rep ;
2009-01-07 13:39:40 +01:00
}
2019-09-12 20:44:24 +02:00
/**
* Get array of social network dictionary
*
* @ return array Array of Social Networks Dictionary
*/
function getArrayOfSocialNetworks ()
{
2020-09-07 10:18:17 +02:00
global $conf , $db ;
2021-02-21 10:18:05 +01:00
2020-09-07 10:18:17 +02:00
$socialnetworks = array ();
2021-02-21 10:18:05 +01:00
// Enable caching of array
require_once DOL_DOCUMENT_ROOT . '/core/lib/memory.lib.php' ;
$cachekey = 'socialnetworks_' . $conf -> entity ;
$dataretrieved = dol_getcache ( $cachekey );
if ( ! is_null ( $dataretrieved )) {
$socialnetworks = $dataretrieved ;
} else {
$sql = " SELECT rowid, code, label, url, icon, active FROM " . MAIN_DB_PREFIX . " c_socialnetworks " ;
$sql .= " WHERE entity= " . $conf -> entity ;
$resql = $db -> query ( $sql );
if ( $resql ) {
while ( $obj = $db -> fetch_object ( $resql )) {
$socialnetworks [ $obj -> code ] = array (
'rowid' => $obj -> rowid ,
'label' => $obj -> label ,
'url' => $obj -> url ,
'icon' => $obj -> icon ,
'active' => $obj -> active ,
);
}
2020-09-07 10:18:17 +02:00
}
2021-02-21 10:18:05 +01:00
dol_setcache ( $cachekey , $socialnetworks ); // If setting cache fails, this is not a problem, so we do not test result.
2020-09-07 10:18:17 +02:00
}
2021-02-21 10:18:05 +01:00
2020-09-07 10:18:17 +02:00
return $socialnetworks ;
2019-09-12 20:44:24 +02:00
}
2013-11-04 21:41:36 +01:00
/**
2018-10-12 11:02:03 +02:00
* Show social network link
2013-11-04 21:41:36 +01:00
*
2020-12-12 17:00:23 +01:00
* @ param string $value Skype to show ( only skype , without 'Name of recipient' before )
* @ param int $cid Id of contact if known
* @ param int $socid Id of third party if known
* @ param string $type 'skype' , 'facebook' , ...
* @ param array $dictsocialnetworks socialnetworks availables
* @ return string HTML Link
2013-11-04 21:41:36 +01:00
*/
2020-12-12 17:00:23 +01:00
function dol_print_socialnetworks ( $value , $cid , $socid , $type , $dictsocialnetworks = array ())
2013-11-04 21:41:36 +01:00
{
2019-11-11 23:59:36 +01:00
global $conf , $user , $langs ;
2013-11-04 21:41:36 +01:00
2019-11-11 23:59:36 +01:00
$htmllink = $value ;
2013-11-04 21:41:36 +01:00
2021-02-14 21:30:54 +01:00
if ( empty ( $value )) {
return ' ' ;
}
2013-11-04 21:41:36 +01:00
2020-12-12 17:00:23 +01:00
if ( ! empty ( $type )) {
2019-10-17 20:24:04 +02:00
$htmllink = '<div class="divsocialnetwork inline-block valignmiddle">' ;
2021-02-14 21:30:54 +01:00
// Use dictionary definition for picto $dictsocialnetworks[$type]['icon']
$htmllink .= '<span class="fa paddingright ' . ( $dictsocialnetworks [ $type ][ 'icon' ] ? $dictsocialnetworks [ $type ][ 'icon' ] : 'fa-link' ) . '"></span>' ;
2020-12-12 17:00:23 +01:00
if ( $type == 'skype' ) {
2022-01-30 16:30:19 +01:00
$htmllink .= dol_escape_htmltag ( $value );
2019-11-11 23:59:36 +01:00
$htmllink .= ' ' ;
$htmllink .= '<a href="skype:' ;
2022-01-30 16:30:19 +01:00
$htmllink .= dol_string_nospecial ( $value , '_' , '' , array ( '@' ));
$htmllink .= '?call" alt="' . $langs -> trans ( " Call " ) . ' ' . $value . '" title="' . dol_escape_htmltag ( $langs -> trans ( " Call " ) . ' ' . $value ) . '">' ;
2019-11-11 23:59:36 +01:00
$htmllink .= '<img src="' . DOL_URL_ROOT . '/theme/common/skype_callbutton.png" border="0">' ;
$htmllink .= '</a><a href="skype:' ;
2022-01-30 16:30:19 +01:00
$htmllink .= dol_string_nospecial ( $value , '_' , '' , array ( '@' ));
$htmllink .= '?chat" alt="' . $langs -> trans ( " Chat " ) . ' ' . $value . '" title="' . dol_escape_htmltag ( $langs -> trans ( " Chat " ) . ' ' . $value ) . '">' ;
2019-11-11 23:59:36 +01:00
$htmllink .= '<img class="paddingleft" src="' . DOL_URL_ROOT . '/theme/common/skype_chatbutton.png" border="0">' ;
$htmllink .= '</a>' ;
2020-12-12 17:00:23 +01:00
if (( $cid || $socid ) && ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create ) {
$addlink = 'AC_SKYPE' ;
$link = '' ;
2021-02-14 21:30:54 +01:00
if ( ! empty ( $conf -> global -> AGENDA_ADDACTIONFORSKYPE )) {
$link = '<a href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $addlink . '&contactid=' . $cid . '&socid=' . $socid . '">' . img_object ( $langs -> trans ( " AddAction " ), " calendar " ) . '</a>' ;
}
2020-12-12 17:00:23 +01:00
$htmllink .= ( $link ? ' ' . $link : '' );
}
} else {
if ( ! empty ( $dictsocialnetworks [ $type ][ 'url' ])) {
$link = str_replace ( '{socialid}' , $value , $dictsocialnetworks [ $type ][ 'url' ]);
2022-01-30 16:30:19 +01:00
$htmllink .= ' <a href="' . $link . '" target="_blank" rel="noopener noreferrer">' . dol_escape_htmltag ( $value ) . '</a>' ;
2020-12-12 17:00:23 +01:00
} else {
2022-01-30 16:30:19 +01:00
$htmllink .= dol_escape_htmltag ( $value );
2020-12-12 17:00:23 +01:00
}
2013-11-04 21:41:36 +01:00
}
2019-11-11 23:59:36 +01:00
$htmllink .= '</div>' ;
2020-05-21 15:05:19 +02:00
} else {
2013-11-04 21:41:36 +01:00
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$htmllink .= img_warning ( $langs -> trans ( " ErrorBadSocialNetworkValue " , $value ));
2013-11-04 21:41:36 +01:00
}
2019-09-11 22:27:09 +02:00
return $htmllink ;
2013-11-04 21:41:36 +01:00
}
2022-01-28 11:22:12 +01:00
/**
* Format profIDs according to country
*
2022-01-28 19:06:41 +01:00
* @ param string $profID Value of profID to format
* @ param string $profIDtype Type of profID to format ( '1' , '2' , '3' , '4' , '5' , '6' or 'VAT' )
2022-01-28 11:22:12 +01:00
* @ param string $countrycode Country code to use for formatting
* @ param int $addcpButton Add button to copy to clipboard ( 1 => show only on hoover ; 2 => always display )
* @ param string $separ Separation between numbers for a better visibility example : xxx xxx xxx xxxxx
* @ return string Formated profID
*/
function dol_print_profids ( $profID , $profIDtype , $countrycode = '' , $addcpButton = 1 , $separ = ' ' )
{
global $mysoc ;
2022-01-28 19:06:41 +01:00
if ( empty ( $profID ) || empty ( $profIDtype )) {
return '' ;
}
2022-01-28 11:22:12 +01:00
if ( empty ( $countrycode )) $countrycode = $mysoc -> country_code ;
$newProfID = $profID ;
$id = substr ( $profIDtype , - 1 );
$ret = '' ;
if ( strtoupper ( $countrycode ) == 'FR' ) {
// France
if ( $id == 1 && dol_strlen ( $newProfID ) == 9 ) $newProfID = substr ( $newProfID , 0 , 3 ) . $separ . substr ( $newProfID , 3 , 3 ) . $separ . substr ( $newProfID , 6 , 3 );
if ( $id == 2 && dol_strlen ( $newProfID ) == 14 ) $newProfID = substr ( $newProfID , 0 , 3 ) . $separ . substr ( $newProfID , 3 , 3 ) . $separ . substr ( $newProfID , 6 , 3 ) . $separ . substr ( $newProfID , 9 , 5 );
2022-01-28 19:06:41 +01:00
if ( $profIDtype === 'VAT' && dol_strlen ( $newProfID ) == 13 ) $newProfID = substr ( $newProfID , 0 , 4 ) . $separ . substr ( $newProfID , 4 , 3 ) . $separ . substr ( $newProfID , 7 , 3 ) . $separ . substr ( $newProfID , 10 , 3 );
2022-01-28 11:22:12 +01:00
}
if ( ! empty ( $addcpButton )) $ret = showValueWithClipboardCPButton ( dol_escape_htmltag ( $profID ), ( $addcpButton == 1 ? 1 : 0 ), $newProfID );
2022-01-28 11:31:17 +01:00
else $ret = $newProfID ;
2022-01-28 11:22:12 +01:00
return $ret ;
}
2008-08-06 16:50:06 +02:00
/**
2010-11-07 12:27:22 +01:00
* Format phone numbers according to country
2011-09-03 01:57:26 +02:00
*
2015-10-16 16:14:33 +02:00
* @ param string $phone Phone number to format
* @ param string $countrycode Country code to use for formatting
* @ param int $cid Id of contact if known
* @ param int $socid Id of third party if known
* @ param string $addlink '' = no link to create action , 'AC_TEL' = add link to clicktodial ( if module enabled ) and add link to create event ( if conf -> global -> AGENDA_ADDACTIONFORPHONE set )
* @ param string $separ Separation between numbers for a better visibility example : xx . xx . xx . xx . xx
2021-08-04 00:12:49 +02:00
* @ param string $withpicto Show picto ( 'fax' , 'phone' , 'mobile' )
2015-10-16 16:14:33 +02:00
* @ param string $titlealt Text to show on alt
2016-01-22 03:07:46 +01:00
* @ param int $adddivfloat Add div float around phone .
2015-10-16 16:14:33 +02:00
* @ return string Formated phone number
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_phone ( $phone , $countrycode = '' , $cid = 0 , $socid = 0 , $addlink = '' , $separ = " " , $withpicto = '' , $titlealt = '' , $adddivfloat = 0 )
2008-08-06 16:50:06 +02:00
{
2018-01-02 11:24:28 +01:00
global $conf , $user , $langs , $mysoc , $hookmanager ;
2012-08-03 23:29:08 +02:00
// Clean phone parameter
2019-01-27 11:55:16 +01:00
$phone = preg_replace ( " /[ \ s.-]/ " , " " , trim ( $phone ));
2021-02-23 22:03:23 +01:00
if ( empty ( $phone )) {
return '' ;
}
if ( ! empty ( $conf -> global -> MAIN_PHONE_SEPAR )) {
$separ = $conf -> global -> MAIN_PHONE_SEPAR ;
}
if ( empty ( $countrycode )) {
$countrycode = $mysoc -> country_code ;
}
2012-08-03 23:29:08 +02:00
2013-04-15 22:26:03 +02:00
// Short format for small screens
2021-02-23 22:03:23 +01:00
if ( $conf -> dol_optimize_smallscreen ) {
$separ = '' ;
}
2013-04-15 22:26:03 +02:00
2019-11-11 23:59:36 +01:00
$newphone = $phone ;
2021-02-23 22:03:23 +01:00
if ( strtoupper ( $countrycode ) == " FR " ) {
2012-08-03 23:29:08 +02:00
// France
if ( dol_strlen ( $phone ) == 10 ) {
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 2 ) . $separ . substr ( $newphone , 2 , 2 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 7 ) {
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 9 ) {
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 2 ) . $separ . substr ( $newphone , 2 , 3 ) . $separ . substr ( $newphone , 5 , 2 ) . $separ . substr ( $newphone , 7 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 11 ) {
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 2 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 12 ) {
2021-06-24 14:20:19 +02:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 1 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " CA " ) {
2017-10-13 13:28:26 +02:00
if ( dol_strlen ( $phone ) == 10 ) {
2019-11-11 23:59:36 +01:00
$newphone = ( $separ != '' ? '(' : '' ) . substr ( $newphone , 0 , 3 ) . ( $separ != '' ? ')' : '' ) . $separ . substr ( $newphone , 3 , 3 ) . ( $separ != '' ? '-' : '' ) . substr ( $newphone , 6 , 4 );
2017-10-13 13:28:26 +02:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " PT " ) { //Portugal
if ( dol_strlen ( $phone ) == 13 ) { //ex: +351_ABC_DEF_GHI
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " SR " ) { //Suriname
if ( dol_strlen ( $phone ) == 10 ) { //ex: +597_ABC_DEF
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 11 ) { //ex: +597_ABC_DEFG
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " DE " ) { //Allemagne
if ( dol_strlen ( $phone ) == 14 ) { //ex: +49_ABCD_EFGH_IJK
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 4 ) . $separ . substr ( $newphone , 7 , 4 ) . $separ . substr ( $newphone , 11 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 13 ) { //ex: +49_ABC_DEFG_HIJ
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 4 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " ES " ) { //Espagne
if ( dol_strlen ( $phone ) == 12 ) { //ex: +34_ABC_DEF_GHI
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " BF " ) { // Burkina Faso
if ( dol_strlen ( $phone ) == 12 ) { //ex : +22 A BC_DE_FG_HI
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 1 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " RO " ) { // Roumanie
if ( dol_strlen ( $phone ) == 12 ) { //ex : +40 AB_CDE_FG_HI
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " TR " ) { //Turquie
if ( dol_strlen ( $phone ) == 13 ) { //ex : +90 ABC_DEF_GHIJ
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " US " ) { //Etat-Unis
if ( dol_strlen ( $phone ) == 12 ) { //ex: +1 ABC_DEF_GHIJ
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 2 ) . $separ . substr ( $newphone , 2 , 3 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " MX " ) { //Mexique
if ( dol_strlen ( $phone ) == 12 ) { //ex: +52 ABCD_EFG_HI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 4 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 11 ) { //ex: +52 AB_CD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 2 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 13 ) { //ex: +52 ABC_DEF_GHIJ
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " ML " ) { //Mali
if ( dol_strlen ( $phone ) == 12 ) { //ex: +223 AB_CD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " TH " ) { //Thaïlande
if ( dol_strlen ( $phone ) == 11 ) { //ex: +66_ABC_DE_FGH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 12 ) { //ex: +66_A_BCD_EF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 1 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " MU " ) {
2020-09-07 10:18:17 +02:00
//Maurice
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $phone ) == 11 ) { //ex: +230_ABC_DE_FG
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 12 ) { //ex: +230_ABCD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 4 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " ZA " ) { //Afrique du sud
if ( dol_strlen ( $phone ) == 12 ) { //ex: +27_AB_CDE_FG_HI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " SY " ) { //Syrie
if ( dol_strlen ( $phone ) == 12 ) { //ex: +963_AB_CD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 13 ) { //ex: +963_AB_CD_EF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " AE " ) { //Emirats Arabes Unis
if ( dol_strlen ( $phone ) == 12 ) { //ex: +971_ABC_DEF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 13 ) { //ex: +971_ABC_DEF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 14 ) { //ex: +971_ABC_DEF_GHIK
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " DZ " ) { //Algérie
if ( dol_strlen ( $phone ) == 13 ) { //ex: +213_ABC_DEF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " BE " ) { //Belgique
if ( dol_strlen ( $phone ) == 11 ) { //ex: +32_ABC_DE_FGH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 12 ) { //ex: +32_ABC_DEF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " PF " ) { //Polynésie française
if ( dol_strlen ( $phone ) == 12 ) { //ex: +689_AB_CD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " CO " ) { //Colombie
if ( dol_strlen ( $phone ) == 13 ) { //ex: +57_ABC_DEF_GH_IJ
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 2 ) . $separ . substr ( $newphone , 11 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " JO " ) { //Jordanie
if ( dol_strlen ( $phone ) == 12 ) { //ex: +962_A_BCD_EF_GH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 1 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " JM " ) { //Jamaïque
if ( dol_strlen ( $newphone ) == 12 ) { //ex: +1867_ABC_DEFG
2019-08-01 16:14:53 +02:00
$newphone = substr ( $newphone , 0 , 5 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 4 );
2019-08-01 15:46:34 +02:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " MG " ) { //Madagascar
if ( dol_strlen ( $phone ) == 13 ) { //ex: +261_AB_CD_EF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 2 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " GB " ) { //Royaume uni
if ( dol_strlen ( $phone ) == 13 ) { //ex: +44_ABCD_EFG_HIJ
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 4 ) . $separ . substr ( $newphone , 7 , 3 ) . $separ . substr ( $newphone , 10 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " CH " ) { //Suisse
if ( dol_strlen ( $phone ) == 12 ) { //ex: +41_AB_CDE_FG_HI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 2 ) . $separ . substr ( $newphone , 10 , 2 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 15 ) { // +41_AB_CDE_FGH_IJKL
2019-11-11 23:59:36 +01:00
$newphone = $newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 3 ) . $separ . substr ( $newphone , 8 , 3 ) . $separ . substr ( $newphone , 11 , 4 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " TN " ) { //Tunisie
if ( dol_strlen ( $phone ) == 12 ) { //ex: +216_AB_CDE_FGH
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 2 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 3 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " GF " ) { //Guyane francaise
if ( dol_strlen ( $phone ) == 13 ) { //ex: +594_ABC_DE_FG_HI (ABC=594 de nouveau)
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 ) . $separ . substr ( $newphone , 11 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " GP " ) { //Guadeloupe
if ( dol_strlen ( $phone ) == 13 ) { //ex: +590_ABC_DE_FG_HI (ABC=590 de nouveau)
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 ) . $separ . substr ( $newphone , 11 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " MQ " ) { //Martinique
if ( dol_strlen ( $phone ) == 13 ) { //ex: +596_ABC_DE_FG_HI (ABC=596 de nouveau)
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 4 ) . $separ . substr ( $newphone , 4 , 3 ) . $separ . substr ( $newphone , 7 , 2 ) . $separ . substr ( $newphone , 9 , 2 ) . $separ . substr ( $newphone , 11 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " IT " ) { //Italie
if ( dol_strlen ( $phone ) == 12 ) { //ex: +39_ABC_DEF_GHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 3 );
2021-02-23 22:03:23 +01:00
} elseif ( dol_strlen ( $phone ) == 13 ) { //ex: +39_ABC_DEF_GH_IJ
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 3 ) . $separ . substr ( $newphone , 6 , 3 ) . $separ . substr ( $newphone , 9 , 2 ) . $separ . substr ( $newphone , 11 , 2 );
2018-02-15 10:47:32 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( strtoupper ( $countrycode ) == " AU " ) {
2020-09-07 10:18:17 +02:00
//Australie
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $phone ) == 12 ) {
2020-09-07 10:18:17 +02:00
//ex: +61_A_BCDE_FGHI
2019-01-27 11:55:16 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 1 ) . $separ . substr ( $newphone , 4 , 4 ) . $separ . substr ( $newphone , 8 , 4 );
2018-02-15 10:47:32 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $addlink )) { // Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set)
if ( $conf -> browser -> layout == 'phone' || ( ! empty ( $conf -> clicktodial -> enabled ) && ! empty ( $conf -> global -> CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS ))) { // If phone or option for, we use link of phone
2020-04-08 15:13:19 +02:00
$newphoneform = $newphone ;
2019-11-11 23:59:36 +01:00
$newphone = '<a href="tel:' . $phone . '"' ;
2020-04-08 15:13:19 +02:00
$newphone .= '>' . $newphoneform . '</a>' ;
2021-02-23 22:03:23 +01:00
} elseif ( ! empty ( $conf -> clicktodial -> enabled ) && $addlink == 'AC_TEL' ) { // If click to dial, we use click to dial url
if ( empty ( $user -> clicktodial_loaded )) {
$user -> fetch_clicktodial ();
}
2012-08-03 23:29:08 +02:00
2013-03-31 16:44:24 +02:00
// Define urlmask
2019-11-11 23:59:36 +01:00
$urlmask = 'ErrorClickToDialModuleNotConfigured' ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> CLICKTODIAL_URL )) {
$urlmask = $conf -> global -> CLICKTODIAL_URL ;
}
if ( ! empty ( $user -> clicktodial_url )) {
$urlmask = $user -> clicktodial_url ;
}
2013-03-31 16:44:24 +02:00
2019-11-11 23:59:36 +01:00
$clicktodial_poste = ( ! empty ( $user -> clicktodial_poste ) ? urlencode ( $user -> clicktodial_poste ) : '' );
$clicktodial_login = ( ! empty ( $user -> clicktodial_login ) ? urlencode ( $user -> clicktodial_login ) : '' );
$clicktodial_password = ( ! empty ( $user -> clicktodial_password ) ? urlencode ( $user -> clicktodial_password ) : '' );
2012-08-03 23:29:08 +02:00
// This line is for backward compatibility
$url = sprintf ( $urlmask , urlencode ( $phone ), $clicktodial_poste , $clicktodial_login , $clicktodial_password );
// Thoose lines are for substitution
2019-11-11 23:59:36 +01:00
$substitarray = array ( '__PHONEFROM__' => $clicktodial_poste ,
2012-08-03 23:29:08 +02:00
'__PHONETO__' => urlencode ( $phone ),
'__LOGIN__' => $clicktodial_login ,
'__PASS__' => $clicktodial_password );
$url = make_substitutions ( $url , $substitarray );
2019-11-11 23:59:36 +01:00
$newphonesav = $newphone ;
2021-08-04 20:07:12 +02:00
if ( empty ( $conf -> global -> CLICKTODIAL_DO_NOT_USE_AJAX_CALL )) {
// Default and recommended: New method using ajax without submiting a page making a javascript history.go(-1) back
$newphone = '<a href="' . $url . '" class="cssforclicktodial"' ; // Call of ajax is handled by the lib_foot.js.php on class 'cssforclicktodial'
$newphone .= '>' . $newphonesav . '</a>' ;
} else {
// Old method
$newphone = '<a href="' . $url . '"' ;
if ( ! empty ( $conf -> global -> CLICKTODIAL_FORCENEWTARGET )) {
2021-11-22 02:35:55 +01:00
$newphone .= ' target="_blank" rel="noopener noreferrer"' ;
2021-08-04 20:07:12 +02:00
}
$newphone .= '>' . $newphonesav . '</a>' ;
2021-02-23 22:03:23 +01:00
}
2012-08-03 23:29:08 +02:00
}
2012-09-15 11:21:22 +02:00
//if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create)
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create ) {
2021-03-01 20:37:16 +01:00
$type = 'AC_TEL' ;
$link = '' ;
2021-02-23 22:03:23 +01:00
if ( $addlink == 'AC_FAX' ) {
$type = 'AC_FAX' ;
}
if ( ! empty ( $conf -> global -> AGENDA_ADDACTIONFORPHONE )) {
$link = '<a href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&backtopage=1&actioncode=' . $type . ( $cid ? '&contactid=' . $cid : '' ) . ( $socid ? '&socid=' . $socid : '' ) . '">' . img_object ( $langs -> trans ( " AddAction " ), " calendar " ) . '</a>' ;
}
if ( $link ) {
$newphone = '<div>' . $newphone . ' ' . $link . '</div>' ;
}
2012-08-03 23:29:08 +02:00
}
}
2021-02-23 22:03:23 +01:00
if ( empty ( $titlealt )) {
2019-11-11 23:59:36 +01:00
$titlealt = ( $withpicto == 'fax' ? $langs -> trans ( " Fax " ) : $langs -> trans ( " Phone " ));
2015-10-11 12:27:04 +02:00
}
2019-11-11 23:59:36 +01:00
$rep = '' ;
2018-01-30 18:02:24 +01:00
2018-01-02 11:24:28 +01:00
if ( $hookmanager ) {
2019-11-11 23:59:36 +01:00
$parameters = array ( 'countrycode' => $countrycode , 'cid' => $cid , 'socid' => $socid , 'titlealt' => $titlealt , 'picto' => $withpicto );
2018-03-15 22:22:42 +01:00
$reshook = $hookmanager -> executeHooks ( 'printPhone' , $parameters , $phone );
2019-11-11 23:59:36 +01:00
$rep .= $hookmanager -> resPrint ;
2018-03-15 22:22:42 +01:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $reshook )) {
2018-01-02 11:24:28 +01:00
$picto = '' ;
2019-11-11 23:59:36 +01:00
if ( $withpicto ) {
if ( $withpicto == 'fax' ) {
2018-01-02 11:24:28 +01:00
$picto = 'phoning_fax' ;
2020-05-21 15:05:19 +02:00
} elseif ( $withpicto == 'phone' ) {
2018-01-02 11:24:28 +01:00
$picto = 'phoning' ;
2020-05-21 15:05:19 +02:00
} elseif ( $withpicto == 'mobile' ) {
2018-01-02 11:24:28 +01:00
$picto = 'phoning_mobile' ;
2019-11-11 23:59:36 +01:00
} else {
2018-01-02 11:24:28 +01:00
$picto = '' ;
}
2017-10-10 10:19:04 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $adddivfloat ) {
$rep .= '<div class="nospan float" style="margin-right: 10px">' ;
} else {
$rep .= '<span style="margin-right: 10px;">' ;
}
2019-11-11 23:59:36 +01:00
$rep .= ( $withpicto ? img_picto ( $titlealt , 'object_' . $picto . '.png' ) . ' ' : '' ) . $newphone ;
2021-02-23 22:03:23 +01:00
if ( $adddivfloat ) {
$rep .= '</div>' ;
} else {
$rep .= '</span>' ;
}
2019-02-03 14:29:45 +01:00
}
2018-01-30 18:02:24 +01:00
2016-01-21 22:42:10 +01:00
return $rep ;
2008-08-06 16:50:06 +02:00
}
2009-10-14 13:04:09 +02:00
/**
2010-11-07 12:27:22 +01:00
* Return an IP formated to be shown on screen
2011-09-03 01:57:26 +02:00
*
2011-10-03 18:10:50 +02:00
* @ param string $ip IP
2012-01-15 02:39:43 +01:00
* @ param int $mode 0 = return IP + country / flag , 1 = return only country / flag , 2 = return only IP
2011-10-03 18:10:50 +02:00
* @ return string Formated IP , with country if GeoIP module is enabled
2009-10-14 13:04:09 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_ip ( $ip , $mode = 0 )
2009-10-14 00:01:27 +02:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs ;
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
$ret = '' ;
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $mode )) {
$ret .= $ip ;
}
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( $mode != 2 ) {
2019-11-11 23:59:36 +01:00
$countrycode = dolGetCountryCodeFromIp ( $ip );
2021-02-23 22:03:23 +01:00
if ( $countrycode ) { // If success, countrycode is us, fr, ...
if ( file_exists ( DOL_DOCUMENT_ROOT . '/theme/common/flags/' . $countrycode . '.png' )) {
2019-11-11 23:59:36 +01:00
$ret .= ' ' . img_picto ( $countrycode . ' ' . $langs -> trans ( " AccordingToGeoIPDatabase " ), DOL_URL_ROOT . '/theme/common/flags/' . $countrycode . '.png' , '' , 1 );
2021-02-23 22:03:23 +01:00
} else {
$ret .= ' (' . $countrycode . ')' ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-08-21 17:28:54 +02:00
// Nothing
}
2012-08-03 23:29:08 +02:00
}
return $ret ;
2011-05-12 21:01:14 +02:00
}
2009-10-17 15:47:17 +02:00
2018-11-21 15:40:15 +01:00
/**
* Return the IP of remote user .
* Take HTTP_X_FORWARDED_FOR ( defined when using proxy )
* Then HTTP_CLIENT_IP if defined ( rare )
2019-02-15 15:17:24 +01:00
* Then REMOTE_ADDR ( no way to be modified by user but may be wrong if user is using a proxy )
2018-11-21 15:40:15 +01:00
*
* @ return string Ip of remote user .
*/
function getUserRemoteIP ()
{
2020-09-17 21:34:31 +02:00
if ( empty ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]) || preg_match ( '/[^0-9\.\:,\[\]]/' , $_SERVER [ 'HTTP_X_FORWARDED_FOR' ])) {
if ( empty ( $_SERVER [ 'HTTP_CLIENT_IP' ]) || preg_match ( '/[^0-9\.\:,\[\]]/' , $_SERVER [ 'HTTP_CLIENT_IP' ])) {
2020-12-23 13:17:40 +01:00
if ( empty ( $_SERVER [ " HTTP_CF_CONNECTING_IP " ])) {
2021-06-27 14:54:17 +02:00
$ip = ( empty ( $_SERVER [ 'REMOTE_ADDR' ]) ? '' : $_SERVER [ 'REMOTE_ADDR' ]); // value may have been the IP of the proxy and not the client
2020-12-23 13:17:40 +01:00
} else {
$ip = $_SERVER [ " HTTP_CF_CONNECTING_IP " ]; // value here may have been forged by client
}
2020-09-17 21:34:31 +02:00
} else {
2020-12-23 13:17:40 +01:00
$ip = $_SERVER [ 'HTTP_CLIENT_IP' ]; // value is clean here but may have been forged by proxy
2020-09-17 21:34:31 +02:00
}
} else {
2020-12-23 13:17:40 +01:00
$ip = $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]; // value is clean here but may have been forged by proxy
2020-09-17 21:34:31 +02:00
}
2018-11-21 15:40:15 +01:00
return $ip ;
}
2020-12-18 15:08:00 +01:00
/**
* Return if we are using a HTTPS connexion
* Check HTTPS ( no way to be modified by user but may be empty or wrong if user is using a proxy )
* Take HTTP_X_FORWARDED_PROTO ( defined when using proxy )
* Then HTTP_X_FORWARDED_SSL
*
* @ return boolean True if user is using HTTPS
*/
2020-12-28 12:33:00 +01:00
function isHTTPS ()
2020-12-18 15:08:00 +01:00
{
$isSecure = false ;
if ( isset ( $_SERVER [ 'HTTPS' ]) && $_SERVER [ 'HTTPS' ] == 'on' ) {
$isSecure = true ;
2021-02-23 22:03:23 +01:00
} elseif ( ! empty ( $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ]) && $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ] == 'https' || ! empty ( $_SERVER [ 'HTTP_X_FORWARDED_SSL' ]) && $_SERVER [ 'HTTP_X_FORWARDED_SSL' ] == 'on' ) {
2020-12-18 15:08:00 +01:00
$isSecure = true ;
}
return $isSecure ;
}
2017-10-28 13:36:23 +02:00
/**
* Return a country code from IP . Empty string if not found .
*
* @ param string $ip IP
* @ return string Country code ( 'us' , 'fr' , ... )
*/
function dolGetCountryCodeFromIp ( $ip )
{
global $conf ;
2019-11-11 23:59:36 +01:00
$countrycode = '' ;
2017-10-28 13:36:23 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> geoipmaxmind -> enabled )) {
2019-11-11 23:59:36 +01:00
$datafile = $conf -> global -> GEOIPMAXMIND_COUNTRY_DATAFILE ;
2017-10-28 13:36:23 +02:00
//$ip='24.24.24.24';
2019-08-21 18:26:41 +02:00
//$datafile='/usr/share/GeoIP/GeoIP.dat'; Note that this must be downloaded datafile (not same than datafile provided with ubuntu packages)
2017-10-28 13:36:23 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/class/dolgeoip.class.php' ;
2019-11-11 23:59:36 +01:00
$geoip = new DolGeoIP ( 'country' , $datafile );
2017-10-28 13:36:23 +02:00
//print 'ip='.$ip.' databaseType='.$geoip->gi->databaseType." GEOIP_CITY_EDITION_REV1=".GEOIP_CITY_EDITION_REV1."\n";
2019-11-11 23:59:36 +01:00
$countrycode = $geoip -> getCountryCodeFromIP ( $ip );
2017-10-28 13:36:23 +02:00
}
return $countrycode ;
}
2011-07-03 20:31:13 +02:00
/**
* Return country code for current user .
* If software is used inside a local network , detection may fails ( we need a public ip )
2011-09-03 01:57:26 +02:00
*
2011-10-03 18:10:50 +02:00
* @ return string Country code ( fr , es , it , us , ... )
2011-07-03 20:31:13 +02:00
*/
function dol_user_country ()
{
2019-11-11 23:59:36 +01:00
global $conf , $langs , $user ;
2012-08-03 23:29:08 +02:00
//$ret=$user->xxx;
2019-11-11 23:59:36 +01:00
$ret = '' ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> geoipmaxmind -> enabled )) {
2019-11-11 23:59:36 +01:00
$ip = getUserRemoteIP ();
$datafile = $conf -> global -> GEOIPMAXMIND_COUNTRY_DATAFILE ;
2012-08-03 23:29:08 +02:00
//$ip='24.24.24.24';
//$datafile='E:\Mes Sites\Web\Admin1\awstats\maxmind\GeoIP.dat';
2012-08-23 02:04:35 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/class/dolgeoip.class.php' ;
2019-11-11 23:59:36 +01:00
$geoip = new DolGeoIP ( 'country' , $datafile );
$countrycode = $geoip -> getCountryCodeFromIP ( $ip );
$ret = $countrycode ;
2012-08-03 23:29:08 +02:00
}
return $ret ;
2011-07-03 20:31:13 +02:00
}
2011-05-12 21:01:14 +02:00
/**
* Format address string
2011-09-03 01:57:26 +02:00
*
2020-04-01 18:11:28 +02:00
* @ param string $address Address string , already formatted with dol_format_address ()
2015-10-10 01:51:12 +02:00
* @ param int $htmlid Html ID ( for example 'gmap' )
2020-04-01 18:11:28 +02:00
* @ param int $element 'thirdparty' | 'contact' | 'member' | 'other'
2015-10-10 01:51:12 +02:00
* @ param int $id Id of object
* @ param int $noprint No output . Result is the function return
2016-11-16 09:40:29 +01:00
* @ param string $charfornl Char to use instead of nl2br . '' means we use a standad nl2br .
2015-10-10 01:51:12 +02:00
* @ return string | void Nothing if noprint is 0 , formatted address if noprint is 1
2019-03-11 01:01:15 +01:00
* @ see dol_format_address ()
2011-05-12 21:01:14 +02:00
*/
2020-04-01 18:11:28 +02:00
function dol_print_address ( $address , $htmlid , $element , $id , $noprint = 0 , $charfornl = '' )
2011-05-12 21:01:14 +02:00
{
2013-08-05 18:06:57 +02:00
global $conf , $user , $langs , $hookmanager ;
2012-08-03 23:29:08 +02:00
2015-10-10 01:51:12 +02:00
$out = '' ;
2015-11-01 17:27:41 +01:00
2021-02-23 22:03:23 +01:00
if ( $address ) {
2017-10-13 13:28:26 +02:00
if ( $hookmanager ) {
2020-04-01 18:11:28 +02:00
$parameters = array ( 'element' => $element , 'id' => $id );
2017-10-13 13:28:26 +02:00
$reshook = $hookmanager -> executeHooks ( 'printAddress' , $parameters , $address );
2019-11-11 23:59:36 +01:00
$out .= $hookmanager -> resPrint ;
2017-10-13 13:28:26 +02:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $reshook )) {
if ( empty ( $charfornl )) {
$out .= nl2br ( $address );
} else {
$out .= preg_replace ( '/[\r\n]+/' , $charfornl , $address );
}
2017-10-13 13:28:26 +02:00
2020-04-01 18:11:28 +02:00
// TODO Remove this block, we can add this using the hook now
2019-11-11 23:59:36 +01:00
$showgmap = $showomap = 0 ;
2021-02-23 22:03:23 +01:00
if (( $element == 'thirdparty' || $element == 'societe' ) && ! empty ( $conf -> google -> enabled ) && ! empty ( $conf -> global -> GOOGLE_ENABLE_GMAPS )) {
$showgmap = 1 ;
}
if ( $element == 'contact' && ! empty ( $conf -> google -> enabled ) && ! empty ( $conf -> global -> GOOGLE_ENABLE_GMAPS_CONTACTS )) {
$showgmap = 1 ;
}
if ( $element == 'member' && ! empty ( $conf -> google -> enabled ) && ! empty ( $conf -> global -> GOOGLE_ENABLE_GMAPS_MEMBERS )) {
$showgmap = 1 ;
}
if (( $element == 'thirdparty' || $element == 'societe' ) && ! empty ( $conf -> openstreetmap -> enabled ) && ! empty ( $conf -> global -> OPENSTREETMAP_ENABLE_MAPS )) {
$showomap = 1 ;
}
if ( $element == 'contact' && ! empty ( $conf -> openstreetmap -> enabled ) && ! empty ( $conf -> global -> OPENSTREETMAP_ENABLE_MAPS_CONTACTS )) {
$showomap = 1 ;
}
if ( $element == 'member' && ! empty ( $conf -> openstreetmap -> enabled ) && ! empty ( $conf -> global -> OPENSTREETMAP_ENABLE_MAPS_MEMBERS )) {
$showomap = 1 ;
}
if ( $showgmap ) {
2020-04-01 18:11:28 +02:00
$url = dol_buildpath ( '/google/gmaps.php?mode=' . $element . '&id=' . $id , 1 );
2019-11-11 23:59:36 +01:00
$out .= ' <a href="' . $url . '" target="_gmaps"><img id="' . $htmlid . '" class="valigntextbottom" src="' . DOL_URL_ROOT . '/theme/common/gmap.png"></a>' ;
2017-10-13 13:28:26 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $showomap ) {
2020-04-01 18:11:28 +02:00
$url = dol_buildpath ( '/openstreetmap/maps.php?mode=' . $element . '&id=' . $id , 1 );
2019-11-11 23:59:36 +01:00
$out .= ' <a href="' . $url . '" target="_gmaps"><img id="' . $htmlid . '_openstreetmap" class="valigntextbottom" src="' . DOL_URL_ROOT . '/theme/common/gmap.png"></a>' ;
2017-10-13 13:28:26 +02:00
}
}
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $noprint ) {
return $out ;
} else {
print $out ;
}
2009-10-14 00:01:27 +02:00
}
2011-05-12 21:01:14 +02:00
2009-08-11 19:58:25 +02:00
/**
2020-10-22 20:01:59 +02:00
* Return true if email syntax is ok .
2011-09-03 01:57:26 +02:00
*
2020-12-29 03:48:11 +01:00
* @ param string $address email ( Ex : " toto@examle.com " . Long form " John Do <johndo@example.com> " will be false )
2015-03-19 11:47:30 +01:00
* @ param int $acceptsupervisorkey If 1 , the special string '__SUPERVISOREMAIL__' is also accepted as valid
2022-03-17 12:39:39 +01:00
* @ param int $acceptuserkey If 1 , the special string '__USER_EMAIL__' is also accepted as valid
2015-03-19 11:47:30 +01:00
* @ return boolean true if email syntax is OK , false if KO or empty string
2020-10-22 20:01:59 +02:00
* @ see isValidMXRecord ()
2009-08-11 19:58:25 +02:00
*/
2022-03-17 12:39:39 +01:00
function isValidEmail ( $address , $acceptsupervisorkey = 0 , $acceptuserkey = 0 )
2009-08-11 19:58:25 +02:00
{
2021-02-23 22:03:23 +01:00
if ( $acceptsupervisorkey && $address == '__SUPERVISOREMAIL__' ) {
return true ;
}
2022-03-17 12:39:39 +01:00
if ( $acceptuserkey && $address == '__USER_EMAIL__' ) {
return true ;
}
2021-02-23 22:03:23 +01:00
if ( filter_var ( $address , FILTER_VALIDATE_EMAIL )) {
return true ;
}
2014-07-18 11:18:25 +02:00
return false ;
2009-08-11 19:58:25 +02:00
}
2018-07-04 11:07:28 +02:00
/**
* Return if the domain name has a valid MX record .
* WARNING : This need function idn_to_ascii , checkdnsrr and getmxrr
*
* @ param string $domain Domain name ( Ex : " yahoo.com " , " yhaoo.com " , " dolibarr.fr " )
* @ return int - 1 if error ( function not available ), 0 = Not valid , 1 = Valid
2020-10-22 20:01:59 +02:00
* @ see isValidEmail ()
2018-07-04 11:07:28 +02:00
*/
function isValidMXRecord ( $domain )
{
2021-02-23 22:03:23 +01:00
if ( function_exists ( 'idn_to_ascii' ) && function_exists ( 'checkdnsrr' )) {
if ( ! checkdnsrr ( idn_to_ascii ( $domain ), 'MX' )) {
2018-07-04 11:07:28 +02:00
return 0 ;
}
2021-02-23 22:03:23 +01:00
if ( function_exists ( 'getmxrr' )) {
2019-11-11 23:59:36 +01:00
$mxhosts = array ();
$weight = array ();
2018-07-04 11:07:28 +02:00
getmxrr ( idn_to_ascii ( $domain ), $mxhosts , $weight );
2021-02-23 22:03:23 +01:00
if ( count ( $mxhosts ) > 1 ) {
return 1 ;
}
if ( count ( $mxhosts ) == 1 && ! empty ( $mxhosts [ 0 ])) {
return 1 ;
}
2018-07-04 11:07:28 +02:00
return 0 ;
}
}
return - 1 ;
}
2011-03-05 17:27:26 +01:00
/**
2011-09-03 01:57:26 +02:00
* Return true if phone number syntax is ok
2015-04-24 01:15:29 +02:00
* TODO Decide what to do with this
2011-09-03 01:57:26 +02:00
*
2012-03-18 19:23:01 +01:00
* @ param string $phone phone ( Ex : " 0601010101 " )
* @ return boolean true if phone syntax is OK , false if KO or empty string
2011-03-05 17:27:26 +01:00
*/
2012-02-19 18:34:22 +01:00
function isValidPhone ( $phone )
2011-03-05 17:27:26 +01:00
{
2012-08-03 23:29:08 +02:00
return true ;
2011-03-05 17:27:26 +01:00
}
2008-08-06 16:50:06 +02:00
2008-11-17 00:43:10 +01:00
/**
2011-09-03 01:57:26 +02:00
* Make a strlen call . Works even if mbstring module not enabled
*
* @ param string $string String to calculate length
* @ param string $stringencoding Encoding of string
* @ return int Length of string
2008-11-17 00:43:10 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_strlen ( $string , $stringencoding = 'UTF-8' )
2008-11-17 00:43:10 +01:00
{
2021-02-23 22:03:23 +01:00
if ( function_exists ( 'mb_strlen' )) {
return mb_strlen ( $string , $stringencoding );
} else {
return strlen ( $string );
}
2008-11-17 00:43:10 +01:00
}
/**
2018-11-15 13:39:12 +01:00
* Make a substring . Works even if mbstring module is not enabled for better compatibility .
2011-09-03 01:57:26 +02:00
*
2011-10-03 18:10:50 +02:00
* @ param string $string String to scan
* @ param string $start Start position
2018-11-15 13:39:12 +01:00
* @ param int $length Length ( in nb of characters or nb of bytes depending on trunconbytes param )
2011-10-03 18:10:50 +02:00
* @ param string $stringencoding Page code used for input string encoding
2018-11-15 13:39:12 +01:00
* @ param int $trunconbytes 1 = Length is max of bytes instead of max of characters
2011-10-03 18:10:50 +02:00
* @ return string substring
2008-11-17 00:43:10 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_substr ( $string , $start , $length , $stringencoding = '' , $trunconbytes = 0 )
2008-11-17 00:43:10 +01:00
{
2012-08-03 23:29:08 +02:00
global $langs ;
2021-02-23 22:03:23 +01:00
if ( empty ( $stringencoding )) {
$stringencoding = $langs -> charset_output ;
}
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
$ret = '' ;
2021-02-23 22:03:23 +01:00
if ( empty ( $trunconbytes )) {
if ( function_exists ( 'mb_substr' )) {
2019-11-11 23:59:36 +01:00
$ret = mb_substr ( $string , $start , $length , $stringencoding );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$ret = substr ( $string , $start , $length );
2018-11-15 13:39:12 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( function_exists ( 'mb_strcut' )) {
2019-11-11 23:59:36 +01:00
$ret = mb_strcut ( $string , $start , $length , $stringencoding );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$ret = substr ( $string , $start , $length );
2018-11-15 13:39:12 +01:00
}
2012-08-03 23:29:08 +02:00
}
return $ret ;
2008-11-17 00:43:10 +01:00
}
2009-01-07 11:57:36 +01:00
2008-08-06 16:50:06 +02:00
/**
2021-02-21 13:32:54 +01:00
* Truncate a string to a particular length adding '…' if string larger than length .
* If length = max length + 1 , we do no truncate to avoid having just 1 char replaced with '…' .
2011-05-13 20:08:55 +02:00
* MAIN_DISABLE_TRUNC = 1 can disable all truncings
2011-08-17 17:56:22 +02:00
*
2011-12-01 22:58:02 +01:00
* @ param string $string String to truncate
2021-02-21 13:32:54 +01:00
* @ param int $size Max string size visible ( excluding … ) . 0 for no limit . WARNING : Final string size can have 3 more chars ( if we added … , or if size was max + 1 so it does not worse to replace with ... )
2020-11-21 17:42:07 +01:00
* @ param string $trunc Where to trunc : 'right' , 'left' , 'middle' ( size must be a 2 power ), 'wrap'
2011-12-01 22:58:02 +01:00
* @ param string $stringencoding Tell what is source string encoding
2021-02-21 13:00:31 +01:00
* @ param int $nodot Truncation do not add … after truncation . So it ' s an exact truncation .
2018-11-15 13:39:12 +01:00
* @ param int $display Trunc is used to display data and can be changed for small screen . TODO Remove this param ( must be dealt with CSS )
2017-06-30 18:30:01 +02:00
* @ return string Truncated string . WARNING : length is never higher than $size if $nodot is set , but can be 3 chars higher otherwise .
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_trunc ( $string , $size = 40 , $trunc = 'right' , $stringencoding = 'UTF-8' , $nodot = 0 , $display = 0 )
2008-08-06 16:50:06 +02:00
{
2012-08-03 23:29:08 +02:00
global $conf ;
2021-03-16 22:01:59 +01:00
if ( empty ( $size ) || ! empty ( $conf -> global -> MAIN_DISABLE_TRUNC )) {
2021-02-21 13:00:31 +01:00
return $string ;
}
2016-11-16 09:40:29 +01:00
2021-02-21 13:00:31 +01:00
if ( empty ( $stringencoding )) {
$stringencoding = 'UTF-8' ;
}
2014-12-09 20:17:13 +01:00
// reduce for small screen
2021-02-23 22:03:23 +01:00
if ( $conf -> dol_optimize_smallscreen == 1 && $display == 1 ) {
$size = round ( $size / 3 );
}
2016-02-09 15:57:24 +01:00
2012-08-03 23:29:08 +02:00
// We go always here
2021-02-21 13:00:31 +01:00
if ( $trunc == 'right' ) {
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
2021-02-21 15:59:19 +01:00
if ( dol_strlen ( $newstring , $stringencoding ) > ( $size + ( $nodot ? 0 : 1 ))) {
2021-02-21 13:00:31 +01:00
// If nodot is 0 and size is 1 chars more, we don't trunc and don't add …
return dol_substr ( $newstring , 0 , $size , $stringencoding ) . ( $nodot ? '' : '…' );
} else {
//return 'u'.$size.'-'.$newstring.'-'.dol_strlen($newstring,$stringencoding).'-'.$string;
return $string ;
}
} elseif ( $trunc == 'middle' ) {
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
if ( dol_strlen ( $newstring , $stringencoding ) > 2 && dol_strlen ( $newstring , $stringencoding ) > ( $size + 1 )) {
2019-11-11 23:59:36 +01:00
$size1 = round ( $size / 2 );
$size2 = round ( $size / 2 );
2021-02-21 13:00:31 +01:00
return dol_substr ( $newstring , 0 , $size1 , $stringencoding ) . '…' . dol_substr ( $newstring , dol_strlen ( $newstring , $stringencoding ) - $size2 , $size2 , $stringencoding );
} else {
return $string ;
}
} elseif ( $trunc == 'left' ) {
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
2021-02-21 15:59:19 +01:00
if ( dol_strlen ( $newstring , $stringencoding ) > ( $size + ( $nodot ? 0 : 1 ))) {
2021-02-21 13:00:31 +01:00
// If nodot is 0 and size is 1 chars more, we don't trunc and don't add …
return '…' . dol_substr ( $newstring , dol_strlen ( $newstring , $stringencoding ) - $size , $size , $stringencoding );
} else {
return $string ;
}
} elseif ( $trunc == 'wrap' ) {
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
if ( dol_strlen ( $newstring , $stringencoding ) > ( $size + 1 )) {
return dol_substr ( $newstring , 0 , $size , $stringencoding ) . " \n " . dol_trunc ( dol_substr ( $newstring , $size , dol_strlen ( $newstring , $stringencoding ) - $size , $stringencoding ), $size , $trunc );
} else {
return $string ;
}
} else {
return 'BadParam3CallingDolTrunc' ;
}
2008-08-06 16:50:06 +02:00
}
/**
2011-07-18 05:49:10 +02:00
* Show picto whatever it ' s its name ( generic function )
2011-08-17 17:56:22 +02:00
*
2019-07-20 13:09:25 +02:00
* @ param string $titlealt Text on title tag for tooltip . Not used if param notitle is set to 1.
* @ param string $picto Name of image file to show ( 'filenew' , ... )
* If no extension provided , we use '.png' . Image must be stored into theme / xxx / img directory .
* Example : picto . png if picto . png is stored into htdocs / theme / mytheme / img
* Example : picto . png @ mymodule if picto . png is stored into htdocs / mymodule / img
* Example : / mydir / mysubdir / picto . png if picto . png is stored into htdocs / mydir / mysubdir ( pictoisfullpath must be set to 1 )
2021-12-21 16:31:28 +01:00
* Example : fontawesome_envelope - open - text_fas_red_1em if you want to use fontaweseome icons : fontawesome_ < icon - name > _ < style > _ < color > _ < size > ( only icon - name is mandatory )
2021-02-16 17:05:38 +01:00
* @ param string $moreatt Add more attribute on img tag ( For example 'class="pictofixedwidth"' )
2019-07-20 13:09:25 +02:00
* @ param boolean | int $pictoisfullpath If true or 1 , image path is a full path
* @ param int $srconly Return only content of the src attribute of img .
* @ param int $notitle 1 = Disable tag title . Use it if you add js tooltip , to avoid duplicate tooltip .
* @ param string $alt Force alt for bind people
2020-02-25 12:37:44 +01:00
* @ param string $morecss Add more class css on img tag ( For example 'myclascss' ) .
2019-11-01 03:25:09 +01:00
* @ param string $marginleftonlyshort 1 = Add a short left margin on picto , 2 = Add a larger left margin on picto , 0 = No margin left . Works for fontawesome picto only .
2019-07-20 13:09:25 +02:00
* @ return string Return img tag
2019-03-15 15:07:52 +01:00
* @ see img_object (), img_picto_common ()
2008-08-06 16:50:06 +02:00
*/
2019-07-20 13:09:25 +02:00
function img_picto ( $titlealt , $picto , $moreatt = '' , $pictoisfullpath = false , $srconly = 0 , $notitle = 0 , $alt = '' , $morecss = '' , $marginleftonlyshort = 2 )
2008-08-06 16:50:06 +02:00
{
2017-10-20 21:39:19 +02:00
global $conf , $langs ;
2018-04-03 13:13:40 +02:00
// We forge fullpathpicto for image to $path/img/$picto. By default, we take DOL_URL_ROOT/theme/$conf->theme/img/$picto
$url = DOL_URL_ROOT ;
2020-12-06 07:58:46 +01:00
$theme = isset ( $conf -> theme ) ? $conf -> theme : null ;
2018-04-03 13:13:40 +02:00
$path = 'theme/' . $theme ;
2012-08-03 23:29:08 +02:00
// Define fullpathpicto to use into src
2018-04-03 13:13:40 +02:00
if ( $pictoisfullpath ) {
2012-08-04 08:45:38 +02:00
// Clean parameters
2019-11-11 23:59:36 +01:00
if ( ! preg_match ( '/(\.png|\.gif|\.svg)$/i' , $picto )) {
2018-04-03 13:13:40 +02:00
$picto .= '.png' ;
}
2018-04-05 19:52:54 +02:00
$fullpathpicto = $picto ;
2019-11-11 23:59:36 +01:00
$reg = array ();
2019-02-20 06:01:13 +01:00
if ( preg_match ( '/class="([^"]+)"/' , $moreatt , $reg )) {
2020-09-07 10:18:17 +02:00
$morecss .= ( $morecss ? ' ' : '' ) . $reg [ 1 ];
$moreatt = str_replace ( 'class="' . $reg [ 1 ] . '"' , '' , $moreatt );
2019-02-20 06:01:13 +01:00
}
2019-02-10 10:45:49 +01:00
} else {
2019-09-30 17:08:57 +02:00
$pictowithouttext = preg_replace ( '/(\.png|\.gif|\.svg)$/' , '' , $picto );
2021-10-26 17:23:51 +02:00
if ( strpos ( $pictowithouttext , 'fontawesome_' ) !== false ) {
$pictowithouttext = explode ( '_' , $pictowithouttext );
$marginleftonlyshort = 0 ;
$fakey = 'fa-' . $pictowithouttext [ 1 ];
$fa = $pictowithouttext [ 2 ] ? $pictowithouttext [ 2 ] : 'fa' ;
$facolor = $pictowithouttext [ 3 ] ? $pictowithouttext [ 3 ] : '' ;
$fasize = $pictowithouttext [ 4 ] ? $pictowithouttext [ 4 ] : '' ;
// This snippet only needed since function img_edit accepts only one additional parameter: no separate one for css only.
// class/style need to be extracted to avoid duplicate class/style validation errors when $moreatt is added to the end of the attributes.
$morestyle = '' ;
$reg = array ();
if ( preg_match ( '/class="([^"]+)"/' , $moreatt , $reg )) {
$morecss .= ( $morecss ? ' ' : '' ) . $reg [ 1 ];
$moreatt = str_replace ( 'class="' . $reg [ 1 ] . '"' , '' , $moreatt );
}
if ( preg_match ( '/style="([^"]+)"/' , $moreatt , $reg )) {
$morestyle = $reg [ 1 ];
$moreatt = str_replace ( 'style="' . $reg [ 1 ] . '"' , '' , $moreatt );
}
$moreatt = trim ( $moreatt );
$enabledisablehtml = '<span class="' . $fa . ' ' . $fakey . ( $marginleftonlyshort ? ( $marginleftonlyshort == 1 ? ' marginleftonlyshort' : ' marginleftonly' ) : '' );
$enabledisablehtml .= ( $morecss ? ' ' . $morecss : '' ) . '" style="' . ( $fasize ? ( 'font-size: ' . $fasize . ';' ) : '' ) . ( $facolor ? ( ' color: ' . $facolor . ';' ) : '' ) . ( $morestyle ? ' ' . $morestyle : '' ) . '"' . (( $notitle || empty ( $titlealt )) ? '' : ' title="' . dol_escape_htmltag ( $titlealt ) . '"' ) . ( $moreatt ? ' ' . $moreatt : '' ) . '>' ;
/* if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) {
$enabledisablehtml .= $titlealt ;
} */
$enabledisablehtml .= '</span>' ;
return $enabledisablehtml ;
}
2021-04-29 10:01:10 +02:00
$pictowithouttext = str_replace ( 'object_' , '' , $pictowithouttext );
2020-08-21 13:00:12 +02:00
if ( empty ( $srconly ) && in_array ( $pictowithouttext , array (
2020-09-07 10:18:17 +02:00
'1downarrow' , '1uparrow' , '1leftarrow' , '1rightarrow' , '1uparrow_selected' , '1downarrow_selected' , '1leftarrow_selected' , '1rightarrow_selected' ,
2021-12-18 23:51:14 +01:00
'accountancy' , 'accounting_account' , 'account' , 'accountline' , 'action' , 'add' , 'address' , 'angle-double-down' , 'angle-double-up' , 'asset' ,
2022-02-13 19:26:16 +01:00
'bank_account' , 'barcode' , 'bank' , 'bell' , 'bill' , 'billa' , 'billr' , 'billd' , 'bookmark' , 'bom' , 'briefcase-medical' , 'bug' , 'building' ,
2022-01-16 13:11:12 +01:00
'card' , 'calendar' , 'calendarmonth' , 'calendarweek' , 'calendarday' , 'calendarperuser' , 'calendarpertype' ,
2021-06-07 01:43:24 +02:00
'cash-register' , 'category' , 'chart' , 'check' , 'clock' , 'close_title' , 'cog' , 'collab' , 'company' , 'contact' , 'country' , 'contract' , 'conversation' , 'cron' , 'cubes' ,
'multicurrency' ,
2021-04-30 15:22:17 +02:00
'delete' , 'dolly' , 'dollyrevert' , 'donation' , 'download' , 'dynamicprice' ,
2021-11-23 11:10:16 +01:00
'edit' , 'ellipsis-h' , 'email' , 'entity' , 'eraser' , 'establishment' , 'expensereport' , 'external-link-alt' , 'external-link-square-alt' ,
2021-04-15 13:22:03 +02:00
'filter' , 'file-code' , 'file-export' , 'file-import' , 'file-upload' , 'autofill' , 'folder' , 'folder-open' , 'folder-plus' ,
2021-05-05 19:13:40 +02:00
'generate' , 'globe' , 'globe-americas' , 'graph' , 'grip' , 'grip_title' , 'group' ,
2020-09-11 13:14:14 +02:00
'help' , 'holiday' ,
2021-05-02 13:13:55 +02:00
'images' , 'incoterm' , 'info' , 'intervention' , 'inventory' , 'intracommreport' , 'knowledgemanagement' ,
2022-02-21 19:09:26 +01:00
'label' , 'language' , 'line' , 'link' , 'list' , 'list-alt' , 'listlight' , 'loan' , 'lot' , 'long-arrow-alt-right' ,
2021-02-27 00:31:29 +01:00
'margin' , 'map-marker-alt' , 'member' , 'meeting' , 'money-bill-alt' , 'movement' , 'mrp' , 'note' , 'next' ,
2020-09-07 10:18:17 +02:00
'off' , 'on' , 'order' ,
2022-01-16 13:11:12 +01:00
'paiment' , 'paragraph' , 'play' , 'pdf' , 'phone' , 'phoning' , 'phoning_mobile' , 'phoning_fax' , 'playdisabled' , 'previous' , 'poll' , 'pos' , 'printer' , 'product' , 'propal' , 'puce' ,
'stock' , 'resize' , 'service' , 'stats' , 'trip' ,
2021-09-10 09:21:37 +02:00
'security' , 'setup' , 'share-alt' , 'sign-out' , 'split' , 'stripe' , 'stripe-s' , 'switch_off' , 'switch_on' , 'switch_on_red' , 'tools' , 'unlink' , 'uparrow' , 'user' , 'vcard' , 'wrench' ,
2022-01-19 18:23:31 +01:00
'github' , 'google' , 'jabber' , 'skype' , 'twitter' , 'facebook' , 'linkedin' , 'instagram' , 'snapchat' , 'youtube' , 'google-plus-g' , 'whatsapp' ,
2020-09-14 12:50:07 +02:00
'chevron-left' , 'chevron-right' , 'chevron-down' , 'chevron-top' , 'commercial' , 'companies' ,
'generic' , 'home' , 'hrm' , 'members' , 'products' , 'invoicing' ,
2021-11-15 09:02:01 +01:00
'partnership' , 'payment' , 'payment_vat' , 'pencil-ruler' , 'preview' , 'project' , 'projectpub' , 'projecttask' , 'question' , 'refresh' , 'region' ,
2021-07-06 15:55:43 +02:00
'salary' , 'shipment' , 'state' , 'supplier_invoice' , 'supplier_invoicea' , 'supplier_invoicer' , 'supplier_invoiced' ,
2021-06-10 01:10:35 +02:00
'technic' , 'ticket' ,
2020-09-11 13:32:40 +02:00
'error' , 'warning' ,
2021-11-25 14:17:20 +01:00
'recent' , 'reception' , 'recruitmentcandidature' , 'recruitmentjobposition' , 'resource' , 'recurring' ,
2021-12-06 02:48:34 +01:00
'shapes' , 'square' , 'stop-circle' , 'supplier' , 'supplier_proposal' , 'supplier_order' , 'supplier_invoice' ,
2021-02-27 12:45:07 +01:00
'timespent' , 'title_setup' , 'title_accountancy' , 'title_bank' , 'title_hrm' , 'title_agenda' ,
2022-02-13 19:26:16 +01:00
'uncheck' , 'user-cog' , 'user-injured' , 'user-md' , 'vat' , 'website' , 'workstation' ,
2021-03-29 16:25:34 +02:00
'conferenceorbooth' , 'eventorganization'
2021-02-23 22:03:23 +01:00
))) {
2019-11-05 09:52:33 +01:00
$fakey = $pictowithouttext ;
2021-03-01 20:37:16 +01:00
$facolor = '' ;
$fasize = '' ;
2019-11-11 23:59:36 +01:00
$fa = 'fas' ;
2022-01-16 13:11:12 +01:00
if ( in_array ( $pictowithouttext , array ( 'card' , 'bell' , 'clock' , 'establishment' , 'generic' , 'minus-square' , 'object_generic' , 'pdf' , 'plus-square' , 'timespent' , 'note' , 'off' , 'on' , 'object_bookmark' , 'bookmark' , 'vcard' ))) {
2019-11-11 23:59:36 +01:00
$fa = 'far' ;
2019-11-05 09:52:33 +01:00
}
2022-01-19 18:23:31 +01:00
if ( in_array ( $pictowithouttext , array ( 'black-tie' , 'github' , 'google' , 'skype' , 'twitter' , 'facebook' , 'linkedin' , 'instagram' , 'snapchat' , 'stripe' , 'stripe-s' , 'youtube' , 'google-plus-g' , 'whatsapp' ))) {
2019-11-11 23:59:36 +01:00
$fa = 'fab' ;
2019-11-05 09:52:33 +01:00
}
2020-04-07 16:45:08 +02:00
2020-09-07 10:18:17 +02:00
$arrayconvpictotofa = array (
2021-12-18 23:51:14 +01:00
'account' => 'university' , 'accounting_account' => 'clipboard-list' , 'accountline' => 'receipt' , 'accountancy' => 'search-dollar' , 'action' => 'calendar-alt' , 'add' => 'plus-circle' , 'address' => 'address-book' , 'asset' => 'money-check-alt' , 'autofill' => 'fill' ,
2021-06-10 01:10:35 +02:00
'bank_account' => 'university' ,
'bill' => 'file-invoice-dollar' , 'billa' => 'file-excel' , 'billr' => 'file-invoice-dollar' , 'billd' => 'file-medical' ,
'supplier_invoice' => 'file-invoice-dollar' , 'supplier_invoicea' => 'file-excel' , 'supplier_invoicer' => 'file-invoice-dollar' , 'supplier_invoiced' => 'file-medical' ,
2021-02-04 20:29:57 +01:00
'bom' => 'shapes' ,
2022-01-16 13:11:12 +01:00
'card' => 'address-card' , 'chart' => 'chart-line' , 'company' => 'building' , 'contact' => 'address-book' , 'contract' => 'suitcase' , 'collab' => 'people-arrows' , 'conversation' => 'comments' , 'country' => 'globe-americas' , 'cron' => 'business-time' ,
2021-03-13 18:56:02 +01:00
'donation' => 'file-alt' , 'dynamicprice' => 'hand-holding-usd' ,
2020-09-07 10:18:17 +02:00
'setup' => 'cog' , 'companies' => 'building' , 'products' => 'cube' , 'commercial' => 'suitcase' , 'invoicing' => 'coins' ,
2021-04-15 13:22:03 +02:00
'accounting' => 'search-dollar' , 'category' => 'tag' , 'dollyrevert' => 'dolly' ,
2021-05-05 19:13:40 +02:00
'generate' => 'plus-square' , 'hrm' => 'user-tie' , 'incoterm' => 'truck-loading' ,
2021-05-02 13:13:55 +02:00
'margin' => 'calculator' , 'members' => 'user-friends' , 'ticket' => 'ticket-alt' , 'globe' => 'external-link-alt' , 'lot' => 'barcode' ,
2021-11-23 11:10:16 +01:00
'email' => 'at' , 'establishment' => 'building' , 'edit' => 'pencil-alt' , 'entity' => 'globe' ,
'graph' => 'chart-line' , 'grip_title' => 'arrows-alt' , 'grip' => 'arrows-alt' , 'help' => 'question-circle' ,
2021-03-12 15:34:31 +01:00
'generic' => 'file' , 'holiday' => 'umbrella-beach' ,
2022-02-21 19:09:26 +01:00
'info' => 'info-circle' , 'inventory' => 'boxes' , 'intracommreport' => 'globe-europe' , 'knowledgemanagement' => 'ticket-alt' , 'label' => 'layer-group' , 'line' => 'bars' , 'loan' => 'money-bill-alt' ,
2021-02-15 20:13:38 +01:00
'member' => 'user-alt' , 'meeting' => 'chalkboard-teacher' , 'mrp' => 'cubes' , 'next' => 'arrow-alt-circle-right' ,
2021-04-27 22:14:19 +02:00
'trip' => 'wallet' , 'expensereport' => 'wallet' , 'group' => 'users' , 'movement' => 'people-carry' ,
2020-09-07 10:18:17 +02:00
'sign-out' => 'sign-out-alt' ,
2021-10-26 16:45:40 +02:00
'switch_off' => 'toggle-off' , 'switch_on' => 'toggle-on' , 'switch_on_red' => 'toggle-on' , 'check' => 'check' , 'bookmark' => 'star' ,
2021-10-26 15:27:12 +02:00
'bank' => 'university' , 'close_title' => 'times' , 'delete' => 'trash' , 'filter' => 'filter' ,
'list-alt' => 'list-alt' , 'calendar' => 'calendar-alt' , 'calendarmonth' => 'calendar-alt' , 'calendarweek' => 'calendar-week' , 'calendarday' => 'calendar-day' , 'calendarperuser' => 'table' ,
2020-09-07 10:18:17 +02:00
'intervention' => 'ambulance' , 'invoice' => 'file-invoice-dollar' , 'multicurrency' => 'dollar-sign' , 'order' => 'file-invoice' ,
'error' => 'exclamation-triangle' , 'warning' => 'exclamation-triangle' ,
'other' => 'square' ,
2021-03-18 11:39:23 +01:00
'playdisabled' => 'play' , 'pdf' => 'file-pdf' , 'poll' => 'check-double' , 'pos' => 'cash-register' , 'preview' => 'binoculars' , 'project' => 'project-diagram' , 'projectpub' => 'project-diagram' , 'projecttask' => 'tasks' , 'propal' => 'file-signature' ,
2022-01-16 13:11:12 +01:00
'partnership' => 'handshake' , 'payment' => 'money-check-alt' , 'payment_vat' => 'money-check-alt' , 'phoning' => 'phone' , 'phoning_mobile' => 'mobile-alt' , 'phoning_fax' => 'fax' , 'previous' => 'arrow-alt-circle-left' , 'printer' => 'print' , 'product' => 'cube' , 'puce' => 'angle-right' ,
2021-05-19 14:13:42 +02:00
'recent' => 'question' , 'reception' => 'dolly' , 'recruitmentjobposition' => 'id-card-alt' , 'recruitmentcandidature' => 'id-badge' ,
2020-09-07 10:18:17 +02:00
'resize' => 'crop' , 'supplier_order' => 'dol-order_supplier' , 'supplier_proposal' => 'file-signature' ,
2021-11-25 14:17:20 +01:00
'refresh' => 'redo' , 'region' => 'map-marked' , 'resource' => 'laptop-house' , 'recurring' => 'history' ,
2022-01-16 13:11:12 +01:00
'service' => 'concierge-bell' ,
2021-07-06 15:55:43 +02:00
'state' => 'map-marked-alt' , 'security' => 'key' , 'salary' => 'wallet' , 'shipment' => 'dolly' , 'stock' => 'box-open' , 'stats' => 'chart-bar' , 'split' => 'code-branch' , 'stripe' => 'stripe-s' ,
2021-10-26 16:45:40 +02:00
'supplier' => 'building' , 'technic' => 'cogs' ,
2021-02-27 12:45:07 +01:00
'timespent' => 'clock' , 'title_setup' => 'tools' , 'title_accountancy' => 'money-check-alt' , 'title_bank' => 'university' , 'title_hrm' => 'umbrella-beach' ,
2020-09-07 10:18:17 +02:00
'title_agenda' => 'calendar-alt' ,
2021-11-15 09:02:01 +01:00
'uncheck' => 'times' , 'uparrow' => 'share' , 'vat' => 'money-check-alt' , 'vcard' => 'address-card' ,
2020-09-07 10:18:17 +02:00
'jabber' => 'comment-o' ,
2021-04-05 14:56:47 +02:00
'website' => 'globe-americas' , 'workstation' => 'pallet' ,
2021-03-23 01:32:17 +01:00
'conferenceorbooth' => 'chalkboard-teacher' , 'eventorganization' => 'project-diagram'
2020-09-07 10:18:17 +02:00
);
2020-04-07 16:45:08 +02:00
if ( $pictowithouttext == 'off' ) {
2020-09-07 10:18:17 +02:00
$fakey = 'fa-square' ;
2018-04-03 13:13:40 +02:00
$fasize = '1.3em' ;
2020-05-21 15:05:19 +02:00
} elseif ( $pictowithouttext == 'on' ) {
2020-09-07 10:18:17 +02:00
$fakey = 'fa-check-square' ;
2018-04-03 13:13:40 +02:00
$fasize = '1.3em' ;
2020-05-21 15:05:19 +02:00
} elseif ( $pictowithouttext == 'listlight' ) {
2018-10-01 00:20:47 +02:00
$fakey = 'fa-download' ;
2019-11-11 23:59:36 +01:00
$marginleftonlyshort = 1 ;
2020-05-21 15:05:19 +02:00
} elseif ( $pictowithouttext == 'printer' ) {
2018-04-03 13:13:40 +02:00
$fakey = 'fa-print' ;
$fasize = '1.2em' ;
2020-05-21 15:05:19 +02:00
} elseif ( $pictowithouttext == 'note' ) {
2020-09-07 10:18:17 +02:00
$fakey = 'fa-sticky-note' ;
2019-11-11 23:59:36 +01:00
$marginleftonlyshort = 1 ;
2020-05-21 15:05:19 +02:00
} elseif ( in_array ( $pictowithouttext , array ( '1uparrow' , '1downarrow' , '1leftarrow' , '1rightarrow' , '1uparrow_selected' , '1downarrow_selected' , '1leftarrow_selected' , '1rightarrow_selected' ))) {
2020-09-07 10:18:17 +02:00
$convertarray = array ( '1uparrow' => 'caret-up' , '1downarrow' => 'caret-down' , '1leftarrow' => 'caret-left' , '1rightarrow' => 'caret-right' , '1uparrow_selected' => 'caret-up' , '1downarrow_selected' => 'caret-down' , '1leftarrow_selected' => 'caret-left' , '1rightarrow_selected' => 'caret-right' );
$fakey = 'fa-' . $convertarray [ $pictowithouttext ];
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/selected/' , $pictowithouttext )) {
$facolor = '#888' ;
}
2018-09-12 21:57:32 +02:00
$marginleftonlyshort = 1 ;
2020-12-12 21:27:56 +01:00
} elseif ( ! empty ( $arrayconvpictotofa [ $pictowithouttext ])) {
2019-09-30 17:08:57 +02:00
$fakey = 'fa-' . $arrayconvpictotofa [ $pictowithouttext ];
2020-05-21 15:05:19 +02:00
} else {
2019-09-30 17:08:57 +02:00
$fakey = 'fa-' . $pictowithouttext ;
2020-04-07 16:45:08 +02:00
}
2021-02-08 19:56:38 +01:00
2021-03-13 18:56:02 +01:00
if ( in_array ( $pictowithouttext , array ( 'dollyrevert' , 'member' , 'members' , 'contract' , 'group' , 'resource' , 'shipment' ))) {
2021-07-04 20:08:34 +02:00
$morecss .= ' em092' ;
2021-02-06 12:10:27 +01:00
}
2021-04-29 15:49:44 +02:00
if ( in_array ( $pictowithouttext , array ( 'conferenceorbooth' , 'collab' , 'eventorganization' , 'holiday' , 'info' , 'project' , 'workstation' ))) {
2021-07-04 20:08:34 +02:00
$morecss .= ' em088' ;
2021-02-18 23:13:55 +01:00
}
2021-05-10 15:29:23 +02:00
if ( in_array ( $pictowithouttext , array ( 'asset' , 'intervention' , 'payment' , 'loan' , 'partnership' , 'stock' , 'technic' ))) {
2021-07-04 20:08:34 +02:00
$morecss .= ' em080' ;
2021-02-04 22:03:58 +01:00
}
2020-04-07 16:45:08 +02:00
// Define $marginleftonlyshort
$arrayconvpictotomarginleftonly = array (
'bank' , 'check' , 'delete' , 'generic' , 'grip' , 'grip_title' , 'jabber' ,
2021-09-10 09:21:37 +02:00
'grip_title' , 'grip' , 'listlight' , 'note' , 'on' , 'off' , 'playdisabled' , 'printer' , 'resize' , 'sign-out' , 'stats' , 'switch_on' , 'switch_on_red' , 'switch_off' ,
2020-04-07 16:45:08 +02:00
'uparrow' , '1uparrow' , '1downarrow' , '1leftarrow' , '1rightarrow' , '1uparrow_selected' , '1downarrow_selected' , '1leftarrow_selected' , '1rightarrow_selected'
);
2020-04-10 10:59:32 +02:00
if ( ! isset ( $arrayconvpictotomarginleftonly [ $pictowithouttext ])) {
2019-11-11 23:59:36 +01:00
$marginleftonlyshort = 0 ;
2018-04-03 13:13:40 +02:00
}
2019-10-12 19:16:36 +02:00
2020-04-07 16:45:08 +02:00
// Add CSS
$arrayconvpictotomorcess = array (
2021-12-18 23:51:14 +01:00
'action' => 'infobox-action' , 'account' => 'infobox-bank_account' , 'accounting_account' => 'infobox-bank_account' , 'accountline' => 'infobox-bank_account' , 'accountancy' => 'infobox-bank_account' , 'asset' => 'infobox-bank_account' ,
2020-05-19 23:22:40 +02:00
'bank_account' => 'bg-infobox-bank_account' ,
2021-02-27 19:43:56 +01:00
'bill' => 'infobox-commande' , 'billa' => 'infobox-commande' , 'billr' => 'infobox-commande' , 'billd' => 'infobox-commande' ,
2021-09-29 16:31:40 +02:00
'margin' => 'infobox-bank_account' , 'conferenceorbooth' => 'infobox-project' ,
2021-03-13 18:56:02 +01:00
'cash-register' => 'infobox-bank_account' , 'contract' => 'infobox-contrat' , 'check' => 'font-status4' , 'collab' => 'infobox-action' , 'conversation' => 'infobox-contrat' ,
2021-05-02 13:13:55 +02:00
'donation' => 'infobox-commande' , 'dolly' => 'infobox-commande' , 'dollyrevert' => 'flip infobox-order_supplier' ,
2021-04-30 15:22:17 +02:00
'ecm' => 'infobox-action' , 'eventorganization' => 'infobox-project' ,
2020-05-26 22:30:11 +02:00
'hrm' => 'infobox-adherent' , 'group' => 'infobox-adherent' , 'intervention' => 'infobox-contrat' ,
2021-05-02 13:13:55 +02:00
'incoterm' => 'infobox-supplier_proposal' ,
2020-05-26 22:30:11 +02:00
'multicurrency' => 'infobox-bank_account' ,
'members' => 'infobox-adherent' , 'member' => 'infobox-adherent' , 'money-bill-alt' => 'infobox-bank_account' ,
'order' => 'infobox-commande' ,
'user' => 'infobox-adherent' , 'users' => 'infobox-adherent' ,
2021-09-10 09:21:37 +02:00
'error' => 'pictoerror' , 'warning' => 'pictowarning' , 'switch_on' => 'font-status4' , 'switch_on_red' => 'font-status8' ,
2021-04-30 15:22:17 +02:00
'holiday' => 'infobox-holiday' , 'info' => 'opacityhigh' , 'invoice' => 'infobox-commande' ,
'knowledgemanagement' => 'infobox-contrat rotate90' , 'loan' => 'infobox-bank_account' ,
2021-11-15 09:02:01 +01:00
'payment' => 'infobox-bank_account' , 'payment_vat' => 'infobox-bank_account' , 'poll' => 'infobox-adherent' , 'pos' => 'infobox-bank_account' , 'project' => 'infobox-project' , 'projecttask' => 'infobox-project' , 'propal' => 'infobox-propal' ,
2021-04-13 22:58:37 +02:00
'reception' => 'flip' , 'recruitmentjobposition' => 'infobox-adherent' , 'recruitmentcandidature' => 'infobox-adherent' ,
2020-08-21 13:00:12 +02:00
'resource' => 'infobox-action' ,
2021-05-02 13:13:55 +02:00
'salary' => 'infobox-bank_account' , 'shipment' => 'infobox-commande' , 'supplier_invoice' => 'infobox-order_supplier' , 'supplier_invoicea' => 'infobox-order_supplier' , 'supplier_invoiced' => 'infobox-order_supplier' ,
2021-05-11 14:50:04 +02:00
'supplier' => 'infobox-order_supplier' , 'supplier_order' => 'infobox-order_supplier' , 'supplier_proposal' => 'infobox-supplier_proposal' ,
2021-04-27 22:14:19 +02:00
'ticket' => 'infobox-contrat' , 'title_accountancy' => 'infobox-bank_account' , 'title_hrm' => 'infobox-holiday' , 'expensereport' => 'infobox-expensereport' , 'trip' => 'infobox-expensereport' , 'title_agenda' => 'infobox-action' ,
2021-11-15 09:02:01 +01:00
'vat' => 'infobox-bank_account' ,
2020-05-26 22:30:11 +02:00
//'title_setup'=>'infobox-action', 'tools'=>'infobox-action',
2020-04-07 16:45:08 +02:00
'list-alt' => 'imgforviewmode' , 'calendar' => 'imgforviewmode' , 'calendarweek' => 'imgforviewmode' , 'calendarmonth' => 'imgforviewmode' , 'calendarday' => 'imgforviewmode' , 'calendarperuser' => 'imgforviewmode'
);
2020-04-10 10:59:32 +02:00
if ( ! empty ( $arrayconvpictotomorcess [ $pictowithouttext ])) {
2020-04-07 16:45:08 +02:00
$morecss .= ( $morecss ? ' ' : '' ) . $arrayconvpictotomorcess [ $pictowithouttext ];
}
// Define $color
$arrayconvpictotocolor = array (
2020-09-18 04:30:24 +02:00
'address' => '#6c6aa8' , 'building' => '#6c6aa8' , 'bom' => '#a69944' ,
2021-03-15 13:25:08 +01:00
'cog' => '#999' , 'companies' => '#6c6aa8' , 'company' => '#6c6aa8' , 'contact' => '#6c6aa8' , 'cron' => '#555' ,
'dynamicprice' => '#a69944' ,
2021-02-27 02:44:52 +01:00
'edit' => '#444' , 'note' => '#999' , 'error' => '' , 'help' => '#bbb' , 'listlight' => '#999' , 'language' => '#555' ,
2021-05-02 13:13:55 +02:00
//'dolly'=>'#a69944', 'dollyrevert'=>'#a69944',
'lot' => '#a69944' ,
2021-03-09 15:35:10 +01:00
'map-marker-alt' => '#aaa' , 'mrp' => '#a69944' , 'product' => '#a69944' , 'service' => '#a69944' , 'inventory' => '#a69944' , 'stock' => '#a69944' , 'movement' => '#a69944' ,
2020-04-07 21:11:18 +02:00
'other' => '#ddd' ,
2021-04-28 23:25:26 +02:00
'partnership' => '#6c6aa8' , 'playdisabled' => '#ccc' , 'printer' => '#444' , 'projectpub' => '#986c6a' , 'reception' => '#a69944' , 'resize' => '#444' , 'rss' => '#cba' ,
2021-05-02 13:13:55 +02:00
//'shipment'=>'#a69944',
2021-12-06 02:48:34 +01:00
'security' => '#999' , 'square' => '#888' , 'stop-circle' => '#888' , 'stats' => '#444' , 'switch_off' => '#999' , 'technic' => '#999' , 'timespent' => '#555' ,
2021-07-06 15:55:43 +02:00
'uncheck' => '#800' , 'uparrow' => '#555' , 'user-cog' => '#999' , 'country' => '#aaa' , 'globe-americas' => '#aaa' , 'region' => '#aaa' , 'state' => '#aaa' ,
2021-04-05 14:56:47 +02:00
'website' => '#304' , 'workstation' => '#a69944'
2020-04-07 16:45:08 +02:00
);
if ( isset ( $arrayconvpictotocolor [ $pictowithouttext ])) {
$facolor = $arrayconvpictotocolor [ $pictowithouttext ];
}
// This snippet only needed since function img_edit accepts only one additional parameter: no separate one for css only.
2020-09-07 10:18:17 +02:00
// class/style need to be extracted to avoid duplicate class/style validation errors when $moreatt is added to the end of the attributes.
2020-10-30 05:45:36 +01:00
$morestyle = '' ;
2020-09-07 10:18:17 +02:00
$reg = array ();
2018-04-03 13:13:40 +02:00
if ( preg_match ( '/class="([^"]+)"/' , $moreatt , $reg )) {
2020-09-07 10:18:17 +02:00
$morecss .= ( $morecss ? ' ' : '' ) . $reg [ 1 ];
$moreatt = str_replace ( 'class="' . $reg [ 1 ] . '"' , '' , $moreatt );
}
if ( preg_match ( '/style="([^"]+)"/' , $moreatt , $reg )) {
2020-10-30 05:45:36 +01:00
$morestyle = $reg [ 1 ];
2020-09-07 10:18:17 +02:00
$moreatt = str_replace ( 'style="' . $reg [ 1 ] . '"' , '' , $moreatt );
}
$moreatt = trim ( $moreatt );
2019-01-21 16:19:31 +01:00
2020-09-07 10:18:17 +02:00
$enabledisablehtml = '<span class="' . $fa . ' ' . $fakey . ( $marginleftonlyshort ? ( $marginleftonlyshort == 1 ? ' marginleftonlyshort' : ' marginleftonly' ) : '' );
$enabledisablehtml .= ( $morecss ? ' ' . $morecss : '' ) . '" style="' . ( $fasize ? ( 'font-size: ' . $fasize . ';' ) : '' ) . ( $facolor ? ( ' color: ' . $facolor . ';' ) : '' ) . ( $morestyle ? ' ' . $morestyle : '' ) . '"' . (( $notitle || empty ( $titlealt )) ? '' : ' title="' . dol_escape_htmltag ( $titlealt ) . '"' ) . ( $moreatt ? ' ' . $moreatt : '' ) . '>' ;
2020-10-27 11:40:30 +01:00
/* if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) {
2019-11-11 23:59:36 +01:00
$enabledisablehtml .= $titlealt ;
2020-10-27 11:40:30 +01:00
} */
2019-11-11 23:59:36 +01:00
$enabledisablehtml .= '</span>' ;
2018-03-14 20:08:44 +01:00
2017-10-20 21:39:19 +02:00
return $enabledisablehtml ;
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_OVERWRITE_THEME_PATH )) {
$path = $conf -> global -> MAIN_OVERWRITE_THEME_PATH . '/theme/' . $theme ; // If the theme does not have the same name as the module
2020-05-21 15:05:19 +02:00
} elseif ( ! empty ( $conf -> global -> MAIN_OVERWRITE_THEME_RES )) {
2019-11-11 23:59:36 +01:00
$path = $conf -> global -> MAIN_OVERWRITE_THEME_RES . '/theme/' . $conf -> global -> MAIN_OVERWRITE_THEME_RES ; // To allow an external module to overwrite image resources whatever is activated theme
2020-05-21 15:05:19 +02:00
} elseif ( ! empty ( $conf -> modules_parts [ 'theme' ]) && array_key_exists ( $theme , $conf -> modules_parts [ 'theme' ])) {
2019-11-11 23:59:36 +01:00
$path = $theme . '/theme/' . $theme ; // If the theme have the same name as the module
2018-04-03 13:13:40 +02:00
}
2014-10-08 14:51:16 +02:00
2013-03-02 14:43:36 +01:00
// If we ask an image into $url/$mymodule/img (instead of default path)
2020-03-24 19:06:37 +01:00
$regs = array ();
2019-01-04 15:22:59 +01:00
if ( preg_match ( '/^([^@]+)@([^@]+)$/i' , $picto , $regs )) {
2012-08-04 02:15:39 +02:00
$picto = $regs [ 1 ];
2019-11-11 23:59:36 +01:00
$path = $regs [ 2 ]; // $path is $mymodule
2012-08-04 02:15:39 +02:00
}
2017-06-02 20:01:25 +02:00
2012-08-04 08:45:38 +02:00
// Clean parameters
2019-11-11 23:59:36 +01:00
if ( ! preg_match ( '/(\.png|\.gif|\.svg)$/i' , $picto )) {
2018-04-03 13:13:40 +02:00
$picto .= '.png' ;
}
2013-07-07 03:26:51 +02:00
// If alt path are defined, define url where img file is, according to physical path
2018-04-03 13:13:40 +02:00
// ex: array(["main"]=>"/home/maindir/htdocs", ["alt0"]=>"/home/moddir0/htdocs", ...)
foreach ( $conf -> file -> dol_document_root as $type => $dirroot ) {
if ( $type == 'main' ) {
continue ;
}
// This need a lot of time, that's why enabling alternative dir like "custom" dir is not recommanded
if ( file_exists ( $dirroot . '/' . $path . '/img/' . $picto )) {
$url = DOL_URL_ROOT . $conf -> file -> dol_url_root [ $type ];
2013-07-07 13:17:48 +02:00
break ;
}
}
2012-08-03 23:29:08 +02:00
2013-03-02 14:43:36 +01:00
// $url is '' or '/custom', $path is current theme or
2012-08-04 02:15:39 +02:00
$fullpathpicto = $url . '/' . $path . '/img/' . $picto ;
2012-08-03 23:29:08 +02:00
}
2018-04-03 13:13:40 +02:00
if ( $srconly ) {
return $fullpathpicto ;
}
2019-01-21 16:19:31 +01:00
// tag title is used for tooltip on <a>, tag alt can be used with very simple text on image for blind people
2021-08-10 19:44:55 +02:00
return '<img src="' . $fullpathpicto . '"' . ( $notitle ? '' : ' alt="' . dol_escape_htmltag ( $alt ) . '"' ) . (( $notitle || empty ( $titlealt )) ? '' : ' title="' . dol_escape_htmltag ( $titlealt ) . '"' ) . ( $moreatt ? ' ' . $moreatt . ( $morecss ? ' class="' . $morecss . '"' : '' ) : ' class="inline-block' . ( $morecss ? ' ' . $morecss : '' ) . '"' ) . '>' ; // Alt is used for accessibility, title for popup
2008-08-06 16:50:06 +02:00
}
2012-08-04 02:15:39 +02:00
/**
* Show a picto called object_picto ( generic function )
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-08-04 02:15:39 +02:00
* @ param string $picto Name of image to show object_picto ( example : user , group , action , bill , contract , propal , product , ... )
* For external modules use imagename @ mymodule to search into directory " img " of module .
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag ( ie : class = " datecallink " )
2012-08-04 02:15:39 +02:00
* @ param int $pictoisfullpath If 1 , image path is a full path
2016-10-28 17:43:29 +02:00
* @ param int $srconly Return only content of the src attribute of img .
* @ param int $notitle 1 = Disable tag title . Use it if you add js tooltip , to avoid duplicate tooltip .
2012-08-04 02:15:39 +02:00
* @ return string Return img tag
2020-04-20 02:14:43 +02:00
* @ see img_picto (), img_picto_common ()
2012-08-04 02:15:39 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_object ( $titlealt , $picto , $moreatt = '' , $pictoisfullpath = false , $srconly = 0 , $notitle = 0 )
2012-08-04 02:15:39 +02:00
{
2021-02-23 22:03:23 +01:00
if ( strpos ( $picto , '^' ) === 0 ) {
return img_picto ( $titlealt , str_replace ( '^' , '' , $picto ), $moreatt , $pictoisfullpath , $srconly , $notitle );
} else {
return img_picto ( $titlealt , 'object_' . $picto , $moreatt , $pictoisfullpath , $srconly , $notitle );
}
2012-08-04 02:15:39 +02:00
}
2016-02-13 07:53:50 +01:00
/**
* Show weather picto
*
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2019-08-18 03:42:38 +02:00
* @ param string | int $picto Name of image file to show ( If no extension provided , we use '.png' ) . Image must be stored into htdocs / theme / common directory . Or level of meteo image ( 0 - 4 ) .
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag
2016-02-13 07:53:50 +01:00
* @ param int $pictoisfullpath If 1 , image path is a full path
2019-02-20 06:01:13 +01:00
* @ param string $morecss More CSS
2016-02-13 07:53:50 +01:00
* @ return string Return img tag
2020-04-20 02:14:43 +02:00
* @ see img_object (), img_picto ()
2016-02-13 07:53:50 +01:00
*/
2019-02-20 06:01:13 +01:00
function img_weather ( $titlealt , $picto , $moreatt = '' , $pictoisfullpath = 0 , $morecss = '' )
2016-02-13 07:53:50 +01:00
{
global $conf ;
2020-09-15 11:28:49 +02:00
if ( is_numeric ( $picto )) {
//$leveltopicto = array(0=>'weather-clear.png', 1=>'weather-few-clouds.png', 2=>'weather-clouds.png', 3=>'weather-many-clouds.png', 4=>'weather-storm.png');
//$picto = $leveltopicto[$picto];
2020-09-15 03:42:35 +02:00
return '<i class="fa fa-weather-level' . $picto . '"></i>' ;
2020-09-15 11:28:49 +02:00
} elseif ( ! preg_match ( '/(\.png|\.gif)$/i' , $picto )) {
$picto .= '.png' ;
}
2016-02-13 07:53:50 +01:00
$path = DOL_URL_ROOT . '/theme/' . $conf -> theme . '/img/weather/' . $picto ;
2019-02-20 06:01:13 +01:00
return img_picto ( $titlealt , $path , $moreatt , 1 , 0 , 0 , '' , $morecss );
2016-02-13 07:53:50 +01:00
}
2008-09-02 02:27:05 +02:00
/**
2010-11-13 17:59:53 +01:00
* Show picto ( generic function )
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2011-09-12 19:08:02 +02:00
* @ param string $picto Name of image file to show ( If no extension provided , we use '.png' ) . Image must be stored into htdocs / theme / common directory .
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag
2011-09-12 19:08:02 +02:00
* @ param int $pictoisfullpath If 1 , image path is a full path
2021-08-10 19:44:55 +02:00
* @ param int $notitle 1 = Disable tag title . Use it if you add js tooltip , to avoid duplicate tooltip .
2011-09-12 19:08:02 +02:00
* @ return string Return img tag
2020-04-20 02:14:43 +02:00
* @ see img_object (), img_picto ()
2008-09-02 02:27:05 +02:00
*/
2021-08-10 19:44:55 +02:00
function img_picto_common ( $titlealt , $picto , $moreatt = '' , $pictoisfullpath = 0 , $notitle = 0 )
2008-09-02 02:27:05 +02:00
{
2012-08-03 23:29:08 +02:00
global $conf ;
2012-07-30 23:23:58 +02:00
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/(\.png|\.gif)$/i' , $picto )) {
$picto .= '.png' ;
}
2012-07-30 23:23:58 +02:00
2021-02-23 22:03:23 +01:00
if ( $pictoisfullpath ) {
$path = $picto ;
} else {
2012-08-03 23:29:08 +02:00
$path = DOL_URL_ROOT . '/theme/common/' . $picto ;
2012-08-04 08:45:38 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_MODULE_CAN_OVERWRITE_COMMONICONS )) {
2012-08-03 23:29:08 +02:00
$themepath = DOL_DOCUMENT_ROOT . '/theme/' . $conf -> theme . '/img/' . $picto ;
2012-07-30 23:23:58 +02:00
2021-02-23 22:03:23 +01:00
if ( file_exists ( $themepath )) {
$path = $themepath ;
}
2012-08-03 23:29:08 +02:00
}
}
2012-07-30 23:23:58 +02:00
2021-08-10 19:44:55 +02:00
return img_picto ( $titlealt , $path , $moreatt , 1 , 0 , $notitle );
2008-09-02 02:27:05 +02:00
}
2008-08-06 16:50:06 +02:00
/**
2011-05-03 21:03:08 +02:00
* Show logo action
2011-08-17 17:56:22 +02:00
*
2015-05-06 23:13:07 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
* @ param string $numaction Action id or code to show
2020-04-27 17:35:14 +02:00
* @ param string $picto Name of image file to show ( 'filenew' , ... )
2020-04-27 18:01:07 +02:00
* If no extension provided , we use '.png' . Image must be stored into theme / xxx / img directory .
* Example : picto . png if picto . png is stored into htdocs / theme / mytheme / img
* Example : picto . png @ mymodule if picto . png is stored into htdocs / mymodule / img
* Example : / mydir / mysubdir / picto . png if picto . png is stored into htdocs / mydir / mysubdir ( pictoisfullpath must be set to 1 )
2015-05-06 23:13:07 +02:00
* @ return string Return an img tag
2008-08-06 16:50:06 +02:00
*/
2020-04-27 18:01:07 +02:00
function img_action ( $titlealt , $numaction , $picto = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $titlealt ) || $titlealt == 'default' ) {
2020-05-21 16:00:12 +02:00
if ( $numaction == '-1' || $numaction == 'ST_NO' ) {
$numaction = - 1 ;
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeDoNotContact' );
} elseif ( $numaction == '0' || $numaction == 'ST_NEVER' ) {
$numaction = 0 ;
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeNeverContacted' );
} elseif ( $numaction == '1' || $numaction == 'ST_TODO' ) {
$numaction = 1 ;
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeToContact' );
} elseif ( $numaction == '2' || $numaction == 'ST_PEND' ) {
$numaction = 2 ;
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeContactInProcess' );
} elseif ( $numaction == '3' || $numaction == 'ST_DONE' ) {
$numaction = 3 ;
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeContactDone' );
} else {
$titlealt = $langs -> transnoentitiesnoconv ( 'ChangeStatus ' . $numaction );
$numaction = 0 ;
}
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! is_numeric ( $numaction )) {
$numaction = 0 ;
}
2012-08-03 23:29:08 +02:00
2020-04-27 17:35:14 +02:00
return img_picto ( $titlealt , ! empty ( $picto ) ? $picto : 'stcomm' . $numaction . '.png' );
2008-08-06 16:50:06 +02:00
}
/**
2011-08-17 17:56:22 +02:00
* Show pdf logo
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2011-12-01 22:58:02 +01:00
* @ param int $size Taille de l ' icone : 3 = 16 x16px , 2 = 14 x14px
* @ return string Retourne tag img
2008-08-06 16:50:06 +02:00
*/
2014-07-29 21:34:23 +02:00
function img_pdf ( $titlealt = 'default' , $size = 3 )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Show' );
}
2012-07-30 22:36:43 +02:00
2014-07-29 21:34:23 +02:00
return img_picto ( $titlealt , 'pdf' . $size . '.png' );
2008-08-06 16:50:06 +02:00
}
/**
2011-08-17 17:56:22 +02:00
* Show logo +
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2014-09-19 14:36:55 +02:00
* @ param string $other Add more attributes on img
2012-02-04 15:20:32 +01:00
* @ return string Return tag img
2008-08-06 16:50:06 +02:00
*/
2014-09-19 14:36:55 +02:00
function img_edit_add ( $titlealt = 'default' , $other = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Add' );
}
2012-07-30 22:36:43 +02:00
2014-09-19 14:36:55 +02:00
return img_picto ( $titlealt , 'edit_add.png' , $other );
2008-08-06 16:50:06 +02:00
}
/**
2011-08-17 17:56:22 +02:00
* Show logo -
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2014-09-19 14:36:55 +02:00
* @ param string $other Add more attributes on img
2014-07-29 21:34:23 +02:00
* @ return string Return tag img
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_edit_remove ( $titlealt = 'default' , $other = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Remove' );
}
2012-07-30 22:36:43 +02:00
2014-09-19 14:36:55 +02:00
return img_picto ( $titlealt , 'edit_remove.png' , $other );
2008-08-06 16:50:06 +02:00
}
/**
2011-08-17 17:56:22 +02:00
* Show logo editer / modifier fiche
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2019-10-18 19:55:21 +02:00
* @ param integer $float If you have to put the style " float: right "
2012-02-04 15:20:32 +01:00
* @ param string $other Add more attributes on img
2014-07-29 21:34:23 +02:00
* @ return string Return tag img
2008-08-06 16:50:06 +02:00
*/
2019-01-21 16:19:31 +01:00
function img_edit ( $titlealt = 'default' , $float = 0 , $other = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Modify' );
}
2012-07-30 22:36:43 +02:00
2019-11-11 23:59:36 +01:00
return img_picto ( $titlealt , 'edit.png' , ( $float ? 'style="float: ' . ( $langs -> tab_translate [ " DIRECTION " ] == 'rtl' ? 'left' : 'right' ) . '"' : " " ) . ( $other ? ' ' . $other : '' ));
2008-08-06 16:50:06 +02:00
}
2008-10-03 01:08:14 +02:00
/**
2011-08-17 17:56:22 +02:00
* Show logo view card
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2019-10-18 19:55:21 +02:00
* @ param integer $float If you have to put the style " float: right "
2012-02-04 15:20:32 +01:00
* @ param string $other Add more attributes on img
2014-07-29 21:34:23 +02:00
* @ return string Return tag img
2008-10-03 01:08:14 +02:00
*/
2021-07-06 04:29:25 +02:00
function img_view ( $titlealt = 'default' , $float = 0 , $other = 'class="valignmiddle"' )
2008-10-03 01:08:14 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'View' );
}
2012-07-30 23:27:12 +02:00
2017-03-31 14:21:51 +02:00
$moreatt = ( $float ? 'style="float: right" ' : '' ) . $other ;
2012-08-04 08:45:38 +02:00
2017-03-31 14:21:51 +02:00
return img_picto ( $titlealt , 'view.png' , $moreatt );
2008-10-03 01:08:14 +02:00
}
2008-08-06 16:50:06 +02:00
/**
2011-03-09 00:50:27 +01:00
* Show delete logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ param string $other Add more attributes on img
2020-04-08 16:13:29 +02:00
* @ param string $morecss More CSS
2012-02-04 15:20:32 +01:00
* @ return string Retourne tag img
2008-08-06 16:50:06 +02:00
*/
2020-04-08 16:13:29 +02:00
function img_delete ( $titlealt = 'default' , $other = 'class="pictodelete"' , $morecss = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Delete' );
}
2008-08-06 16:50:06 +02:00
2020-04-08 16:13:29 +02:00
return img_picto ( $titlealt , 'delete.png' , $other , false , 0 , 0 , '' , $morecss );
2012-07-30 22:36:43 +02:00
}
2008-08-06 16:50:06 +02:00
2013-03-08 11:38:30 +01:00
/**
* Show printer logo
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2013-03-08 11:38:30 +01:00
* @ param string $other Add more attributes on img
* @ return string Retourne tag img
*/
2019-01-27 15:20:16 +01:00
function img_printer ( $titlealt = " default " , $other = '' )
2013-03-08 11:38:30 +01:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2021-02-23 22:03:23 +01:00
if ( $titlealt == " default " ) {
$titlealt = $langs -> trans ( " Print " );
}
2019-01-27 11:55:16 +01:00
return img_picto ( $titlealt , 'printer.png' , $other );
2013-03-08 11:38:30 +01:00
}
2017-04-09 13:12:25 +02:00
/**
2017-06-03 01:55:05 +02:00
* Show split logo
2017-04-09 13:12:25 +02:00
*
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
* @ param string $other Add more attributes on img
* @ return string Retourne tag img
*/
function img_split ( $titlealt = 'default' , $other = 'class="pictosplit"' )
{
2019-12-23 12:24:27 +01:00
global $langs ;
2017-04-09 13:12:25 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Split' );
}
2017-04-09 13:12:25 +02:00
return img_picto ( $titlealt , 'split.png' , $other );
}
2008-08-06 16:50:06 +02:00
/**
2011-03-09 00:50:27 +01:00
* Show help logo with cursor " ? "
2011-08-17 17:56:22 +02:00
*
2017-02-17 17:11:14 +01:00
* @ param int $usehelpcursor 1 = Use help cursor , 2 = Use click pointer cursor , 0 = No specific cursor
2016-10-21 10:36:11 +02:00
* @ param int | string $usealttitle Text to use as alt title
* @ return string Return tag img
2008-08-06 16:50:06 +02:00
*/
2012-07-30 23:23:58 +02:00
function img_help ( $usehelpcursor = 1 , $usealttitle = 1 )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 23:23:58 +02:00
2021-02-23 22:03:23 +01:00
if ( $usealttitle ) {
if ( is_string ( $usealttitle )) {
$usealttitle = dol_escape_htmltag ( $usealttitle );
} else {
$usealttitle = $langs -> trans ( 'Info' );
}
2012-08-03 23:29:08 +02:00
}
2012-07-30 23:23:58 +02:00
2019-11-11 23:59:36 +01:00
return img_picto ( $usealttitle , 'info.png' , 'style="vertical-align: middle;' . ( $usehelpcursor == 1 ? ' cursor: help' : ( $usehelpcursor == 2 ? ' cursor: pointer' : '' )) . '"' );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show info logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2014-07-29 21:34:23 +02:00
function img_info ( $titlealt = 'default' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Informations' );
}
2012-07-30 22:36:43 +02:00
2015-06-04 10:42:12 +02:00
return img_picto ( $titlealt , 'info.png' , 'style="vertical-align: middle;"' );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show warning logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2018-01-12 01:10:03 +01:00
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' ) . If 1 , add float : right . Can ' t be " class " attribute .
2019-05-22 15:37:59 +02:00
* @ param string $morecss Add more CSS
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-05-22 15:37:59 +02:00
function img_warning ( $titlealt = 'default' , $moreatt = '' , $morecss = 'pictowarning' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Warning' );
}
2012-07-30 22:36:43 +02:00
2017-03-31 14:21:51 +02:00
//return '<div class="imglatecoin">'.img_picto($titlealt, 'warning_white.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')).'</div>';
2019-11-11 23:59:36 +01:00
return img_picto ( $titlealt , 'warning.png' , 'class="' . $morecss . '"' . ( $moreatt ? ( $moreatt == '1' ? ' style="float: right"' : ' ' . $moreatt ) : '' ));
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show error logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2014-07-29 21:34:23 +02:00
function img_error ( $titlealt = 'default' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Error' );
}
2012-07-30 22:36:43 +02:00
2019-12-23 12:24:27 +01:00
return img_picto ( $titlealt , 'error.png' );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show next logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
2017-10-13 13:28:26 +02:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_next ( $titlealt = 'default' , $moreatt = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2008-08-06 16:50:06 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Next' );
}
2008-08-06 16:50:06 +02:00
2017-03-31 14:21:51 +02:00
//return img_picto($titlealt, 'next.png', $moreatt);
2017-03-30 15:39:50 +02:00
return '<span class="fa fa-chevron-right paddingright paddingleft" title="' . dol_escape_htmltag ( $titlealt ) . '"></span>' ;
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show previous logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_previous ( $titlealt = 'default' , $moreatt = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Previous' );
}
2012-07-30 22:36:43 +02:00
2017-03-31 14:21:51 +02:00
//return img_picto($titlealt, 'previous.png', $moreatt);
2017-03-30 15:39:50 +02:00
return '<span class="fa fa-chevron-left paddingright paddingleft" title="' . dol_escape_htmltag ( $titlealt ) . '"></span>' ;
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show down arrow logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ param int $selected Selected
2015-03-22 21:18:25 +01:00
* @ param string $moreclass Add more CSS classes
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_down ( $titlealt = 'default' , $selected = 0 , $moreclass = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Down' );
}
2012-07-30 22:36:43 +02:00
2019-11-11 23:59:36 +01:00
return img_picto ( $titlealt , ( $selected ? '1downarrow_selected.png' : '1downarrow.png' ), 'class="imgdown' . ( $moreclass ? " " . $moreclass : " " ) . '"' );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show top arrow logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ param int $selected Selected
2015-03-22 21:18:25 +01:00
* @ param string $moreclass Add more CSS classes
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_up ( $titlealt = 'default' , $selected = 0 , $moreclass = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Up' );
}
2012-07-30 22:36:43 +02:00
2019-11-11 23:59:36 +01:00
return img_picto ( $titlealt , ( $selected ? '1uparrow_selected.png' : '1uparrow.png' ), 'class="imgup' . ( $moreclass ? " " . $moreclass : " " ) . '"' );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show left arrow logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ param int $selected Selected
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_left ( $titlealt = 'default' , $selected = 0 , $moreatt = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2020-05-21 16:00:12 +02:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Left' );
}
2012-07-30 22:36:43 +02:00
2017-03-31 14:21:51 +02:00
return img_picto ( $titlealt , ( $selected ? '1leftarrow_selected.png' : '1leftarrow.png' ), $moreatt );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show right arrow logo
2011-08-17 17:56:22 +02:00
*
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ param int $selected Selected
2017-03-31 14:21:51 +02:00
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_right ( $titlealt = 'default' , $selected = 0 , $moreatt = '' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Right' );
}
2012-07-30 22:36:43 +02:00
2017-03-31 14:21:51 +02:00
return img_picto ( $titlealt , ( $selected ? '1rightarrow_selected.png' : '1rightarrow.png' ), $moreatt );
2008-08-06 16:50:06 +02:00
}
/**
2012-07-31 14:41:15 +02:00
* Show tick logo if allowed
2011-08-17 17:56:22 +02:00
*
2012-02-04 15:20:32 +01:00
* @ param string $allow Allow
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2012-02-04 15:20:32 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2014-07-29 21:34:23 +02:00
function img_allow ( $allow , $titlealt = 'default' )
2008-08-06 16:50:06 +02:00
{
2019-12-23 12:24:27 +01:00
global $langs ;
2011-05-12 21:01:14 +02:00
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Active' );
}
2012-07-30 22:36:43 +02:00
2021-02-23 22:03:23 +01:00
if ( $allow == 1 ) {
return img_picto ( $titlealt , 'tick.png' );
}
2012-08-04 08:45:38 +02:00
2012-08-03 23:29:08 +02:00
return '-' ;
2011-05-12 21:01:14 +02:00
}
2008-08-06 16:50:06 +02:00
2018-03-13 22:43:50 +01:00
/**
* Return image of a credit card according to its brand name
*
2020-05-21 16:00:12 +02:00
* @ param string $brand Brand name of credit card
* @ param string $morecss More CSS
2018-03-13 22:43:50 +01:00
* @ return string Return img tag
*/
2020-03-24 21:40:25 +01:00
function img_credit_card ( $brand , $morecss = null )
2018-03-13 22:43:50 +01:00
{
2021-02-23 22:03:23 +01:00
if ( is_null ( $morecss )) {
$morecss = 'fa-2x' ;
}
2020-03-24 21:40:25 +01:00
2020-05-21 16:00:12 +02:00
if ( $brand == 'visa' || $brand == 'Visa' ) {
$brand = 'cc-visa' ;
} elseif ( $brand == 'mastercard' || $brand == 'MasterCard' ) {
$brand = 'cc-mastercard' ;
} elseif ( $brand == 'amex' || $brand == 'American Express' ) {
$brand = 'cc-amex' ;
} elseif ( $brand == 'discover' || $brand == 'Discover' ) {
$brand = 'cc-discover' ;
} elseif ( $brand == 'jcb' || $brand == 'JCB' ) {
$brand = 'cc-jcb' ;
} elseif ( $brand == 'diners' || $brand == 'Diners club' ) {
$brand = 'cc-diners-club' ;
} elseif ( ! in_array ( $brand , array ( 'cc-visa' , 'cc-mastercard' , 'cc-amex' , 'cc-discover' , 'cc-jcb' , 'cc-diners-club' ))) {
$brand = 'credit-card' ;
}
2018-03-13 22:43:50 +01:00
2020-03-24 21:40:25 +01:00
return '<span class="fa fa-' . $brand . ' fa-fw' . ( $morecss ? ' ' . $morecss : '' ) . '"></span>' ;
2018-03-13 22:43:50 +01:00
}
2008-08-06 16:50:06 +02:00
/**
2010-11-13 15:34:06 +01:00
* Show MIME img of a file
2012-02-12 16:50:58 +01:00
*
* @ param string $file Filename
2014-07-29 21:34:23 +02:00
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
2017-11-10 20:20:59 +01:00
* @ param string $morecss More css
2012-02-12 16:50:58 +01:00
* @ return string Return img tag
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function img_mime ( $file , $titlealt = '' , $morecss = '' )
2008-08-06 16:50:06 +02:00
{
2012-08-03 23:29:08 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2010-11-20 14:08:44 +01:00
2012-08-03 23:29:08 +02:00
$mimetype = dol_mimetype ( $file , '' , 1 );
$mimeimg = dol_mimetype ( $file , '' , 2 );
2017-11-10 20:20:59 +01:00
$mimefa = dol_mimetype ( $file , '' , 4 );
2009-05-19 02:14:27 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $titlealt )) {
$titlealt = 'Mime type: ' . $mimetype ;
}
2009-10-23 16:58:33 +02:00
2017-11-10 20:20:59 +01:00
//return img_picto_common($titlealt, 'mime/'.$mimeimg, 'class="'.$morecss.'"');
2021-09-30 00:28:47 +02:00
return '<i class="fa fa-' . $mimefa . ' paddingright' . ( $morecss ? ' ' . $morecss : '' ) . '"' . ( $titlealt ? ' title="' . $titlealt . '"' : '' ) . '></i>' ;
2008-08-06 16:50:06 +02:00
}
2014-09-17 17:59:00 +02:00
/**
* Show search logo
*
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
* @ param string $other Add more attributes on img
* @ return string Retourne tag img
*/
function img_search ( $titlealt = 'default' , $other = '' )
{
global $conf , $langs ;
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Search' );
}
2014-09-19 14:36:55 +02:00
2014-09-17 17:59:00 +02:00
$img = img_picto ( $titlealt , 'search.png' , $other , false , 1 );
2014-09-19 14:36:55 +02:00
2014-09-17 17:59:00 +02:00
$input = '<input type="image" class="liste_titre" name="button_search" src="' . $img . '" ' ;
2019-11-11 23:59:36 +01:00
$input .= 'value="' . dol_escape_htmltag ( $titlealt ) . '" title="' . dol_escape_htmltag ( $titlealt ) . '" >' ;
2014-09-17 17:59:00 +02:00
return $input ;
}
/**
* Show search logo
*
* @ param string $titlealt Text on alt and title of image . Alt only if param notitle is set to 1. If text is " TextA:TextB " , use Text A on alt and Text B on title .
* @ param string $other Add more attributes on img
* @ return string Retourne tag img
*/
function img_searchclear ( $titlealt = 'default' , $other = '' )
{
global $conf , $langs ;
2021-02-23 22:03:23 +01:00
if ( $titlealt == 'default' ) {
$titlealt = $langs -> trans ( 'Search' );
}
2014-09-19 14:36:55 +02:00
2014-09-17 17:59:00 +02:00
$img = img_picto ( $titlealt , 'searchclear.png' , $other , false , 1 );
2014-09-19 14:36:55 +02:00
2014-09-17 17:59:00 +02:00
$input = '<input type="image" class="liste_titre" name="button_removefilter" src="' . $img . '" ' ;
2019-11-11 23:59:36 +01:00
$input .= 'value="' . dol_escape_htmltag ( $titlealt ) . '" title="' . dol_escape_htmltag ( $titlealt ) . '" >' ;
2014-09-17 17:59:00 +02:00
return $input ;
}
2008-08-06 16:50:06 +02:00
/**
2016-03-03 10:42:49 +01:00
* Show information for admin users or standard users
2012-02-12 16:50:58 +01:00
*
2020-02-11 10:38:09 +01:00
* @ param string $text Text info
* @ param integer $infoonimgalt Info is shown only on alt of star picto , otherwise it is show on output after the star picto
* @ param int $nodiv No div
2021-03-04 15:57:03 +01:00
* @ param string $admin '1' = Info for admin users . '0' = Info for standard users ( change only the look ), 'error' , 'warning' , 'xxx' = Other
2020-02-11 10:38:09 +01:00
* @ param string $morecss More CSS ( '' , 'warning' , 'error' )
* @ param string $textfordropdown Show a text to click to dropdown the info box .
* @ return string String with info text
2008-08-06 16:50:06 +02:00
*/
2020-02-11 10:38:09 +01:00
function info_admin ( $text , $infoonimgalt = 0 , $nodiv = 0 , $admin = '1' , $morecss = '' , $textfordropdown = '' )
2008-08-06 16:50:06 +02:00
{
2012-08-03 23:29:08 +02:00
global $conf , $langs ;
2021-02-23 22:03:23 +01:00
if ( $infoonimgalt ) {
2020-02-11 10:38:09 +01:00
$result = img_picto ( $text , 'info' , 'class="hideonsmartphone' . ( $morecss ? ' ' . $morecss : '' ) . '"' );
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> use_javascript_ajax )) {
$textfordropdown = '' ;
}
2020-02-11 10:38:09 +01:00
$class = ( empty ( $admin ) ? 'undefined' : ( $admin == '1' ? 'info' : $admin ));
$result = ( $nodiv ? '' : '<div class="' . $class . ' hideonsmartphone' . ( $morecss ? ' ' . $morecss : '' ) . ( $textfordropdown ? ' hidden' : '' ) . '">' ) . '<span class="fa fa-info-circle" title="' . dol_escape_htmltag ( $admin ? $langs -> trans ( 'InfoAdmin' ) : $langs -> trans ( 'Note' )) . '"></span> ' . $text . ( $nodiv ? '' : '</div>' );
if ( $textfordropdown ) {
2021-10-26 15:27:12 +02:00
$tmpresult = '<span class="' . $class . 'text opacitymedium cursorpointer">' . $langs -> trans ( $textfordropdown ) . ' ' . img_picto ( $langs -> trans ( $textfordropdown ), '1downarrow' ) . '</span>' ;
2021-11-29 15:09:18 +01:00
$tmpresult .= ' < script type = " text/javascript " >
2020-02-11 10:38:09 +01:00
jQuery ( document ) . ready ( function () {
jQuery ( " .'. $class .'text " ) . click ( function () {
console . log ( " toggle text " );
jQuery ( " .'. $class .' " ) . toggle ();
});
});
</ script > ' ;
$result = $tmpresult . $result ;
}
2012-08-03 23:29:08 +02:00
}
2017-05-25 08:48:59 +02:00
2020-02-11 10:38:09 +01:00
return $result ;
2008-08-06 16:50:06 +02:00
}
/**
2019-10-18 19:55:21 +02:00
* Displays error message system with all the information to facilitate the diagnosis and the escalation of the bugs .
* This function must be called when a blocking technical error is encountered .
* However , one must try to call it only within php pages , classes must return their error through their property " error " .
2012-02-04 14:39:47 +01:00
*
2021-11-01 03:23:38 +01:00
* @ param DoliDB | string $db Database handler
2020-10-25 15:42:15 +01:00
* @ param string | string [] $error String or array of errors strings to show
2020-10-24 09:42:52 +02:00
* @ param array $errors Array of errors
2014-03-16 17:37:54 +01:00
* @ return void
2019-03-11 01:01:15 +01:00
* @ see dol_htmloutput_errors ()
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_error ( $db = '' , $error = '' , $errors = null )
2008-08-06 16:50:06 +02:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs , $argv ;
2012-08-03 23:29:08 +02:00
global $dolibarr_main_prod ;
$out = '' ;
$syslog = '' ;
2020-09-25 15:01:15 +02:00
// If error occurs before the $lang object was loaded
2021-02-23 22:03:23 +01:00
if ( ! $langs ) {
2019-11-11 23:59:36 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php' ;
2012-08-03 23:29:08 +02:00
$langs = new Translate ( '' , $conf );
$langs -> load ( " main " );
}
2020-09-25 15:01:15 +02:00
// Load translation files required by the error messages
2020-09-07 10:18:17 +02:00
$langs -> loadLangs ( array ( 'main' , 'errors' ));
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( $_SERVER [ 'DOCUMENT_ROOT' ]) { // Mode web
2019-11-11 23:59:36 +01:00
$out .= $langs -> trans ( " DolibarrHasDetectedError " ) . " .<br> \n " ;
2021-11-05 14:23:19 +01:00
if ( getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) > 0 ) {
2021-02-23 22:03:23 +01:00
$out .= " You use an experimental or develop level of features, so please do NOT report any bugs or vulnerability, except if problem is confirmed after moving option MAIN_FEATURES_LEVEL back to 0.<br> \n " ;
}
2019-11-11 23:59:36 +01:00
$out .= $langs -> trans ( " InformationToHelpDiagnose " ) . " :<br> \n " ;
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " Date " ) . " :</b> " . dol_print_date ( time (), 'dayhourlog' ) . " <br> \n " ;
2020-06-06 18:30:04 +02:00
$out .= " <b> " . $langs -> trans ( " Dolibarr " ) . " :</b> " . DOL_VERSION . " - https://www.dolibarr.org<br> \n " ;
2021-02-23 22:03:23 +01:00
if ( isset ( $conf -> global -> MAIN_FEATURES_LEVEL )) {
2021-11-05 14:23:19 +01:00
$out .= " <b> " . $langs -> trans ( " LevelOfFeature " ) . " :</b> " . getDolGlobalInt ( 'MAIN_FEATURES_LEVEL' ) . " <br> \n " ;
2021-02-23 22:03:23 +01:00
}
if ( function_exists ( " phpversion " )) {
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " PHP " ) . " :</b> " . phpversion () . " <br> \n " ;
2012-08-03 23:29:08 +02:00
}
2021-02-07 21:21:21 +01:00
$out .= " <b> " . $langs -> trans ( " Server " ) . " :</b> " . ( isset ( $_SERVER [ " SERVER_SOFTWARE " ]) ? dol_htmlentities ( $_SERVER [ " SERVER_SOFTWARE " ], ENT_COMPAT ) : '' ) . " <br> \n " ;
2021-02-23 22:03:23 +01:00
if ( function_exists ( " php_uname " )) {
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " OS " ) . " :</b> " . php_uname () . " <br> \n " ;
2015-01-17 16:22:37 +01:00
}
2021-02-07 21:21:21 +01:00
$out .= " <b> " . $langs -> trans ( " UserAgent " ) . " :</b> " . ( isset ( $_SERVER [ " HTTP_USER_AGENT " ]) ? dol_htmlentities ( $_SERVER [ " HTTP_USER_AGENT " ], ENT_COMPAT ) : '' ) . " <br> \n " ;
2019-11-11 23:59:36 +01:00
$out .= " <br> \n " ;
2021-02-07 21:21:21 +01:00
$out .= " <b> " . $langs -> trans ( " RequestedUrl " ) . " :</b> " . dol_htmlentities ( $_SERVER [ " REQUEST_URI " ], ENT_COMPAT ) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " Referer " ) . " :</b> " . ( isset ( $_SERVER [ " HTTP_REFERER " ]) ? dol_htmlentities ( $_SERVER [ " HTTP_REFERER " ], ENT_COMPAT ) : '' ) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " MenuManager " ) . " :</b> " . ( isset ( $conf -> standard_menu ) ? dol_htmlentities ( $conf -> standard_menu , ENT_COMPAT ) : '' ) . " <br> \n " ;
2019-11-11 23:59:36 +01:00
$out .= " <br> \n " ;
$syslog .= " url= " . dol_escape_htmltag ( $_SERVER [ " REQUEST_URI " ]);
$syslog .= " , query_string= " . dol_escape_htmltag ( $_SERVER [ " QUERY_STRING " ]);
2020-05-21 15:05:19 +02:00
} else // Mode CLI
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$out .= '> ' . $langs -> transnoentities ( " ErrorInternalErrorDetected " ) . " : \n " . $argv [ 0 ] . " \n " ;
$syslog .= " pid= " . dol_getmypid ();
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> modules )) {
2020-09-07 10:18:17 +02:00
$out .= " <b> " . $langs -> trans ( " Modules " ) . " :</b> " . join ( ', ' , $conf -> modules ) . " <br> \n " ;
2019-04-23 10:24:05 +02:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $db )) {
if ( $_SERVER [ 'DOCUMENT_ROOT' ]) { // Mode web
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " DatabaseTypeManager " ) . " :</b> " . $db -> type . " <br> \n " ;
2020-09-25 15:01:15 +02:00
$out .= " <b> " . $langs -> trans ( " RequestLastAccessInError " ) . " :</b> " . ( $db -> lastqueryerror () ? dol_escape_htmltag ( $db -> lastqueryerror ()) : $langs -> trans ( " ErrorNoRequestInError " )) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " ReturnCodeLastAccessInError " ) . " :</b> " . ( $db -> lasterrno () ? dol_escape_htmltag ( $db -> lasterrno ()) : $langs -> trans ( " ErrorNoRequestInError " )) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " InformationLastAccessInError " ) . " :</b> " . ( $db -> lasterror () ? dol_escape_htmltag ( $db -> lasterror ()) : $langs -> trans ( " ErrorNoRequestInError " )) . " <br> \n " ;
2019-11-11 23:59:36 +01:00
$out .= " <br> \n " ;
2020-05-21 15:05:19 +02:00
} else // Mode CLI
2012-08-03 23:29:08 +02:00
{
2017-10-13 13:28:26 +02:00
// No dol_escape_htmltag for output, we are in CLI mode
2019-11-11 23:59:36 +01:00
$out .= '> ' . $langs -> transnoentities ( " DatabaseTypeManager " ) . " : \n " . $db -> type . " \n " ;
$out .= '> ' . $langs -> transnoentities ( " RequestLastAccessInError " ) . " : \n " . ( $db -> lastqueryerror () ? $db -> lastqueryerror () : $langs -> transnoentities ( " ErrorNoRequestInError " )) . " \n " ;
$out .= '> ' . $langs -> transnoentities ( " ReturnCodeLastAccessInError " ) . " : \n " . ( $db -> lasterrno () ? $db -> lasterrno () : $langs -> transnoentities ( " ErrorNoRequestInError " )) . " \n " ;
$out .= '> ' . $langs -> transnoentities ( " InformationLastAccessInError " ) . " : \n " . ( $db -> lasterror () ? $db -> lasterror () : $langs -> transnoentities ( " ErrorNoRequestInError " )) . " \n " ;
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
$syslog .= " , sql= " . $db -> lastquery ();
$syslog .= " , db_error= " . $db -> lasterror ();
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( $error || $errors ) {
2012-08-03 23:29:08 +02:00
$langs -> load ( " errors " );
2015-05-03 20:07:16 +02:00
// Merge all into $errors array
2021-02-23 22:03:23 +01:00
if ( is_array ( $error ) && is_array ( $errors )) {
$errors = array_merge ( $error , $errors );
} elseif ( is_array ( $error )) {
$errors = $error ;
} elseif ( is_array ( $errors )) {
$errors = array_merge ( array ( $error ), $errors );
} else {
$errors = array_merge ( array ( $error ));
}
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
foreach ( $errors as $msg ) {
if ( empty ( $msg )) {
continue ;
}
if ( $_SERVER [ 'DOCUMENT_ROOT' ]) { // Mode web
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " Message " ) . " :</b> " . dol_escape_htmltag ( $msg ) . " <br> \n " ;
2020-05-21 15:05:19 +02:00
} else // Mode CLI
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$out .= '> ' . $langs -> transnoentities ( " Message " ) . " : \n " . $msg . " \n " ;
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
$syslog .= " , msg= " . $msg ;
2012-08-03 23:29:08 +02:00
}
}
2021-02-23 22:03:23 +01:00
if ( empty ( $dolibarr_main_prod ) && $_SERVER [ 'DOCUMENT_ROOT' ] && function_exists ( 'xdebug_print_function_stack' ) && function_exists ( 'xdebug_call_file' )) {
2012-08-03 23:29:08 +02:00
xdebug_print_function_stack ();
2019-11-11 23:59:36 +01:00
$out .= '<b>XDebug informations:</b>' . " <br> \n " ;
$out .= 'File: ' . xdebug_call_file () . " <br> \n " ;
$out .= 'Line: ' . xdebug_call_line () . " <br> \n " ;
$out .= 'Function: ' . xdebug_call_function () . " <br> \n " ;
$out .= " <br> \n " ;
2012-08-03 23:29:08 +02:00
}
2020-09-25 15:01:15 +02:00
// Return a http error code if possible
2020-10-07 15:01:28 +02:00
if ( ! headers_sent ()) {
2020-09-25 15:01:15 +02:00
http_response_code ( 500 );
}
if ( empty ( $dolibarr_main_prod )) {
print $out ;
} else {
2021-02-23 22:03:23 +01:00
if ( empty ( $langs -> defaultlang )) {
$langs -> setDefaultLang ();
}
2020-12-01 02:41:19 +01:00
$langs -> loadLangs ( array ( " main " , " errors " )); // Reload main because language may have been set only on previous line so we have to reload files we need.
2020-05-21 00:47:16 +02:00
// This should not happen, except if there is a bug somewhere. Enabled and check log in such case.
2021-05-04 19:43:33 +02:00
print 'This website or feature is currently temporarly not available or failed after a technical error.<br><br>This may be due to a maintenance operation. Current status of operation (' . dol_print_date ( dol_now (), 'dayhourrfc' ) . ') are on next line...<br><br>' . " \n " ;
2017-09-06 11:39:30 +02:00
print $langs -> trans ( " DolibarrHasDetectedError " ) . '. ' ;
print $langs -> trans ( " YouCanSetOptionDolibarrMainProdToZero " );
define ( " MAIN_CORE_ERROR " , 1 );
}
2020-09-25 15:01:15 +02:00
2012-08-03 23:29:08 +02:00
dol_syslog ( " Error " . $syslog , LOG_ERR );
2008-08-06 16:50:06 +02:00
}
2009-10-10 17:32:28 +02:00
/**
2012-11-20 11:23:34 +01:00
* Show a public email and error code to contact if technical error
2012-02-04 14:39:47 +01:00
*
2012-12-02 12:59:06 +01:00
* @ param string $prefixcode Prefix of public error code
2017-06-02 09:13:04 +02:00
* @ param string $errormessage Complete error message
2017-12-19 18:26:27 +01:00
* @ param array $errormessages Array of error messages
2018-01-30 18:02:24 +01:00
* @ param string $morecss More css
2018-04-19 12:12:54 +02:00
* @ param string $email Email
2012-02-04 15:20:32 +01:00
* @ return void
2009-10-10 17:32:28 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_error_email ( $prefixcode , $errormessage = '' , $errormessages = array (), $morecss = 'error' , $email = '' )
2009-10-10 17:32:28 +02:00
{
2019-11-11 23:59:36 +01:00
global $langs , $conf ;
2009-10-10 17:32:28 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $email )) {
$email = $conf -> global -> MAIN_INFO_SOCIETE_MAIL ;
}
2018-04-19 12:12:19 +02:00
2012-08-03 23:29:08 +02:00
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$now = dol_now ();
2018-04-19 12:12:19 +02:00
2018-01-30 18:02:24 +01:00
print '<br><div class="center login_main_message"><div class="' . $morecss . '">' ;
2019-09-11 00:28:09 +02:00
print $langs -> trans ( " ErrorContactEMail " , $email , $prefixcode . dol_print_date ( $now , '%Y%m%d%H%M%S' ));
2021-02-23 22:03:23 +01:00
if ( $errormessage ) {
print '<br><br>' . $errormessage ;
}
if ( is_array ( $errormessages ) && count ( $errormessages )) {
foreach ( $errormessages as $mesgtoshow ) {
2017-12-19 18:26:27 +01:00
print '<br><br>' . $mesgtoshow ;
}
}
2017-06-02 09:13:04 +02:00
print '</div></div>' ;
2009-10-10 17:32:28 +02:00
}
2008-08-06 16:50:06 +02:00
/**
2011-05-03 21:03:08 +02:00
* Show title line of an array
2011-11-02 14:14:46 +01:00
*
2012-02-04 14:39:47 +01:00
* @ param string $name Label of field
* @ param string $file Url used when we click on sort picto
* @ param string $field Field to use for new sorting
* @ param string $begin ( " " by defaut )
* @ param string $moreparam Add more parameters on sort url links ( " " by default )
2017-09-16 10:12:44 +02:00
* @ param string $moreattrib Options of attribute td ( " " by defaut , example : 'align="center"' )
2012-02-04 14:39:47 +01:00
* @ param string $sortfield Current field used to sort
* @ param string $sortorder Current sort order
2015-06-30 13:14:19 +02:00
* @ param string $prefix Prefix for css . Use space after prefix to add your own CSS tag .
2017-08-31 18:29:57 +02:00
* @ param string $tooltip Tooltip
2020-12-19 15:56:21 +01:00
* @ param string $forcenowrapcolumntitle No need for use 'wrapcolumntitle' css style
2012-02-04 14:39:47 +01:00
* @ return void
2011-07-06 11:25:05 +02:00
*/
2020-12-19 15:56:21 +01:00
function print_liste_field_titre ( $name , $file = " " , $field = " " , $begin = " " , $moreparam = " " , $moreattrib = " " , $sortfield = " " , $sortorder = " " , $prefix = " " , $tooltip = " " , $forcenowrapcolumntitle = 0 )
2011-08-30 19:56:45 +02:00
{
2020-12-19 15:56:21 +01:00
print getTitleFieldOfList ( $name , 0 , $file , $field , $begin , $moreparam , $moreattrib , $sortfield , $sortorder , $prefix , 0 , $tooltip , $forcenowrapcolumntitle );
2011-08-30 19:56:45 +02:00
}
/**
* Get title line of an array
2011-09-02 23:56:37 +02:00
*
2020-12-20 18:41:54 +01:00
* @ param string $name Translation key of field to show or complete HTML string to show
2017-08-31 18:29:57 +02:00
* @ param int $thead 0 = To use with standard table format , 1 = To use inside < thead >< tr > , 2 = To use with < div >
* @ param string $file Url used when we click on sort picto
2018-04-28 19:54:41 +02:00
* @ param string $field Field to use for new sorting . Empty if this field is not sortable . Example " t.abc " or " t.abc,t.def "
2017-08-31 18:29:57 +02:00
* @ param string $begin ( " " by defaut )
* @ param string $moreparam Add more parameters on sort url links ( " " by default )
2017-09-05 09:43:22 +02:00
* @ param string $moreattrib Add more attributes on th ( " " by defaut , example : 'align="center"' ) . To add more css class , use param $prefix .
2017-08-31 18:29:57 +02:00
* @ param string $sortfield Current field used to sort ( Ex : 'd.datep,d.id' )
* @ param string $sortorder Current sort order ( Ex : 'asc,desc' )
2017-09-05 09:43:22 +02:00
* @ param string $prefix Prefix for css . Use space after prefix to add your own CSS tag , for example 'mycss ' .
2017-07-16 12:07:59 +02:00
* @ param string $disablesortlink 1 = Disable sort link
2017-08-31 18:29:57 +02:00
* @ param string $tooltip Tooltip
2020-12-19 15:56:21 +01:00
* @ param string $forcenowrapcolumntitle No need for use 'wrapcolumntitle' css style
2015-02-10 10:52:48 +01:00
* @ return string
2011-08-30 19:56:45 +02:00
*/
2020-12-19 15:56:21 +01:00
function getTitleFieldOfList ( $name , $thead = 0 , $file = " " , $field = " " , $begin = " " , $moreparam = " " , $moreattrib = " " , $sortfield = " " , $sortorder = " " , $prefix = " " , $disablesortlink = 0 , $tooltip = '' , $forcenowrapcolumntitle = 0 )
2008-08-06 16:50:06 +02:00
{
2017-08-31 18:29:57 +02:00
global $conf , $langs , $form ;
2012-08-03 23:29:08 +02:00
//print "$name, $file, $field, $begin, $options, $moreattrib, $sortfield, $sortorder<br>\n";
2011-09-03 01:57:26 +02:00
2021-02-23 22:03:23 +01:00
if ( $moreattrib == 'class="right"' ) {
$prefix .= 'right ' ; // For backward compatibility
}
2019-02-11 15:06:52 +01:00
2019-11-11 23:59:36 +01:00
$sortorder = strtoupper ( $sortorder );
$out = '' ;
$sortimg = '' ;
2015-11-01 17:27:41 +01:00
2019-11-11 23:59:36 +01:00
$tag = 'th' ;
2021-02-23 22:03:23 +01:00
if ( $thead == 2 ) {
$tag = 'div' ;
}
2013-11-18 12:20:53 +01:00
2019-11-11 23:59:36 +01:00
$tmpsortfield = explode ( ',' , $sortfield );
$sortfield1 = trim ( $tmpsortfield [ 0 ]); // If $sortfield is 'd.datep,d.id', it becomes 'd.datep'
$tmpfield = explode ( ',' , $field );
$field1 = trim ( $tmpfield [ 0 ]); // If $field is 'd.datep,d.id', it becomes 'd.datep'
2017-05-16 23:38:23 +02:00
2020-12-19 15:56:21 +01:00
if ( empty ( $conf -> global -> MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE ) && empty ( $forcenowrapcolumntitle )) {
2020-02-24 21:18:49 +01:00
$prefix = 'wrapcolumntitle ' . $prefix ;
}
2020-12-19 15:56:21 +01:00
2017-05-16 23:38:23 +02:00
//var_dump('field='.$field.' field1='.$field1.' sortfield='.$sortfield.' sortfield1='.$sortfield1);
// If field is used as sort criteria we use a specific css class liste_titre_sel
2012-08-03 23:29:08 +02:00
// Example if (sortfield,field)=("nom","xxx.nom") or (sortfield,field)=("nom","nom")
2020-09-23 23:02:31 +02:00
$liste_titre = 'liste_titre' ;
2020-02-24 21:18:49 +01:00
if ( $field1 && ( $sortfield1 == $field1 || $sortfield1 == preg_replace ( " /^[^ \ .]+ \ ./ " , " " , $field1 ))) {
2020-09-23 23:02:31 +02:00
$liste_titre = 'liste_titre_sel' ;
2020-02-24 21:18:49 +01:00
}
2022-02-02 17:57:20 +01:00
2020-09-23 23:02:31 +02:00
$out .= '<' . $tag . ' class="' . $prefix . $liste_titre . '" ' . $moreattrib ;
//$out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:&;]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : '');
2020-12-20 18:41:54 +01:00
$out .= ( $name && empty ( $conf -> global -> MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE ) && empty ( $forcenowrapcolumntitle ) && ! dol_textishtml ( $name )) ? ' title="' . dol_escape_htmltag ( $langs -> trans ( $name )) . '"' : '' ;
2020-09-23 23:02:31 +02:00
$out .= '>' ;
2013-04-14 02:09:41 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $thead ) && $field && empty ( $disablesortlink )) { // If this is a sort field
2020-09-20 21:27:11 +02:00
$options = preg_replace ( '/sortfield=([a-zA-Z0-9,\s\.]+)/i' , '' , ( is_scalar ( $moreparam ) ? $moreparam : '' ));
2019-11-11 23:59:36 +01:00
$options = preg_replace ( '/sortorder=([a-zA-Z0-9,\s\.]+)/i' , '' , $options );
$options = preg_replace ( '/&+/i' , '&' , $options );
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/^&/' , $options )) {
$options = '&' . $options ;
}
2013-04-14 02:09:41 +02:00
2019-11-11 23:59:36 +01:00
$sortordertouseinlink = '' ;
2021-02-23 22:03:23 +01:00
if ( $field1 != $sortfield1 ) { // We are on another field than current sorted field
if ( preg_match ( '/^DESC/i' , $sortorder )) {
2019-11-11 23:59:36 +01:00
$sortordertouseinlink .= str_repeat ( 'desc,' , count ( explode ( ',' , $field )));
2020-05-21 15:05:19 +02:00
} else // We reverse the var $sortordertouseinlink
2018-04-28 19:54:41 +02:00
{
2019-11-11 23:59:36 +01:00
$sortordertouseinlink .= str_repeat ( 'asc,' , count ( explode ( ',' , $field )));
2018-04-28 19:54:41 +02:00
}
2020-05-21 15:05:19 +02:00
} else // We are on field that is the first current sorting criteria
2015-10-09 13:01:50 +02:00
{
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^ASC/i' , $sortorder )) { // We reverse the var $sortordertouseinlink
2019-11-11 23:59:36 +01:00
$sortordertouseinlink .= str_repeat ( 'desc,' , count ( explode ( ',' , $field )));
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$sortordertouseinlink .= str_repeat ( 'asc,' , count ( explode ( ',' , $field )));
2018-04-28 19:54:41 +02:00
}
2015-10-09 13:01:50 +02:00
}
2019-11-11 23:59:36 +01:00
$sortordertouseinlink = preg_replace ( '/,$/' , '' , $sortordertouseinlink );
2020-02-24 21:18:49 +01:00
$out .= '<a class="reposition" href="' . $file . '?sortfield=' . $field . '&sortorder=' . $sortordertouseinlink . '&begin=' . $begin . $options . '"' ;
//$out .= (empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : '');
$out .= '>' ;
2012-08-03 23:29:08 +02:00
}
2020-12-09 19:26:41 +01:00
if ( $tooltip ) {
// You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
$tmptooltip = explode ( ':' , $tooltip );
$out .= $form -> textwithpicto ( $langs -> trans ( $name ), $langs -> trans ( $tmptooltip [ 0 ]), 1 , 'help' , '' , 0 , 3 , ( empty ( $tmptooltip [ 1 ]) ? '' : 'extra_' . str_replace ( '.' , '_' , $field ) . '_' . $tmptooltip [ 1 ]));
2021-02-23 22:03:23 +01:00
} else {
$out .= $langs -> trans ( $name );
2020-12-09 19:26:41 +01:00
}
2013-04-14 02:09:41 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $thead ) && $field && empty ( $disablesortlink )) { // If this is a sort field
2019-11-11 23:59:36 +01:00
$out .= '</a>' ;
2012-08-03 23:29:08 +02:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $thead ) && $field ) { // If this is a sort field
2020-09-20 21:27:11 +02:00
$options = preg_replace ( '/sortfield=([a-zA-Z0-9,\s\.]+)/i' , '' , ( is_scalar ( $moreparam ) ? $moreparam : '' ));
2019-11-11 23:59:36 +01:00
$options = preg_replace ( '/sortorder=([a-zA-Z0-9,\s\.]+)/i' , '' , $options );
$options = preg_replace ( '/&+/i' , '&' , $options );
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/^&/' , $options )) {
$options = '&' . $options ;
}
2012-08-03 23:29:08 +02:00
2021-02-23 22:03:23 +01:00
if ( ! $sortorder || $field1 != $sortfield1 ) {
2015-10-09 13:01:50 +02:00
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",0).'</a>';
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",0).'</a>';
2020-05-21 15:05:19 +02:00
} else {
2017-04-29 00:44:25 +02:00
if ( preg_match ( '/^DESC/' , $sortorder )) {
2015-10-09 13:01:50 +02:00
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",0).'</a>';
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",1).'</a>';
2020-04-08 15:13:01 +02:00
$sortimg .= '<span class="nowrap">' . img_up ( " Z-A " , 0 , 'paddingleft' ) . '</span>' ;
2012-08-03 23:29:08 +02:00
}
2017-04-29 00:44:25 +02:00
if ( preg_match ( '/^ASC/' , $sortorder )) {
2015-10-09 13:01:50 +02:00
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=asc&begin='.$begin.$options.'">'.img_down("A-Z",1).'</a>';
//$out.= '<a href="'.$file.'?sortfield='.$field.'&sortorder=desc&begin='.$begin.$options.'">'.img_up("Z-A",0).'</a>';
2020-04-08 15:13:01 +02:00
$sortimg .= '<span class="nowrap">' . img_down ( " A-Z " , 0 , 'paddingleft' ) . '</span>' ;
2012-08-03 23:29:08 +02:00
}
}
}
2015-11-01 17:27:41 +01:00
2019-11-11 23:59:36 +01:00
$out .= $sortimg ;
2015-11-01 17:27:41 +01:00
2019-11-11 23:59:36 +01:00
$out .= '</' . $tag . '>' ;
2012-08-03 23:29:08 +02:00
return $out ;
2008-08-06 16:50:06 +02:00
}
/**
2014-12-26 04:44:15 +01:00
* Show a title .
2012-02-04 14:39:47 +01:00
*
* @ param string $title Title to show
2021-10-31 17:22:40 +01:00
* @ return void
2015-08-15 02:44:05 +02:00
* @ deprecated Use load_fiche_titre instead
2019-03-11 01:01:15 +01:00
* @ see load_fiche_titre ()
2008-08-06 16:50:06 +02:00
*/
2012-02-04 14:39:47 +01:00
function print_titre ( $title )
2008-08-06 16:50:06 +02:00
{
2019-11-11 23:59:36 +01:00
dol_syslog ( __FUNCTION__ . " is deprecated " , LOG_WARNING );
2015-04-23 23:21:06 +02:00
2012-08-03 23:29:08 +02:00
print '<div class="titre">' . $title . '</div>' ;
2008-08-06 16:50:06 +02:00
}
2010-05-02 09:34:08 +02:00
/**
2010-12-05 21:33:24 +01:00
* Show a title with picto
2012-02-04 15:20:32 +01:00
*
2013-11-18 12:20:53 +01:00
* @ param string $title Title to show
2019-02-03 22:58:56 +01:00
* @ param string $mesg Added message to show on right
* @ param string $picto Icon to use before title ( should be a 32 x32 transparent png file )
* @ param int $pictoisfullpath 1 = Icon name is a full absolute url of image
* @ param int $id To force an id on html objects
* @ return void
* @ deprecated Use print load_fiche_titre instead
*/
2019-09-30 10:14:55 +02:00
function print_fiche_titre ( $title , $mesg = '' , $picto = 'generic' , $pictoisfullpath = 0 , $id = '' )
2019-02-03 22:58:56 +01:00
{
print load_fiche_titre ( $title , $mesg , $picto , $pictoisfullpath , $id );
}
/**
* Load a title with picto
*
* @ param string $titre Title to show
* @ param string $morehtmlright Added message to show on right
* @ param string $picto Icon to use before title ( should be a 32 x32 transparent png file )
* @ param int $pictoisfullpath 1 = Icon name is a full absolute url of image
* @ param string $id To force an id on html objects
* @ param string $morecssontable More css on table
* @ param string $morehtmlcenter Added message to show on center
* @ return string
2019-03-11 01:01:15 +01:00
* @ see print_barre_liste ()
2019-02-03 22:58:56 +01:00
*/
2019-09-30 10:14:55 +02:00
function load_fiche_titre ( $titre , $morehtmlright = '' , $picto = 'generic' , $pictoisfullpath = 0 , $id = '' , $morecssontable = '' , $morehtmlcenter = '' )
2019-02-03 22:58:56 +01:00
{
global $conf ;
2019-11-11 23:59:36 +01:00
$return = '' ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $picto == 'setup' ) {
$picto = 'generic' ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$return .= " \n " ;
2020-02-06 18:06:36 +01:00
$return .= '<table ' . ( $id ? 'id="' . $id . '" ' : '' ) . 'class="centpercent notopnoleftnoright table-fiche-title' . ( $morecssontable ? ' ' . $morecssontable : '' ) . '">' ; // maring bottom must be same than into print_barre_list
2020-02-05 14:04:19 +01:00
$return .= '<tr class="titre">' ;
2021-02-23 22:03:23 +01:00
if ( $picto ) {
$return .= '<td class="nobordernopadding widthpictotitle valignmiddle col-picto">' . img_picto ( '' , $picto , 'class="valignmiddle widthpictotitle pictotitle"' , $pictoisfullpath ) . '</td>' ;
}
2019-11-11 23:59:36 +01:00
$return .= '<td class="nobordernopadding valignmiddle col-title">' ;
$return .= '<div class="titre inline-block">' . $titre . '</div>' ;
$return .= '</td>' ;
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $morehtmlcenter )) {
2019-11-11 23:59:36 +01:00
$return .= '<td class="nobordernopadding center valignmiddle">' . $morehtmlcenter . '</td>' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $morehtmlright )) {
2019-11-11 23:59:36 +01:00
$return .= '<td class="nobordernopadding titre_right wordbreakimp right valignmiddle">' . $morehtmlright . '</td>' ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$return .= '</tr></table>' . " \n " ;
2019-02-03 22:58:56 +01:00
return $return ;
}
/**
* Print a title with navigation controls for pagination
*
* @ param string $titre Title to show ( required )
* @ param int $page Numero of page to show in navigation links ( required )
* @ param string $file Url of page ( required )
* @ param string $options More parameters for links ( '' by default , does not include sortfield neither sortorder ) . Value must be 'urlencoded' before calling function .
* @ param string $sortfield Field to sort on ( '' by default )
* @ param string $sortorder Order to sort ( '' by default )
* @ param string $morehtmlcenter String in the middle ( '' by default ) . We often find here string $massaction comming from $form -> selectMassAction ()
* @ param int $num Number of records found by select with limit + 1
* @ param int | string $totalnboflines Total number of records / lines for all pages ( if known ) . Use a negative value of number to not show number . Use '' if unknown .
* @ param string $picto Icon to use before title ( should be a 32 x32 transparent png file )
* @ param int $pictoisfullpath 1 = Icon name is a full absolute url of image
2020-07-08 18:06:14 +02:00
* @ param string $morehtmlright More html to show ( after arrows )
2019-02-03 22:58:56 +01:00
* @ param string $morecss More css to the table
* @ param int $limit Max number of lines ( - 1 = use default , 0 = no limit , > 0 = limit ) .
* @ param int $hideselectlimit Force to hide select limit
* @ param int $hidenavigation Force to hide all navigation tools
2020-03-13 12:53:22 +01:00
* @ param int $pagenavastextinput 1 = Do not suggest list of pages to navigate but suggest the page number into an input field .
2020-07-08 18:06:14 +02:00
* @ param string $morehtmlrightbeforearrow More html to show ( before arrows )
2019-02-03 22:58:56 +01:00
* @ return void
*/
2020-07-08 18:06:14 +02:00
function print_barre_liste ( $titre , $page , $file , $options = '' , $sortfield = '' , $sortorder = '' , $morehtmlcenter = '' , $num = - 1 , $totalnboflines = '' , $picto = 'generic' , $pictoisfullpath = 0 , $morehtmlright = '' , $morecss = '' , $limit = - 1 , $hideselectlimit = 0 , $hidenavigation = 0 , $pagenavastextinput = 0 , $morehtmlrightbeforearrow = '' )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
global $conf , $langs ;
2019-02-03 22:58:56 +01:00
$savlimit = $limit ;
$savtotalnboflines = $totalnboflines ;
2020-12-24 02:52:49 +01:00
$totalnboflines = abs (( int ) $totalnboflines );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $picto == 'setup' ) {
$picto = 'title_setup.png' ;
}
if (( $conf -> browser -> name == 'ie' ) && $picto == 'generic' ) {
$picto = 'title.gif' ;
}
if ( $limit < 0 ) {
$limit = $conf -> liste_limit ;
}
if ( $savlimit != 0 && (( $num > $limit ) || ( $num == - 1 ) || ( $limit == 0 ))) {
2019-02-03 22:58:56 +01:00
$nextpage = 1 ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
$nextpage = 0 ;
}
//print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage;
print " \n " ;
2021-02-08 15:08:24 +01:00
print " <!-- Begin title --> \n " ;
2019-11-11 23:59:36 +01:00
print '<table class="centpercent notopnoleftnoright table-fiche-title' . ( $morecss ? ' ' . $morecss : '' ) . '"><tr>' ; // maring bottom must be same than into load_fiche_tire
2019-02-03 22:58:56 +01:00
// Left
2020-02-04 16:37:30 +01:00
2021-02-23 22:03:23 +01:00
if ( $picto && $titre ) {
print '<td class="nobordernopadding widthpictotitle valignmiddle col-picto">' . img_picto ( '' , $picto , 'class="valignmiddle pictotitle widthpictotitle"' , $pictoisfullpath ) . '</td>' ;
}
2019-10-15 02:45:12 +02:00
print '<td class="nobordernopadding valignmiddle col-title">' ;
2019-02-03 22:58:56 +01:00
print '<div class="titre inline-block">' . $titre ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $titre ) && $savtotalnboflines >= 0 && ( string ) $savtotalnboflines != '' ) {
print '<span class="opacitymedium colorblack paddingleft">(' . $totalnboflines . ')</span>' ;
}
2019-02-03 22:58:56 +01:00
print '</div></td>' ;
// Center
2021-02-23 22:03:23 +01:00
if ( $morehtmlcenter ) {
2019-02-03 22:58:56 +01:00
print '<td class="nobordernopadding center valignmiddle">' . $morehtmlcenter . '</td>' ;
}
// Right
print '<td class="nobordernopadding valignmiddle right">' ;
2020-10-20 09:30:41 +02:00
print '<input type="hidden" name="pageplusoneold" value="' . (( int ) $page + 1 ) . '">' ;
2021-02-23 22:03:23 +01:00
if ( $sortfield ) {
$options .= " &sortfield= " . urlencode ( $sortfield );
}
if ( $sortorder ) {
$options .= " &sortorder= " . urlencode ( $sortorder );
}
2019-02-03 22:58:56 +01:00
// Show navigation bar
$pagelist = '' ;
2021-02-23 22:03:23 +01:00
if ( $savlimit != 0 && ( $page > 0 || $num > $limit )) {
if ( $totalnboflines ) { // If we know total nb of lines
2019-02-03 22:58:56 +01:00
// Define nb of extra page links before and after selected page + ... + first or last
2019-12-16 12:38:51 +01:00
$maxnbofpage = ( empty ( $conf -> dol_optimize_smallscreen ) ? 4 : 0 );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $limit > 0 ) {
$nbpages = ceil ( $totalnboflines / $limit );
} else {
$nbpages = 1 ;
}
2019-11-11 23:59:36 +01:00
$cpt = ( $page - $maxnbofpage );
2021-02-23 22:03:23 +01:00
if ( $cpt < 0 ) {
$cpt = 0 ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $cpt >= 1 ) {
2020-03-13 12:53:22 +01:00
if ( empty ( $pagenavastextinput )) {
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=0' . $options . '">1</a></li>' ;
2021-02-23 22:03:23 +01:00
if ( $cpt > 2 ) {
$pagelist .= '<li class="pagination"><span class="inactive">...</span></li>' ;
} elseif ( $cpt == 2 ) {
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=1' . $options . '">2</a></li>' ;
}
2020-03-13 12:53:22 +01:00
}
2019-02-03 22:58:56 +01:00
}
2020-05-21 01:41:27 +02:00
do {
2020-03-13 12:53:22 +01:00
if ( $pagenavastextinput ) {
2021-02-23 22:03:23 +01:00
if ( $cpt == $page ) {
2020-03-13 12:53:22 +01:00
$pagelist .= '<li class="pagination"><input type="text" class="width25 center pageplusone" name="pageplusone" value="' . ( $page + 1 ) . '"></li>' ;
2020-03-17 03:24:24 +01:00
$pagelist .= '/' ;
2020-03-13 12:53:22 +01:00
}
} else {
2021-02-23 22:03:23 +01:00
if ( $cpt == $page ) {
2020-03-13 12:53:22 +01:00
$pagelist .= '<li class="pagination"><span class="active">' . ( $page + 1 ) . '</span></li>' ;
2020-05-21 15:05:19 +02:00
} else {
2020-03-13 12:53:22 +01:00
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . $cpt . $options . '">' . ( $cpt + 1 ) . '</a></li>' ;
}
2019-02-03 22:58:56 +01:00
}
$cpt ++ ;
2020-05-21 15:05:19 +02:00
} while ( $cpt < $nbpages && $cpt <= ( $page + $maxnbofpage ));
2019-02-03 22:58:56 +01:00
2020-03-13 12:53:22 +01:00
if ( empty ( $pagenavastextinput )) {
2021-02-23 22:03:23 +01:00
if ( $cpt < $nbpages ) {
if ( $cpt < $nbpages - 2 ) {
$pagelist .= '<li class="pagination"><span class="inactive">...</span></li>' ;
} elseif ( $cpt == $nbpages - 2 ) {
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . ( $nbpages - 2 ) . $options . '">' . ( $nbpages - 1 ) . '</a></li>' ;
}
2020-03-13 12:53:22 +01:00
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . ( $nbpages - 1 ) . $options . '">' . $nbpages . '</a></li>' ;
}
} else {
//var_dump($page.' '.$cpt.' '.$nbpages);
2022-01-05 14:04:02 +01:00
$pagelist .= '<li class="pagination paginationlastpage"><a href="' . $file . '?page=' . ( $nbpages - 1 ) . $options . '">' . $nbpages . '</a></li>' ;
2019-02-03 22:58:56 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$pagelist .= '<li class="pagination"><span class="active">' . ( $page + 1 ) . " </li> " ;
2019-02-03 22:58:56 +01:00
}
}
2020-07-08 18:06:14 +02:00
if ( $savlimit || $morehtmlright || $morehtmlrightbeforearrow ) {
print_fleche_navigation ( $page , $file , $options , $nextpage , $pagelist , $morehtmlright , $savlimit , $totalnboflines , $hideselectlimit , $morehtmlrightbeforearrow ); // output the div and ul for previous/last completed with page numbers into $pagelist
2019-11-14 11:00:49 +01:00
}
2019-02-03 22:58:56 +01:00
2020-03-13 12:53:22 +01:00
// js to autoselect page field on focus
if ( $pagenavastextinput ) {
print ajax_autoselect ( '.pageplusone' );
}
2019-02-03 22:58:56 +01:00
print '</td>' ;
print '</tr></table>' . " \n " ;
print " <!-- End title --> \n \n " ;
}
/**
* Function to show navigation arrows into lists
*
* @ param int $page Number of page
* @ param string $file Page URL ( in most cases provided with $_SERVER [ " PHP_SELF " ])
2019-03-16 14:48:41 +01:00
* @ param string $options Other url parameters to propagate ( " " by default , may include sortfield and sortorder )
2019-02-03 22:58:56 +01:00
* @ param integer $nextpage Do we show a next page button
* @ param string $betweenarrows HTML content to show between arrows . MUST contains '<li> </li>' tags or '<li><span> </span></li>' .
* @ param string $afterarrows HTML content to show after arrows . Must NOT contains '<li> </li>' tags .
* @ param int $limit Max nb of record to show ( - 1 = no combo with limit , 0 = no limit , > 0 = limit )
* @ param int $totalnboflines Total number of records / lines for all pages ( if known )
* @ param int $hideselectlimit Force to hide select limit
2020-07-08 18:06:14 +02:00
* @ param string $beforearrows HTML content to show before arrows . Must NOT contains '<li> </li>' tags .
2019-02-03 22:58:56 +01:00
* @ return void
*/
2020-07-08 18:06:14 +02:00
function print_fleche_navigation ( $page , $file , $options = '' , $nextpage = 0 , $betweenarrows = '' , $afterarrows = '' , $limit = - 1 , $totalnboflines = 0 , $hideselectlimit = 0 , $beforearrows = '' )
2019-02-03 22:58:56 +01:00
{
global $conf , $langs ;
print '<div class="pagination"><ul>' ;
2021-02-23 22:03:23 +01:00
if ( $beforearrows ) {
2020-07-08 18:06:14 +02:00
print '<li class="paginationbeforearrows">' ;
print $beforearrows ;
print '</li>' ;
}
2021-02-23 22:03:23 +01:00
if (( int ) $limit > 0 && empty ( $hideselectlimit )) {
2021-01-04 13:37:21 +01:00
$pagesizechoices = '10:10,15:15,20:20,30:30,40:40,50:50,100:100,250:250,500:500,1000:1000,5000:5000,25000:25000' ;
2019-02-03 22:58:56 +01:00
//$pagesizechoices.=',0:'.$langs->trans("All"); // Not yet supported
//$pagesizechoices.=',2:2';
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_PAGESIZE_CHOICES )) {
$pagesizechoices = $conf -> global -> MAIN_PAGESIZE_CHOICES ;
}
2019-02-03 22:58:56 +01:00
print '<li class="pagination">' ;
print '<select class="flat selectlimit" name="limit" title="' . dol_escape_htmltag ( $langs -> trans ( " MaxNbOfRecordPerPage " )) . '">' ;
2019-11-11 23:59:36 +01:00
$tmpchoice = explode ( ',' , $pagesizechoices );
$tmpkey = $limit . ':' . $limit ;
2021-02-23 22:03:23 +01:00
if ( ! in_array ( $tmpkey , $tmpchoice )) {
$tmpchoice [] = $tmpkey ;
}
2019-11-11 23:59:36 +01:00
$tmpkey = $conf -> liste_limit . ':' . $conf -> liste_limit ;
2021-02-23 22:03:23 +01:00
if ( ! in_array ( $tmpkey , $tmpchoice )) {
$tmpchoice [] = $tmpkey ;
}
2019-02-03 22:58:56 +01:00
asort ( $tmpchoice , SORT_NUMERIC );
2021-02-23 22:03:23 +01:00
foreach ( $tmpchoice as $val ) {
2019-11-11 23:59:36 +01:00
$selected = '' ;
$tmp = explode ( ':' , $val );
$key = $tmp [ 0 ];
$val = $tmp [ 1 ];
2021-02-23 22:03:23 +01:00
if ( $key != '' && $val != '' ) {
if (( int ) $key == ( int ) $limit ) {
2019-02-03 22:58:56 +01:00
$selected = ' selected="selected"' ;
}
print '<option name="' . $key . '"' . $selected . '>' . dol_escape_htmltag ( $val ) . '</option>' . " \n " ;
}
}
print '</select>' ;
2021-02-23 22:03:23 +01:00
if ( $conf -> use_javascript_ajax ) {
2019-02-03 22:58:56 +01:00
print ' <!-- JS CODE TO ENABLE select limit to launch submit of page -->
< script >
jQuery ( document ) . ready ( function () {
jQuery ( " .selectlimit " ) . change ( function () {
console . log ( " Change limit. Send submit " );
$ ( this ) . parents ( \ ' form : first\ ' ) . submit ();
});
});
</ script >
' ;
}
print '</li>' ;
}
2021-02-23 22:03:23 +01:00
if ( $page > 0 ) {
2020-07-08 18:06:14 +02:00
print '<li class="pagination paginationpage paginationpageleft"><a class="paginationprevious" href="' . $file . '?page=' . ( $page - 1 ) . $options . '"><i class="fa fa-chevron-left" title="' . dol_escape_htmltag ( $langs -> trans ( " Previous " )) . '"></i></a></li>' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $betweenarrows ) {
2020-05-11 11:53:13 +02:00
print '<!--<div class="betweenarrows nowraponall inline-block">-->' ;
2019-02-03 22:58:56 +01:00
print $betweenarrows ;
2020-05-11 11:53:13 +02:00
print '<!--</div>-->' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $nextpage > 0 ) {
2020-07-08 18:06:14 +02:00
print '<li class="pagination paginationpage paginationpageright"><a class="paginationnext" href="' . $file . '?page=' . ( $page + 1 ) . $options . '"><i class="fa fa-chevron-right" title="' . dol_escape_htmltag ( $langs -> trans ( " Next " )) . '"></i></a></li>' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $afterarrows ) {
2019-02-03 22:58:56 +01:00
print '<li class="paginationafterarrows">' ;
print $afterarrows ;
print '</li>' ;
}
print '</ul></div>' . " \n " ;
}
/**
* Return a string with VAT rate label formated for view output
* Used into pdf and HTML pages
*
* @ param string $rate Rate value to format ( '19.6' , '19,6' , '19.6%' , '19,6%' , '19.6 (CODEX)' , ... )
* @ param boolean $addpercent Add a percent % sign in output
* @ param int $info_bits Miscellaneous information on vat ( 0 = Default , 1 = French NPR vat )
* @ param int $usestarfornpr - 1 = Never show , 0 or 1 = Use '*' for NPR vat rates
* @ return string String with formated amounts ( '19,6' or '19,6%' or '8.5% (NPR)' or '8.5% *' or '19,6 (CODEX)' )
*/
function vatrate ( $rate , $addpercent = false , $info_bits = 0 , $usestarfornpr = 0 )
{
2019-11-11 23:59:36 +01:00
$morelabel = '' ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/%/' , $rate )) {
2019-11-11 23:59:36 +01:00
$rate = str_replace ( '%' , '' , $rate );
$addpercent = true ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\((.*)\)/' , $rate , $reg )) {
2019-11-11 23:59:36 +01:00
$morelabel = ' (' . $reg [ 1 ] . ')' ;
$rate = preg_replace ( '/\s*' . preg_quote ( $morelabel , '/' ) . '/' , '' , $rate );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\*/' , $rate )) {
2019-11-11 23:59:36 +01:00
$rate = str_replace ( '*' , '' , $rate );
2019-02-03 22:58:56 +01:00
$info_bits |= 1 ;
}
// If rate is '9/9/9' we don't change it. If rate is '9.000' we apply price()
2021-02-23 22:03:23 +01:00
if ( ! preg_match ( '/\//' , $rate )) {
$ret = price ( $rate , 0 , '' , 0 , 0 ) . ( $addpercent ? '%' : '' );
} else {
2019-02-03 22:58:56 +01:00
// TODO Split on / and output with a price2num to have clean numbers without ton of 000.
2019-11-11 23:59:36 +01:00
$ret = $rate . ( $addpercent ? '%' : '' );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if (( $info_bits & 1 ) && $usestarfornpr >= 0 ) {
$ret .= ' *' ;
}
2019-11-11 23:59:36 +01:00
$ret .= $morelabel ;
2019-02-03 22:58:56 +01:00
return $ret ;
}
/**
* Function to format a value into an amount for visual output
* Function used into PDF and HTML pages
*
2021-11-01 03:23:38 +01:00
* @ param float $amount Amount to format
* @ param integer $form Type of format , HTML or not ( not by default )
* @ param Translate | string $outlangs Object langs for output
* @ param int $trunc 1 = Truncate if there is more decimals than MAIN_MAX_DECIMALS_SHOWN ( default ), 0 = Does not truncate . Deprecated because amount are rounded ( to unit or total amount accurancy ) before beeing inserted into database or after a computation , so this parameter should be useless .
* @ param int $rounding Minimum number of decimal to show . If 0 , no change , if - 1 , we use min ( $conf -> global -> MAIN_MAX_DECIMALS_UNIT , $conf -> global -> MAIN_MAX_DECIMALS_TOT )
* @ param int $forcerounding Force the number of decimal to forcerounding decimal ( - 1 = do not force )
* @ param string $currency_code To add currency symbol ( '' = add nothing , 'auto' = Use default currency , 'XXX' = add currency symbols for XXX currency )
* @ return string String with formated amount
2019-02-03 22:58:56 +01:00
*
2021-11-01 03:23:38 +01:00
* @ see price2num () Revert function of price
2019-02-03 22:58:56 +01:00
*/
function price ( $amount , $form = 0 , $outlangs = '' , $trunc = 1 , $rounding = - 1 , $forcerounding = - 1 , $currency_code = '' )
{
2019-11-11 23:59:36 +01:00
global $langs , $conf ;
2019-02-03 22:58:56 +01:00
// Clean parameters
2021-02-23 22:03:23 +01:00
if ( empty ( $amount )) {
$amount = 0 ; // To have a numeric value if amount not defined or = ''
}
2019-11-11 23:59:36 +01:00
$amount = ( is_numeric ( $amount ) ? $amount : 0 ); // Check if amount is numeric, for example, an error occured when amount value = o (letter) instead 0 (number)
2021-02-23 22:03:23 +01:00
if ( $rounding < 0 ) {
$rounding = min ( $conf -> global -> MAIN_MAX_DECIMALS_UNIT , $conf -> global -> MAIN_MAX_DECIMALS_TOT );
}
2019-11-11 23:59:36 +01:00
$nbdecimal = $rounding ;
2019-02-03 22:58:56 +01:00
// Output separators by default (french)
2021-03-01 20:37:16 +01:00
$dec = ',' ;
$thousand = ' ' ;
2019-02-03 22:58:56 +01:00
// If $outlangs not forced, we use use language
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $outlangs )) {
$outlangs = $langs ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $outlangs -> transnoentitiesnoconv ( " SeparatorDecimal " ) != " SeparatorDecimal " ) {
$dec = $outlangs -> transnoentitiesnoconv ( " SeparatorDecimal " );
}
if ( $outlangs -> transnoentitiesnoconv ( " SeparatorThousand " ) != " SeparatorThousand " ) {
$thousand = $outlangs -> transnoentitiesnoconv ( " SeparatorThousand " );
}
if ( $thousand == 'None' ) {
$thousand = '' ;
} elseif ( $thousand == 'Space' ) {
$thousand = ' ' ;
}
2019-02-03 22:58:56 +01:00
//print "outlangs=".$outlangs->defaultlang." amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'<br>";
//print "amount=".$amount."-";
2019-11-11 23:59:36 +01:00
$amount = str_replace ( ',' , '.' , $amount ); // should be useless
2019-02-03 22:58:56 +01:00
//print $amount."-";
$datas = explode ( '.' , $amount );
2019-11-11 23:59:36 +01:00
$decpart = isset ( $datas [ 1 ]) ? $datas [ 1 ] : '' ;
$decpart = preg_replace ( '/0+$/i' , '' , $decpart ); // Supprime les 0 de fin de partie decimale
2019-02-03 22:58:56 +01:00
//print "decpart=".$decpart."<br>";
2019-11-11 23:59:36 +01:00
$end = '' ;
2019-02-03 22:58:56 +01:00
// We increase nbdecimal if there is more decimal than asked (to not loose information)
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $decpart ) > $nbdecimal ) {
$nbdecimal = dol_strlen ( $decpart );
}
2019-02-03 22:58:56 +01:00
// Si on depasse max
2021-02-23 22:03:23 +01:00
if ( $trunc && $nbdecimal > $conf -> global -> MAIN_MAX_DECIMALS_SHOWN ) {
2019-11-11 23:59:36 +01:00
$nbdecimal = $conf -> global -> MAIN_MAX_DECIMALS_SHOWN ;
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.\.\./i' , $conf -> global -> MAIN_MAX_DECIMALS_SHOWN )) {
2019-02-03 22:58:56 +01:00
// Si un affichage est tronque, on montre des ...
2019-11-11 23:59:36 +01:00
$end = '...' ;
2019-02-03 22:58:56 +01:00
}
}
// If force rounding
2021-02-23 22:03:23 +01:00
if ( $forcerounding >= 0 ) {
$nbdecimal = $forcerounding ;
}
2019-02-03 22:58:56 +01:00
// Format number
2019-11-11 23:59:36 +01:00
$output = number_format ( $amount , $nbdecimal , $dec , $thousand );
2021-02-23 22:03:23 +01:00
if ( $form ) {
2019-11-11 23:59:36 +01:00
$output = preg_replace ( '/\s/' , ' ' , $output );
$output = preg_replace ( '/\'/' , ''' , $output );
2019-02-03 22:58:56 +01:00
}
// Add symbol of currency if requested
2019-11-11 23:59:36 +01:00
$cursymbolbefore = $cursymbolafter = '' ;
2021-02-23 22:03:23 +01:00
if ( $currency_code ) {
if ( $currency_code == 'auto' ) {
$currency_code = $conf -> currency ;
}
2019-02-03 22:58:56 +01:00
2020-04-22 18:23:48 +02:00
$listofcurrenciesbefore = array ( 'AUD' , 'CAD' , 'CNY' , 'COP' , 'CLP' , 'GBP' , 'HKD' , 'MXN' , 'PEN' , 'USD' );
2019-11-11 23:59:36 +01:00
$listoflanguagesbefore = array ( 'nl_NL' );
2021-02-23 22:03:23 +01:00
if ( in_array ( $currency_code , $listofcurrenciesbefore ) || in_array ( $outlangs -> defaultlang , $listoflanguagesbefore )) {
2020-09-07 10:18:17 +02:00
$cursymbolbefore .= $outlangs -> getCurrencySymbol ( $currency_code );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$tmpcur = $outlangs -> getCurrencySymbol ( $currency_code );
$cursymbolafter .= ( $tmpcur == $currency_code ? ' ' . $tmpcur : $tmpcur );
2019-02-03 22:58:56 +01:00
}
}
2019-11-11 23:59:36 +01:00
$output = $cursymbolbefore . $output . $end . ( $cursymbolafter ? ' ' : '' ) . $cursymbolafter ;
2019-02-03 22:58:56 +01:00
return $output ;
}
/**
* Function that return a number with universal decimal format ( decimal separator is '.' ) from an amount typed by a user .
2020-01-16 10:12:39 +01:00
* Function to use on each input amount before any numeric test or database insert . A better name for this function
2020-04-22 12:40:11 +02:00
* should be roundtext2num () .
2019-02-03 22:58:56 +01:00
*
2020-11-24 10:56:05 +01:00
* @ param string | float $amount Amount to convert / clean or round
2021-01-31 12:48:40 +01:00
* @ param string | int $rounding '' = No rounding
2020-11-24 10:56:05 +01:00
* 'MU' = Round to Max unit price ( MAIN_MAX_DECIMALS_UNIT )
* 'MT' = Round to Max for totals with Tax ( MAIN_MAX_DECIMALS_TOT )
* 'MS' = Round to Max for stock quantity ( MAIN_MAX_DECIMALS_STOCK )
2021-01-11 13:46:23 +01:00
* 'CU' = Round to Max unit price of foreign currency accuracy
* 'CT' = Round to Max for totals with Tax of foreign currency accuracy
2021-01-31 12:48:40 +01:00
* Numeric = Nb of digits for rounding ( For example 2 for a percentage )
2020-11-27 14:24:15 +01:00
* @ param int $option Put 1 if you know that content is already universal format number ( so no correction on decimal will be done )
2022-01-09 14:19:55 +01:00
* Put 2 if you know that number is a user input ( so we know we have to fix decimal separator ) .
2020-11-24 10:56:05 +01:00
* @ return string Amount with universal numeric format ( Example : '99.99999' ) .
2021-08-27 18:18:50 +02:00
* If conversion fails to return a numeric , it returns :
2021-08-27 23:36:06 +02:00
* - text unchanged or partial if ( $rounding = '' ) : price2num ( 'W9ç' , '' , 0 ) => '9ç' , price2num ( 'W9ç' , '' , 1 ) => 'W9ç' , price2num ( 'W9ç' , '' , 2 ) => '9ç'
* - '0' if ( $rounding is defined ) : price2num ( 'W9ç' , 'MT' , 0 ) => '9' , price2num ( 'W9ç' , 'MT' , 1 ) => '0' , price2num ( 'W9ç' , 'MT' , 2 ) => '9'
* Note : The best way to guarantee a numeric value is to add a cast ( float ) before the price2num () .
2021-08-27 18:18:50 +02:00
* If amount is null or '' , it returns '' if $rounding = '' or '0' if $rounding is defined .
2019-02-03 22:58:56 +01:00
*
2020-11-24 10:56:05 +01:00
* @ see price () Opposite function of price2num
2019-02-03 22:58:56 +01:00
*/
2020-11-27 14:24:15 +01:00
function price2num ( $amount , $rounding = '' , $option = 0 )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
global $langs , $conf ;
2019-02-03 22:58:56 +01:00
// Round PHP function does not allow number like '1,234.56' nor '1.234,56' nor '1 234,56'
// Numbers must be '1234.56'
// Decimal delimiter for PHP and database SQL requests must be '.'
2021-03-01 20:37:16 +01:00
$dec = ',' ;
$thousand = ' ' ;
2022-03-29 10:22:03 +02:00
if ( is_null ( $langs )) { // $langs is not defined, we use english values.
$dec = '.' ;
$thousand = ',' ;
} else {
if ( $langs -> transnoentitiesnoconv ( " SeparatorDecimal " ) != " SeparatorDecimal " ) {
$dec = $langs -> transnoentitiesnoconv ( " SeparatorDecimal " );
}
if ( $langs -> transnoentitiesnoconv ( " SeparatorThousand " ) != " SeparatorThousand " ) {
$thousand = $langs -> transnoentitiesnoconv ( " SeparatorThousand " );
}
2021-02-23 22:03:23 +01:00
}
if ( $thousand == 'None' ) {
$thousand = '' ;
} elseif ( $thousand == 'Space' ) {
$thousand = ' ' ;
}
2019-02-03 22:58:56 +01:00
//print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'<br>";
// Convert value to universal number format (no thousand separator, '.' as decimal separator)
2020-11-27 14:24:15 +01:00
if ( $option != 1 ) { // If not a PHP number or unknown, we change or clean format
2021-03-03 12:05:43 +01:00
//print "\n".'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'<br>';
2020-11-29 21:29:22 +01:00
if ( ! is_numeric ( $amount )) {
2021-01-16 16:50:34 +01:00
$amount = preg_replace ( '/[a-zA-Z\/\\\*\(\)\<\>\_]/' , '' , $amount );
2020-11-29 21:29:22 +01:00
}
2019-02-03 22:58:56 +01:00
2021-03-02 23:09:55 +01:00
if ( $option == 2 && $thousand == '.' && preg_match ( '/\.(\d\d\d)$/' , ( string ) $amount )) { // It means the . is used as a thousand separator and string come from input data, so 1.123 is 1123
2020-11-27 14:24:15 +01:00
$amount = str_replace ( $thousand , '' , $amount );
2020-11-24 10:56:05 +01:00
}
2020-11-27 14:24:15 +01:00
2019-02-03 22:58:56 +01:00
// Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number
// to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup.
2020-11-27 14:24:15 +01:00
// So if number was already a good number, it is converted into local Dolibarr setup.
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $amount )) {
2019-02-03 22:58:56 +01:00
// We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10
2019-11-11 23:59:36 +01:00
$temps = sprintf ( " %0.10F " , $amount - intval ( $amount )); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000
$temps = preg_replace ( '/([\.1-9])0+$/' , '\\1' , $temps ); // temps=0. or 0.00002 or 9999.1
$nbofdec = max ( 0 , dol_strlen ( $temps ) - 2 ); // -2 to remove "0."
$amount = number_format ( $amount , $nbofdec , $dec , $thousand );
2019-02-03 22:58:56 +01:00
}
2020-11-27 14:24:15 +01:00
//print "QQ".$amount."<br>\n";
2020-11-24 10:56:05 +01:00
2019-02-03 22:58:56 +01:00
// Now make replace (the main goal of function)
2020-11-23 19:45:11 +01:00
if ( $thousand != ',' && $thousand != '.' ) {
$amount = str_replace ( ',' , '.' , $amount ); // To accept 2 notations for french users
}
2021-11-11 13:49:21 +01:00
2019-11-11 23:59:36 +01:00
$amount = str_replace ( ' ' , '' , $amount ); // To avoid spaces
$amount = str_replace ( $thousand , '' , $amount ); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount = str_replace ( $dec , '.' , $amount );
2021-11-11 13:49:21 +01:00
$amount = preg_replace ( '/[^0-9\-\.]/' , '' , $amount ); // Clean non numeric chars (so it clean some UTF8 spaces for example.
2019-02-03 22:58:56 +01:00
}
2021-03-03 12:05:43 +01:00
//print ' XX'.$amount.' '.$rounding;
2019-02-03 22:58:56 +01:00
2021-11-11 13:49:21 +01:00
// Now, $amount is a real PHP float number. We make a rounding if required.
2021-02-23 22:03:23 +01:00
if ( $rounding ) {
2019-11-11 23:59:36 +01:00
$nbofdectoround = '' ;
2021-01-02 16:18:16 +01:00
if ( $rounding == 'MU' ) {
$nbofdectoround = $conf -> global -> MAIN_MAX_DECIMALS_UNIT ;
2021-02-23 22:03:23 +01:00
} elseif ( $rounding == 'MT' ) {
2021-01-02 16:18:16 +01:00
$nbofdectoround = $conf -> global -> MAIN_MAX_DECIMALS_TOT ;
2021-02-23 22:03:23 +01:00
} elseif ( $rounding == 'MS' ) {
2021-12-19 00:01:11 +01:00
$nbofdectoround = isset ( $conf -> global -> MAIN_MAX_DECIMALS_STOCK ) ? $conf -> global -> MAIN_MAX_DECIMALS_STOCK : 5 ;
2021-02-23 22:03:23 +01:00
} elseif ( $rounding == 'CU' ) {
2021-01-11 13:36:53 +01:00
$nbofdectoround = max ( $conf -> global -> MAIN_MAX_DECIMALS_UNIT , 8 ); // TODO Use param of currency
2021-02-23 22:03:23 +01:00
} elseif ( $rounding == 'CT' ) {
2021-01-11 13:36:53 +01:00
$nbofdectoround = max ( $conf -> global -> MAIN_MAX_DECIMALS_TOT , 8 ); // TODO Use param of currency
2021-02-23 22:03:23 +01:00
} elseif ( is_numeric ( $rounding )) {
$nbofdectoround = ( int ) $rounding ;
2021-01-02 16:18:16 +01:00
}
2021-12-19 00:01:11 +01:00
2021-03-03 12:05:43 +01:00
//print " RR".$amount.' - '.$nbofdectoround.'<br>';
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $nbofdectoround )) {
$amount = round ( is_string ( $amount ) ? ( float ) $amount : $amount , $nbofdectoround ); // $nbofdectoround can be 0.
} else {
return 'ErrorBadParameterProvidedToFunction' ;
}
2021-03-03 12:05:43 +01:00
//print ' SS'.$amount.' - '.$nbofdec.' - '.$dec.' - '.$thousand.' - '.$nbofdectoround.'<br>';
2019-02-03 22:58:56 +01:00
// Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number
// to format defined by LC_NUMERIC after a calculation and we want source format to be defined by Dolibarr setup.
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $amount )) {
2019-02-03 22:58:56 +01:00
// We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10
2019-11-11 23:59:36 +01:00
$temps = sprintf ( " %0.10F " , $amount - intval ( $amount )); // temps=0.0000000000 or 0.0000200000 or 9999.1000000000
$temps = preg_replace ( '/([\.1-9])0+$/' , '\\1' , $temps ); // temps=0. or 0.00002 or 9999.1
$nbofdec = max ( 0 , dol_strlen ( $temps ) - 2 ); // -2 to remove "0."
$amount = number_format ( $amount , min ( $nbofdec , $nbofdectoround ), $dec , $thousand ); // Convert amount to format with dolibarr dec and thousand
2019-02-03 22:58:56 +01:00
}
//print "TT".$amount.'<br>';
// Always make replace because each math function (like round) replace
// with local values and we want a number that has a SQL string format x.y
2021-02-23 22:03:23 +01:00
if ( $thousand != ',' && $thousand != '.' ) {
$amount = str_replace ( ',' , '.' , $amount ); // To accept 2 notations for french users
}
2021-11-11 13:49:21 +01:00
2019-11-11 23:59:36 +01:00
$amount = str_replace ( ' ' , '' , $amount ); // To avoid spaces
$amount = str_replace ( $thousand , '' , $amount ); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount = str_replace ( $dec , '.' , $amount );
2021-11-11 13:49:21 +01:00
$amount = preg_replace ( '/[^0-9\-\.]/' , '' , $amount ); // Clean non numeric chars (so it clean some UTF8 spaces for example.
2019-02-03 22:58:56 +01:00
}
return $amount ;
}
/**
* Output a dimension with best unit
*
2021-10-19 21:38:36 +02:00
* @ param float $dimension Dimension
* @ param int $unit Unit scale of dimension ( Example : 0 = kg , - 3 = g , - 6 = mg , 98 = ounce , 99 = pound , ... )
* @ param string $type 'weight' , 'volume' , ...
* @ param Translate $outputlangs Translate language object
* @ param int $round - 1 = non rounding , x = number of decimal
2019-02-03 22:58:56 +01:00
* @ param string $forceunitoutput 'no' or numeric ( - 3 , - 6 , ... ) compared to $unit ( In most case , this value is value defined into $conf -> global -> MAIN_WEIGHT_DEFAULT_UNIT )
2021-10-19 21:38:36 +02:00
* @ param int $use_short_label 1 = Use short label ( 'g' instead of 'gram' ) . Short labels are not translated .
* @ return string String to show dimensions
2019-02-03 22:58:56 +01:00
*/
2021-10-19 21:38:36 +02:00
function showDimensionInBestUnit ( $dimension , $unit , $type , $outputlangs , $round = - 1 , $forceunitoutput = 'no' , $use_short_label = 0 )
2019-02-03 22:58:56 +01:00
{
require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php' ;
2021-02-23 22:03:23 +01:00
if (( $forceunitoutput == 'no' && $dimension < 1 / 10000 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == - 6 )) {
2019-02-03 22:58:56 +01:00
$dimension = $dimension * 1000000 ;
$unit = $unit - 6 ;
2021-02-23 22:03:23 +01:00
} elseif (( $forceunitoutput == 'no' && $dimension < 1 / 10 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == - 3 )) {
2019-02-03 22:58:56 +01:00
$dimension = $dimension * 1000 ;
$unit = $unit - 3 ;
2021-02-23 22:03:23 +01:00
} elseif (( $forceunitoutput == 'no' && $dimension > 100000000 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == 6 )) {
2019-02-03 22:58:56 +01:00
$dimension = $dimension / 1000000 ;
$unit = $unit + 6 ;
2021-02-23 22:03:23 +01:00
} elseif (( $forceunitoutput == 'no' && $dimension > 100000 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == 3 )) {
2019-02-03 22:58:56 +01:00
$dimension = $dimension / 1000 ;
$unit = $unit + 3 ;
}
// Special case when we want output unit into pound or ounce
/* TODO
if ( $unit < 90 && $type == 'weight' && is_numeric ( $forceunitoutput ) && (( $forceunitoutput == 98 ) || ( $forceunitoutput == 99 ))
{
2021-02-23 22:03:23 +01:00
$dimension = // convert dimension from standard unit into ounce or pound
$unit = $forceunitoutput ;
2019-02-03 22:58:56 +01:00
}
if ( $unit > 90 && $type == 'weight' && is_numeric ( $forceunitoutput ) && $forceunitoutput < 90 )
{
2021-02-23 22:03:23 +01:00
$dimension = // convert dimension from standard unit into ounce or pound
$unit = $forceunitoutput ;
2019-02-03 22:58:56 +01:00
} */
2021-10-19 21:38:36 +02:00
$ret = price ( $dimension , 0 , $outputlangs , 0 , 0 , $round );
$ret .= ' ' . measuringUnitString ( 0 , $type , $unit , $use_short_label , $outputlangs );
2019-02-03 22:58:56 +01:00
return $ret ;
}
/**
* Return localtax rate for a particular vat , when selling a product with vat $vatrate , from a $thirdparty_buyer to a $thirdparty_seller
* Note : This function applies same rules than get_default_tva
*
* @ param float $vatrate Vat rate . Can be '8.5' or '8.5 (VATCODEX)' for example
* @ param int $local Local tax to search and return ( 1 or 2 return only tax rate 1 or tax rate 2 )
* @ param Societe $thirdparty_buyer Object of buying third party
* @ param Societe $thirdparty_seller Object of selling third party ( $mysoc if not defined )
* @ param int $vatnpr If vat rate is NPR or not
* @ return mixed 0 if not found , localtax rate if found
2019-03-11 01:01:15 +01:00
* @ see get_default_tva ()
2019-02-03 22:58:56 +01:00
*/
function get_localtax ( $vatrate , $local , $thirdparty_buyer = " " , $thirdparty_seller = " " , $vatnpr = 0 )
{
global $db , $conf , $mysoc ;
2021-02-23 22:03:23 +01:00
if ( empty ( $thirdparty_seller ) || ! is_object ( $thirdparty_seller )) {
$thirdparty_seller = $mysoc ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
dol_syslog ( " get_localtax tva= " . $vatrate . " local= " . $local . " thirdparty_buyer id= " . ( is_object ( $thirdparty_buyer ) ? $thirdparty_buyer -> id : '' ) . " /country_code= " . ( is_object ( $thirdparty_buyer ) ? $thirdparty_buyer -> country_code : '' ) . " thirdparty_seller id= " . $thirdparty_seller -> id . " /country_code= " . $thirdparty_seller -> country_code . " thirdparty_seller localtax1_assuj= " . $thirdparty_seller -> localtax1_assuj . " thirdparty_seller localtax2_assuj= " . $thirdparty_seller -> localtax2_assuj );
2019-02-03 22:58:56 +01:00
$vatratecleaned = $vatrate ;
2020-01-01 21:54:47 +01:00
$reg = array ();
2020-12-17 08:52:39 +01:00
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) { // If vat is "xx (yy)"
2019-02-03 22:58:56 +01:00
$vatratecleaned = trim ( $reg [ 1 ]);
$vatratecode = $reg [ 2 ];
}
/* if ( $thirdparty_buyer -> country_code != $thirdparty_seller -> country_code )
{
return 0 ;
} */
// Some test to guess with no need to make database access
2020-12-17 08:52:39 +01:00
if ( $mysoc -> country_code == 'ES' ) { // For spain localtaxes 1 and 2, tax is qualified if buyer use local tax
if ( $local == 1 ) {
2021-02-23 22:03:23 +01:00
if ( ! $mysoc -> localtax1_assuj || ( string ) $vatratecleaned == " 0 " ) {
return 0 ;
}
2020-12-17 08:52:39 +01:00
if ( $thirdparty_seller -> id == $mysoc -> id ) {
2021-02-23 22:03:23 +01:00
if ( ! $thirdparty_buyer -> localtax1_assuj ) {
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( ! $thirdparty_seller -> localtax1_assuj ) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
}
}
2020-12-17 08:52:39 +01:00
if ( $local == 2 ) {
2019-02-03 22:58:56 +01:00
//if (! $mysoc->localtax2_assuj || (string) $vatratecleaned == "0") return 0;
2021-02-23 22:03:23 +01:00
if ( ! $mysoc -> localtax2_assuj ) {
return 0 ; // If main vat is 0, IRPF may be different than 0.
}
2020-12-17 08:52:39 +01:00
if ( $thirdparty_seller -> id == $mysoc -> id ) {
2021-02-23 22:03:23 +01:00
if ( ! $thirdparty_buyer -> localtax2_assuj ) {
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( ! $thirdparty_seller -> localtax2_assuj ) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
}
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $local == 1 && ! $thirdparty_seller -> localtax1_assuj ) {
return 0 ;
}
if ( $local == 2 && ! $thirdparty_seller -> localtax2_assuj ) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
}
// For some country MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY is forced to on.
2020-12-17 08:52:39 +01:00
if ( in_array ( $mysoc -> country_code , array ( 'ES' ))) {
2019-02-03 22:58:56 +01:00
$conf -> global -> MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY = 1 ;
}
// Search local taxes
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY )) {
2020-12-17 08:52:39 +01:00
if ( $local == 1 ) {
if ( $thirdparty_seller != $mysoc ) {
2021-02-23 22:03:23 +01:00
if ( ! isOnlyOneLocalTax ( $local )) { // TODO We should provide $vatrate to search on correct line and not always on line with highest vat rate
2019-02-03 22:58:56 +01:00
return $thirdparty_seller -> localtax1_value ;
}
2020-12-17 08:52:39 +01:00
} else { // i am the seller
if ( ! isOnlyOneLocalTax ( $local )) { // TODO If seller is me, why not always returning this, even if there is only one locatax vat.
2019-02-03 22:58:56 +01:00
return $conf -> global -> MAIN_INFO_VALUE_LOCALTAX1 ;
}
}
}
2020-12-17 08:52:39 +01:00
if ( $local == 2 ) {
if ( $thirdparty_seller != $mysoc ) {
2021-02-23 22:03:23 +01:00
if ( ! isOnlyOneLocalTax ( $local )) { // TODO We should provide $vatrate to search on correct line and not always on line with highest vat rate
// TODO We should also return value defined on thirdparty only if defined
2019-02-03 22:58:56 +01:00
return $thirdparty_seller -> localtax2_value ;
}
2020-12-17 08:52:39 +01:00
} else { // i am the seller
if ( in_array ( $mysoc -> country_code , array ( 'ES' ))) {
2019-02-03 22:58:56 +01:00
return $thirdparty_buyer -> localtax2_value ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
return $conf -> global -> MAIN_INFO_VALUE_LOCALTAX2 ;
}
}
}
}
// By default, search value of local tax on line of common tax
2019-11-11 23:59:36 +01:00
$sql = " SELECT t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type " ;
2021-02-23 22:03:23 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t, " . MAIN_DB_PREFIX . " c_country as c " ;
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( $thirdparty_seller -> country_code ) . " ' " ;
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
if ( ! empty ( $vatratecode )) {
$sql .= " AND t.code =' " . $db -> escape ( $vatratecode ) . " ' " ; // If we have the code, we use it in priority
} else {
$sql .= " AND t.recuperableonly = ' " . $db -> escape ( $vatnpr ) . " ' " ;
}
2021-07-06 03:53:42 +02:00
2021-02-23 22:03:23 +01:00
$resql = $db -> query ( $sql );
if ( $resql ) {
$obj = $db -> fetch_object ( $resql );
if ( $obj ) {
if ( $local == 1 ) {
return $obj -> localtax1 ;
} elseif ( $local == 2 ) {
return $obj -> localtax2 ;
}
}
2019-02-03 22:58:56 +01:00
}
return 0 ;
}
/**
* Return true if LocalTax ( 1 or 2 ) is unique .
* Example : If localtax1 is 5 on line with highest common vat rate , return true
* Example : If localtax1 is 5 : 8 : 15 on line with highest common vat rate , return false
*
* @ param int $local Local tax to test ( 1 or 2 )
* @ return boolean True if LocalTax have multiple values , False if not
*/
function isOnlyOneLocalTax ( $local )
{
2019-11-11 23:59:36 +01:00
$tax = get_localtax_by_third ( $local );
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$valors = explode ( " : " , $tax );
2019-02-03 22:58:56 +01:00
2020-12-17 08:52:39 +01:00
if ( count ( $valors ) > 1 ) {
2019-02-03 22:58:56 +01:00
return false ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
return true ;
}
}
/**
* Get values of localtaxes ( 1 or 2 ) for company country for the common vat with the highest value
*
* @ param int $local LocalTax to get
* @ return number Values of localtax
*/
function get_localtax_by_third ( $local )
{
global $db , $mysoc ;
2019-11-11 23:59:36 +01:00
$sql = " SELECT t.localtax1, t.localtax2 " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t inner join " . MAIN_DB_PREFIX . " c_country as c ON c.rowid=t.fk_pays " ;
2020-09-19 22:41:05 +02:00
$sql .= " WHERE c.code = ' " . $db -> escape ( $mysoc -> country_code ) . " ' AND t.active = 1 AND t.taux=( " ;
2019-11-11 23:59:36 +01:00
$sql .= " SELECT max(tt.taux) FROM " . MAIN_DB_PREFIX . " c_tva as tt inner join " . MAIN_DB_PREFIX . " c_country as c ON c.rowid=tt.fk_pays " ;
2020-09-19 22:41:05 +02:00
$sql .= " WHERE c.code = ' " . $db -> escape ( $mysoc -> country_code ) . " ' AND tt.active = 1 " ;
2019-11-11 23:59:36 +01:00
$sql .= " ) " ;
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-02-03 22:58:56 +01:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $local == 1 ) {
return $obj -> localtax1 ;
} elseif ( $local == 2 ) {
return $obj -> localtax2 ;
}
2019-02-03 22:58:56 +01:00
}
return 0 ;
}
/**
2020-12-17 08:52:39 +01:00
* Get tax ( VAT ) main information from Id .
* You can also call getLocalTaxesFromRate () after to get only localtax fields .
2019-02-03 22:58:56 +01:00
*
* @ param int | string $vatrate VAT ID or Rate . Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example : '8.5' or '8.5 (8.5NPR)' or 123.
* @ param Societe $buyer Company object
* @ param Societe $seller Company object
* @ param int $firstparamisid 1 if first param is id into table ( use this if you can )
* @ return array array ( 'rowid' => , 'code' => ... )
2019-03-11 01:01:15 +01:00
* @ see getLocalTaxesFromRate ()
2019-02-03 22:58:56 +01:00
*/
function getTaxesFromId ( $vatrate , $buyer = null , $seller = null , $firstparamisid = 1 )
{
global $db , $mysoc ;
dol_syslog ( " getTaxesFromId vat id or rate = " . $vatrate );
// Search local taxes
2020-12-17 08:52:39 +01:00
$sql = " SELECT t.rowid, t.code, t.taux as rate, t.recuperableonly as npr, t.accountancy_code_sell, t.accountancy_code_buy, " ;
$sql .= " t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type " ;
2019-11-11 23:59:36 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t " ;
2020-12-17 08:52:39 +01:00
if ( $firstparamisid ) {
$sql .= " WHERE t.rowid = " . ( int ) $vatrate ;
} else {
2019-02-03 22:58:56 +01:00
$vatratecleaned = $vatrate ;
$vatratecode = '' ;
2020-12-17 08:52:39 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) { // If vat is "xx (yy)"
2019-02-03 22:58:56 +01:00
$vatratecleaned = $reg [ 1 ];
$vatratecode = $reg [ 2 ];
}
2019-11-11 23:59:36 +01:00
$sql .= " , " . MAIN_DB_PREFIX . " c_country as c " ;
2020-09-19 22:41:05 +02:00
/* if ( $mysoc -> country_code == 'ES' ) $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( $buyer -> country_code ) . " ' " ; // vat in spain use the buyer country ??
else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( $seller -> country_code ) . " ' " ; */
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( $seller -> country_code ) . " ' " ;
2019-11-11 23:59:36 +01:00
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
2021-02-23 22:03:23 +01:00
if ( $vatratecode ) {
$sql .= " AND t.code = ' " . $db -> escape ( $vatratecode ) . " ' " ;
}
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2020-12-17 08:52:39 +01:00
if ( $resql ) {
2019-02-03 22:58:56 +01:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
return array (
2020-12-17 08:52:39 +01:00
'rowid' => $obj -> rowid ,
'code' => $obj -> code ,
'rate' => $obj -> rate ,
'localtax1' => $obj -> localtax1 ,
'localtax1_type' => $obj -> localtax1_type ,
'localtax2' => $obj -> localtax2 ,
'localtax2_type' => $obj -> localtax2_type ,
'npr' => $obj -> npr ,
'accountancy_code_sell' => $obj -> accountancy_code_sell ,
'accountancy_code_buy' => $obj -> accountancy_code_buy
2021-02-23 22:03:23 +01:00
);
} else {
return array ();
}
} else {
dol_print_error ( $db );
}
2019-02-03 22:58:56 +01:00
return array ();
}
/**
* Get type and rate of localtaxes for a particular vat rate / country of a thirdparty .
* This does not take into account the seller setup if subject to vat or not , only country .
2020-12-06 17:59:49 +01:00
*
* TODO This function is ALSO called to retrieve type for building PDF . Such call of function must be removed .
* Instead this function must be called when adding a line to get the array of possible values for localtax and type , and then
* provide the selected value to the function calcul_price_total .
2019-02-03 22:58:56 +01:00
*
* @ param int | string $vatrate VAT ID or Rate + Code . Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example : '8.5' or '8.5 (8.5NPR)' or 123.
* @ param int $local Number of localtax ( 1 or 2 , or 0 to return 1 & 2 )
* @ param Societe $buyer Company object
* @ param Societe $seller Company object
* @ param int $firstparamisid 1 if first param is ID into table instead of Rate + code ( use this if you can )
2020-12-06 17:59:49 +01:00
* @ return array array ( localtax_type1 ( 1 - 6 or 0 if not found ), rate localtax1 , localtax_type2 , rate localtax2 , accountancycodecust , accountancycodesupp )
2019-03-11 01:01:15 +01:00
* @ see getTaxesFromId ()
2019-02-03 22:58:56 +01:00
*/
function getLocalTaxesFromRate ( $vatrate , $local , $buyer , $seller , $firstparamisid = 0 )
{
global $db , $mysoc ;
dol_syslog ( " getLocalTaxesFromRate vatrate= " . $vatrate . " local= " . $local );
// Search local taxes
2020-01-01 22:27:47 +01:00
$sql = " SELECT t.taux as rate, t.code, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy " ;
2019-02-03 22:58:56 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t " ;
2020-12-06 17:59:49 +01:00
if ( $firstparamisid ) {
$sql .= " WHERE t.rowid = " . ( int ) $vatrate ;
} else {
2019-02-03 22:58:56 +01:00
$vatratecleaned = $vatrate ;
$vatratecode = '' ;
2020-01-01 22:27:47 +01:00
$reg = array ();
2020-12-06 17:59:49 +01:00
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) { // If vat is "x.x (yy)"
2019-02-03 22:58:56 +01:00
$vatratecleaned = $reg [ 1 ];
$vatratecode = $reg [ 2 ];
}
2019-11-11 23:59:36 +01:00
$sql .= " , " . MAIN_DB_PREFIX . " c_country as c " ;
2021-02-23 22:03:23 +01:00
if ( $mysoc -> country_code == 'ES' ) {
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( $buyer -> country_code ) . " ' " ; // local tax in spain use the buyer country ??
} else {
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $db -> escape ( empty ( $seller -> country_code ) ? $mysoc -> country_code : $seller -> country_code ) . " ' " ;
}
2019-11-11 23:59:36 +01:00
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
2021-02-23 22:03:23 +01:00
if ( $vatratecode ) {
$sql .= " AND t.code = ' " . $db -> escape ( $vatratecode ) . " ' " ;
}
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2020-12-06 17:59:49 +01:00
if ( $resql ) {
2019-02-03 22:58:56 +01:00
$obj = $db -> fetch_object ( $resql );
2020-01-01 22:27:47 +01:00
2020-12-06 17:59:49 +01:00
if ( $obj ) {
$vateratestring = $obj -> rate . ( $obj -> code ? ' (' . $obj -> code . ')' : '' );
2020-01-01 22:27:47 +01:00
2020-12-06 17:59:49 +01:00
if ( $local == 1 ) {
return array ( $obj -> localtax1_type , get_localtax ( $vateratestring , $local , $buyer , $seller ), $obj -> accountancy_code_sell , $obj -> accountancy_code_buy );
} elseif ( $local == 2 ) {
return array ( $obj -> localtax2_type , get_localtax ( $vateratestring , $local , $buyer , $seller ), $obj -> accountancy_code_sell , $obj -> accountancy_code_buy );
} else {
return array ( $obj -> localtax1_type , get_localtax ( $vateratestring , 1 , $buyer , $seller ), $obj -> localtax2_type , get_localtax ( $vateratestring , 2 , $buyer , $seller ), $obj -> accountancy_code_sell , $obj -> accountancy_code_buy );
}
2019-02-03 22:58:56 +01:00
}
}
2020-12-18 14:40:45 +01:00
return array ();
2019-02-03 22:58:56 +01:00
}
/**
2021-06-22 10:57:16 +02:00
* Return vat rate of a product in a particular country , or default country vat if product is unknown .
* Function called by get_default_tva () .
2019-02-03 22:58:56 +01:00
*
* @ param int $idprod Id of product or 0 if not a predefined product
2021-06-22 10:57:16 +02:00
* @ param Societe $thirdpartytouse Thirdparty with a -> country_code defined ( FR , US , IT , ... )
2019-02-03 22:58:56 +01:00
* @ param int $idprodfournprice Id product_fournisseur_price ( for " supplier " proposal / order / invoice )
* @ return float | string Vat rate to use with format 5.0 or '5.0 (XXX)'
2019-03-11 01:01:15 +01:00
* @ see get_product_localtax_for_country ()
2019-02-03 22:58:56 +01:00
*/
2021-06-22 10:57:16 +02:00
function get_product_vat_for_country ( $idprod , $thirdpartytouse , $idprodfournprice = 0 )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
global $db , $conf , $mysoc ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php' ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$ret = 0 ;
$found = 0 ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $idprod > 0 ) {
2019-02-03 22:58:56 +01:00
// Load product
2019-11-11 23:59:36 +01:00
$product = new Product ( $db );
$result = $product -> fetch ( $idprod );
2019-02-03 22:58:56 +01:00
2021-06-22 10:57:16 +02:00
if ( $mysoc -> country_code == $thirdpartytouse -> country_code ) { // If country to consider is ours
2021-02-23 22:03:23 +01:00
if ( $idprodfournprice > 0 ) { // We want vat for product for a "supplier" object
2019-02-03 22:58:56 +01:00
$product -> get_buyprice ( $idprodfournprice , 0 , 0 , 0 );
2019-11-11 23:59:36 +01:00
$ret = $product -> vatrate_supplier ;
2021-02-23 22:03:23 +01:00
if ( $product -> default_vat_code ) {
$ret .= ' (' . $product -> default_vat_code . ')' ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$ret = $product -> tva_tx ; // Default vat of product we defined
2021-02-23 22:03:23 +01:00
if ( $product -> default_vat_code ) {
$ret .= ' (' . $product -> default_vat_code . ')' ;
}
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$found = 1 ;
2020-05-21 15:05:19 +02:00
} else {
2021-06-22 10:57:16 +02:00
// TODO Read default product vat according to product and another countrycode.
// Vat for couple anothercountrycode/product is data that is not managed and store yet, so we will fallback on next rule.
2019-02-03 22:58:56 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( ! $found ) {
if ( empty ( $conf -> global -> MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS )) {
2019-02-03 22:58:56 +01:00
// If vat of product for the country not found or not defined, we return the first higher vat of country.
$sql = " SELECT t.taux as vat_rate, t.code as default_vat_code " ;
2019-11-11 23:59:36 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t, " . MAIN_DB_PREFIX . " c_country as c " ;
2021-06-22 10:57:16 +02:00
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code=' " . $db -> escape ( $thirdpartytouse -> country_code ) . " ' " ;
2019-11-11 23:59:36 +01:00
$sql .= " ORDER BY t.taux DESC, t.code ASC, t.recuperableonly ASC " ;
$sql .= $db -> plimit ( 1 );
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-11-11 23:59:36 +01:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
2019-11-11 23:59:36 +01:00
$ret = $obj -> vat_rate ;
2021-02-23 22:03:23 +01:00
if ( $obj -> default_vat_code ) {
$ret .= ' (' . $obj -> default_vat_code . ')' ;
}
2019-02-03 22:58:56 +01:00
}
2021-10-26 15:27:12 +02:00
$db -> free ( $resql );
2021-02-23 22:03:23 +01:00
} else {
dol_print_error ( $db );
}
} else {
$ret = $conf -> global -> MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS ; // Forced value if autodetect fails
}
2019-02-03 22:58:56 +01:00
}
dol_syslog ( " get_product_vat_for_country: ret= " . $ret );
return $ret ;
}
/**
2021-06-22 10:57:16 +02:00
* Return localtax vat rate of a product in a particular country or default country vat if product is unknown
2019-02-03 22:58:56 +01:00
*
* @ param int $idprod Id of product
* @ param int $local 1 for localtax1 , 2 for localtax 2
2021-06-22 10:57:16 +02:00
* @ param Societe $thirdpartytouse Thirdparty with a -> country_code defined ( FR , US , IT , ... )
2019-02-03 22:58:56 +01:00
* @ return int < 0 if KO , Vat rate if OK
2019-03-11 01:01:15 +01:00
* @ see get_product_vat_for_country ()
2019-02-03 22:58:56 +01:00
*/
2021-06-22 10:57:16 +02:00
function get_product_localtax_for_country ( $idprod , $local , $thirdpartytouse )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
global $db , $mysoc ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( ! class_exists ( 'Product' )) {
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php' ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$ret = 0 ;
$found = 0 ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $idprod > 0 ) {
2019-02-03 22:58:56 +01:00
// Load product
2019-11-11 23:59:36 +01:00
$product = new Product ( $db );
$result = $product -> fetch ( $idprod );
2019-02-03 22:58:56 +01:00
2021-06-22 10:57:16 +02:00
if ( $mysoc -> country_code == $thirdpartytouse -> country_code ) { // If selling country is ours
2019-02-03 22:58:56 +01:00
/* Not defined yet , so we don ' t use this
if ( $local == 1 ) $ret = $product -> localtax1_tx ;
elseif ( $local == 2 ) $ret = $product -> localtax2_tx ;
$found = 1 ;
*/
2020-05-21 15:05:19 +02:00
} else {
2021-06-22 10:57:16 +02:00
// TODO Read default product vat according to product and another countrycode.
// Vat for couple anothercountrycode/product is data that is not managed and store yet, so we will fallback on next rule.
2019-02-03 22:58:56 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( ! $found ) {
2019-02-03 22:58:56 +01:00
// If vat of product for the country not found or not defined, we return higher vat of country.
$sql = " SELECT taux as vat_rate, localtax1, localtax2 " ;
2019-11-11 23:59:36 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t, " . MAIN_DB_PREFIX . " c_country as c " ;
2021-06-22 10:57:16 +02:00
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code=' " . $db -> escape ( $thirdpartytouse -> country_code ) . " ' " ;
2019-11-11 23:59:36 +01:00
$sql .= " ORDER BY t.taux DESC, t.recuperableonly ASC " ;
$sql .= $db -> plimit ( 1 );
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-11-11 23:59:36 +01:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
if ( $local == 1 ) {
$ret = $obj -> localtax1 ;
} elseif ( $local == 2 ) {
$ret = $obj -> localtax2 ;
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
} else {
dol_print_error ( $db );
}
2019-02-03 22:58:56 +01:00
}
dol_syslog ( " get_product_localtax_for_country: ret= " . $ret );
return $ret ;
}
/**
* Function that return vat rate of a product line ( according to seller , buyer and product vat rate )
2021-06-21 11:36:28 +02:00
* VATRULE 1 : Si vendeur non assujeti a TVA , TVA par defaut = 0. Fin de regle .
* VATRULE 2 : Si le ( pays vendeur = pays acheteur ) alors TVA par defaut = TVA du produit vendu . Fin de regle .
* VATRULE 3 : Si ( vendeur et acheteur dans Communaute europeenne ) et ( bien vendu = moyen de transports neuf comme auto , bateau , avion ) alors TVA par defaut = 0 ( La TVA doit etre paye par acheteur au centre d ' impots de son pays et non au vendeur ) . Fin de regle .
* VATRULE 4 : Si ( vendeur et acheteur dans Communaute europeenne ) et ( acheteur = particulier ) alors TVA par defaut = TVA du produit vendu . Fin de regle
* VATRULE 5 : Si ( vendeur et acheteur dans Communaute europeenne ) et ( acheteur = entreprise ) alors TVA par defaut = 0. Fin de regle
* VATRULE 6 : Sinon TVA proposee par defaut = 0. Fin de regle .
2019-02-03 22:58:56 +01:00
*
* @ param Societe $thirdparty_seller Objet societe vendeuse
* @ param Societe $thirdparty_buyer Objet societe acheteuse
* @ param int $idprod Id product
* @ param int $idprodfournprice Id product_fournisseur_price ( for supplier order / invoice )
* @ return float | string Vat rate to use with format 5.0 or '5.0 (XXX)' , - 1 if we can ' t guess it
2019-03-11 01:01:15 +01:00
* @ see get_default_npr (), get_default_localtax ()
2019-02-03 22:58:56 +01:00
*/
function get_default_tva ( Societe $thirdparty_seller , Societe $thirdparty_buyer , $idprod = 0 , $idprodfournprice = 0 )
{
global $conf ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php' ;
// Note: possible values for tva_assuj are 0/1 or franchise/reel
2019-11-11 23:59:36 +01:00
$seller_use_vat = (( is_numeric ( $thirdparty_seller -> tva_assuj ) && ! $thirdparty_seller -> tva_assuj ) || ( ! is_numeric ( $thirdparty_seller -> tva_assuj ) && $thirdparty_seller -> tva_assuj == 'franchise' )) ? 0 : 1 ;
2019-02-03 22:58:56 +01:00
$seller_country_code = $thirdparty_seller -> country_code ;
$seller_in_cee = isInEEC ( $thirdparty_seller );
$buyer_country_code = $thirdparty_buyer -> country_code ;
$buyer_in_cee = isInEEC ( $thirdparty_buyer );
2019-11-11 23:59:36 +01:00
dol_syslog ( " get_default_tva: seller use vat= " . $seller_use_vat . " , seller country= " . $seller_country_code . " , seller in cee= " . $seller_in_cee . " , buyer vat number= " . $thirdparty_buyer -> tva_intra . " buyer country= " . $buyer_country_code . " , buyer in cee= " . $buyer_in_cee . " , idprod= " . $idprod . " , idprodfournprice= " . $idprodfournprice . " , SERVICE_ARE_ECOMMERCE_200238EC= " . ( ! empty ( $conf -> global -> SERVICES_ARE_ECOMMERCE_200238EC ) ? $conf -> global -> SERVICES_ARE_ECOMMERCE_200238EC : '' ));
2019-02-03 22:58:56 +01:00
// If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm)
// we use the buyer VAT.
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> SERVICE_ARE_ECOMMERCE_200238EC )) {
2021-06-21 11:36:28 +02:00
if ( $seller_in_cee && $buyer_in_cee ) {
$isacompany = $thirdparty_buyer -> isACompany ();
if ( $isacompany && ! empty ( $conf -> global -> MAIN_USE_VAT_COMPANIES_IN_EEC_WITH_INVALID_VAT_ID_ARE_INDIVIDUAL )) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php' ;
if ( ! isValidVATID ( $thirdparty_buyer )) {
$isacompany = 0 ;
}
}
if ( ! $isacompany ) {
//print 'VATRULE 0';
return get_product_vat_for_country ( $idprod , $thirdparty_buyer , $idprodfournprice );
}
2019-02-03 22:58:56 +01:00
}
}
// If seller does not use VAT
2021-02-23 22:03:23 +01:00
if ( ! $seller_use_vat ) {
2019-02-03 22:58:56 +01:00
//print 'VATRULE 1';
return 0 ;
}
// Le test ci-dessus ne devrait pas etre necessaire. Me signaler l'exemple du cas juridique concerne si le test suivant n'est pas suffisant.
// Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle.
if (( $seller_country_code == $buyer_country_code )
2021-02-23 22:03:23 +01:00
|| ( in_array ( $seller_country_code , array ( 'FR,MC' )) && in_array ( $buyer_country_code , array ( 'FR' , 'MC' )))) { // Warning ->country_code not always defined
2019-02-03 22:58:56 +01:00
//print 'VATRULE 2';
return get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice );
}
// Si (vendeur et acheteur dans Communaute europeenne) et (bien vendu = moyen de transports neuf comme auto, bateau, avion) alors TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle.
2021-06-21 11:13:30 +02:00
// 'VATRULE 3' - Not supported
2019-02-03 22:58:56 +01:00
// Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = entreprise) alors TVA par defaut=0. Fin de regle
// Si (vendeur et acheteur dans Communaute europeenne) et (acheteur = particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle
2021-02-23 22:03:23 +01:00
if (( $seller_in_cee && $buyer_in_cee )) {
2019-11-11 23:59:36 +01:00
$isacompany = $thirdparty_buyer -> isACompany ();
2021-06-21 11:13:30 +02:00
if ( $isacompany && ! empty ( $conf -> global -> MAIN_USE_VAT_COMPANIES_IN_EEC_WITH_INVALID_VAT_ID_ARE_INDIVIDUAL )) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php' ;
if ( ! isValidVATID ( $thirdparty_buyer )) {
$isacompany = 0 ;
2021-01-15 16:06:22 +01:00
}
2021-06-21 11:13:30 +02:00
}
if ( ! $isacompany ) {
2019-02-03 22:58:56 +01:00
//print 'VATRULE 4';
return get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice );
2021-06-21 11:13:30 +02:00
} else {
//print 'VATRULE 5';
return 0 ;
2019-02-03 22:58:56 +01:00
}
}
2021-06-21 11:13:30 +02:00
// Si (vendeur dans Communaute europeene et acheteur hors Communaute europeenne et acheteur particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle
2021-06-21 11:36:28 +02:00
// I don't see any use case that need this rule.
2021-06-21 11:13:30 +02:00
if ( ! empty ( $conf -> global -> MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC ) && empty ( $buyer_in_cee )) {
$isacompany = $thirdparty_buyer -> isACompany ();
if ( ! $isacompany ) {
return get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice );
//print 'VATRULE extra';
}
2019-02-03 22:58:56 +01:00
}
// Sinon la TVA proposee par defaut=0. Fin de regle.
// Rem: Cela signifie qu'au moins un des 2 est hors Communaute europeenne et que le pays differe
2021-06-21 11:13:30 +02:00
//print 'VATRULE 6';
2019-02-03 22:58:56 +01:00
return 0 ;
}
/**
* Fonction qui renvoie si tva doit etre tva percue recuperable
*
* @ param Societe $thirdparty_seller Thirdparty seller
* @ param Societe $thirdparty_buyer Thirdparty buyer
* @ param int $idprod Id product
* @ param int $idprodfournprice Id supplier price for product
* @ return float 0 or 1
2019-03-11 01:01:15 +01:00
* @ see get_default_tva (), get_default_localtax ()
2019-02-03 22:58:56 +01:00
*/
function get_default_npr ( Societe $thirdparty_seller , Societe $thirdparty_buyer , $idprod = 0 , $idprodfournprice = 0 )
{
global $db ;
2021-02-23 22:03:23 +01:00
if ( $idprodfournprice > 0 ) {
2019-11-14 21:30:16 +01:00
if ( ! class_exists ( 'ProductFournisseur' )) {
2019-11-11 23:59:36 +01:00
require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php' ;
2019-11-14 21:16:18 +01:00
}
2019-02-03 22:58:56 +01:00
$prodprice = new ProductFournisseur ( $db );
$prodprice -> fetch_product_fournisseur_price ( $idprodfournprice );
return $prodprice -> fourn_tva_npr ;
2021-02-23 22:03:23 +01:00
} elseif ( $idprod > 0 ) {
2019-11-14 21:30:16 +01:00
if ( ! class_exists ( 'Product' )) {
2019-11-11 23:59:36 +01:00
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php' ;
2019-11-14 21:16:18 +01:00
}
2019-02-03 22:58:56 +01:00
$prod = new Product ( $db );
$prod -> fetch ( $idprod );
return $prod -> tva_npr ;
}
return 0 ;
}
/**
* Function that return localtax of a product line ( according to seller , buyer and product vat rate )
* Si vendeur non assujeti a TVA , TVA par defaut = 0. Fin de regle .
* Si le ( pays vendeur = pays acheteur ) alors TVA par defaut = TVA du produit vendu . Fin de regle .
* Sinon TVA proposee par defaut = 0. Fin de regle .
*
* @ param Societe $thirdparty_seller Thirdparty seller
* @ param Societe $thirdparty_buyer Thirdparty buyer
* @ param int $local Localtax to process ( 1 or 2 )
* @ param int $idprod Id product
* @ return integer localtax , - 1 si ne peut etre determine
2019-03-11 01:01:15 +01:00
* @ see get_default_tva (), get_default_npr ()
2019-02-03 22:58:56 +01:00
*/
function get_default_localtax ( $thirdparty_seller , $thirdparty_buyer , $local , $idprod = 0 )
{
global $mysoc ;
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $thirdparty_seller )) {
return - 1 ;
}
if ( ! is_object ( $thirdparty_buyer )) {
return - 1 ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $local == 1 ) { // Localtax 1
if ( $mysoc -> country_code == 'ES' ) {
if ( is_numeric ( $thirdparty_buyer -> localtax1_assuj ) && ! $thirdparty_buyer -> localtax1_assuj ) {
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
// Si vendeur non assujeti a Localtax1, localtax1 par default=0
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $thirdparty_seller -> localtax1_assuj ) && ! $thirdparty_seller -> localtax1_assuj ) {
return 0 ;
}
if ( ! is_numeric ( $thirdparty_seller -> localtax1_assuj ) && $thirdparty_seller -> localtax1_assuj == 'localtax1off' ) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( $local == 2 ) { //I Localtax 2
2019-02-03 22:58:56 +01:00
// Si vendeur non assujeti a Localtax2, localtax2 par default=0
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $thirdparty_seller -> localtax2_assuj ) && ! $thirdparty_seller -> localtax2_assuj ) {
return 0 ;
}
if ( ! is_numeric ( $thirdparty_seller -> localtax2_assuj ) && $thirdparty_seller -> localtax2_assuj == 'localtax2off' ) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $thirdparty_seller -> country_code == $thirdparty_buyer -> country_code ) {
2019-02-03 22:58:56 +01:00
return get_product_localtax_for_country ( $idprod , $local , $thirdparty_seller );
}
return 0 ;
}
/**
* Return yes or no in current language
*
2020-02-05 19:23:00 +01:00
* @ param string | int $yesno Value to test ( 1 , 'yes' , 'true' or 0 , 'no' , 'false' )
* @ param integer $case 1 = Yes / No , 0 = yes / no , 2 = Disabled checkbox , 3 = Disabled checkbox + Yes / No
* @ param int $color 0 = texte only , 1 = Text is formated with a color font style ( 'ok' or 'error' ), 2 = Text is formated with 'ok' color .
* @ return string HTML string
2019-02-03 22:58:56 +01:00
*/
function yn ( $yesno , $case = 1 , $color = 0 )
{
global $langs ;
2021-03-01 20:37:16 +01:00
$result = 'unknown' ;
$classname = '' ;
2021-02-23 22:03:23 +01:00
if ( $yesno == 1 || strtolower ( $yesno ) == 'yes' || strtolower ( $yesno ) == 'true' ) { // A mettre avant test sur no a cause du == 0
2019-11-11 23:59:36 +01:00
$result = $langs -> trans ( 'yes' );
2021-02-23 22:03:23 +01:00
if ( $case == 1 || $case == 3 ) {
$result = $langs -> trans ( " Yes " );
}
if ( $case == 2 ) {
$result = '<input type="checkbox" value="1" checked disabled>' ;
}
if ( $case == 3 ) {
$result = '<input type="checkbox" value="1" checked disabled> ' . $result ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$classname = 'ok' ;
2021-02-23 22:03:23 +01:00
} elseif ( $yesno == 0 || strtolower ( $yesno ) == 'no' || strtolower ( $yesno ) == 'false' ) {
2019-11-11 23:59:36 +01:00
$result = $langs -> trans ( " no " );
2021-02-23 22:03:23 +01:00
if ( $case == 1 || $case == 3 ) {
$result = $langs -> trans ( " No " );
}
if ( $case == 2 ) {
$result = '<input type="checkbox" value="0" disabled>' ;
}
if ( $case == 3 ) {
$result = '<input type="checkbox" value="0" disabled> ' . $result ;
}
2019-03-27 11:05:43 +01:00
2021-02-23 22:03:23 +01:00
if ( $color == 2 ) {
$classname = 'ok' ;
} else {
$classname = 'error' ;
}
}
if ( $color ) {
2021-10-05 09:46:48 +02:00
return '<span class="' . $classname . '">' . $result . '</span>' ;
2019-03-27 11:05:43 +01:00
}
return $result ;
}
2019-02-03 22:58:56 +01:00
/**
* Return a path to have a the directory according to object where files are stored .
2020-12-10 18:13:30 +01:00
* New usage : $conf -> module -> multidir_output [ $object -> entity ] . '/' . get_exdir ( 0 , 0 , 0 , 1 , $object , '' ) . '/'
* or : $conf -> module -> dir_output . '/' . get_exdir ( 0 , 0 , 0 , 0 , $object , '' ) if multidir_output not defined .
* Example out with new usage : $object is invoice -> 'INYYMM-ABCD'
* Example out with old usage : '015' with level 3 -> " 0/1/5/ " , '015' with level 1 -> " 5/ " , 'ABC-1' with level 3 -> " 0/0/1/ "
2019-02-03 22:58:56 +01:00
*
2020-11-18 12:37:18 +01:00
* @ param string | int $num Id of object ( deprecated , $object will be used in future )
* @ param int $level Level of subdirs to return ( 1 , 2 or 3 levels ) . ( deprecated , global option will be used in future )
* @ param int $alpha 0 = Keep number only to forge path , 1 = Use alpha part afer the - ( By default , use 0 ) . ( deprecated , global option will be used in future )
* @ param int $withoutslash 0 = With slash at end ( except if '/' , we return '' ), 1 = without slash at end
* @ param Object $object Object to use to get ref to forge the path .
* @ param string $modulepart Type of object ( 'invoice_supplier, ' donation ', ' invoice ', ...' ) . Use '' for autodetect from $object .
* @ return string Dir to use ending . Example '' or '1/' or '1/2/'
2019-02-03 22:58:56 +01:00
*/
2020-11-18 12:37:18 +01:00
function get_exdir ( $num , $level , $alpha , $withoutslash , $object , $modulepart = '' )
2019-02-03 22:58:56 +01:00
{
global $conf ;
2021-02-23 22:03:23 +01:00
if ( empty ( $modulepart ) && ! empty ( $object -> module )) {
$modulepart = $object -> module ;
}
2020-11-18 12:37:18 +01:00
2019-02-03 22:58:56 +01:00
$path = '' ;
2020-12-10 18:13:30 +01:00
$arrayforoldpath = array ( 'cheque' , 'category' , 'holiday' , 'supplier_invoice' , 'invoice_supplier' , 'mailing' , 'supplier_payment' );
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> PRODUCT_USE_OLD_PATH_FOR_PHOTO )) {
$arrayforoldpath [] = 'product' ;
}
2020-12-10 18:13:30 +01:00
if ( ! empty ( $level ) && in_array ( $modulepart , $arrayforoldpath )) {
2021-01-30 13:57:42 +01:00
// This part should be removed once all code is using "get_exdir" to forge path, with parameter $object and $modulepart provided.
2021-02-23 22:03:23 +01:00
if ( empty ( $alpha )) {
$num = preg_replace ( '/([^0-9])/i' , '' , $num );
} else {
$num = preg_replace ( '/^.*\-/i' , '' , $num );
}
2019-02-03 22:58:56 +01:00
$num = substr ( " 000 " . $num , - $level );
2021-02-23 22:03:23 +01:00
if ( $level == 1 ) {
$path = substr ( $num , 0 , 1 );
}
if ( $level == 2 ) {
$path = substr ( $num , 1 , 1 ) . '/' . substr ( $num , 0 , 1 );
}
if ( $level == 3 ) {
$path = substr ( $num , 2 , 1 ) . '/' . substr ( $num , 1 , 1 ) . '/' . substr ( $num , 0 , 1 );
}
2020-05-21 15:05:19 +02:00
} else {
2020-11-18 12:37:18 +01:00
// We will enhance here a common way of forging path for document storage.
2020-12-17 11:57:12 +01:00
// In a future, we may distribute directories on several levels depending on setup and object.
2020-11-18 12:37:18 +01:00
// Here, $object->id, $object->ref and $modulepart are required.
2019-02-03 22:58:56 +01:00
//var_dump($modulepart);
2020-12-17 11:57:12 +01:00
$path = dol_sanitizeFileName ( empty ( $object -> ref ) ? ( string ) $object -> id : $object -> ref );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $withoutslash ) && ! empty ( $path )) {
$path .= '/' ;
}
2019-02-03 22:58:56 +01:00
return $path ;
}
/**
* Creation of a directory ( this can create recursive subdir )
*
2019-06-04 20:02:29 +02:00
* @ param string $dir Directory to create ( Separator must be '/' . Example : '/mydir/mysubdir' )
* @ param string $dataroot Data root directory ( To avoid having the data root in the loop . Using this will also lost the warning on first dir PHP has no permission when open_basedir is used )
* @ param string | null $newmask Mask for new file ( Defaults to $conf -> global -> MAIN_UMASK or 0755 if unavailable ) . Example : '0444'
* @ return int < 0 if KO , 0 = already exists , > 0 if OK
2019-02-03 22:58:56 +01:00
*/
function dol_mkdir ( $dir , $dataroot = '' , $newmask = null )
{
global $conf ;
dol_syslog ( " functions.lib::dol_mkdir: dir= " . $dir , LOG_INFO );
2019-11-11 23:59:36 +01:00
$dir_osencoded = dol_osencode ( $dir );
2021-02-23 22:03:23 +01:00
if ( @ is_dir ( $dir_osencoded )) {
return 0 ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$nberr = 0 ;
$nbcreated = 0 ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$ccdir = '' ;
if ( ! empty ( $dataroot )) {
2019-02-03 22:58:56 +01:00
// Remove data root from loop
$dir = str_replace ( $dataroot . '/' , '' , $dir );
$ccdir = $dataroot . '/' ;
}
$cdir = explode ( " / " , $dir );
2019-11-11 23:59:36 +01:00
$num = count ( $cdir );
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i < $num ; $i ++ ) {
if ( $i > 0 ) {
$ccdir .= '/' . $cdir [ $i ];
} else {
$ccdir .= $cdir [ $i ];
}
if ( preg_match ( " /^.: $ / " , $ccdir , $regs )) {
continue ; // Si chemin Windows incomplet, on poursuit par rep suivant
}
2019-02-03 22:58:56 +01:00
// Attention, le is_dir() peut echouer bien que le rep existe.
// (ex selon config de open_basedir)
2021-02-23 22:03:23 +01:00
if ( $ccdir ) {
2019-11-11 23:59:36 +01:00
$ccdir_osencoded = dol_osencode ( $ccdir );
2021-02-23 22:03:23 +01:00
if ( !@ is_dir ( $ccdir_osencoded )) {
2019-02-03 22:58:56 +01:00
dol_syslog ( " functions.lib::dol_mkdir: Directory ' " . $ccdir . " ' does not exists or is outside open_basedir PHP setting. " , LOG_DEBUG );
umask ( 0 );
2019-11-11 23:59:36 +01:00
$dirmaskdec = octdec ( $newmask );
2019-02-03 22:58:56 +01:00
if ( empty ( $newmask )) {
2019-02-10 10:45:49 +01:00
$dirmaskdec = empty ( $conf -> global -> MAIN_UMASK ) ? octdec ( '0755' ) : octdec ( $conf -> global -> MAIN_UMASK );
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$dirmaskdec |= octdec ( '0111' ); // Set x bit required for directories
2021-02-23 22:03:23 +01:00
if ( !@ mkdir ( $ccdir_osencoded , $dirmaskdec )) {
2019-02-03 22:58:56 +01:00
// Si le is_dir a renvoye une fausse info, alors on passe ici.
dol_syslog ( " functions.lib::dol_mkdir: Fails to create directory ' " . $ccdir . " ' or directory already exists. " , LOG_WARNING );
$nberr ++ ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
dol_syslog ( " functions.lib::dol_mkdir: Directory ' " . $ccdir . " ' created " , LOG_DEBUG );
2019-11-11 23:59:36 +01:00
$nberr = 0 ; // On remet a zero car si on arrive ici, cela veut dire que les echecs precedents peuvent etre ignore
2019-02-03 22:58:56 +01:00
$nbcreated ++ ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$nberr = 0 ; // On remet a zero car si on arrive ici, cela veut dire que les echecs precedents peuvent etre ignores
2019-02-03 22:58:56 +01:00
}
}
}
return ( $nberr ? - $nberr : $nbcreated );
}
/**
* Return picto saying a field is required
*
* @ return string Chaine avec picto obligatoire
*/
function picto_required ()
{
return '<span class="fieldrequired">*</span>' ;
}
/**
* Clean a string from all HTML tags and entities .
* This function differs from strip_tags because :
* - < br > are replaced with \n if removelinefeed = 0 or 1
* - if entities are found , they are decoded BEFORE the strip
* - you can decide to convert line feed into a space
*
* @ param string $stringtoclean String to clean
* @ param integer $removelinefeed 1 = Replace all new lines by 1 space , 0 = Only ending new lines are removed others are replaced with \n , 2 = Ending new lines are removed but others are kept with a same number of \n than nb of < br > when there is both " ...<br> \n ... "
* @ param string $pagecodeto Encoding of input / output string
2021-01-25 22:46:09 +01:00
* @ param integer $strip_tags 0 = Use internal strip , 1 = Use strip_tags () php function ( bugged when text contains a < char that is not for a html tag or when tags is not closed like '<img onload=aaa' )
2020-10-31 14:51:32 +01:00
* @ param integer $removedoublespaces Replace double space into one space
2019-02-03 22:58:56 +01:00
* @ return string String cleaned
*
2020-08-02 15:53:34 +02:00
* @ see dol_escape_htmltag () strip_tags () dol_string_onlythesehtmltags () dol_string_neverthesehtmltags (), dolStripPhpCode ()
2019-02-03 22:58:56 +01:00
*/
2020-10-31 12:30:47 +01:00
function dol_string_nohtmltag ( $stringtoclean , $removelinefeed = 1 , $pagecodeto = 'UTF-8' , $strip_tags = 0 , $removedoublespaces = 1 )
2019-02-03 22:58:56 +01:00
{
2021-02-23 22:03:23 +01:00
if ( $removelinefeed == 2 ) {
$stringtoclean = preg_replace ( '/<br[^>]*>(\n|\r)+/ims' , '<br>' , $stringtoclean );
}
2019-02-03 22:58:56 +01:00
$temp = preg_replace ( '/<br[^>]*>/i' , " \n " , $stringtoclean );
2020-12-06 17:30:27 +01:00
// We remove entities BEFORE stripping (in case of an open separator char that is entity encoded and not the closing other, the strip will fails)
2020-10-31 14:32:18 +01:00
$temp = dol_html_entity_decode ( $temp , ENT_COMPAT | ENT_HTML5 , $pagecodeto );
2020-09-17 21:09:16 +02:00
2020-12-06 17:30:27 +01:00
$temp = str_replace ( '< ' , '__ltspace__' , $temp );
2019-02-03 22:58:56 +01:00
if ( $strip_tags ) {
$temp = strip_tags ( $temp );
} else {
2021-03-14 15:38:10 +01:00
$temp = str_replace ( '<>' , '' , $temp ); // No reason to have this into a text, except if value is to try bypass the next html cleaning
2019-02-03 22:58:56 +01:00
$pattern = " /<[^<>]+>/ " ;
2020-09-17 21:09:16 +02:00
// Example of $temp: <a href="/myurl" title="<u>A title</u>">0000-021</a>
2021-01-25 22:46:09 +01:00
$temp = preg_replace ( $pattern , " " , $temp ); // pass 1 - $temp after pass 1: <a href="/myurl" title="A title">0000-021
$temp = preg_replace ( $pattern , " " , $temp ); // pass 2 - $temp after pass 2: 0000-021
2021-03-14 15:38:10 +01:00
// Remove '<' into remainging, so remove non closing html tags like '<abc' or '<<abc'. Note: '<123abc' is not a html tag (can be kept), but '<abc123' is (must be removed).
$temp = preg_replace ( '/<+([a-z]+)/i' , '\1' , $temp );
2019-02-03 22:58:56 +01:00
}
$temp = dol_html_entity_decode ( $temp , ENT_COMPAT , $pagecodeto );
2020-10-31 12:55:26 +01:00
// Remove also carriage returns
2021-02-23 22:03:23 +01:00
if ( $removelinefeed == 1 ) {
$temp = str_replace ( array ( " \r \n " , " \r " , " \n " ), " " , $temp );
}
2019-02-03 22:58:56 +01:00
2020-10-31 12:30:47 +01:00
// And double quotes
if ( $removedoublespaces ) {
while ( strpos ( $temp , " " )) {
$temp = str_replace ( " " , " " , $temp );
}
2019-02-03 22:58:56 +01:00
}
2020-12-06 17:30:27 +01:00
$temp = str_replace ( '__ltspace__' , '< ' , $temp );
2019-02-03 22:58:56 +01:00
return trim ( $temp );
}
/**
* Clean a string to keep only desirable HTML tags .
2020-12-06 17:30:27 +01:00
* WARNING : This also clean HTML comments ( used to obfuscate tag name ) .
2019-02-03 22:58:56 +01:00
*
2020-02-09 18:28:34 +01:00
* @ param string $stringtoclean String to clean
2020-10-16 00:06:26 +02:00
* @ param int $cleanalsosomestyles Remove absolute / fixed positioning from inline styles
2021-03-17 21:36:20 +01:00
* @ param int $removeclassattribute 1 = Remove the class attribute from tags
2020-12-06 17:30:27 +01:00
* @ param int $cleanalsojavascript Remove also occurence of 'javascript:' .
2021-03-25 03:44:38 +01:00
* @ param int $allowiframe Allow iframe tags .
2020-02-09 18:28:34 +01:00
* @ return string String cleaned
2019-02-03 22:58:56 +01:00
*
2019-03-11 01:01:15 +01:00
* @ see dol_escape_htmltag () strip_tags () dol_string_nohtmltag () dol_string_neverthesehtmltags ()
2019-02-03 22:58:56 +01:00
*/
2021-03-25 03:44:38 +01:00
function dol_string_onlythesehtmltags ( $stringtoclean , $cleanalsosomestyles = 1 , $removeclassattribute = 1 , $cleanalsojavascript = 0 , $allowiframe = 0 )
2019-02-03 22:58:56 +01:00
{
$allowed_tags = array (
2020-02-17 20:55:17 +01:00
" html " , " head " , " meta " , " body " , " article " , " a " , " abbr " , " b " , " blockquote " , " br " , " cite " , " div " , " dl " , " dd " , " dt " , " em " , " font " , " img " , " ins " , " hr " , " i " , " li " , " link " ,
2022-04-12 14:57:12 +02:00
" ol " , " p " , " q " , " s " , " section " , " span " , " strike " , " strong " , " title " , " table " , " tr " , " th " , " td " , " u " , " ul " , " sup " , " sub " , " blockquote " , " pre " , " h1 " , " h2 " , " h3 " , " h4 " , " h5 " , " h6 " ,
" comment " // this tags is added to manage comment <!--...--> that are replaced into <comment>...</comment>
2019-02-03 22:58:56 +01:00
);
2021-03-25 03:44:38 +01:00
if ( $allowiframe ) {
$allowed_tags [] = " iframe " ;
}
2020-09-18 13:58:09 +02:00
2019-02-03 22:58:56 +01:00
$allowed_tags_string = join ( " >< " , $allowed_tags );
2020-02-09 18:28:34 +01:00
$allowed_tags_string = '<' . $allowed_tags_string . '>' ;
2021-02-23 12:58:43 +01:00
$stringtoclean = str_replace ( '<!DOCTYPE html>' , '__!DOCTYPE_HTML__' , $stringtoclean ); // Replace DOCTYPE to avoid to have it removed by the strip_tags
2020-10-15 19:36:08 +02:00
$stringtoclean = dol_string_nounprintableascii ( $stringtoclean , 0 );
2022-04-12 14:57:12 +02:00
//$stringtoclean = preg_replace('/<!--[^>]*-->/', '', $stringtoclean);
$stringtoclean = preg_replace ( '/<!--([^>]*)-->/' , '<comment>\1</comment>' , $stringtoclean );
2021-03-14 18:57:18 +01:00
$stringtoclean = preg_replace ( '/:/i' , ':' , $stringtoclean );
$stringtoclean = preg_replace ( '/:|�+58|:/i' , '' , $stringtoclean ); // refused string ':' encoded (no reason to have a : encoded like this) to disable 'javascript:...'
2020-12-06 17:30:27 +01:00
$stringtoclean = preg_replace ( '/javascript\s*:/i' , '' , $stringtoclean );
2021-07-06 00:47:43 +02:00
$temp = strip_tags ( $stringtoclean , $allowed_tags_string ); // Warning: This remove also undesired </> changing string obfuscated with </> that pass injection detection into harmfull string
2020-10-15 19:36:08 +02:00
if ( $cleanalsosomestyles ) { // Clean for remaining html tags
2020-12-06 17:30:27 +01:00
$temp = preg_replace ( '/position\s*:\s*(absolute|fixed)\s*!\s*important/i' , '' , $temp ); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless
2020-08-03 12:28:12 +02:00
}
2020-10-15 19:36:08 +02:00
if ( $removeclassattribute ) { // Clean for remaining html tags
2020-12-06 17:30:27 +01:00
$temp = preg_replace ( '/(<[^>]+)\s+class=((["\']).*?\\3|\\w*)/i' , '\\1' , $temp );
2020-02-09 18:28:34 +01:00
}
2019-02-03 22:58:56 +01:00
2020-10-15 19:36:08 +02:00
// Remove 'javascript:' that we should not find into a text with
2021-03-14 18:57:18 +01:00
// Warning: This is not reliable to fight against obfuscated javascript, there is a lot of other solution to include js into a common html tag (only filtered by a GETPOST(.., powerfullfilter)).
2020-10-15 19:36:08 +02:00
if ( $cleanalsojavascript ) {
$temp = preg_replace ( '/javascript\s*:/i' , '' , $temp );
}
2019-02-03 22:58:56 +01:00
2021-02-23 12:58:43 +01:00
$temp = str_replace ( '__!DOCTYPE_HTML__' , '<!DOCTYPE html>' , $temp ); // Restore the DOCTYPE
2022-04-12 14:57:12 +02:00
$temp = preg_replace ( '/<comment>([^>]*)<\/comment>/' , '<!--\1-->' , $temp ); // Restore html comments
2019-02-03 22:58:56 +01:00
return $temp ;
}
2021-03-17 21:36:20 +01:00
/**
* Clean a string from some undesirable HTML tags .
2021-12-17 12:01:25 +01:00
* Note : Complementary to dol_string_onlythesehtmltags () .
* This method is used for example when option MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES is set to 1.
2021-03-17 21:36:20 +01:00
*
* @ param string $stringtoclean String to clean
* @ param array $allowed_attributes Array of tags not allowed
* @ return string String cleaned
*
* @ see dol_escape_htmltag () strip_tags () dol_string_nohtmltag () dol_string_onlythesehtmltags () dol_string_neverthesehtmltags ()
*/
2021-03-25 03:44:38 +01:00
function dol_string_onlythesehtmlattributes ( $stringtoclean , $allowed_attributes = array ( " allow " , " allowfullscreen " , " alt " , " class " , " contenteditable " , " data-html " , " frameborder " , " height " , " href " , " id " , " name " , " src " , " style " , " target " , " title " , " width " ))
2021-03-17 21:36:20 +01:00
{
2021-03-21 18:01:43 +01:00
if ( class_exists ( 'DOMDocument' ) && ! empty ( $stringtoclean )) {
2021-12-17 12:01:25 +01:00
$stringtoclean = '<?xml encoding="UTF-8"><html><body>' . $stringtoclean . '</body></html>' ;
2021-03-25 00:03:31 +01:00
2021-12-17 12:01:25 +01:00
$dom = new DOMDocument ( null , 'UTF-8' );
2021-03-17 21:36:20 +01:00
$dom -> loadHTML ( $stringtoclean , LIBXML_ERR_NONE | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NONET | LIBXML_NOWARNING | LIBXML_NOXMLDECL );
2021-12-17 12:01:25 +01:00
2021-03-17 21:36:20 +01:00
if ( is_object ( $dom )) {
for ( $els = $dom -> getElementsByTagname ( '*' ), $i = $els -> length - 1 ; $i >= 0 ; $i -- ) {
for ( $attrs = $els -> item ( $i ) -> attributes , $ii = $attrs -> length - 1 ; $ii >= 0 ; $ii -- ) {
2021-11-28 12:01:42 +01:00
//var_dump($attrs->item($ii));
if ( ! empty ( $attrs -> item ( $ii ) -> name )) {
// Delete attribute if not into allowed_attributes
if ( ! in_array ( $attrs -> item ( $ii ) -> name , $allowed_attributes )) {
$els -> item ( $i ) -> removeAttribute ( $attrs -> item ( $ii ) -> name );
} elseif ( in_array ( $attrs -> item ( $ii ) -> name , array ( 'style' ))) {
$valuetoclean = $attrs -> item ( $ii ) -> value ;
2022-02-24 12:37:20 +01:00
if ( isset ( $valuetoclean )) {
do {
$oldvaluetoclean = $valuetoclean ;
$valuetoclean = preg_replace ( '/\/\*.*\*\//m' , '' , $valuetoclean ); // clean css comments
$valuetoclean = preg_replace ( '/position\s*:\s*[a-z]+/mi' , '' , $valuetoclean );
if ( $els -> item ( $i ) -> tagName == 'a' ) { // more paranoiac cleaning for clickable tags.
$valuetoclean = preg_replace ( '/display\s*://m' , '' , $valuetoclean );
$valuetoclean = preg_replace ( '/z-index\s*://m' , '' , $valuetoclean );
$valuetoclean = preg_replace ( '/\s+(top|left|right|bottom)\s*://m' , '' , $valuetoclean );
}
} while ( $oldvaluetoclean != $valuetoclean );
}
2021-11-28 12:01:42 +01:00
$attrs -> item ( $ii ) -> value = $valuetoclean ;
}
2021-03-17 21:36:20 +01:00
}
}
}
}
2021-03-25 00:03:09 +01:00
$return = $dom -> saveHTML ();
//$return = '<html><body>aaaa</p>bb<p>ssdd</p>'."\n<p>aaa</p>aa<p>bb</p>";
2021-07-06 00:47:43 +02:00
2021-12-17 12:01:25 +01:00
$return = preg_replace ( '/^' . preg_quote ( '<?xml encoding="UTF-8">' , '/' ) . '/' , '' , $return );
$return = preg_replace ( '/^' . preg_quote ( '<html><body>' , '/' ) . '/' , '' , $return );
$return = preg_replace ( '/' . preg_quote ( '</body></html>' , '/' ) . '$/' , '' , $return );
return trim ( $return );
2021-03-17 21:36:20 +01:00
} else {
return $stringtoclean ;
}
}
2019-02-03 22:58:56 +01:00
/**
* Clean a string from some undesirable HTML tags .
2020-10-15 19:36:08 +02:00
* Note . Not as secured as dol_string_onlythesehtmltags () .
2019-02-03 22:58:56 +01:00
*
2020-02-09 18:28:34 +01:00
* @ param string $stringtoclean String to clean
* @ param array $disallowed_tags Array of tags not allowed
* @ param string $cleanalsosomestyles Clean also some tags
* @ return string String cleaned
2019-02-03 22:58:56 +01:00
*
2021-03-17 21:36:20 +01:00
* @ see dol_escape_htmltag () strip_tags () dol_string_nohtmltag () dol_string_onlythesehtmltags () dol_string_onlythesehtmlattributes ()
2019-02-03 22:58:56 +01:00
*/
2020-02-09 18:28:34 +01:00
function dol_string_neverthesehtmltags ( $stringtoclean , $disallowed_tags = array ( 'textarea' ), $cleanalsosomestyles = 0 )
2019-02-03 22:58:56 +01:00
{
$temp = $stringtoclean ;
2021-02-23 22:03:23 +01:00
foreach ( $disallowed_tags as $tagtoremove ) {
2019-02-03 22:58:56 +01:00
$temp = preg_replace ( '/<\/?' . $tagtoremove . '>/' , '' , $temp );
$temp = preg_replace ( '/<\/?' . $tagtoremove . '\s+[^>]*>/' , '' , $temp );
}
2020-02-09 18:28:34 +01:00
if ( $cleanalsosomestyles ) {
2020-02-13 10:44:08 +01:00
$temp = preg_replace ( '/position\s*:\s*(absolute|fixed)\s*!\s*important/' , '' , $temp ); // Note: If hacker try to introduce css comment into string to avoid this, string should be encoded by the dol_htmlentitiesbr so be harmless
2020-02-09 18:28:34 +01:00
}
2019-02-03 22:58:56 +01:00
return $temp ;
}
/**
* Return first line of text . Cut will depends if content is HTML or not .
*
* @ param string $text Input text
* @ param int $nboflines Nb of lines to get ( default is 1 = first line only )
2019-03-11 01:01:15 +01:00
* @ param string $charset Charset of $text string ( UTF - 8 by default )
2019-02-03 22:58:56 +01:00
* @ return string Output text
2019-03-11 01:01:15 +01:00
* @ see dol_nboflines_bis (), dol_string_nohtmltag (), dol_escape_htmltag ()
2019-02-03 22:58:56 +01:00
*/
2019-03-11 01:01:15 +01:00
function dolGetFirstLineOfText ( $text , $nboflines = 1 , $charset = 'UTF-8' )
2019-02-03 22:58:56 +01:00
{
2021-02-23 22:03:23 +01:00
if ( $nboflines == 1 ) {
if ( dol_textishtml ( $text )) {
2019-11-11 23:59:36 +01:00
$firstline = preg_replace ( '/<br[^>]*>.*$/s' , '' , $text ); // The s pattern modifier means the . can match newline characters
$firstline = preg_replace ( '/<div[^>]*>.*$/s' , '' , $firstline ); // The s pattern modifier means the . can match newline characters
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$firstline = preg_replace ( '/[\n\r].*/' , '' , $text );
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
return $firstline . (( strlen ( $firstline ) != strlen ( $text )) ? '...' : '' );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$ishtml = 0 ;
2021-02-23 22:03:23 +01:00
if ( dol_textishtml ( $text )) {
2019-11-11 23:59:36 +01:00
$text = preg_replace ( '/\n/' , '' , $text );
$ishtml = 1 ;
2019-02-03 22:58:56 +01:00
$repTable = array ( " \t " => " " , " \n " => " " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
$repTable = array ( " \t " => " " , " \n " => " <br> " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
}
$text = strtr ( $text , $repTable );
2021-02-23 22:03:23 +01:00
if ( $charset == 'UTF-8' ) {
$pattern = '/(<br[^>]*>)/Uu' ;
2021-03-01 20:37:16 +01:00
} else {
// /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support
2021-02-23 22:03:23 +01:00
$pattern = '/(<br[^>]*>)/U' ; // /U is to have UNGREEDY regex to limit to one html tag.
}
2019-02-03 22:58:56 +01:00
$a = preg_split ( $pattern , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
2019-11-11 23:59:36 +01:00
$firstline = '' ;
$i = 0 ;
$nba = count ( $a ); // 2x nb of lines in $a because $a contains also a line for each new line separator
2021-02-23 22:03:23 +01:00
while (( $i < $nba ) && ( $i < ( $nboflines * 2 ))) {
if ( $i % 2 == 0 ) {
$firstline .= $a [ $i ];
} elseif (( $i < (( $nboflines * 2 ) - 1 )) && ( $i < ( $nba - 1 ))) {
$firstline .= ( $ishtml ? " <br> \n " : " \n " );
}
2019-02-03 22:58:56 +01:00
$i ++ ;
}
unset ( $a );
2019-11-11 23:59:36 +01:00
return $firstline . (( $i < $nba ) ? '...' : '' );
2019-02-03 22:58:56 +01:00
}
}
/**
2020-05-14 14:10:04 +02:00
* Replace CRLF in string with a HTML BR tag .
* WARNING : The content after operation contains some HTML tags ( the < br > ) so be sure to also have encode the special chars of stringtoencode into HTML before .
2019-02-03 22:58:56 +01:00
*
* @ param string $stringtoencode String to encode
* @ param int $nl2brmode 0 = Adding br before \n , 1 = Replacing \n by br
* @ param bool $forxml false = Use < br > , true = Use < br />
* @ return string String encoded
2019-03-11 01:01:15 +01:00
* @ see dol_nboflines (), dolGetFirstLineOfText ()
2019-02-03 22:58:56 +01:00
*/
function dol_nl2br ( $stringtoencode , $nl2brmode = 0 , $forxml = false )
{
if ( ! $nl2brmode ) {
return nl2br ( $stringtoencode , $forxml );
} else {
2019-11-11 23:59:36 +01:00
$ret = preg_replace ( '/(\r\n|\r|\n)/i' , ( $forxml ? '<br />' : '<br>' ), $stringtoencode );
2019-02-03 22:58:56 +01:00
return $ret ;
}
}
/**
* This function is called to encode a string into a HTML string but differs from htmlentities because
2019-08-30 16:22:24 +02:00
* a detection is done before to see if text is already HTML or not . Also , all entities but & , < , > , " are converted.
2019-02-03 22:58:56 +01:00
* This permits to encode special chars to entities with no double encoding for already encoded HTML strings .
* This function also remove last EOL or BR if $removelasteolbr = 1 ( default ) .
* For PDF usage , you can show text by 2 ways :
* - writeHTMLCell -> param must be encoded into HTML .
* - MultiCell -> param must not be encoded into HTML .
* Because writeHTMLCell convert also \n into < br > , if function
* is used to build PDF , nl2brmode must be 1.
*
* @ param string $stringtoencode String to encode
* @ param int $nl2brmode 0 = Adding br before \n , 1 = Replacing \n by br ( for use with FPDF writeHTMLCell function for example )
* @ param string $pagecodefrom Pagecode stringtoencode is encoded
* @ param int $removelasteolbr 1 = Remove last br or lasts \n ( default ), 0 = Do nothing
* @ return string String encoded
*/
function dol_htmlentitiesbr ( $stringtoencode , $nl2brmode = 0 , $pagecodefrom = 'UTF-8' , $removelasteolbr = 1 )
{
2019-11-11 23:59:36 +01:00
$newstring = $stringtoencode ;
2021-02-23 22:03:23 +01:00
if ( dol_textishtml ( $stringtoencode )) { // Check if text is already HTML or not
2019-11-11 23:59:36 +01:00
$newstring = preg_replace ( '/<br(\s[\sa-zA-Z_="]*)?\/?>/i' , '<br>' , $newstring ); // Replace "<br type="_moz" />" by "<br>". It's same and avoid pb with FPDF.
2021-02-23 22:03:23 +01:00
if ( $removelasteolbr ) {
$newstring = preg_replace ( '/<br>$/i' , '' , $newstring ); // Remove last <br> (remove only last one)
}
2019-11-11 23:59:36 +01:00
$newstring = strtr ( $newstring , array ( '&' => '__and__' , '<' => '__lt__' , '>' => '__gt__' , '"' => '__dquot__' ));
$newstring = dol_htmlentities ( $newstring , ENT_COMPAT , $pagecodefrom ); // Make entity encoding
$newstring = strtr ( $newstring , array ( '__and__' => '&' , '__lt__' => '<' , '__gt__' => '>' , '__dquot__' => '"' ));
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $removelasteolbr ) {
$newstring = preg_replace ( '/(\r\n|\r|\n)$/i' , '' , $newstring ); // Remove last \n (may remove several)
}
2019-11-11 23:59:36 +01:00
$newstring = dol_nl2br ( dol_htmlentities ( $newstring , ENT_COMPAT , $pagecodefrom ), $nl2brmode );
2019-02-03 22:58:56 +01:00
}
// Other substitutions that htmlentities does not do
//$newstring=str_replace(chr(128),'€',$newstring); // 128 = 0x80. Not in html entity table. // Seems useles with TCPDF. Make bug with UTF8 languages
return $newstring ;
}
/**
* This function is called to decode a HTML string ( it decodes entities and br tags )
*
* @ param string $stringtodecode String to decode
* @ param string $pagecodeto Page code for result
* @ return string String decoded
*/
function dol_htmlentitiesbr_decode ( $stringtodecode , $pagecodeto = 'UTF-8' )
{
2020-10-31 14:32:18 +01:00
$ret = dol_html_entity_decode ( $stringtodecode , ENT_COMPAT | ENT_HTML5 , $pagecodeto );
2019-11-11 23:59:36 +01:00
$ret = preg_replace ( '/' . " \r \n " . '<br(\s[\sa-zA-Z_="]*)?\/?>/i' , " <br> " , $ret );
$ret = preg_replace ( '/<br(\s[\sa-zA-Z_="]*)?\/?>' . " \r \n " . '/i' , " \r \n " , $ret );
$ret = preg_replace ( '/<br(\s[\sa-zA-Z_="]*)?\/?>' . " \n " . '/i' , " \n " , $ret );
$ret = preg_replace ( '/<br(\s[\sa-zA-Z_="]*)?\/?>/i' , " \n " , $ret );
2019-02-03 22:58:56 +01:00
return $ret ;
}
/**
* This function remove all ending \n and br at end
*
* @ param string $stringtodecode String to decode
* @ return string String decoded
*/
function dol_htmlcleanlastbr ( $stringtodecode )
{
2021-10-19 21:48:25 +02:00
$ret = preg_replace ( '/ $/i' , " " , $stringtodecode ); // Because wysiwyg editor may add a at end of last line
$ret = preg_replace ( '/(<br>|<br(\s[\sa-zA-Z_="]*)?\/?>|' . " \n " . '|' . " \r " . ')+$/i' , " " , $ret );
2019-02-03 22:58:56 +01:00
return $ret ;
}
/**
* Replace html_entity_decode functions to manage errors
*
2020-01-18 19:53:48 +01:00
* @ param string $a Operand a
2020-10-15 19:36:08 +02:00
* @ param string $b Operand b ( ENT_QUOTES | ENT_HTML5 = convert simple , double quotes , colon , e accent , ... )
2020-01-18 19:53:48 +01:00
* @ param string $c Operand c
2020-09-17 14:43:58 +02:00
* @ param string $keepsomeentities Entities but & , < , > , " are not converted.
2020-01-18 19:53:48 +01:00
* @ return string String decoded
2019-02-03 22:58:56 +01:00
*/
2020-01-18 19:53:48 +01:00
function dol_html_entity_decode ( $a , $b , $c = 'UTF-8' , $keepsomeentities = 0 )
2019-02-03 22:58:56 +01:00
{
2020-01-18 19:53:48 +01:00
$newstring = $a ;
2021-02-23 22:03:23 +01:00
if ( $keepsomeentities ) {
$newstring = strtr ( $newstring , array ( '&' => '__andamp__' , '<' => '__andlt__' , '>' => '__andgt__' , '"' => '__dquot__' ));
}
2020-01-18 19:53:48 +01:00
$newstring = html_entity_decode ( $newstring , $b , $c );
2021-02-23 22:03:23 +01:00
if ( $keepsomeentities ) {
$newstring = strtr ( $newstring , array ( '__andamp__' => '&' , '__andlt__' => '<' , '__andgt__' => '>' , '__dquot__' => '"' ));
}
2020-01-18 19:53:48 +01:00
return $newstring ;
2019-02-03 22:58:56 +01:00
}
/**
* Replace htmlentities functions .
* Goal of this function is to be sure to have default values of htmlentities that match what we need .
*
* @ param string $string The input string to encode
* @ param int $flags Flags ( see PHP doc above )
* @ param string $encoding Encoding page code
* @ param bool $double_encode When double_encode is turned off , PHP will not encode existing html entities
* @ return string $ret Encoded string
*/
2021-10-27 16:39:34 +02:00
function dol_htmlentities ( $string , $flags = ENT_QUOTES | ENT_SUBSTITUTE , $encoding = 'UTF-8' , $double_encode = false )
2019-02-03 22:58:56 +01:00
{
return htmlentities ( $string , $flags , $encoding , $double_encode );
}
/**
* Check if a string is a correct iso string
* If not , it will we considered not HTML encoded even if it is by FPDF .
* Example , if string contains euro symbol that has ascii code 128
*
2019-08-29 13:17:14 +02:00
* @ param string $s String to check
* @ param string $clean Clean if it is not an ISO . Warning , if file is utf8 , you will get a bad formated file .
* @ return int | string 0 if bad iso , 1 if good iso , Or the clean string if $clean is 1
2019-02-03 22:58:56 +01:00
*/
2019-08-29 13:17:14 +02:00
function dol_string_is_good_iso ( $s , $clean = 0 )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$len = dol_strlen ( $s );
$out = '' ;
$ok = 1 ;
2021-02-23 22:03:23 +01:00
for ( $scursor = 0 ; $scursor < $len ; $scursor ++ ) {
2019-11-11 23:59:36 +01:00
$ordchar = ord ( $s [ $scursor ]);
2019-02-03 22:58:56 +01:00
//print $scursor.'-'.$ordchar.'<br>';
2021-02-23 22:03:23 +01:00
if ( $ordchar < 32 && $ordchar != 13 && $ordchar != 10 ) {
2021-03-01 20:37:16 +01:00
$ok = 0 ;
break ;
2021-02-23 22:03:23 +01:00
} elseif ( $ordchar > 126 && $ordchar < 160 ) {
2021-03-01 20:37:16 +01:00
$ok = 0 ;
break ;
2021-02-23 22:03:23 +01:00
} elseif ( $clean ) {
2019-11-11 23:59:36 +01:00
$out .= $s [ $scursor ];
2019-08-29 13:17:14 +02:00
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $clean ) {
return $out ;
}
2019-02-03 22:58:56 +01:00
return $ok ;
}
/**
* Return nb of lines of a clear text
*
* @ param string $s String to check
* @ param int $maxchar Not yet used
* @ return int Number of lines
2019-03-11 01:01:15 +01:00
* @ see dol_nboflines_bis (), dolGetFirstLineOfText ()
2019-02-03 22:58:56 +01:00
*/
function dol_nboflines ( $s , $maxchar = 0 )
{
2021-02-23 22:03:23 +01:00
if ( $s == '' ) {
return 0 ;
}
2019-11-11 23:59:36 +01:00
$arraystring = explode ( " \n " , $s );
$nb = count ( $arraystring );
2019-02-03 22:58:56 +01:00
return $nb ;
}
/**
* Return nb of lines of a formated text with \n and < br > ( WARNING : string must not have mixed \n and br separators )
*
* @ param string $text Text
* @ param int $maxlinesize Largeur de ligne en caracteres ( ou 0 si pas de limite - defaut )
* @ param string $charset Give the charset used to encode the $text variable in memory .
* @ return int Number of lines
2019-03-11 01:01:15 +01:00
* @ see dol_nboflines (), dolGetFirstLineOfText ()
2019-02-03 22:58:56 +01:00
*/
function dol_nboflines_bis ( $text , $maxlinesize = 0 , $charset = 'UTF-8' )
{
$repTable = array ( " \t " => " " , " \n " => " <br> " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
2021-02-23 22:03:23 +01:00
if ( dol_textishtml ( $text )) {
$repTable = array ( " \t " => " " , " \n " => " " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
}
2019-02-03 22:58:56 +01:00
$text = strtr ( $text , $repTable );
2021-02-23 22:03:23 +01:00
if ( $charset == 'UTF-8' ) {
$pattern = '/(<br[^>]*>)/Uu' ;
2021-03-01 20:37:16 +01:00
} else {
// /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support
2021-02-23 22:03:23 +01:00
$pattern = '/(<br[^>]*>)/U' ; // /U is to have UNGREEDY regex to limit to one html tag.
}
2019-02-03 22:58:56 +01:00
$a = preg_split ( $pattern , $text , - 1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
2019-11-11 23:59:36 +01:00
$nblines = ( int ) floor (( count ( $a ) + 1 ) / 2 );
2019-02-03 22:58:56 +01:00
// count possible auto line breaks
2021-02-23 22:03:23 +01:00
if ( $maxlinesize ) {
foreach ( $a as $line ) {
if ( dol_strlen ( $line ) > $maxlinesize ) {
2019-02-03 22:58:56 +01:00
//$line_dec = html_entity_decode(strip_tags($line));
$line_dec = html_entity_decode ( $line );
2021-02-23 22:03:23 +01:00
if ( dol_strlen ( $line_dec ) > $maxlinesize ) {
2019-11-11 23:59:36 +01:00
$line_dec = wordwrap ( $line_dec , $maxlinesize , '\n' , true );
$nblines += substr_count ( $line_dec , '\n' );
2019-02-03 22:58:56 +01:00
}
}
}
}
unset ( $a );
return $nblines ;
}
/**
* Return if a text is a html content
*
* @ param string $msg Content to check
* @ param int $option 0 = Full detection , 1 = Fast check
* @ return boolean true / false
2019-03-11 01:01:15 +01:00
* @ see dol_concatdesc ()
2019-02-03 22:58:56 +01:00
*/
function dol_textishtml ( $msg , $option = 0 )
{
2021-02-23 22:03:23 +01:00
if ( $option == 1 ) {
if ( preg_match ( '/<html/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<body/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<\/textarea/i' , $msg )) {
return true ;
2021-05-04 13:33:18 +02:00
} elseif ( preg_match ( '/<(b|em|i|u)>/i' , $msg )) {
return true ;
2021-02-23 22:03:23 +01:00
} elseif ( preg_match ( '/<br/i' , $msg )) {
return true ;
}
2019-02-03 22:58:56 +01:00
return false ;
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/<html/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<body/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<\/textarea/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<(b|em|i|u)>/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<br\/>/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/<(br|div|font|li|p|span|strong|table)>/i' , $msg )) {
return true ;
2021-05-04 13:33:18 +02:00
} elseif ( preg_match ( '/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/?>/i' , $msg )) {
2021-02-23 22:03:23 +01:00
return true ;
} elseif ( preg_match ( '/<img\s+[^<>]*src[^<>]*>/i' , $msg )) {
return true ; // must accept <img src="http://example.com/aaa.png" />
} elseif ( preg_match ( '/<a\s+[^<>]*href[^<>]*>/i' , $msg )) {
return true ; // must accept <a href="http://example.com/aaa.png" />
} elseif ( preg_match ( '/<h[0-9]>/i' , $msg )) {
return true ;
} elseif ( preg_match ( '/&[A-Z0-9]{1,6};/i' , $msg )) {
return true ; // Html entities names (http://www.w3schools.com/tags/ref_entities.asp)
} elseif ( preg_match ( '/&#[0-9]{2,3};/i' , $msg )) {
return true ; // Html entities numbers (http://www.w3schools.com/tags/ref_entities.asp)
}
2019-02-03 22:58:56 +01:00
return false ;
}
}
/**
* Concat 2 descriptions with a new line between them ( second operand after first one with appropriate new line separator )
* text1 html + text2 html => text1 + '<br>' + text2
* text1 html + text2 txt => text1 + '<br>' + dol_nl2br ( text2 )
* text1 txt + text2 html => dol_nl2br ( text1 ) + '<br>' + text2
* text1 txt + text2 txt => text1 + '\n' + text2
*
* @ param string $text1 Text 1
* @ param string $text2 Text 2
2020-05-14 14:10:04 +02:00
* @ param bool $forxml true = Use < br /> instead of < br > if we have to add a br tag
2019-03-22 13:00:48 +01:00
* @ param bool $invert invert order of description lines ( we often use config MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION in this parameter )
2019-02-03 22:58:56 +01:00
* @ return string Text 1 + new line + Text2
2019-03-11 01:01:15 +01:00
* @ see dol_textishtml ()
2019-02-03 22:58:56 +01:00
*/
function dol_concatdesc ( $text1 , $text2 , $forxml = false , $invert = false )
{
2021-02-23 22:03:23 +01:00
if ( ! empty ( $invert )) {
2020-09-07 10:18:17 +02:00
$tmp = $text1 ;
$text1 = $text2 ;
$text2 = $tmp ;
}
2019-02-03 22:58:56 +01:00
2020-09-07 10:18:17 +02:00
$ret = '' ;
$ret .= ( ! dol_textishtml ( $text1 ) && dol_textishtml ( $text2 )) ? dol_nl2br ( dol_escape_htmltag ( $text1 , 0 , 1 , '' , 1 ), 0 , $forxml ) : $text1 ;
$ret .= ( ! empty ( $text1 ) && ! empty ( $text2 )) ? (( dol_textishtml ( $text1 ) || dol_textishtml ( $text2 )) ? ( $forxml ? " <br \ > \n " : " <br> \n " ) : " \n " ) : " " ;
$ret .= ( dol_textishtml ( $text1 ) && ! dol_textishtml ( $text2 )) ? dol_nl2br ( dol_escape_htmltag ( $text2 , 0 , 1 , '' , 1 ), 0 , $forxml ) : $text2 ;
return $ret ;
2019-02-03 22:58:56 +01:00
}
/**
* Return array of possible common substitutions . This includes several families like : 'system' , 'mycompany' , 'object' , 'objectamount' , 'date' , 'user'
*
* @ param Translate $outputlangs Output language
* @ param int $onlykey 1 = Do not calculate some heavy values of keys ( performance enhancement when we need only the keys ), 2 = Values are trunc and html sanitized ( to use for help tooltip )
* @ param array $exclude Array of family keys we want to exclude . For example array ( 'system' , 'mycompany' , 'object' , 'objectamount' , 'date' , 'user' , ... )
* @ param Object $object Object for keys on object
* @ return array Array of substitutions
2019-03-11 01:01:15 +01:00
* @ see setSubstitFromObject ()
2019-02-03 22:58:56 +01:00
*/
function getCommonSubstitutionArray ( $outputlangs , $onlykey = 0 , $exclude = null , $object = null )
{
global $db , $conf , $mysoc , $user , $extrafields ;
2019-11-11 23:59:36 +01:00
$substitutionarray = array ();
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( empty ( $exclude ) || ! in_array ( 'user' , $exclude )) {
2019-02-03 22:58:56 +01:00
// Add SIGNATURE into substitutionarray first, so, when we will make the substitution,
// this will include signature content first and then replace var found into content of signature
$signature = $user -> signature ;
2020-09-08 21:27:28 +02:00
$substitutionarray = array_merge ( $substitutionarray , array (
2020-09-06 19:25:25 +02:00
'__USER_SIGNATURE__' => ( string ) (( $signature && empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN )) ? ( $onlykey == 2 ? dol_trunc ( dol_string_nohtmltag ( $signature ), 30 ) : $signature ) : '' )
2021-02-23 22:03:23 +01:00
));
2019-02-03 22:58:56 +01:00
2021-02-19 15:06:36 +01:00
if ( is_object ( $user )) {
$substitutionarray = array_merge ( $substitutionarray , array (
'__USER_ID__' => ( string ) $user -> id ,
'__USER_LOGIN__' => ( string ) $user -> login ,
'__USER_EMAIL__' => ( string ) $user -> email ,
2022-01-20 13:49:23 +01:00
'__USER_PHONE__' => ( string ) dol_print_phone ( $user -> office_phone ),
'__USER_PHONEPRO__' => ( string ) dol_print_phone ( $user -> user_mobile ),
'__USER_PHONEMOBILE__' => ( string ) dol_print_phone ( $user -> personal_mobile ),
2022-01-19 10:51:31 +01:00
'__USER_FAX__' => ( string ) $user -> office_fax ,
2021-02-19 15:06:36 +01:00
'__USER_LASTNAME__' => ( string ) $user -> lastname ,
'__USER_FIRSTNAME__' => ( string ) $user -> firstname ,
'__USER_FULLNAME__' => ( string ) $user -> getFullName ( $outputlangs ),
'__USER_SUPERVISOR_ID__' => ( string ) ( $user -> fk_user ? $user -> fk_user : '0' ),
2022-01-23 16:36:47 +01:00
'__USER_JOB__' => ( string ) $user -> job ,
2021-02-19 15:06:36 +01:00
'__USER_REMOTE_IP__' => ( string ) getUserRemoteIP ()
2021-02-23 22:03:23 +01:00
));
2021-02-19 15:06:36 +01:00
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if (( empty ( $exclude ) || ! in_array ( 'mycompany' , $exclude )) && is_object ( $mysoc )) {
2020-09-07 10:18:17 +02:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__MYCOMPANY_NAME__' => $mysoc -> name ,
'__MYCOMPANY_EMAIL__' => $mysoc -> email ,
2022-01-20 13:45:51 +01:00
'__MYCOMPANY_PHONE__' => dol_print_phone ( $mysoc -> phone ),
'__MYCOMPANY_FAX__' => dol_print_phone ( $mysoc -> fax ),
2019-02-03 22:58:56 +01:00
'__MYCOMPANY_PROFID1__' => $mysoc -> idprof1 ,
'__MYCOMPANY_PROFID2__' => $mysoc -> idprof2 ,
'__MYCOMPANY_PROFID3__' => $mysoc -> idprof3 ,
'__MYCOMPANY_PROFID4__' => $mysoc -> idprof4 ,
'__MYCOMPANY_PROFID5__' => $mysoc -> idprof5 ,
'__MYCOMPANY_PROFID6__' => $mysoc -> idprof6 ,
'__MYCOMPANY_CAPITAL__' => $mysoc -> capital ,
2021-02-19 15:06:36 +01:00
'__MYCOMPANY_FULLADDRESS__' => ( method_exists ( $mysoc , 'getFullAddress' ) ? $mysoc -> getFullAddress ( 1 , ', ' ) : '' ), // $mysoc may be stdClass
2019-02-03 22:58:56 +01:00
'__MYCOMPANY_ADDRESS__' => $mysoc -> address ,
'__MYCOMPANY_ZIP__' => $mysoc -> zip ,
'__MYCOMPANY_TOWN__' => $mysoc -> town ,
'__MYCOMPANY_COUNTRY__' => $mysoc -> country ,
'__MYCOMPANY_COUNTRY_ID__' => $mysoc -> country_id ,
2020-09-07 10:18:17 +02:00
'__MYCOMPANY_COUNTRY_CODE__' => $mysoc -> country_code ,
'__MYCOMPANY_CURRENCY_CODE__' => $conf -> currency
2019-02-03 22:58:56 +01:00
));
}
2021-02-23 22:03:23 +01:00
if (( $onlykey || is_object ( $object )) && ( empty ( $exclude ) || ! in_array ( 'object' , $exclude ))) {
if ( $onlykey ) {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__ID__' ] = '__ID__' ;
$substitutionarray [ '__REF__' ] = '__REF__' ;
2021-08-12 15:05:00 +02:00
$substitutionarray [ '__NEWREF__' ] = '__NEWREF__' ;
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__REF_CLIENT__' ] = '__REF_CLIENT__' ;
$substitutionarray [ '__REF_SUPPLIER__' ] = '__REF_SUPPLIER__' ;
2019-10-22 14:39:33 +02:00
$substitutionarray [ '__NOTE_PUBLIC__' ] = '__NOTE_PUBLIC__' ;
$substitutionarray [ '__NOTE_PRIVATE__' ] = '__NOTE_PRIVATE__' ;
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__EXTRAFIELD_XXX__' ] = '__EXTRAFIELD_XXX__' ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> societe -> enabled )) { // Most objects are concerned
2019-09-23 13:04:22 +02:00
$substitutionarray [ '__THIRDPARTY_ID__' ] = '__THIRDPARTY_ID__' ;
$substitutionarray [ '__THIRDPARTY_NAME__' ] = '__THIRDPARTY_NAME__' ;
$substitutionarray [ '__THIRDPARTY_NAME_ALIAS__' ] = '__THIRDPARTY_NAME_ALIAS__' ;
2019-10-21 21:06:48 +02:00
$substitutionarray [ '__THIRDPARTY_CODE_CLIENT__' ] = '__THIRDPARTY_CODE_CLIENT__' ;
$substitutionarray [ '__THIRDPARTY_CODE_FOURNISSEUR__' ] = '__THIRDPARTY_CODE_FOURNISSEUR__' ;
2019-09-23 13:04:22 +02:00
$substitutionarray [ '__THIRDPARTY_EMAIL__' ] = '__THIRDPARTY_EMAIL__' ;
2019-10-21 21:06:48 +02:00
$substitutionarray [ '__THIRDPARTY_PHONE__' ] = '__THIRDPARTY_PHONE__' ;
$substitutionarray [ '__THIRDPARTY_FAX__' ] = '__THIRDPARTY_FAX__' ;
2019-11-08 16:34:20 +01:00
$substitutionarray [ '__THIRDPARTY_ADDRESS__' ] = '__THIRDPARTY_ADDRESS__' ;
2019-10-21 21:06:48 +02:00
$substitutionarray [ '__THIRDPARTY_ZIP__' ] = '__THIRDPARTY_ZIP__' ;
$substitutionarray [ '__THIRDPARTY_TOWN__' ] = '__THIRDPARTY_TOWN__' ;
2019-11-08 16:34:20 +01:00
$substitutionarray [ '__THIRDPARTY_IDPROF1__' ] = '__THIRDPARTY_IDPROF1__' ;
$substitutionarray [ '__THIRDPARTY_IDPROF2__' ] = '__THIRDPARTY_IDPROF2__' ;
$substitutionarray [ '__THIRDPARTY_IDPROF3__' ] = '__THIRDPARTY_IDPROF3__' ;
$substitutionarray [ '__THIRDPARTY_IDPROF4__' ] = '__THIRDPARTY_IDPROF4__' ;
$substitutionarray [ '__THIRDPARTY_IDPROF5__' ] = '__THIRDPARTY_IDPROF5__' ;
$substitutionarray [ '__THIRDPARTY_IDPROF6__' ] = '__THIRDPARTY_IDPROF6__' ;
2019-10-22 12:37:36 +02:00
$substitutionarray [ '__THIRDPARTY_TVAINTRA__' ] = '__THIRDPARTY_TVAINTRA__' ;
2019-11-08 16:34:20 +01:00
$substitutionarray [ '__THIRDPARTY_NOTE_PUBLIC__' ] = '__THIRDPARTY_NOTE_PUBLIC__' ;
$substitutionarray [ '__THIRDPARTY_NOTE_PRIVATE__' ] = '__THIRDPARTY_NOTE_PRIVATE__' ;
2019-09-23 13:04:22 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> adherent -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'adherent' )) {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__MEMBER_ID__' ] = '__MEMBER_ID__' ;
$substitutionarray [ '__MEMBER_CIVILITY__' ] = '__MEMBER_CIVILITY__' ;
$substitutionarray [ '__MEMBER_FIRSTNAME__' ] = '__MEMBER_FIRSTNAME__' ;
$substitutionarray [ '__MEMBER_LASTNAME__' ] = '__MEMBER_LASTNAME__' ;
2021-04-19 14:19:32 +02:00
$substitutionarray [ '__MEMBER_USER_LOGIN_INFORMATION__' ] = 'Login and pass of the external user account' ;
2019-10-22 14:39:33 +02:00
/* $substitutionarray [ '__MEMBER_NOTE_PUBLIC__' ] = '__MEMBER_NOTE_PUBLIC__' ;
$substitutionarray [ '__MEMBER_NOTE_PRIVATE__' ] = '__MEMBER_NOTE_PRIVATE__' ; */
2019-02-03 22:58:56 +01:00
}
2021-07-02 12:30:07 +02:00
// add variables subtitutions ticket
2021-04-16 12:39:39 +02:00
if ( ! empty ( $conf -> ticket -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'ticket' )) {
$substitutionarray [ '__TICKET_TRACKID__' ] = '__TICKET_TRACKID__' ;
$substitutionarray [ '__TICKET_SUBJECT__' ] = '__TICKET_SUBJECT__' ;
$substitutionarray [ '__TICKET_TYPE__' ] = '__TICKET_TYPE__' ;
$substitutionarray [ '__TICKET_SEVERITY__' ] = '__TICKET_SEVERITY__' ;
$substitutionarray [ '__TICKET_CATEGORY__' ] = '__TICKET_CATEGORY__' ;
$substitutionarray [ '__TICKET_ANALYTIC_CODE__' ] = '__TICKET_ANALYTIC_CODE__' ;
$substitutionarray [ '__TICKET_MESSAGE__' ] = '__TICKET_MESSAGE__' ;
$substitutionarray [ '__TICKET_PROGRESSION__' ] = '__TICKET_PROGRESSION__' ;
$substitutionarray [ '__TICKET_USER_ASSIGN__' ] = '__TICKET_USER_ASSIGN__' ;
2021-07-02 12:30:07 +02:00
}
2021-04-16 12:39:39 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> recruitment -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'candidature' )) {
2020-09-06 19:19:55 +02:00
$substitutionarray [ '__CANDIDATE_FULLNAME__' ] = '__CANDIDATE_FULLNAME__' ;
$substitutionarray [ '__CANDIDATE_FIRSTNAME__' ] = '__CANDIDATE_FIRSTNAME__' ;
$substitutionarray [ '__CANDIDATE_LASTNAME__' ] = '__CANDIDATE_LASTNAME__' ;
2020-08-23 22:11:16 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> projet -> enabled )) { // Most objects
2019-09-23 13:04:22 +02:00
$substitutionarray [ '__PROJECT_ID__' ] = '__PROJECT_ID__' ;
$substitutionarray [ '__PROJECT_REF__' ] = '__PROJECT_REF__' ;
$substitutionarray [ '__PROJECT_NAME__' ] = '__PROJECT_NAME__' ;
2019-10-22 14:39:33 +02:00
/* $substitutionarray [ '__PROJECT_NOTE_PUBLIC__' ] = '__PROJECT_NOTE_PUBLIC__' ;
$substitutionarray [ '__PROJECT_NOTE_PRIVATE__' ] = '__PROJECT_NOTE_PRIVATE__' ; */
2019-09-23 13:04:22 +02:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> contrat -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'contract' )) {
2019-09-23 13:04:22 +02:00
$substitutionarray [ '__CONTRACT_HIGHEST_PLANNED_START_DATE__' ] = 'Highest date planned for a service start' ;
$substitutionarray [ '__CONTRACT_HIGHEST_PLANNED_START_DATETIME__' ] = 'Highest date and hour planned for service start' ;
$substitutionarray [ '__CONTRACT_LOWEST_EXPIRATION_DATE__' ] = 'Lowest data for planned expiration of service' ;
$substitutionarray [ '__CONTRACT_LOWEST_EXPIRATION_DATETIME__' ] = 'Lowest date and hour for planned expiration of service' ;
}
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__ONLINE_PAYMENT_URL__' ] = 'UrlToPayOnlineIfApplicable' ;
$substitutionarray [ '__ONLINE_PAYMENT_TEXT_AND_URL__' ] = 'TextAndUrlToPayOnlineIfApplicable' ;
$substitutionarray [ '__SECUREKEYPAYMENT__' ] = 'Security key (if key is not unique per record)' ;
$substitutionarray [ '__SECUREKEYPAYMENT_MEMBER__' ] = 'Security key for payment on a member subscription (one key per member)' ;
$substitutionarray [ '__SECUREKEYPAYMENT_ORDER__' ] = 'Security key for payment on an order' ;
$substitutionarray [ '__SECUREKEYPAYMENT_INVOICE__' ] = 'Security key for payment on an invoice' ;
2021-09-28 11:56:43 +02:00
$substitutionarray [ '__SECUREKEYPAYMENT_CONTRACTLINE__' ] = 'Security key for payment on a service of a contract' ;
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_PROPOSAL__' ] = 'Direct download url of a proposal' ;
$substitutionarray [ '__DIRECTDOWNLOAD_URL_ORDER__' ] = 'Direct download url of an order' ;
$substitutionarray [ '__DIRECTDOWNLOAD_URL_INVOICE__' ] = 'Direct download url of an invoice' ;
2021-06-21 21:51:41 +02:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_CONTRACT__' ] = 'Direct download url of a contract' ;
$substitutionarray [ '__DIRECTDOWNLOAD_URL_SUPPLIER_PROPOSAL__' ] = 'Direct download url of a supplier proposal' ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> expedition -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'shipping' )) {
2020-11-08 14:39:20 +01:00
$substitutionarray [ '__SHIPPINGTRACKNUM__' ] = 'Shipping tracking number' ;
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__SHIPPINGTRACKNUMURL__' ] = 'Shipping tracking url' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> reception -> enabled ) && ( ! is_object ( $object ) || $object -> element == 'reception' )) {
2020-11-08 14:39:20 +01:00
$substitutionarray [ '__RECEPTIONTRACKNUM__' ] = 'Shippin tracking number of shipment' ;
$substitutionarray [ '__RECEPTIONTRACKNUMURL__' ] = 'Shipping tracking url' ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__ID__' ] = $object -> id ;
$substitutionarray [ '__REF__' ] = $object -> ref ;
2021-08-12 15:05:00 +02:00
$substitutionarray [ '__NEWREF__' ] = $object -> newref ;
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__REF_CLIENT__' ] = ( isset ( $object -> ref_client ) ? $object -> ref_client : ( isset ( $object -> ref_customer ) ? $object -> ref_customer : null ));
$substitutionarray [ '__REF_SUPPLIER__' ] = ( isset ( $object -> ref_supplier ) ? $object -> ref_supplier : null );
2019-10-22 14:39:33 +02:00
$substitutionarray [ '__NOTE_PUBLIC__' ] = ( isset ( $object -> note_public ) ? $object -> note_public : null );
$substitutionarray [ '__NOTE_PRIVATE__' ] = ( isset ( $object -> note_private ) ? $object -> note_private : null );
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__DATE_DELIVERY__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , 'day' , 0 , $outputlangs ) : '' );
2021-02-22 11:30:00 +01:00
$substitutionarray [ '__DATE_DELIVERY_DAY__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %d " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_DAY_TEXT__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %A " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_MON__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %m " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_MON_TEXT__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %b " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_YEAR__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %Y " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_HH__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %H " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_MM__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %M " ) : '' );
$substitutionarray [ '__DATE_DELIVERY_SS__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , " %S " ) : '' );
2019-10-22 14:39:33 +02:00
2019-02-03 22:58:56 +01:00
// For backward compatibility
2021-05-25 15:59:36 +02:00
$substitutionarray [ '__REFCLIENT__' ] = ( isset ( $object -> ref_client ) ? $object -> ref_client : ( isset ( $object -> ref_customer ) ? $object -> ref_customer : null ));
$substitutionarray [ '__REFSUPPLIER__' ] = ( isset ( $object -> ref_supplier ) ? $object -> ref_supplier : null );
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__SUPPLIER_ORDER_DATE_DELIVERY__' ] = ( isset ( $object -> date_livraison ) ? dol_print_date ( $object -> date_livraison , 'day' , 0 , $outputlangs ) : '' );
2020-11-16 13:00:18 +01:00
$substitutionarray [ '__SUPPLIER_ORDER_DELAY_DELIVERY__' ] = ( isset ( $object -> availability_code ) ? ( $outputlangs -> transnoentities ( " AvailabilityType " . $object -> availability_code ) != ( 'AvailabilityType' . $object -> availability_code ) ? $outputlangs -> transnoentities ( " AvailabilityType " . $object -> availability_code ) : $outputlangs -> convToOutputCharset ( isset ( $object -> availability ) ? $object -> availability : '' )) : '' );
2020-01-13 18:19:51 +01:00
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && ( $object -> element == 'adherent' || $object -> element == 'member' ) && $object -> id > 0 ) {
2020-12-01 02:41:19 +01:00
$birthday = ( empty ( $object -> birth ) ? '' : dol_print_date ( $object -> birth , 'day' ));
2020-11-17 13:13:11 +01:00
2020-09-18 18:29:52 +02:00
$substitutionarray [ '__MEMBER_ID__' ] = ( isset ( $object -> id ) ? $object -> id : '' );
2021-02-23 22:03:23 +01:00
if ( method_exists ( $object , 'getCivilityLabel' )) {
$substitutionarray [ '__MEMBER_CIVILITY__' ] = $object -> getCivilityLabel ();
}
2020-09-18 18:29:52 +02:00
$substitutionarray [ '__MEMBER_FIRSTNAME__' ] = ( isset ( $object -> firstname ) ? $object -> firstname : '' );
$substitutionarray [ '__MEMBER_LASTNAME__' ] = ( isset ( $object -> lastname ) ? $object -> lastname : '' );
2021-04-19 14:19:32 +02:00
$substitutionarray [ '__MEMBER_USER_LOGIN_INFORMATION__' ] = '' ;
2021-02-23 22:03:23 +01:00
if ( method_exists ( $object , 'getFullName' )) {
$substitutionarray [ '__MEMBER_FULLNAME__' ] = $object -> getFullName ( $outputlangs );
}
2020-09-18 18:29:52 +02:00
$substitutionarray [ '__MEMBER_COMPANY__' ] = ( isset ( $object -> societe ) ? $object -> societe : '' );
$substitutionarray [ '__MEMBER_ADDRESS__' ] = ( isset ( $object -> address ) ? $object -> address : '' );
$substitutionarray [ '__MEMBER_ZIP__' ] = ( isset ( $object -> zip ) ? $object -> zip : '' );
$substitutionarray [ '__MEMBER_TOWN__' ] = ( isset ( $object -> town ) ? $object -> town : '' );
$substitutionarray [ '__MEMBER_COUNTRY__' ] = ( isset ( $object -> country ) ? $object -> country : '' );
$substitutionarray [ '__MEMBER_EMAIL__' ] = ( isset ( $object -> email ) ? $object -> email : '' );
$substitutionarray [ '__MEMBER_BIRTH__' ] = ( isset ( $birthday ) ? $birthday : '' );
$substitutionarray [ '__MEMBER_PHOTO__' ] = ( isset ( $object -> photo ) ? $object -> photo : '' );
$substitutionarray [ '__MEMBER_LOGIN__' ] = ( isset ( $object -> login ) ? $object -> login : '' );
$substitutionarray [ '__MEMBER_PASSWORD__' ] = ( isset ( $object -> pass ) ? $object -> pass : '' );
2022-01-20 13:45:51 +01:00
$substitutionarray [ '__MEMBER_PHONE__' ] = ( isset ( $object -> phone ) ? dol_print_phone ( $object -> phone ) : '' );
$substitutionarray [ '__MEMBER_PHONEPRO__' ] = ( isset ( $object -> phone_perso ) ? dol_print_phone ( $object -> phone_perso ) : '' );
$substitutionarray [ '__MEMBER_PHONEMOBILE__' ] = ( isset ( $object -> phone_mobile ) ? dol_print_phone ( $object -> phone_mobile ) : '' );
2020-09-18 18:29:52 +02:00
$substitutionarray [ '__MEMBER_TYPE__' ] = ( isset ( $object -> type ) ? $object -> type : '' );
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__MEMBER_FIRST_SUBSCRIPTION_DATE__' ] = dol_print_date ( $object -> first_subscription_date , 'dayrfc' );
$substitutionarray [ '__MEMBER_FIRST_SUBSCRIPTION_DATE_START__' ] = dol_print_date ( $object -> first_subscription_date_start , 'dayrfc' );
$substitutionarray [ '__MEMBER_FIRST_SUBSCRIPTION_DATE_END__' ] = dol_print_date ( $object -> first_subscription_date_end , 'dayrfc' );
$substitutionarray [ '__MEMBER_LAST_SUBSCRIPTION_DATE__' ] = dol_print_date ( $object -> last_subscription_date , 'dayrfc' );
$substitutionarray [ '__MEMBER_LAST_SUBSCRIPTION_DATE_START__' ] = dol_print_date ( $object -> last_subscription_date_start , 'dayrfc' );
$substitutionarray [ '__MEMBER_LAST_SUBSCRIPTION_DATE_END__' ] = dol_print_date ( $object -> last_subscription_date_end , 'dayrfc' );
}
2020-08-23 22:11:16 +02:00
if ( is_object ( $object ) && $object -> element == 'societe' ) {
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_ID__' ] = ( is_object ( $object ) ? $object -> id : '' );
$substitutionarray [ '__THIRDPARTY_NAME__' ] = ( is_object ( $object ) ? $object -> name : '' );
$substitutionarray [ '__THIRDPARTY_NAME_ALIAS__' ] = ( is_object ( $object ) ? $object -> name_alias : '' );
$substitutionarray [ '__THIRDPARTY_CODE_CLIENT__' ] = ( is_object ( $object ) ? $object -> code_client : '' );
$substitutionarray [ '__THIRDPARTY_CODE_FOURNISSEUR__' ] = ( is_object ( $object ) ? $object -> code_fournisseur : '' );
$substitutionarray [ '__THIRDPARTY_EMAIL__' ] = ( is_object ( $object ) ? $object -> email : '' );
2022-01-20 13:45:51 +01:00
$substitutionarray [ '__THIRDPARTY_PHONE__' ] = ( is_object ( $object ) ? dol_print_phone ( $object -> phone ) : '' );
$substitutionarray [ '__THIRDPARTY_FAX__' ] = ( is_object ( $object ) ? dol_print_phone ( $object -> fax ) : '' );
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_ADDRESS__' ] = ( is_object ( $object ) ? $object -> address : '' );
$substitutionarray [ '__THIRDPARTY_ZIP__' ] = ( is_object ( $object ) ? $object -> zip : '' );
$substitutionarray [ '__THIRDPARTY_TOWN__' ] = ( is_object ( $object ) ? $object -> town : '' );
2020-01-21 00:28:53 +01:00
$substitutionarray [ '__THIRDPARTY_COUNTRY_ID__' ] = ( is_object ( $object ) ? $object -> country_id : '' );
$substitutionarray [ '__THIRDPARTY_COUNTRY_CODE__' ] = ( is_object ( $object ) ? $object -> country_code : '' );
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_IDPROF1__' ] = ( is_object ( $object ) ? $object -> idprof1 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF2__' ] = ( is_object ( $object ) ? $object -> idprof2 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF3__' ] = ( is_object ( $object ) ? $object -> idprof3 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF4__' ] = ( is_object ( $object ) ? $object -> idprof4 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF5__' ] = ( is_object ( $object ) ? $object -> idprof5 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF6__' ] = ( is_object ( $object ) ? $object -> idprof6 : '' );
$substitutionarray [ '__THIRDPARTY_TVAINTRA__' ] = ( is_object ( $object ) ? $object -> tva_intra : '' );
2020-09-06 19:19:55 +02:00
$substitutionarray [ '__THIRDPARTY_NOTE_PUBLIC__' ] = ( is_object ( $object ) ? dol_htmlentitiesbr ( $object -> note_public ) : '' );
$substitutionarray [ '__THIRDPARTY_NOTE_PRIVATE__' ] = ( is_object ( $object ) ? dol_htmlentitiesbr ( $object -> note_private ) : '' );
} elseif ( is_object ( $object -> thirdparty )) {
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_ID__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> id : '' );
$substitutionarray [ '__THIRDPARTY_NAME__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> name : '' );
$substitutionarray [ '__THIRDPARTY_NAME_ALIAS__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> name_alias : '' );
$substitutionarray [ '__THIRDPARTY_CODE_CLIENT__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> code_client : '' );
$substitutionarray [ '__THIRDPARTY_CODE_FOURNISSEUR__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> code_fournisseur : '' );
$substitutionarray [ '__THIRDPARTY_EMAIL__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> email : '' );
2022-01-20 13:45:51 +01:00
$substitutionarray [ '__THIRDPARTY_PHONE__' ] = ( is_object ( $object -> thirdparty ) ? dol_print_phone ( $object -> thirdparty -> phone ) : '' );
$substitutionarray [ '__THIRDPARTY_FAX__' ] = ( is_object ( $object -> thirdparty ) ? dol_print_phone ( $object -> thirdparty -> fax ) : '' );
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_ADDRESS__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> address : '' );
$substitutionarray [ '__THIRDPARTY_ZIP__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> zip : '' );
$substitutionarray [ '__THIRDPARTY_TOWN__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> town : '' );
2020-01-21 00:28:53 +01:00
$substitutionarray [ '__THIRDPARTY_COUNTRY_ID__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> country_id : '' );
$substitutionarray [ '__THIRDPARTY_COUNTRY_CODE__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> country_code : '' );
2019-11-28 12:36:20 +01:00
$substitutionarray [ '__THIRDPARTY_IDPROF1__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof1 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF2__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof2 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF3__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof3 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF4__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof4 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF5__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof5 : '' );
$substitutionarray [ '__THIRDPARTY_IDPROF6__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> idprof6 : '' );
$substitutionarray [ '__THIRDPARTY_TVAINTRA__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> tva_intra : '' );
2020-08-23 22:11:16 +02:00
$substitutionarray [ '__THIRDPARTY_NOTE_PUBLIC__' ] = ( is_object ( $object -> thirdparty ) ? dol_htmlentitiesbr ( $object -> thirdparty -> note_public ) : '' );
$substitutionarray [ '__THIRDPARTY_NOTE_PRIVATE__' ] = ( is_object ( $object -> thirdparty ) ? dol_htmlentitiesbr ( $object -> thirdparty -> note_private ) : '' );
2020-08-23 22:13:06 +02:00
}
if ( is_object ( $object ) && $object -> element == 'recruitmentcandidature' ) {
2020-09-06 19:19:55 +02:00
$substitutionarray [ '__CANDIDATE_FULLNAME__' ] = $object -> getFullName ( $outputlangs );
$substitutionarray [ '__CANDIDATE_FIRSTNAME__' ] = $object -> firstname ;
$substitutionarray [ '__CANDIDATE_LASTNAME__' ] = $object -> lastname ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $object -> project )) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__PROJECT_ID__' ] = ( is_object ( $object -> project ) ? $object -> project -> id : '' );
$substitutionarray [ '__PROJECT_REF__' ] = ( is_object ( $object -> project ) ? $object -> project -> ref : '' );
$substitutionarray [ '__PROJECT_NAME__' ] = ( is_object ( $object -> project ) ? $object -> project -> title : '' );
2019-09-23 13:04:22 +02:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $object -> projet )) { // Deprecated, for backward compatibility
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__PROJECT_ID__' ] = ( is_object ( $object -> projet ) ? $object -> projet -> id : '' );
$substitutionarray [ '__PROJECT_REF__' ] = ( is_object ( $object -> projet ) ? $object -> projet -> ref : '' );
$substitutionarray [ '__PROJECT_NAME__' ] = ( is_object ( $object -> projet ) ? $object -> projet -> title : '' );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'shipping' ) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__SHIPPINGTRACKNUM__' ] = $object -> tracking_number ;
$substitutionarray [ '__SHIPPINGTRACKNUMURL__' ] = $object -> tracking_url ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'reception' ) {
2020-11-08 14:39:20 +01:00
$substitutionarray [ '__RECEPTIONTRACKNUM__' ] = $object -> tracking_number ;
$substitutionarray [ '__RECEPTIONTRACKNUMURL__' ] = $object -> tracking_url ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'contrat' && $object -> id > 0 && is_array ( $object -> lines )) {
2020-09-06 19:19:55 +02:00
$dateplannedstart = '' ;
$datenextexpiration = '' ;
2021-02-23 22:03:23 +01:00
foreach ( $object -> lines as $line ) {
if ( $line -> date_ouverture_prevue > $dateplannedstart ) {
$dateplannedstart = $line -> date_ouverture_prevue ;
}
if ( $line -> statut == 4 && $line -> date_fin_prevue && ( ! $datenextexpiration || $line -> date_fin_prevue < $datenextexpiration )) {
$datenextexpiration = $line -> date_fin_prevue ;
}
2019-02-03 22:58:56 +01:00
}
2020-09-06 19:19:55 +02:00
$substitutionarray [ '__CONTRACT_HIGHEST_PLANNED_START_DATE__' ] = dol_print_date ( $dateplannedstart , 'dayrfc' );
$substitutionarray [ '__CONTRACT_HIGHEST_PLANNED_START_DATETIME__' ] = dol_print_date ( $dateplannedstart , 'standard' );
$substitutionarray [ '__CONTRACT_LOWEST_EXPIRATION_DATE__' ] = dol_print_date ( $datenextexpiration , 'dayrfc' );
$substitutionarray [ '__CONTRACT_LOWEST_EXPIRATION_DATETIME__' ] = dol_print_date ( $datenextexpiration , 'standard' );
2019-02-03 22:58:56 +01:00
}
2021-07-02 12:30:07 +02:00
// add substition variable for ticket
2021-04-16 12:39:39 +02:00
if ( is_object ( $object ) && $object -> element == 'ticket' ) {
$substitutionarray [ '__TICKET_TRACKID__' ] = $object -> track_id ;
2021-11-19 17:09:51 +01:00
$substitutionarray [ '__REF__' ] = $object -> ref ;
2021-04-16 12:39:39 +02:00
$substitutionarray [ '__TICKET_SUBJECT__' ] = $object -> subject ;
$substitutionarray [ '__TICKET_TYPE__' ] = $object -> type_code ;
$substitutionarray [ '__TICKET_SEVERITY__' ] = $object -> severity_code ;
$substitutionarray [ '__TICKET_CATEGORY__' ] = $object -> category_code ; // For backward compatibility
$substitutionarray [ '__TICKET_ANALYTIC_CODE__' ] = $object -> category_code ;
$substitutionarray [ '__TICKET_MESSAGE__' ] = $object -> message ;
$substitutionarray [ '__TICKET_PROGRESSION__' ] = $object -> progress ;
2021-07-02 12:30:07 +02:00
$userstat = new User ( $db );
if ( $object -> fk_user_assign > 0 ) {
$userstat -> fetch ( $object -> fk_user_assign );
$substitutionarray [ '__TICKET_USER_ASSIGN__' ] = dolGetFirstLastname ( $userstat -> firstname , $userstat -> lastname );
}
2021-04-16 12:39:39 +02:00
2021-07-02 12:30:07 +02:00
if ( $object -> fk_user_create > 0 ) {
$userstat -> fetch ( $object -> fk_user_create );
2021-11-19 17:09:51 +01:00
$substitutionarray [ '__USER_CREATE__' ] = dolGetFirstLastname ( $userstat -> firstname , $userstat -> lastname );
2021-07-02 12:30:07 +02:00
}
}
2019-02-03 22:58:56 +01:00
// Create dynamic tags for __EXTRAFIELD_FIELD__
2021-02-23 22:03:23 +01:00
if ( $object -> table_element && $object -> id > 0 ) {
if ( ! is_object ( $extrafields )) {
$extrafields = new ExtraFields ( $db );
}
2019-02-03 22:58:56 +01:00
$extrafields -> fetch_name_optionals_label ( $object -> table_element , true );
2021-02-23 22:03:23 +01:00
if ( $object -> fetch_optionals () > 0 ) {
if ( is_array ( $extrafields -> attributes [ $object -> table_element ][ 'label' ]) && count ( $extrafields -> attributes [ $object -> table_element ][ 'label' ]) > 0 ) {
2019-02-03 22:58:56 +01:00
foreach ( $extrafields -> attributes [ $object -> table_element ][ 'label' ] as $key => $label ) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '__' ] = $object -> array_options [ 'options_' . $key ];
2020-09-06 19:19:55 +02:00
if ( $extrafields -> attributes [ $object -> table_element ][ 'type' ][ $key ] == 'date' ) {
2020-09-14 04:30:04 +02:00
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '__' ] = dol_print_date ( $object -> array_options [ 'options_' . $key ], 'day' );
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_LOCALE__' ] = dol_print_date ( $object -> array_options [ 'options_' . $key ], 'day' , 'tzserver' , $outputlangs );
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_RFC__' ] = dol_print_date ( $object -> array_options [ 'options_' . $key ], 'dayrfc' );
2020-09-06 19:19:55 +02:00
} elseif ( $extrafields -> attributes [ $object -> table_element ][ 'type' ][ $key ] == 'datetime' ) {
2020-09-08 21:27:28 +02:00
$datetime = $object -> array_options [ 'options_' . $key ];
2020-09-14 04:30:04 +02:00
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '__' ] = ( $datetime != " 0000-00-00 00:00:00 " ? dol_print_date ( $datetime , 'dayhour' ) : '' );
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_LOCALE__' ] = ( $datetime != " 0000-00-00 00:00:00 " ? dol_print_date ( $datetime , 'dayhour' , 'tzserver' , $outputlangs ) : '' );
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_DAY_LOCALE__' ] = ( $datetime != " 0000-00-00 00:00:00 " ? dol_print_date ( $datetime , 'day' , 'tzserver' , $outputlangs ) : '' );
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_RFC__' ] = ( $datetime != " 0000-00-00 00:00:00 " ? dol_print_date ( $datetime , 'dayhourrfc' ) : '' );
2022-01-20 13:45:51 +01:00
} elseif ( $extrafields -> attributes [ $object -> table_element ][ 'type' ][ $key ] == 'phone' ) {
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '__' ] = dol_print_phone ( $object -> array_options [ 'options_' . $key ]);
} elseif ( $extrafields -> attributes [ $object -> table_element ][ 'type' ][ $key ] == 'price' ) {
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '__' ] = $object -> array_options [ 'options_' . $key ];
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_FORMATED__' ] = price ( $object -> array_options [ 'options_' . $key ]);
2020-09-08 21:27:28 +02:00
}
2019-02-03 22:58:56 +01:00
}
}
}
}
// Complete substitution array with the url to make online payment
2019-11-11 23:59:36 +01:00
$paymenturl = '' ;
2021-02-23 22:03:23 +01:00
if ( empty ( $substitutionarray [ '__REF__' ])) {
2019-11-11 23:59:36 +01:00
$paymenturl = '' ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
// Set the online payment url link into __ONLINE_PAYMENT_URL__ key
require_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php' ;
2019-11-11 23:59:36 +01:00
$outputlangs -> loadLangs ( array ( 'paypal' , 'other' ));
$typeforonlinepayment = 'free' ;
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'commande' ) {
$typeforonlinepayment = 'order' ;
}
if ( is_object ( $object ) && $object -> element == 'facture' ) {
$typeforonlinepayment = 'invoice' ;
}
if ( is_object ( $object ) && $object -> element == 'member' ) {
$typeforonlinepayment = 'member' ;
}
if ( is_object ( $object ) && $object -> element == 'contrat' ) {
$typeforonlinepayment = 'contract' ;
}
2019-11-11 23:59:36 +01:00
$url = getOnlinePaymentUrl ( 0 , $typeforonlinepayment , $substitutionarray [ '__REF__' ]);
$paymenturl = $url ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $object -> id > 0 ) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__ONLINE_PAYMENT_TEXT_AND_URL__' ] = ( $paymenturl ? str_replace ( '\n' , " \n " , $outputlangs -> trans ( " PredefinedMailContentLink " , $paymenturl )) : '' );
$substitutionarray [ '__ONLINE_PAYMENT_URL__' ] = $paymenturl ;
2021-11-08 03:47:16 +01:00
2021-11-02 12:37:39 +01:00
if ( is_object ( $object ) && $object -> element == 'propal' ) {
$substitutionarray [ '__ONLINE_SIGN_URL__' ] = getOnlineSignatureUrl ( 0 , 'proposal' , $object -> ref );
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD ) && is_object ( $object ) && $object -> element == 'propal' ) {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_PROPOSAL__' ] = $object -> getLastMainDocLink ( $object -> element );
2021-02-23 22:03:23 +01:00
} else {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_PROPOSAL__' ] = '' ;
}
if ( ! empty ( $conf -> global -> ORDER_ALLOW_EXTERNAL_DOWNLOAD ) && is_object ( $object ) && $object -> element == 'commande' ) {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_ORDER__' ] = $object -> getLastMainDocLink ( $object -> element );
2021-02-23 22:03:23 +01:00
} else {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_ORDER__' ] = '' ;
}
if ( ! empty ( $conf -> global -> INVOICE_ALLOW_EXTERNAL_DOWNLOAD ) && is_object ( $object ) && $object -> element == 'facture' ) {
2019-02-03 22:58:56 +01:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_INVOICE__' ] = $object -> getLastMainDocLink ( $object -> element );
2021-02-23 22:03:23 +01:00
} else {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_INVOICE__' ] = '' ;
}
if ( ! empty ( $conf -> global -> CONTRACT_ALLOW_EXTERNAL_DOWNLOAD ) && is_object ( $object ) && $object -> element == 'contrat' ) {
2021-02-18 21:39:25 +01:00
$substitutionarray [ '__DIRECTDOWNLOAD_URL_CONTRACT__' ] = $object -> getLastMainDocLink ( $object -> element );
2021-02-23 22:03:23 +01:00
} else {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_CONTRACT__' ] = '' ;
}
2021-04-24 08:05:00 +02:00
if ( ! empty ( $conf -> global -> SUPPLIER_PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD ) && is_object ( $object ) && $object -> element == 'supplier_proposal' ) {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_SUPPLIER_PROPOSAL__' ] = $object -> getLastMainDocLink ( $object -> element );
} else {
$substitutionarray [ '__DIRECTDOWNLOAD_URL_SUPPLIER_PROPOSAL__' ] = '' ;
}
2020-03-02 19:23:45 +01:00
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'propal' ) {
$substitutionarray [ '__URL_PROPOSAL__' ] = DOL_MAIN_URL_ROOT . " /comm/propal/card.php?id= " . $object -> id ;
}
if ( is_object ( $object ) && $object -> element == 'commande' ) {
$substitutionarray [ '__URL_ORDER__' ] = DOL_MAIN_URL_ROOT . " /commande/card.php?id= " . $object -> id ;
}
if ( is_object ( $object ) && $object -> element == 'facture' ) {
$substitutionarray [ '__URL_INVOICE__' ] = DOL_MAIN_URL_ROOT . " /compta/facture/card.php?id= " . $object -> id ;
}
if ( is_object ( $object ) && $object -> element == 'contrat' ) {
$substitutionarray [ '__URL_CONTRACT__' ] = DOL_MAIN_URL_ROOT . " /contrat/card.php?id= " . $object -> id ;
}
2021-04-24 08:05:00 +02:00
if ( is_object ( $object ) && $object -> element == 'supplier_proposal' ) {
$substitutionarray [ '__URL_SUPPLIER_PROPOSAL__' ] = DOL_MAIN_URL_ROOT . " /supplier_proposal/card.php?id= " . $object -> id ;
}
2021-08-12 15:13:35 +02:00
if ( is_object ( $object ) && $object -> element == 'shipping' ) {
$substitutionarray [ '__URL_SHIPMENT__' ] = DOL_MAIN_URL_ROOT . " /expedition/card.php?id= " . $object -> id ;
}
2019-02-03 22:58:56 +01:00
}
2020-08-27 15:49:56 +02:00
2021-02-23 22:03:23 +01:00
if ( is_object ( $object ) && $object -> element == 'action' ) {
2020-09-08 21:27:28 +02:00
$substitutionarray [ '__EVENT_LABEL__' ] = $object -> label ;
$substitutionarray [ '__EVENT_DATE__' ] = dol_print_date ( $object -> datep , '%A %d %b %Y' );
$substitutionarray [ '__EVENT_TIME__' ] = dol_print_date ( $object -> datep , '%H:%M:%S' );
}
2019-02-03 22:58:56 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( empty ( $exclude ) || ! in_array ( 'objectamount' , $exclude )) {
2020-12-10 12:01:22 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/functionsnumtoword.lib.php' ;
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__DATE_YMD__' ] = is_object ( $object ) ? ( isset ( $object -> date ) ? dol_print_date ( $object -> date , 'day' , 0 , $outputlangs ) : null ) : '' ;
$substitutionarray [ '__DATE_DUE_YMD__' ] = is_object ( $object ) ? ( isset ( $object -> date_lim_reglement ) ? dol_print_date ( $object -> date_lim_reglement , 'day' , 0 , $outputlangs ) : null ) : '' ;
2019-02-03 22:58:56 +01:00
2022-04-07 19:23:45 +02:00
$already_payed_all = 0 ;
if ( is_object ( $object ) && ( $object instanceof Facture )) {
$already_payed_all = $object -> sumpayed + $object -> sumdeposit + $object -> sumcreditnote ;
}
$substitutionarray [ '__AMOUNT_EXCL_TAX__' ] = is_object ( $object ) ? $object -> total_ht : '' ;
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__AMOUNT__' ] = is_object ( $object ) ? $object -> total_ttc : '' ;
2020-12-10 12:01:22 +01:00
$substitutionarray [ '__AMOUNT_TEXT__' ] = is_object ( $object ) ? dol_convertToWord ( $object -> total_ttc , $outputlangs , '' , true ) : '' ;
$substitutionarray [ '__AMOUNT_TEXTCURRENCY__' ] = is_object ( $object ) ? dol_convertToWord ( $object -> total_ttc , $outputlangs , $conf -> currency , true ) : '' ;
2022-04-07 19:23:45 +02:00
$substitutionarray [ '__AMOUNT_REMAIN__' ] = is_object ( $object ) ? $object -> total_ttc - $already_payed_all : '' ;
2020-11-18 22:25:03 +01:00
$substitutionarray [ '__AMOUNT_VAT__' ] = is_object ( $object ) ? ( isset ( $object -> total_vat ) ? $object -> total_vat : $object -> total_tva ) : '' ;
2020-12-10 12:09:43 +01:00
$substitutionarray [ '__AMOUNT_VAT_TEXT__' ] = is_object ( $object ) ? ( isset ( $object -> total_vat ) ? dol_convertToWord ( $object -> total_vat , $outputlangs , '' , true ) : dol_convertToWord ( $object -> total_tva , $outputlangs , '' , true )) : '' ;
$substitutionarray [ '__AMOUNT_VAT_TEXTCURRENCY__' ] = is_object ( $object ) ? ( isset ( $object -> total_vat ) ? dol_convertToWord ( $object -> total_vat , $outputlangs , $conf -> currency , true ) : dol_convertToWord ( $object -> total_tva , $outputlangs , $conf -> currency , true )) : '' ;
2022-04-07 19:23:45 +02:00
2021-02-23 22:03:23 +01:00
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 1 )) {
$substitutionarray [ '__AMOUNT_TAX2__' ] = is_object ( $object ) ? $object -> total_localtax1 : '' ;
}
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 2 )) {
$substitutionarray [ '__AMOUNT_TAX3__' ] = is_object ( $object ) ? $object -> total_localtax2 : '' ;
}
2019-02-03 22:58:56 +01:00
2022-04-07 19:23:45 +02:00
// Amount keys formated in a currency
2021-06-09 12:26:28 +02:00
$substitutionarray [ '__AMOUNT_EXCL_TAX_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_ht ? price ( $object -> total_ht , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null ) : '' ;
2022-04-07 19:23:45 +02:00
$substitutionarray [ '__AMOUNT_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_ttc ? price ( $object -> total_ttc , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null ) : '' ;
$substitutionarray [ '__AMOUNT_REMAIN_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_ttc ? price ( $object -> total_ttc - $already_payed_all , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null ) : '' ;
2021-06-10 16:53:09 +02:00
$substitutionarray [ '__AMOUNT_VAT_FORMATED__' ] = is_object ( $object ) ? ( isset ( $object -> total_vat ) ? price ( $object -> total_vat , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : ( $object -> total_tva ? price ( $object -> total_tva , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null )) : '' ;
2021-02-23 22:03:23 +01:00
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 1 )) {
2021-06-11 19:05:05 +02:00
$substitutionarray [ '__AMOUNT_TAX2_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_localtax1 ? price ( $object -> total_localtax1 , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null ) : '' ;
2021-02-23 22:03:23 +01:00
}
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 2 )) {
2021-06-11 19:05:05 +02:00
$substitutionarray [ '__AMOUNT_TAX3_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_localtax2 ? price ( $object -> total_localtax2 , 0 , $outputlangs , 0 , - 1 , - 1 , $conf -> currency ) : null ) : '' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
2020-12-13 12:38:47 +01:00
$substitutionarray [ '__AMOUNT_MULTICURRENCY__' ] = ( is_object ( $object ) && isset ( $object -> multicurrency_total_ttc )) ? $object -> multicurrency_total_ttc : '' ;
$substitutionarray [ '__AMOUNT_MULTICURRENCY_TEXT__' ] = ( is_object ( $object ) && isset ( $object -> multicurrency_total_ttc )) ? dol_convertToWord ( $object -> multicurrency_total_ttc , $outputlangs , '' , true ) : '' ;
$substitutionarray [ '__AMOUNT_MULTICURRENCY_TEXTCURRENCY__' ] = ( is_object ( $object ) && isset ( $object -> multicurrency_total_ttc )) ? dol_convertToWord ( $object -> multicurrency_total_ttc , $outputlangs , $object -> multicurrency_code , true ) : '' ;
2020-12-10 12:01:22 +01:00
// TODO Add other keys for foreign multicurrency
2019-02-03 22:58:56 +01:00
// For backward compatibility
2021-02-23 22:03:23 +01:00
if ( $onlykey != 2 ) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__TOTAL_TTC__' ] = is_object ( $object ) ? $object -> total_ttc : '' ;
$substitutionarray [ '__TOTAL_HT__' ] = is_object ( $object ) ? $object -> total_ht : '' ;
2020-11-18 22:25:03 +01:00
$substitutionarray [ '__TOTAL_VAT__' ] = is_object ( $object ) ? ( isset ( $object -> total_vat ) ? $object -> total_vat : $object -> total_tva ) : '' ;
2019-02-03 22:58:56 +01:00
}
}
//var_dump($substitutionarray['__AMOUNT_FORMATED__']);
2021-02-23 22:03:23 +01:00
if ( empty ( $exclude ) || ! in_array ( 'date' , $exclude )) {
2019-02-03 22:58:56 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2019-11-11 23:59:36 +01:00
$tmp = dol_getdate ( dol_now (), true );
$tmp2 = dol_get_prev_day ( $tmp [ 'mday' ], $tmp [ 'mon' ], $tmp [ 'year' ]);
$tmp3 = dol_get_prev_month ( $tmp [ 'mon' ], $tmp [ 'year' ]);
$tmp4 = dol_get_next_day ( $tmp [ 'mday' ], $tmp [ 'mon' ], $tmp [ 'year' ]);
$tmp5 = dol_get_next_month ( $tmp [ 'mon' ], $tmp [ 'year' ]);
2019-02-03 22:58:56 +01:00
2020-10-30 05:45:36 +01:00
$daytext = $outputlangs -> trans ( 'Day' . $tmp [ 'wday' ]);
2020-09-07 10:18:17 +02:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__DAY__' => ( string ) $tmp [ 'mday' ],
2020-10-30 05:45:36 +01:00
'__DAY_TEXT__' => $daytext , // Monday
'__DAY_TEXT_SHORT__' => dol_trunc ( $daytext , 3 , 'right' , 'UTF-8' , 1 ), // Mon
'__DAY_TEXT_MIN__' => dol_trunc ( $daytext , 1 , 'right' , 'UTF-8' , 1 ), // M
2019-02-03 22:58:56 +01:00
'__MONTH__' => ( string ) $tmp [ 'mon' ],
'__MONTH_TEXT__' => $outputlangs -> trans ( 'Month' . sprintf ( " %02d " , $tmp [ 'mon' ])),
'__MONTH_TEXT_SHORT__' => $outputlangs -> trans ( 'MonthShort' . sprintf ( " %02d " , $tmp [ 'mon' ])),
'__MONTH_TEXT_MIN__' => $outputlangs -> trans ( 'MonthVeryShort' . sprintf ( " %02d " , $tmp [ 'mon' ])),
'__YEAR__' => ( string ) $tmp [ 'year' ],
'__PREVIOUS_DAY__' => ( string ) $tmp2 [ 'day' ],
'__PREVIOUS_MONTH__' => ( string ) $tmp3 [ 'month' ],
'__PREVIOUS_YEAR__' => ( string ) ( $tmp [ 'year' ] - 1 ),
'__NEXT_DAY__' => ( string ) $tmp4 [ 'day' ],
'__NEXT_MONTH__' => ( string ) $tmp5 [ 'month' ],
'__NEXT_YEAR__' => ( string ) ( $tmp [ 'year' ] + 1 ),
));
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> multicompany -> enabled )) {
2019-11-11 23:59:36 +01:00
$substitutionarray = array_merge ( $substitutionarray , array ( '__ENTITY_ID__' => $conf -> entity ));
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $exclude ) || ! in_array ( 'system' , $exclude )) {
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__DOL_MAIN_URL_ROOT__' ] = DOL_MAIN_URL_ROOT ;
$substitutionarray [ '__(AnyTranslationKey)__' ] = $outputlangs -> trans ( 'TranslationOfKey' );
$substitutionarray [ '__(AnyTranslationKey|langfile)__' ] = $outputlangs -> trans ( 'TranslationOfKey' ) . ' (load also language file before)' ;
$substitutionarray [ '__[AnyConstantKey]__' ] = $outputlangs -> trans ( 'ValueOfConstantKey' );
2019-02-03 22:58:56 +01:00
}
return $substitutionarray ;
}
/**
* Make substitution into a text string , replacing keys with vals from $substitutionarray ( oldval => newval ),
* and texts like __ ( TranslationKey | langfile ) __ and __ [ ConstantKey ] __ are also replaced .
* Example of usage :
* $substitutionarray = getCommonSubstitutionArray ( $langs , 0 , null , $thirdparty );
* complete_substitutions_array ( $substitutionarray , $langs , $thirdparty );
* $mesg = make_substitutions ( $mesg , $substitutionarray , $langs );
*
2021-05-04 13:33:18 +02:00
* @ param string $text Source string in which we must do substitution
* @ param array $substitutionarray Array with key -> val to substitute . Example : array ( '__MYKEY__' => 'MyVal' , ... )
* @ param Translate $outputlangs Output language
* @ param int $converttextinhtmlifnecessary 0 = Convert only value into HTML if text is already in HTML
* 1 = Will also convert initial $text into HTML if we try to insert one value that is HTML
* @ return string Output string after substitutions
2019-03-11 01:01:15 +01:00
* @ see complete_substitutions_array (), getCommonSubstitutionArray ()
2019-02-03 22:58:56 +01:00
*/
2021-05-04 13:33:18 +02:00
function make_substitutions ( $text , $substitutionarray , $outputlangs = null , $converttextinhtmlifnecessary = 0 )
2019-02-03 22:58:56 +01:00
{
global $conf , $langs ;
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $substitutionarray )) {
return 'ErrorBadParameterSubstitutionArrayWhenCalling_make_substitutions' ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( empty ( $outputlangs )) {
$outputlangs = $langs ;
}
2019-02-03 22:58:56 +01:00
2021-05-04 13:33:18 +02:00
// Is initial text HTML or simple text ?
$msgishtml = 0 ;
if ( dol_textishtml ( $text , 1 )) {
$msgishtml = 1 ;
}
2019-04-25 17:37:54 +02:00
// Make substitution for language keys: __(AnyTranslationKey)__ or __(AnyTranslationKey|langfile)__
2021-02-23 22:03:23 +01:00
if ( is_object ( $outputlangs )) {
2020-03-17 13:33:21 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
while ( preg_match ( '/__\(([^\)]+)\)__/' , $text , $reg )) {
2019-02-03 22:58:56 +01:00
// If key is __(TranslationKey|langfile)__, then force load of langfile.lang
2019-11-11 23:59:36 +01:00
$tmp = explode ( '|' , $reg [ 1 ]);
2021-02-23 22:03:23 +01:00
if ( ! empty ( $tmp [ 1 ])) {
$outputlangs -> load ( $tmp [ 1 ]);
}
2019-02-03 22:58:56 +01:00
2021-05-04 13:33:18 +02:00
$value = $outputlangs -> transnoentitiesnoconv ( $reg [ 1 ]);
if ( empty ( $converttextinhtmlifnecessary )) {
// convert $newval into HTML is necessary
$text = preg_replace ( '/__\(' . preg_quote ( $reg [ 1 ], '/' ) . '\)__/' , $msgishtml ? dol_htmlentitiesbr ( $value ) : $value , $text );
} else {
if ( ! $msgishtml ) {
$valueishtml = dol_textishtml ( $value , 1 );
if ( $valueishtml ) {
$text = dol_htmlentitiesbr ( $text );
$msgishtml = 1 ;
}
} else {
$value = dol_nl2br ( " $value " );
}
$text = preg_replace ( '/__\(' . preg_quote ( $reg [ 1 ], '/' ) . '\)__/' , $value , $text );
}
2019-02-03 22:58:56 +01:00
}
}
2019-04-25 17:37:54 +02:00
// Make substitution for constant keys.
// Must be after the substitution of translation, so if the text of translation contains a string __[xxx]__, it is also converted.
2020-03-17 13:33:21 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
while ( preg_match ( '/__\[([^\]]+)\]__/' , $text , $reg )) {
2019-02-03 22:58:56 +01:00
$keyfound = $reg [ 1 ];
2021-02-23 22:03:23 +01:00
if ( isASecretKey ( $keyfound )) {
2021-05-04 13:33:18 +02:00
$value = '*****forbidden*****' ;
} else {
$value = empty ( $conf -> global -> $keyfound ) ? '' : $conf -> global -> $keyfound ;
}
if ( empty ( $converttextinhtmlifnecessary )) {
// convert $newval into HTML is necessary
$text = preg_replace ( '/__\[' . preg_quote ( $keyfound , '/' ) . '\]__/' , $msgishtml ? dol_htmlentitiesbr ( $value ) : $value , $text );
2021-02-23 22:03:23 +01:00
} else {
2021-05-04 13:33:18 +02:00
if ( ! $msgishtml ) {
$valueishtml = dol_textishtml ( $value , 1 );
if ( $valueishtml ) {
$text = dol_htmlentitiesbr ( $text );
$msgishtml = 1 ;
}
} else {
$value = dol_nl2br ( " $value " );
}
$text = preg_replace ( '/__\[' . preg_quote ( $keyfound , '/' ) . '\]__/' , $value , $text );
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
}
// Make substitition for array $substitutionarray
2021-02-23 22:03:23 +01:00
foreach ( $substitutionarray as $key => $value ) {
if ( ! isset ( $value )) {
continue ; // If value is null, it same than not having substitution key at all into array, we do not replace.
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $key == '__USER_SIGNATURE__' && ( ! empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN ))) {
$value = '' ; // Protection
}
2019-02-03 22:58:56 +01:00
2021-05-04 13:33:18 +02:00
if ( empty ( $converttextinhtmlifnecessary )) {
$text = str_replace ( " $key " , " $value " , $text ); // We must keep the " to work when value is 123.5 for example
} else {
if ( ! $msgishtml ) {
$valueishtml = dol_textishtml ( $value , 1 );
if ( $valueishtml ) {
$text = dol_htmlentitiesbr ( $text );
$msgishtml = 1 ;
}
} else {
$value = dol_nl2br ( " $value " );
}
$text = str_replace ( " $key " , " $value " , $text ); // We must keep the " to work when value is 123.5 for example
}
2019-02-03 22:58:56 +01:00
}
return $text ;
}
/**
* Complete the $substitutionarray with more entries coming from external module that had set the " substitutions=1 " into module_part array .
* In this case , method completesubstitutionarray provided by module is called .
*
* @ param array $substitutionarray Array substitution old value => new value value
* @ param Translate $outputlangs Output language
* @ param Object $object Source object
* @ param mixed $parameters Add more parameters ( useful to pass product lines )
* @ param string $callfunc What is the name of the custom function that will be called ? ( default : completesubstitutionarray )
* @ return void
2019-03-11 01:01:15 +01:00
* @ see make_substitutions ()
2019-02-03 22:58:56 +01:00
*/
function complete_substitutions_array ( & $substitutionarray , $outputlangs , $object = null , $parameters = null , $callfunc = " completesubstitutionarray " )
{
2019-11-11 23:59:36 +01:00
global $conf , $user ;
2019-02-03 22:58:56 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2021-05-04 13:33:18 +02:00
// Note: substitution key for each extrafields, using key __EXTRA_XXX__ is already available into the getCommonSubstitutionArray used to build the substitution array.
2019-02-03 22:58:56 +01:00
// Check if there is external substitution to do, requested by plugins
2019-11-11 23:59:36 +01:00
$dirsubstitutions = array_merge ( array (), ( array ) $conf -> modules_parts [ 'substitutions' ]);
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
foreach ( $dirsubstitutions as $reldir ) {
2019-11-11 23:59:36 +01:00
$dir = dol_buildpath ( $reldir , 0 );
2019-02-03 22:58:56 +01:00
// Check if directory exists
2021-02-23 22:03:23 +01:00
if ( ! dol_is_dir ( $dir )) {
continue ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$substitfiles = dol_dir_list ( $dir , 'files' , 0 , 'functions_' );
2021-02-23 22:03:23 +01:00
foreach ( $substitfiles as $substitfile ) {
2020-12-14 17:40:40 +01:00
$reg = array ();
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/functions_(.*)\.lib\.php/i' , $substitfile [ 'name' ], $reg )) {
2019-11-11 23:59:36 +01:00
$module = $reg [ 1 ];
2019-02-03 22:58:56 +01:00
dol_syslog ( " Library " . $substitfile [ 'name' ] . " found into " . $dir );
// Include the user's functions file
require_once $dir . $substitfile [ 'name' ];
// Call the user's function, and only if it is defined
2019-11-11 23:59:36 +01:00
$function_name = $module . " _ " . $callfunc ;
2020-12-14 17:40:40 +01:00
if ( function_exists ( $function_name )) {
$function_name ( $substitutionarray , $outputlangs , $object , $parameters );
}
2019-02-03 22:58:56 +01:00
}
}
}
2020-11-17 11:58:11 +01:00
if ( ! empty ( $conf -> global -> ODT_ENABLE_ALL_TAGS_IN_SUBSTITUTIONS )) {
2020-11-17 11:54:18 +01:00
// to list all tags in odt template
$tags = '' ;
foreach ( $substitutionarray as $key => $value ) {
2020-12-01 02:41:19 +01:00
$tags .= '{' . $key . '} => ' . $value . " \n " ;
2020-11-17 11:54:18 +01:00
}
$substitutionarray = array_merge ( $substitutionarray , array ( '__ALL_TAGS__' => $tags ));
}
2019-02-03 22:58:56 +01:00
}
/**
* Format output for start and end date
*
* @ param int $date_start Start date
* @ param int $date_end End date
* @ param string $format Output format
* @ param Translate $outputlangs Output language
* @ return void
*/
function print_date_range ( $date_start , $date_end , $format = '' , $outputlangs = '' )
{
print get_date_range ( $date_start , $date_end , $format , $outputlangs );
}
/**
* Format output for start and end date
*
* @ param int $date_start Start date
* @ param int $date_end End date
* @ param string $format Output format
* @ param Translate $outputlangs Output language
2021-07-05 20:32:05 +02:00
* @ param integer $withparenthesis 1 = Add parenthesis , 0 = no parenthesis
2019-02-03 22:58:56 +01:00
* @ return string String
*/
function get_date_range ( $date_start , $date_end , $format = '' , $outputlangs = '' , $withparenthesis = 1 )
{
global $langs ;
2019-11-11 23:59:36 +01:00
$out = '' ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $outputlangs )) {
$outputlangs = $langs ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $date_start && $date_end ) {
2019-11-11 23:59:36 +01:00
$out .= ( $withparenthesis ? ' (' : '' ) . $outputlangs -> transnoentitiesnoconv ( 'DateFromTo' , dol_print_date ( $date_start , $format , false , $outputlangs ), dol_print_date ( $date_end , $format , false , $outputlangs )) . ( $withparenthesis ? ')' : '' );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $date_start && ! $date_end ) {
2019-11-11 23:59:36 +01:00
$out .= ( $withparenthesis ? ' (' : '' ) . $outputlangs -> transnoentitiesnoconv ( 'DateFrom' , dol_print_date ( $date_start , $format , false , $outputlangs )) . ( $withparenthesis ? ')' : '' );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( ! $date_start && $date_end ) {
2019-11-11 23:59:36 +01:00
$out .= ( $withparenthesis ? ' (' : '' ) . $outputlangs -> transnoentitiesnoconv ( 'DateUntil' , dol_print_date ( $date_end , $format , false , $outputlangs )) . ( $withparenthesis ? ')' : '' );
2019-02-03 22:58:56 +01:00
}
return $out ;
}
/**
* Return firstname and lastname in correct order
*
* @ param string $firstname Firstname
* @ param string $lastname Lastname
2020-11-27 01:18:01 +01:00
* @ param int $nameorder - 1 = Auto , 0 = Lastname + Firstname , 1 = Firstname + Lastname , 2 = Firstname , 3 = Firstname if defined else lastname , 4 = Lastname , 5 = Lastname if defined else firstname
2019-02-03 22:58:56 +01:00
* @ return string Firstname + lastname or Lastname + firstname
*/
function dolGetFirstLastname ( $firstname , $lastname , $nameorder = - 1 )
{
global $conf ;
2019-11-11 23:59:36 +01:00
$ret = '' ;
2019-02-03 22:58:56 +01:00
// If order not defined, we use the setup
2021-02-23 22:03:23 +01:00
if ( $nameorder < 0 ) {
$nameorder = ( empty ( $conf -> global -> MAIN_FIRSTNAME_NAME_POSITION ) ? 1 : 0 );
}
2020-11-27 01:18:01 +01:00
if ( $nameorder == 1 ) {
2019-11-11 23:59:36 +01:00
$ret .= $firstname ;
2021-02-23 22:03:23 +01:00
if ( $firstname && $lastname ) {
$ret .= ' ' ;
}
2019-11-11 23:59:36 +01:00
$ret .= $lastname ;
2020-11-27 01:18:01 +01:00
} elseif ( $nameorder == 2 || $nameorder == 3 ) {
2020-09-07 10:18:17 +02:00
$ret .= $firstname ;
2020-11-27 01:18:01 +01:00
if ( empty ( $ret ) && $nameorder == 3 ) {
2020-09-07 10:18:17 +02:00
$ret .= $lastname ;
}
2020-11-27 01:18:01 +01:00
} else { // 0, 4 or 5
2019-11-11 23:59:36 +01:00
$ret .= $lastname ;
2020-11-27 01:18:01 +01:00
if ( empty ( $ret ) && $nameorder == 5 ) {
$ret .= $firstname ;
}
if ( $nameorder == 0 ) {
2021-02-23 22:03:23 +01:00
if ( $firstname && $lastname ) {
$ret .= ' ' ;
}
2020-11-27 01:18:01 +01:00
$ret .= $firstname ;
}
2019-02-03 22:58:56 +01:00
}
return $ret ;
}
/**
* Set event message in dol_events session object . Will be output by calling dol_htmloutput_events .
* Note : Calling dol_htmloutput_events is done into pages by standard llxFooter () function .
* Note : Prefer to use setEventMessages instead .
*
2020-10-25 15:42:15 +01:00
* @ param string | string [] $mesgs Message string or array
2020-10-24 09:42:52 +02:00
* @ param string $style Which style to use ( 'mesgs' by default , 'warnings' , 'errors' )
2019-02-03 22:58:56 +01:00
* @ return void
2019-03-11 01:01:15 +01:00
* @ see dol_htmloutput_events ()
2019-02-03 22:58:56 +01:00
*/
function setEventMessage ( $mesgs , $style = 'mesgs' )
{
//dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); This is not deprecated, it is used by setEventMessages function
2020-10-24 09:42:52 +02:00
if ( ! is_array ( $mesgs )) {
2020-10-27 19:46:07 +01:00
// If mesgs is a string
2021-02-23 22:03:23 +01:00
if ( $mesgs ) {
$_SESSION [ 'dol_events' ][ $style ][] = $mesgs ;
}
2020-10-24 09:42:52 +02:00
} else {
2020-10-27 19:46:07 +01:00
// If mesgs is an array
2021-02-23 22:03:23 +01:00
foreach ( $mesgs as $mesg ) {
if ( $mesg ) {
$_SESSION [ 'dol_events' ][ $style ][] = $mesg ;
}
2019-02-03 22:58:56 +01:00
}
}
}
/**
* Set event messages in dol_events session object . Will be output by calling dol_htmloutput_events .
* Note : Calling dol_htmloutput_events is done into pages by standard llxFooter () function .
*
* @ param string $mesg Message string
* @ param array $mesgs Message array
* @ param string $style Which style to use ( 'mesgs' by default , 'warnings' , 'errors' )
2019-08-18 18:36:18 +02:00
* @ param string $messagekey A key to be used to allow the feature " Never show this message again "
2019-02-03 22:58:56 +01:00
* @ return void
2019-03-11 01:01:15 +01:00
* @ see dol_htmloutput_events ()
2019-02-03 22:58:56 +01:00
*/
2019-08-18 18:36:18 +02:00
function setEventMessages ( $mesg , $mesgs , $style = 'mesgs' , $messagekey = '' )
2019-02-03 22:58:56 +01:00
{
2021-02-23 22:03:23 +01:00
if ( empty ( $mesg ) && empty ( $mesgs )) {
2019-02-03 22:58:56 +01:00
dol_syslog ( " Try to add a message in stack with empty message " , LOG_WARNING );
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $messagekey ) {
2019-08-18 18:36:18 +02:00
// Complete message with a js link to set a cookie "DOLHIDEMESSAGE".$messagekey;
// TODO
2019-11-11 23:59:36 +01:00
$mesg .= '' ;
2019-08-18 18:36:18 +02:00
}
2021-02-23 22:03:23 +01:00
if ( empty ( $messagekey ) || empty ( $_COOKIE [ " DOLHIDEMESSAGE " . $messagekey ])) {
if ( ! in_array (( string ) $style , array ( 'mesgs' , 'warnings' , 'errors' ))) {
dol_print_error ( '' , 'Bad parameter style=' . $style . ' for setEventMessages' );
}
if ( empty ( $mesgs )) {
setEventMessage ( $mesg , $style );
} else {
if ( ! empty ( $mesg ) && ! in_array ( $mesg , $mesgs )) {
setEventMessage ( $mesg , $style ); // Add message string if not already into array
}
2019-08-18 18:36:18 +02:00
setEventMessage ( $mesgs , $style );
}
2019-02-03 22:58:56 +01:00
}
}
}
/**
* Print formated messages to output ( Used to show messages on html output ) .
* Note : Calling dol_htmloutput_events is done into pages by standard llxFooter () function , so there is
* no need to call it explicitely .
*
* @ param int $disabledoutputofmessages Clear all messages stored into session without diplaying them
* @ return void
2019-03-11 01:01:15 +01:00
* @ see dol_htmloutput_mesg ()
2019-02-03 22:58:56 +01:00
*/
function dol_htmloutput_events ( $disabledoutputofmessages = 0 )
{
// Show mesgs
if ( isset ( $_SESSION [ 'dol_events' ][ 'mesgs' ])) {
2021-02-23 22:03:23 +01:00
if ( empty ( $disabledoutputofmessages )) {
dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'mesgs' ]);
}
2019-02-03 22:58:56 +01:00
unset ( $_SESSION [ 'dol_events' ][ 'mesgs' ]);
}
// Show errors
if ( isset ( $_SESSION [ 'dol_events' ][ 'errors' ])) {
2021-02-23 22:03:23 +01:00
if ( empty ( $disabledoutputofmessages )) {
dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'errors' ], 'error' );
}
2019-02-03 22:58:56 +01:00
unset ( $_SESSION [ 'dol_events' ][ 'errors' ]);
}
// Show warnings
if ( isset ( $_SESSION [ 'dol_events' ][ 'warnings' ])) {
2021-02-23 22:03:23 +01:00
if ( empty ( $disabledoutputofmessages )) {
dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'warnings' ], 'warning' );
}
2019-02-03 22:58:56 +01:00
unset ( $_SESSION [ 'dol_events' ][ 'warnings' ]);
}
}
/**
* Get formated messages to output ( Used to show messages on html output ) .
* This include also the translation of the message key .
*
* @ param string $mesgstring Message string or message key
* @ param string [] $mesgarray Array of message strings or message keys
* @ param string $style Style of message output ( 'ok' or 'error' )
* @ param int $keepembedded Set to 1 in error message must be kept embedded into its html place ( this disable jnotify )
* @ return string Return html output
*
2019-03-11 01:01:15 +01:00
* @ see dol_print_error ()
* @ see dol_htmloutput_errors ()
* @ see setEventMessages ()
2019-02-03 22:58:56 +01:00
*/
function get_htmloutput_mesg ( $mesgstring = '' , $mesgarray = '' , $style = 'ok' , $keepembedded = 0 )
{
global $conf , $langs ;
2021-03-01 20:37:16 +01:00
$ret = 0 ;
$return = '' ;
2019-11-11 23:59:36 +01:00
$out = '' ;
$divstart = $divend = '' ;
2019-02-03 22:58:56 +01:00
// If inline message with no format, we add it.
2021-02-23 22:03:23 +01:00
if (( empty ( $conf -> use_javascript_ajax ) || ! empty ( $conf -> global -> MAIN_DISABLE_JQUERY_JNOTIFY ) || $keepembedded ) && ! preg_match ( '/<div class=".*">/i' , $out )) {
2019-11-11 23:59:36 +01:00
$divstart = '<div class="' . $style . ' clearboth">' ;
$divend = '</div>' ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if (( is_array ( $mesgarray ) && count ( $mesgarray )) || $mesgstring ) {
2019-02-03 22:58:56 +01:00
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$out .= $divstart ;
2021-02-23 22:03:23 +01:00
if ( is_array ( $mesgarray ) && count ( $mesgarray )) {
foreach ( $mesgarray as $message ) {
2019-02-03 22:58:56 +01:00
$ret ++ ;
2019-11-11 23:59:36 +01:00
$out .= $langs -> trans ( $message );
2021-02-23 22:03:23 +01:00
if ( $ret < count ( $mesgarray )) {
$out .= " <br> \n " ;
}
2019-02-03 22:58:56 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( $mesgstring ) {
2019-02-03 22:58:56 +01:00
$langs -> load ( " errors " );
$ret ++ ;
2019-11-11 23:59:36 +01:00
$out .= $langs -> trans ( $mesgstring );
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$out .= $divend ;
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $out ) {
if ( ! empty ( $conf -> use_javascript_ajax ) && empty ( $conf -> global -> MAIN_DISABLE_JQUERY_JNOTIFY ) && empty ( $keepembedded )) {
2019-02-03 22:58:56 +01:00
$return = ' < script >
$ ( document ) . ready ( function () {
2019-11-11 23:59:36 +01:00
var block = '.(!empty($conf->global->MAIN_USE_JQUERY_BLOCKUI) ? "true" : "false").'
2019-02-03 22:58:56 +01:00
if ( block ) {
$ . dolEventValid ( " " , " '.dol_escape_js( $out ).' " );
} else {
/* jnotify(message, preset of message type, keepmessage) */
$ . jnotify ( " '.dol_escape_js( $out ).' " ,
2019-11-11 23:59:36 +01:00
" '.( $style == " ok " ? 3000 : $style ).' " ,
'.($style == "ok" ? "false" : "true").' ,
2019-02-03 22:58:56 +01:00
{ remove : function (){} } );
}
});
</ script > ' ;
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
$return = $out ;
}
}
return $return ;
}
/**
* Get formated error messages to output ( Used to show messages on html output ) .
*
* @ param string $mesgstring Error message
* @ param array $mesgarray Error messages array
* @ param int $keepembedded Set to 1 in error message must be kept embedded into its html place ( this disable jnotify )
* @ return string Return html output
*
2019-03-11 01:01:15 +01:00
* @ see dol_print_error ()
* @ see dol_htmloutput_mesg ()
2019-02-03 22:58:56 +01:00
*/
function get_htmloutput_errors ( $mesgstring = '' , $mesgarray = array (), $keepembedded = 0 )
{
return get_htmloutput_mesg ( $mesgstring , $mesgarray , 'error' , $keepembedded );
}
/**
* Print formated messages to output ( Used to show messages on html output ) .
*
* @ param string $mesgstring Message string or message key
* @ param string [] $mesgarray Array of message strings or message keys
* @ param string $style Which style to use ( 'ok' , 'warning' , 'error' )
* @ param int $keepembedded Set to 1 if message must be kept embedded into its html place ( this disable jnotify )
* @ return void
*
2019-03-11 01:01:15 +01:00
* @ see dol_print_error ()
* @ see dol_htmloutput_errors ()
* @ see setEventMessages ()
2019-02-03 22:58:56 +01:00
*/
function dol_htmloutput_mesg ( $mesgstring = '' , $mesgarray = array (), $style = 'ok' , $keepembedded = 0 )
{
2021-02-23 22:03:23 +01:00
if ( empty ( $mesgstring ) && ( ! is_array ( $mesgarray ) || count ( $mesgarray ) == 0 )) {
return ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$iserror = 0 ;
$iswarning = 0 ;
2021-02-23 22:03:23 +01:00
if ( is_array ( $mesgarray )) {
foreach ( $mesgarray as $val ) {
if ( $val && preg_match ( '/class="error"/i' , $val )) {
2021-03-01 20:37:16 +01:00
$iserror ++ ;
break ;
2021-02-23 22:03:23 +01:00
}
if ( $val && preg_match ( '/class="warning"/i' , $val )) {
2021-03-01 20:37:16 +01:00
$iswarning ++ ;
break ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( $mesgstring && preg_match ( '/class="error"/i' , $mesgstring )) {
$iserror ++ ;
} elseif ( $mesgstring && preg_match ( '/class="warning"/i' , $mesgstring )) {
$iswarning ++ ;
}
if ( $style == 'error' ) {
$iserror ++ ;
}
if ( $style == 'warning' ) {
$iswarning ++ ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $iserror || $iswarning ) {
2019-02-03 22:58:56 +01:00
// Remove div from texts
2019-11-11 23:59:36 +01:00
$mesgstring = preg_replace ( '/<\/div><div class="(error|warning)">/' , '<br>' , $mesgstring );
$mesgstring = preg_replace ( '/<div class="(error|warning)">/' , '' , $mesgstring );
$mesgstring = preg_replace ( '/<\/div>/' , '' , $mesgstring );
2019-02-03 22:58:56 +01:00
// Remove div from texts array
2021-02-23 22:03:23 +01:00
if ( is_array ( $mesgarray )) {
2019-11-11 23:59:36 +01:00
$newmesgarray = array ();
2021-02-23 22:03:23 +01:00
foreach ( $mesgarray as $val ) {
if ( is_string ( $val )) {
2019-11-11 23:59:36 +01:00
$tmpmesgstring = preg_replace ( '/<\/div><div class="(error|warning)">/' , '<br>' , $val );
$tmpmesgstring = preg_replace ( '/<div class="(error|warning)">/' , '' , $tmpmesgstring );
$tmpmesgstring = preg_replace ( '/<\/div>/' , '' , $tmpmesgstring );
$newmesgarray [] = $tmpmesgstring ;
2020-05-21 15:05:19 +02:00
} else {
2019-08-01 15:42:44 +02:00
dol_syslog ( " Error call of dol_htmloutput_mesg with an array with a value that is not a string " , LOG_WARNING );
}
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$mesgarray = $newmesgarray ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
print get_htmloutput_mesg ( $mesgstring , $mesgarray , ( $iserror ? 'error' : 'warning' ), $keepembedded );
2021-02-23 22:03:23 +01:00
} else {
print get_htmloutput_mesg ( $mesgstring , $mesgarray , 'ok' , $keepembedded );
}
2019-02-03 22:58:56 +01:00
}
/**
* Print formated error messages to output ( Used to show messages on html output ) .
*
* @ param string $mesgstring Error message
* @ param array $mesgarray Error messages array
* @ param int $keepembedded Set to 1 in error message must be kept embedded into its html place ( this disable jnotify )
* @ return void
*
2019-03-11 01:01:15 +01:00
* @ see dol_print_error ()
* @ see dol_htmloutput_mesg ()
2019-02-03 22:58:56 +01:00
*/
function dol_htmloutput_errors ( $mesgstring = '' , $mesgarray = array (), $keepembedded = 0 )
{
dol_htmloutput_mesg ( $mesgstring , $mesgarray , 'error' , $keepembedded );
}
/**
* 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 ) .
*
2019-05-16 12:25:14 +02:00
* @ param array $array Array to sort ( array of array ( 'key1' => val1 , 'key2' => val2 , 'key3' ... ) or array of objects )
2019-02-03 22:58:56 +01:00
* @ param string $index Key in array to use for sorting criteria
* @ param int $order Sort order ( 'asc' or 'desc' )
2021-01-23 13:55:56 +01:00
* @ param int $natsort 1 = use " natural " sort ( natsort ) for a search criteria thats is strings or unknown , 0 = use " standard " sort ( asort ) for numbers
2019-02-03 22:58:56 +01:00
* @ param int $case_sensitive 1 = sort is case sensitive , 0 = not case sensitive
* @ param int $keepindex If 0 and index key of array to sort is a numeric , than index will be rewrote . If 1 or index key is not numeric , key for index is kept after sorting .
* @ return array Sorted array
*/
function dol_sort_array ( & $array , $index , $order = 'asc' , $natsort = 0 , $case_sensitive = 0 , $keepindex = 0 )
{
// Clean parameters
2019-11-11 23:59:36 +01:00
$order = strtolower ( $order );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( is_array ( $array )) {
2019-11-11 23:59:36 +01:00
$sizearray = count ( $array );
2021-02-23 22:03:23 +01:00
if ( $sizearray > 0 ) {
2019-02-03 22:58:56 +01:00
$temp = array ();
2021-02-23 22:03:23 +01:00
foreach ( array_keys ( $array ) as $key ) {
2020-12-13 16:27:44 +01:00
if ( is_object ( $array [ $key ])) {
2020-12-29 04:27:16 +01:00
$temp [ $key ] = empty ( $array [ $key ] -> $index ) ? 0 : $array [ $key ] -> $index ;
2020-05-21 15:05:19 +02:00
} else {
2020-12-29 04:27:16 +01:00
$temp [ $key ] = empty ( $array [ $key ][ $index ]) ? 0 : $array [ $key ][ $index ];
2019-05-16 12:25:14 +02:00
}
}
2019-02-03 22:58:56 +01:00
2020-09-07 10:18:17 +02:00
if ( ! $natsort ) {
2021-01-23 13:55:56 +01:00
if ( $order == 'asc' ) {
asort ( $temp );
} else {
arsort ( $temp );
}
2020-09-07 10:18:17 +02:00
} else {
2021-01-23 13:55:56 +01:00
if ( $case_sensitive ) {
natsort ( $temp );
} else {
natcasesort ( $temp ); // natecasesort is not sensible to case
}
2021-02-23 22:03:23 +01:00
if ( $order != 'asc' ) {
$temp = array_reverse ( $temp , true );
}
2020-09-07 10:18:17 +02:00
}
2019-02-03 22:58:56 +01:00
$sorted = array ();
2021-02-23 22:03:23 +01:00
foreach ( array_keys ( $temp ) as $key ) {
2019-11-11 23:59:36 +01:00
( is_numeric ( $key ) && empty ( $keepindex )) ? $sorted [] = $array [ $key ] : $sorted [ $key ] = $array [ $key ];
2019-02-03 22:58:56 +01:00
}
return $sorted ;
}
}
return $array ;
}
/**
* Check if a string is in UTF8
*
* @ param string $str String to check
* @ return boolean True if string is UTF8 or ISO compatible with UTF8 , False if not ( ISO with special char or Binary )
*/
function utf8_check ( $str )
{
2020-12-14 13:01:25 +01:00
$str = ( string ) $str ; // Sometimes string is an int.
2019-02-03 22:58:56 +01:00
// We must use here a binary strlen function (so not dol_strlen)
$strLength = dol_strlen ( $str );
2020-12-14 13:01:25 +01:00
for ( $i = 0 ; $i < $strLength ; $i ++ ) {
2021-02-23 22:03:23 +01:00
if ( ord ( $str [ $i ]) < 0x80 ) {
continue ; // 0bbbbbbb
} elseif (( ord ( $str [ $i ]) & 0xE0 ) == 0xC0 ) {
$n = 1 ; // 110bbbbb
} elseif (( ord ( $str [ $i ]) & 0xF0 ) == 0xE0 ) {
$n = 2 ; // 1110bbbb
} elseif (( ord ( $str [ $i ]) & 0xF8 ) == 0xF0 ) {
$n = 3 ; // 11110bbb
} elseif (( ord ( $str [ $i ]) & 0xFC ) == 0xF8 ) {
$n = 4 ; // 111110bb
} elseif (( ord ( $str [ $i ]) & 0xFE ) == 0xFC ) {
$n = 5 ; // 1111110b
} else {
return false ; // Does not match any model
}
2019-11-11 23:59:36 +01:00
for ( $j = 0 ; $j < $n ; $j ++ ) { // n bytes matching 10bbbbbb follow ?
2021-02-23 22:03:23 +01:00
if (( ++ $i == strlen ( $str )) || (( ord ( $str [ $i ]) & 0xC0 ) != 0x80 )) {
return false ;
}
2019-02-03 22:58:56 +01:00
}
}
return true ;
}
2020-02-06 12:58:02 +01:00
/**
* Check if a string is in ASCII
*
* @ param string $str String to check
* @ return boolean True if string is ASCII , False if not ( byte value > 0x7F )
*/
function ascii_check ( $str )
{
if ( function_exists ( 'mb_check_encoding' )) {
//if (mb_detect_encoding($str, 'ASCII', true) return false;
2021-02-23 22:03:23 +01:00
if ( ! mb_check_encoding ( $str , 'ASCII' )) {
return false ;
}
2020-02-06 12:58:02 +01:00
} else {
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[^\x00-\x7f]/' , $str )) {
return false ; // Contains a byte > 7f
}
2020-02-06 12:58:02 +01:00
}
return true ;
}
2019-02-03 22:58:56 +01:00
/**
* Return a string encoded into OS filesystem encoding . This function is used to define
* value to pass to filesystem PHP functions .
*
* @ param string $str String to encode ( UTF - 8 )
* @ return string Encoded string ( UTF - 8 , ISO - 8859 - 1 )
*/
function dol_osencode ( $str )
{
global $conf ;
2019-11-11 23:59:36 +01:00
$tmp = ini_get ( " unicode.filesystem_encoding " ); // Disponible avec PHP 6.0
2021-02-23 22:03:23 +01:00
if ( empty ( $tmp ) && ! empty ( $_SERVER [ " WINDIR " ])) {
$tmp = 'iso-8859-1' ; // By default for windows
}
if ( empty ( $tmp )) {
$tmp = 'utf-8' ; // By default for other
}
if ( ! empty ( $conf -> global -> MAIN_FILESYSTEM_ENCODING )) {
$tmp = $conf -> global -> MAIN_FILESYSTEM_ENCODING ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $tmp == 'iso-8859-1' ) {
return utf8_decode ( $str );
}
2019-02-03 22:58:56 +01:00
return $str ;
}
/**
* Return an id or code from a code or id .
* Store also Code - Id into a cache to speed up next request on same key .
*
* @ param DoliDB $db Database handler
* @ param string $key Code or Id to get Id or Code
* @ param string $tablename Table name without prefix
* @ param string $fieldkey Field to search the key into
* @ param string $fieldid Field to get
* @ param int $entityfilter Filter by entity
* @ return int < 0 if KO , Id of code if OK
* @ see $langs -> getLabelFromKey
*/
function dol_getIdFromCode ( $db , $key , $tablename , $fieldkey = 'code' , $fieldid = 'id' , $entityfilter = 0 )
{
global $cache_codes ;
// If key empty
2021-02-23 22:03:23 +01:00
if ( $key == '' ) {
return '' ;
}
2019-02-03 22:58:56 +01:00
// Check in cache
2021-02-23 22:03:23 +01:00
if ( isset ( $cache_codes [ $tablename ][ $key ][ $fieldid ])) { // Can be defined to 0 or ''
2019-11-11 23:59:36 +01:00
return $cache_codes [ $tablename ][ $key ][ $fieldid ]; // Found in cache
2019-02-03 22:58:56 +01:00
}
2019-04-10 16:42:45 +02:00
dol_syslog ( 'dol_getIdFromCode (value for field ' . $fieldid . ' from key ' . $key . ' not found into cache)' , LOG_DEBUG );
2019-02-03 22:58:56 +01:00
$sql = " SELECT " . $fieldid . " as valuetoget " ;
2019-11-11 23:59:36 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . $tablename ;
$sql .= " WHERE " . $fieldkey . " = ' " . $db -> escape ( $key ) . " ' " ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $entityfilter )) {
2019-11-11 23:59:36 +01:00
$sql .= " AND entity IN ( " . getEntity ( $tablename ) . " ) " ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-02-03 22:58:56 +01:00
$obj = $db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
$cache_codes [ $tablename ][ $key ][ $fieldid ] = $obj -> valuetoget ;
} else {
$cache_codes [ $tablename ][ $key ][ $fieldid ] = '' ;
}
2019-02-03 22:58:56 +01:00
$db -> free ( $resql );
return $cache_codes [ $tablename ][ $key ][ $fieldid ];
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
return - 1 ;
}
}
/**
* Verify if condition in string is ok or not
*
2021-11-18 13:10:52 +01:00
* @ param string $strToEvaluate String with condition to check
2022-03-03 01:59:31 +01:00
* @ return boolean True or False . Note : It returns also True if $strToEvaluate is '' . False if error
2019-02-03 22:58:56 +01:00
*/
2021-11-18 13:10:52 +01:00
function verifCond ( $strToEvaluate )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
global $user , $conf , $langs ;
2019-02-03 22:58:56 +01:00
global $leftmenu ;
2019-11-11 23:59:36 +01:00
global $rights ; // To export to dol_eval function
2019-02-03 22:58:56 +01:00
2021-11-30 16:24:18 +01:00
//print $strToEvaluate."<br>\n";
2019-02-03 22:58:56 +01:00
$rights = true ;
2021-11-30 16:24:18 +01:00
if ( isset ( $strToEvaluate ) && $strToEvaluate !== '' ) {
2022-03-01 18:21:30 +01:00
//$str = 'if(!('.$strToEvaluate.')) $rights = false;';
//dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition
2022-03-03 01:17:44 +01:00
//var_dump($strToEvaluate);
2022-03-03 02:05:13 +01:00
$rep = dol_eval ( $strToEvaluate , 1 , 1 , '1' ); // The dol_eval must contains all the global $xxx for all variables $xxx found into the string condition
2022-03-03 01:59:31 +01:00
$rights = (( $rep && strpos ( $rep , 'Bad string syntax to evaluate' ) === false ) ? true : false );
2022-03-03 01:17:44 +01:00
//var_dump($rights);
2019-02-03 22:58:56 +01:00
}
return $rights ;
}
/**
* Replace eval function to add more security .
* This function is called by verifCond () or trans () and transnoentitiesnoconv () .
*
2022-03-01 16:38:06 +01:00
* @ param string $s String to evaluate
* @ param int $returnvalue 0 = No return ( used to execute eval ( $a = something )) . 1 = Value of eval is returned ( used to eval ( $something )) .
* @ param int $hideerrors 1 = Hide errors
2022-03-03 01:59:31 +01:00
* @ param string $onlysimplestring 0 = Accept all chars , 1 = Accept only simple string with char 'a-z0-9\s^$_->&|=!?():"\',/' and restrict use of (, 2 = Accept also ';' and no restriction on ( .
2022-03-01 16:38:06 +01:00
* @ return mixed Nothing or return result of eval
2019-02-03 22:58:56 +01:00
*/
2022-03-01 16:38:06 +01:00
function dol_eval ( $s , $returnvalue = 0 , $hideerrors = 1 , $onlysimplestring = '1' )
2019-02-03 22:58:56 +01:00
{
// Only global variables can be changed by eval function and returned to caller
global $db , $langs , $user , $conf , $website , $websitepage ;
global $action , $mainmenu , $leftmenu ;
global $rights ;
global $object ;
global $mysoc ;
2019-11-11 23:59:36 +01:00
global $obj ; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
global $soc ; // For backward compatibility
2019-02-03 22:58:56 +01:00
2022-03-03 01:59:31 +01:00
// Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing
2022-03-01 16:38:06 +01:00
if ( $onlysimplestring == '1' ) {
2022-03-03 01:59:31 +01:00
// We must accept: '1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL'
// We must accept: '$conf->barcode->enabled && preg_match(\'/^(AAA|BBB)/\',$leftmenu)'
2022-03-16 21:31:08 +01:00
if ( preg_match ( '/[^a-z0-9\s' . preg_quote ( '^$_+-*>&|=!?():"\',/' , '/' ) . ']/i' , $s )) {
2022-03-01 18:14:24 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate (found chars that are not chars for simplestring): ' . $s );
return '' ;
}
2022-03-03 01:59:31 +01:00
// TODO We can exclude all () that is not '($db)' and 'getDolGlobalInt(' and 'getDolGlobalString(' and 'preg_match('
2022-03-01 19:13:28 +01:00
// ...
2022-03-01 18:14:24 +01:00
}
} elseif ( $onlysimplestring == '2' ) {
2022-03-03 01:59:31 +01:00
// We must accept: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found"
2022-03-16 21:31:08 +01:00
if ( preg_match ( '/[^a-z0-9\s' . preg_quote ( '^$_+-*>&|=!?():"\',/;[]' , '/' ) . ']/i' , $s )) {
2022-03-01 18:14:24 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate (found chars that are not chars for simplestring): ' . $s );
return '' ;
}
2022-03-01 16:38:06 +01:00
}
}
2022-03-01 18:21:30 +01:00
if ( strpos ( $s , '::' ) !== false ) {
2022-03-03 01:59:31 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate (double : char is forbidden): ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate (double : char is forbidden): ' . $s );
return '' ;
}
2022-03-01 18:21:30 +01:00
}
2021-06-09 17:44:42 +02:00
if ( strpos ( $s , '`' ) !== false ) {
2022-03-03 01:17:44 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate (backtick char is forbidden): ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate (backtick char is forbidden): ' . $s );
return '' ;
}
2022-03-01 16:38:06 +01:00
}
if ( strpos ( $s , '.' ) !== false ) {
2022-03-03 01:17:44 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate (dot char is forbidden): ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate (dot char is forbidden): ' . $s );
return '' ;
}
2021-06-09 17:44:42 +02:00
}
2021-10-31 15:59:03 +01:00
// We block use of php exec or php file functions
$forbiddenphpstrings = array ( '$$' );
2021-06-10 11:57:42 +02:00
$forbiddenphpstrings = array_merge ( $forbiddenphpstrings , array ( '_ENV' , '_SESSION' , '_COOKIE' , '_GET' , '_POST' , '_REQUEST' ));
2021-10-31 15:59:03 +01:00
2022-03-03 01:59:31 +01:00
$forbiddenphpfunctions = array ( " exec " , " passthru " , " shell_exec " , " system " , " proc_open " , " popen " , " eval " , " dol_eval " , " executeCLI " , 'verifCond' );
2022-03-01 16:38:06 +01:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " fopen " , " file_put_contents " , " fputs " , " fputscsv " , " fwrite " , " fpassthru " , " require " , " include " , " mkdir " , " rmdir " , " symlink " , " touch " , " unlink " , " umask " ));
2021-10-31 15:59:03 +01:00
$forbiddenphpfunctions = array_merge ( $forbiddenphpfunctions , array ( " function " , " call_user_func " ));
$forbiddenphpregex = 'global\s+\$|\b(' . implode ( '|' , $forbiddenphpfunctions ) . ')\b' ;
2021-06-09 17:44:42 +02:00
do {
$oldstringtoclean = $s ;
2021-06-10 11:57:42 +02:00
$s = str_ireplace ( $forbiddenphpstrings , '__forbiddenstring__' , $s );
2021-10-31 15:59:03 +01:00
$s = preg_replace ( '/' . $forbiddenphpregex . '/i' , '__forbiddenstring__' , $s );
2021-06-09 17:44:42 +02:00
//$s = preg_replace('/\$[a-zA-Z0-9_\->\$]+\(/i', '', $s); // Remove $function( call and $mycall->mymethod(
} while ( $oldstringtoclean != $s );
if ( strpos ( $s , '__forbiddenstring__' ) !== false ) {
2021-06-10 11:57:42 +02:00
dol_syslog ( 'Bad string syntax to evaluate: ' . $s , LOG_WARNING );
2022-03-03 01:17:44 +01:00
if ( $returnvalue ) {
return 'Bad string syntax to evaluate: ' . $s ;
} else {
dol_syslog ( 'Bad string syntax to evaluate: ' . $s );
return '' ;
}
2021-06-09 17:44:42 +02:00
}
2019-02-03 22:58:56 +01:00
//print $s."<br>\n";
2020-10-30 05:45:36 +01:00
if ( $returnvalue ) {
2021-02-23 22:03:23 +01:00
if ( $hideerrors ) {
return @ eval ( 'return ' . $s . ';' );
} else {
return eval ( 'return ' . $s . ';' );
}
2020-05-21 15:05:19 +02:00
} else {
2021-02-23 22:03:23 +01:00
if ( $hideerrors ) {
@ eval ( $s );
} else {
eval ( $s );
}
2019-02-03 22:58:56 +01:00
}
}
/**
* Return if var element is ok
*
* @ param string $element Variable to check
* @ return boolean Return true of variable is not empty
*/
function dol_validElement ( $element )
{
return ( trim ( $element ) != '' );
}
/**
2021-04-18 15:07:22 +02:00
* Return img flag of country for a language code or country code .
2019-02-03 22:58:56 +01:00
*
2020-11-29 15:47:08 +01:00
* @ param string $codelang Language code ( 'en_IN' , 'fr_CA' , ... ) or ISO Country code on 2 characters in uppercase ( 'IN' , 'FR' )
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' or 'class="saturatemedium"' )
2021-08-10 19:44:55 +02:00
* @ param int $notitlealt No title alt
2019-02-03 22:58:56 +01:00
* @ return string HTML img string with flag .
*/
2021-08-10 19:44:55 +02:00
function picto_from_langcode ( $codelang , $moreatt = '' , $notitlealt = 0 )
2019-02-03 22:58:56 +01:00
{
2021-02-23 22:03:23 +01:00
if ( empty ( $codelang )) {
return '' ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $codelang == 'auto' ) {
2021-07-05 19:28:50 +02:00
return '<span class="fa fa-language"></span>' ;
2019-02-03 22:58:56 +01:00
}
$langtocountryflag = array (
'ar_AR' => '' ,
'ca_ES' => 'catalonia' ,
'da_DA' => 'dk' ,
'fr_CA' => 'mq' ,
2020-11-29 15:47:08 +01:00
'sv_SV' => 'se' ,
2021-01-28 12:02:16 +01:00
'sw_SW' => 'unknown' ,
2020-11-29 15:47:08 +01:00
'AQ' => 'unknown' ,
'CW' => 'unknown' ,
'IM' => 'unknown' ,
'JE' => 'unknown' ,
'MF' => 'unknown' ,
'BL' => 'unknown' ,
'SX' => 'unknown'
2019-02-03 22:58:56 +01:00
);
2021-02-23 22:03:23 +01:00
if ( isset ( $langtocountryflag [ $codelang ])) {
$flagImage = $langtocountryflag [ $codelang ];
} else {
2019-02-03 22:58:56 +01:00
$tmparray = explode ( '_' , $codelang );
$flagImage = empty ( $tmparray [ 1 ]) ? $tmparray [ 0 ] : $tmparray [ 1 ];
}
2021-08-10 19:44:55 +02:00
return img_picto_common ( $codelang , 'flags/' . strtolower ( $flagImage ) . '.png' , $moreatt , 0 , $notitlealt );
2019-02-03 22:58:56 +01:00
}
/**
2019-02-28 13:11:14 +01:00
* Return default language from country code .
* Return null if not found .
2019-02-03 22:58:56 +01:00
*
2021-09-20 13:20:54 +02:00
* @ param string $countrycode Country code like 'US' , 'FR' , 'CA' , 'ES' , 'IN' , 'MX' , ...
* @ return string Value of locale like 'en_US' , 'fr_FR' , ... or null if not found
2019-02-03 22:58:56 +01:00
*/
function getLanguageCodeFromCountryCode ( $countrycode )
{
global $mysoc ;
2021-02-23 22:03:23 +01:00
if ( empty ( $countrycode )) {
return null ;
}
2019-02-28 13:11:14 +01:00
2021-02-23 22:03:23 +01:00
if ( strtoupper ( $countrycode ) == 'MQ' ) {
return 'fr_CA' ;
}
if ( strtoupper ( $countrycode ) == 'SE' ) {
return 'sv_SE' ; // se_SE is Sami/Sweden, and we want in priority sv_SE for SE country
}
if ( strtoupper ( $countrycode ) == 'CH' ) {
if ( $mysoc -> country_code == 'FR' ) {
return 'fr_CH' ;
}
if ( $mysoc -> country_code == 'DE' ) {
return 'de_CH' ;
}
2021-05-31 13:35:03 +02:00
if ( $mysoc -> country_code == 'IT' ) {
return 'it_CH' ;
}
2019-02-03 22:58:56 +01:00
}
// Locale list taken from:
// http://stackoverflow.com/questions/3191664/
// list-of-all-locales-and-their-short-codes
$locales = array (
'af-ZA' ,
'am-ET' ,
'ar-AE' ,
'ar-BH' ,
'ar-DZ' ,
'ar-EG' ,
'ar-IQ' ,
'ar-JO' ,
'ar-KW' ,
'ar-LB' ,
'ar-LY' ,
'ar-MA' ,
'ar-OM' ,
'ar-QA' ,
'ar-SA' ,
'ar-SY' ,
'ar-TN' ,
'ar-YE' ,
2021-09-20 13:20:54 +02:00
//'as-IN', // Moved after en-IN
2019-02-03 22:58:56 +01:00
'ba-RU' ,
'be-BY' ,
'bg-BG' ,
'bn-BD' ,
2021-09-20 13:20:54 +02:00
//'bn-IN', // Moved after en-IN
2019-02-03 22:58:56 +01:00
'bo-CN' ,
'br-FR' ,
'ca-ES' ,
'co-FR' ,
'cs-CZ' ,
'cy-GB' ,
'da-DK' ,
'de-AT' ,
'de-CH' ,
'de-DE' ,
'de-LI' ,
'de-LU' ,
'dv-MV' ,
'el-GR' ,
'en-AU' ,
'en-BZ' ,
'en-CA' ,
'en-GB' ,
'en-IE' ,
'en-IN' ,
2021-09-20 13:20:54 +02:00
'as-IN' , // as-IN must be after en-IN (en in priority if country is IN)
'bn-IN' , // bn-IN must be after en-IN (en in priority if country is IN)
2019-02-03 22:58:56 +01:00
'en-JM' ,
'en-MY' ,
'en-NZ' ,
'en-PH' ,
'en-SG' ,
'en-TT' ,
'en-US' ,
'en-ZA' ,
'en-ZW' ,
'es-AR' ,
'es-BO' ,
'es-CL' ,
'es-CO' ,
'es-CR' ,
'es-DO' ,
'es-EC' ,
'es-ES' ,
'es-GT' ,
'es-HN' ,
'es-MX' ,
'es-NI' ,
'es-PA' ,
'es-PE' ,
'es-PR' ,
'es-PY' ,
'es-SV' ,
'es-US' ,
'es-UY' ,
'es-VE' ,
'et-EE' ,
'eu-ES' ,
'fa-IR' ,
'fi-FI' ,
'fo-FO' ,
'fr-BE' ,
'fr-CA' ,
'fr-CH' ,
'fr-FR' ,
'fr-LU' ,
'fr-MC' ,
'fy-NL' ,
'ga-IE' ,
'gd-GB' ,
'gl-ES' ,
'gu-IN' ,
'he-IL' ,
'hi-IN' ,
'hr-BA' ,
'hr-HR' ,
'hu-HU' ,
'hy-AM' ,
'id-ID' ,
'ig-NG' ,
'ii-CN' ,
'is-IS' ,
'it-CH' ,
'it-IT' ,
'ja-JP' ,
'ka-GE' ,
'kk-KZ' ,
'kl-GL' ,
'km-KH' ,
'kn-IN' ,
'ko-KR' ,
'ky-KG' ,
'lb-LU' ,
'lo-LA' ,
'lt-LT' ,
'lv-LV' ,
'mi-NZ' ,
'mk-MK' ,
'ml-IN' ,
'mn-MN' ,
'mr-IN' ,
'ms-BN' ,
'ms-MY' ,
'mt-MT' ,
'nb-NO' ,
'ne-NP' ,
'nl-BE' ,
'nl-NL' ,
'nn-NO' ,
'oc-FR' ,
'or-IN' ,
'pa-IN' ,
'pl-PL' ,
'ps-AF' ,
'pt-BR' ,
'pt-PT' ,
'rm-CH' ,
2021-05-31 13:35:03 +02:00
'ro-MD' ,
2019-02-03 22:58:56 +01:00
'ro-RO' ,
'ru-RU' ,
'rw-RW' ,
'sa-IN' ,
'se-FI' ,
'se-NO' ,
'se-SE' ,
'si-LK' ,
'sk-SK' ,
'sl-SI' ,
'sq-AL' ,
'sv-FI' ,
'sv-SE' ,
'sw-KE' ,
'ta-IN' ,
'te-IN' ,
'th-TH' ,
'tk-TM' ,
'tn-ZA' ,
'tr-TR' ,
'tt-RU' ,
'ug-CN' ,
'uk-UA' ,
'ur-PK' ,
'vi-VN' ,
'wo-SN' ,
'xh-ZA' ,
'yo-NG' ,
'zh-CN' ,
'zh-HK' ,
'zh-MO' ,
'zh-SG' ,
'zh-TW' ,
'zu-ZA' ,
);
$buildprimarykeytotest = strtolower ( $countrycode ) . '-' . strtoupper ( $countrycode );
2021-02-23 22:03:23 +01:00
if ( in_array ( $buildprimarykeytotest , $locales )) {
return strtolower ( $countrycode ) . '_' . strtoupper ( $countrycode );
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( function_exists ( 'locale_get_primary_language' ) && function_exists ( 'locale_get_region' )) { // Need extension php-intl
foreach ( $locales as $locale ) {
2020-09-07 10:18:17 +02:00
$locale_language = locale_get_primary_language ( $locale );
$locale_region = locale_get_region ( $locale );
2021-02-23 22:03:23 +01:00
if ( strtoupper ( $countrycode ) == $locale_region ) {
2021-09-20 13:20:54 +02:00
//var_dump($locale.' - '.$locale_language.' - '.$locale_region);
2020-09-07 10:18:17 +02:00
return strtolower ( $locale_language ) . '_' . strtoupper ( $locale_region );
}
}
2020-05-21 15:05:19 +02:00
} else {
2020-09-07 10:18:17 +02:00
dol_syslog ( " Warning Exention php-intl is not available " , LOG_WARNING );
2019-02-03 22:58:56 +01:00
}
return null ;
}
/**
* Complete or removed entries into a head array ( used to build tabs ) .
* For example , with value added by external modules . Such values are declared into $conf -> modules_parts [ 'tab' ] .
* Or by change using hook completeTabsHead
*
* @ param Conf $conf Object conf
* @ param Translate $langs Object langs
* @ param object | null $object Object object
* @ param array $head Object head
* @ param int $h New position to fill
* @ param string $type Value for object where objectvalue can be
* 'thirdparty' to add a tab in third party view
* 'intervention' to add a tab in intervention view
* 'supplier_order' to add a tab in supplier order view
* 'supplier_invoice' to add a tab in supplier invoice view
* 'invoice' to add a tab in customer invoice view
* 'order' to add a tab in customer order view
* 'contract' to add a tabl in contract view
* 'product' to add a tab in product view
* 'propal' to add a tab in propal view
* 'user' to add a tab in user view
* 'group' to add a tab in group view
* 'member' to add a tab in fundation member view
* 'categories_x' to add a tab in category view ( 'x' : type of category ( 0 = product , 1 = supplier , 2 = customer , 3 = member )
* 'ecm' to add a tab for another ecm view
* 'stock' to add a tab for warehouse view
* @ param string $mode 'add' to complete head , 'remove' to remove entries
* @ return void
*/
function complete_head_from_modules ( $conf , $langs , $object , & $head , & $h , $type , $mode = 'add' )
{
2022-03-08 18:06:26 +01:00
global $hookmanager , $db ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( isset ( $conf -> modules_parts [ 'tabs' ][ $type ]) && is_array ( $conf -> modules_parts [ 'tabs' ][ $type ])) {
foreach ( $conf -> modules_parts [ 'tabs' ][ $type ] as $value ) {
2019-11-11 23:59:36 +01:00
$values = explode ( ':' , $value );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $mode == 'add' && ! preg_match ( '/^\-/' , $values [ 1 ])) {
if ( count ( $values ) == 6 ) { // new declaration with permissions: $value='objecttype:+tabname1:Title1:langfile@mymodule:$user->rights->mymodule->read:/mymodule/mynewtab1.php?id=__ID__'
if ( $values [ 0 ] != $type ) {
continue ;
}
if ( verifCond ( $values [ 4 ])) {
if ( $values [ 3 ]) {
$langs -> load ( $values [ 3 ]);
}
if ( preg_match ( '/SUBSTITUTION_([^_]+)/i' , $values [ 2 ], $reg )) {
2019-11-11 23:59:36 +01:00
$substitutionarray = array ();
2019-02-03 22:58:56 +01:00
complete_substitutions_array ( $substitutionarray , $langs , $object , array ( 'needforkey' => $values [ 2 ]));
2019-11-11 23:59:36 +01:00
$label = make_substitutions ( $reg [ 1 ], $substitutionarray );
2021-02-23 22:03:23 +01:00
} else {
2022-03-23 16:38:57 +01:00
$labeltemp = explode ( ':' , $values [ 2 ]);
2022-03-18 16:55:53 +01:00
$label = $langs -> trans ( $labeltemp [ 0 ]);
if ( ! empty ( $labeltemp [ 1 ]) && is_object ( $object ) && ! empty ( $object -> id )) {
dol_include_once ( $labeltemp [ 2 ]);
2022-03-23 16:38:57 +01:00
$classtoload = $labeltemp [ 1 ];
if ( class_exists ( $classtoload )) {
$obj = new $classtoload ( $db );
$function = $labeltemp [ 3 ];
2022-03-23 16:39:55 +01:00
if ( $obj && $function && method_exists ( $obj , $function )) {
2022-03-23 16:38:57 +01:00
$nbrec = $obj -> $function ( $object -> id , $obj );
$label .= '<span class="badge marginleftonlyshort">' . $nbrec . '</span>' ;
}
2022-03-08 18:06:26 +01:00
}
}
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$head [ $h ][ 0 ] = dol_buildpath ( preg_replace ( '/__ID__/i' , (( is_object ( $object ) && ! empty ( $object -> id )) ? $object -> id : '' ), $values [ 5 ]), 1 );
2019-02-03 22:58:56 +01:00
$head [ $h ][ 1 ] = $label ;
$head [ $h ][ 2 ] = str_replace ( '+' , '' , $values [ 1 ]);
$h ++ ;
}
2021-02-23 22:03:23 +01:00
} elseif ( count ( $values ) == 5 ) { // deprecated
2019-02-03 22:58:56 +01:00
dol_syslog ( 'Passing 5 values in tabs module_parts is deprecated. Please update to 6 with permissions.' , LOG_WARNING );
2021-02-23 22:03:23 +01:00
if ( $values [ 0 ] != $type ) {
continue ;
}
if ( $values [ 3 ]) {
$langs -> load ( $values [ 3 ]);
}
if ( preg_match ( '/SUBSTITUTION_([^_]+)/i' , $values [ 2 ], $reg )) {
2019-11-11 23:59:36 +01:00
$substitutionarray = array ();
2019-02-03 22:58:56 +01:00
complete_substitutions_array ( $substitutionarray , $langs , $object , array ( 'needforkey' => $values [ 2 ]));
2019-11-11 23:59:36 +01:00
$label = make_substitutions ( $reg [ 1 ], $substitutionarray );
2021-02-23 22:03:23 +01:00
} else {
$label = $langs -> trans ( $values [ 2 ]);
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$head [ $h ][ 0 ] = dol_buildpath ( preg_replace ( '/__ID__/i' , (( is_object ( $object ) && ! empty ( $object -> id )) ? $object -> id : '' ), $values [ 4 ]), 1 );
2019-02-03 22:58:56 +01:00
$head [ $h ][ 1 ] = $label ;
$head [ $h ][ 2 ] = str_replace ( '+' , '' , $values [ 1 ]);
$h ++ ;
}
2021-02-23 22:03:23 +01:00
} elseif ( $mode == 'remove' && preg_match ( '/^\-/' , $values [ 1 ])) {
if ( $values [ 0 ] != $type ) {
continue ;
}
2019-11-11 23:59:36 +01:00
$tabname = str_replace ( '-' , '' , $values [ 1 ]);
2021-02-23 22:03:23 +01:00
foreach ( $head as $key => $val ) {
2019-11-11 23:59:36 +01:00
$condition = ( ! empty ( $values [ 3 ]) ? verifCond ( $values [ 3 ]) : 1 );
2019-02-03 22:58:56 +01:00
//var_dump($key.' - '.$tabname.' - '.$head[$key][2].' - '.$values[3].' - '.$condition);
2021-02-23 22:03:23 +01:00
if ( $head [ $key ][ 2 ] == $tabname && $condition ) {
2019-02-03 22:58:56 +01:00
unset ( $head [ $key ]);
break ;
}
}
}
}
}
// No need to make a return $head. Var is modified as a reference
2021-02-23 22:03:23 +01:00
if ( ! empty ( $hookmanager )) {
2021-05-06 22:28:03 +02:00
$parameters = array ( 'object' => $object , 'mode' => $mode , 'head' => & $head );
2019-11-11 23:59:36 +01:00
$reshook = $hookmanager -> executeHooks ( 'completeTabsHead' , $parameters );
2021-07-12 16:55:16 +02:00
if ( $reshook > 0 ) { // Hook ask to replace completely the array
2019-02-03 22:58:56 +01:00
$head = $hookmanager -> resArray ;
2021-07-12 16:55:16 +02:00
} else { // Hook
$head = array_merge ( $head , $hookmanager -> resArray );
2019-02-03 22:58:56 +01:00
}
2021-05-06 22:28:03 +02:00
$h = count ( $head );
2019-02-03 22:58:56 +01:00
}
}
/**
* Print common footer :
* conf -> global -> MAIN_HTML_FOOTER
* js for switch of menu hider
* js for conf -> global -> MAIN_GOOGLE_AN_ID
* js for conf -> global -> MAIN_SHOW_TUNING_INFO or $_SERVER [ " MAIN_SHOW_TUNING_INFO " ]
* js for conf -> logbuffer
*
* @ param string $zone 'private' ( for private pages ) or 'public' ( for public pages )
* @ return void
*/
function printCommonFooter ( $zone = 'private' )
{
2019-03-23 14:37:54 +01:00
global $conf , $hookmanager , $user , $debugbar ;
2019-02-03 22:58:56 +01:00
global $action ;
global $micro_start_time ;
2021-02-23 22:03:23 +01:00
if ( $zone == 'private' ) {
print " \n " . '<!-- Common footer for private page -->' . " \n " ;
} else {
print " \n " . '<!-- Common footer for public page -->' . " \n " ;
}
2019-02-03 22:58:56 +01:00
// A div to store page_y POST parameter so we can read it using javascript
2019-03-16 14:48:41 +01:00
print " \n <!-- A div to store page_y POST parameter --> \n " ;
2022-02-22 23:44:56 +01:00
print '<div id="page_y" style="display: none;">' . ( GETPOST ( 'page_y' ) ? GETPOST ( 'page_y' ) : '' ) . '</div>' . " \n " ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$parameters = array ();
$reshook = $hookmanager -> executeHooks ( 'printCommonFooter' , $parameters ); // Note that $action and $object may have been modified by some hooks
2021-02-23 22:03:23 +01:00
if ( empty ( $reshook )) {
if ( ! empty ( $conf -> global -> MAIN_HTML_FOOTER )) {
print $conf -> global -> MAIN_HTML_FOOTER . " \n " ;
}
2019-02-03 22:58:56 +01:00
print " \n " ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> use_javascript_ajax )) {
2019-02-03 22:58:56 +01:00
print '<script>' . " \n " ;
print 'jQuery(document).ready(function() {' . " \n " ;
2021-02-23 22:03:23 +01:00
if ( $zone == 'private' && empty ( $conf -> dol_use_jmobile )) {
2019-02-03 22:58:56 +01:00
print " \n " ;
print '/* JS CODE TO ENABLE to manage handler to switch left menu page (menuhider) */' . " \n " ;
2019-09-15 15:09:36 +02:00
print 'jQuery("li.menuhider").click(function(event) {' ;
2019-04-03 14:36:27 +02:00
print ' if (!$( "body" ).hasClass( "sidebar-collapse" )){ event.preventDefault(); }' . " \n " ;
2019-02-03 22:58:56 +01:00
print ' console.log("We click on .menuhider");' . " \n " ;
2019-03-15 20:10:39 +01:00
print ' $("body").toggleClass("sidebar-collapse")' . " \n " ;
2019-02-03 22:58:56 +01:00
print '});' . " \n " ;
}
// Management of focus and mandatory for fields
2021-02-23 22:03:23 +01:00
if ( $action == 'create' || $action == 'edit' || ( empty ( $action ) && ( preg_match ( '/new\.php/' , $_SERVER [ " PHP_SELF " ])))) {
2019-02-03 22:58:56 +01:00
print '/* JS CODE TO ENABLE to manage focus and mandatory form fields */' . " \n " ;
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
2021-02-23 22:03:23 +01:00
if ( constant ( 'DOL_URL_ROOT' )) {
$relativepathstring = preg_replace ( '/^' . preg_quote ( constant ( 'DOL_URL_ROOT' ), '/' ) . '/' , '' , $relativepathstring );
}
2019-02-03 22:58:56 +01:00
$relativepathstring = preg_replace ( '/^\//' , '' , $relativepathstring );
$relativepathstring = preg_replace ( '/^custom\//' , '' , $relativepathstring );
2020-01-27 22:22:59 +01:00
//$tmpqueryarraywehave = explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
2021-02-23 22:03:23 +01:00
if ( ! empty ( $user -> default_values [ $relativepathstring ][ 'focus' ])) {
foreach ( $user -> default_values [ $relativepathstring ][ 'focus' ] as $defkey => $defval ) {
2019-02-03 22:58:56 +01:00
$qualified = 0 ;
2021-02-23 22:03:23 +01:00
if ( $defkey != '_noquery_' ) {
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$foundintru = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpqueryarraytohave as $tmpquerytohave ) {
2020-01-27 22:22:59 +01:00
$tmpquerytohaveparam = explode ( '=' , $tmpquerytohave );
//print "console.log('".$tmpquerytohaveparam[0]." ".$tmpquerytohaveparam[1]." ".GETPOST($tmpquerytohaveparam[0])."');";
2021-02-23 22:03:23 +01:00
if ( ! GETPOSTISSET ( $tmpquerytohaveparam [ 0 ]) || ( $tmpquerytohaveparam [ 1 ] != GETPOST ( $tmpquerytohaveparam [ 0 ]))) {
$foundintru = 1 ;
}
}
if ( ! $foundintru ) {
$qualified = 1 ;
2019-02-03 22:58:56 +01:00
}
//var_dump($defkey.'-'.$qualified);
2021-02-23 22:03:23 +01:00
} else {
$qualified = 1 ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $qualified ) {
foreach ( $defval as $paramkey => $paramval ) {
2019-02-03 22:58:56 +01:00
// Set focus on field
print 'jQuery("input[name=\'' . $paramkey . '\']").focus();' . " \n " ;
print 'jQuery("textarea[name=\'' . $paramkey . '\']").focus();' . " \n " ;
2019-11-11 23:59:36 +01:00
print 'jQuery("select[name=\'' . $paramkey . '\']").focus();' . " \n " ; // Not really usefull, but we keep it in case of.
2019-02-03 22:58:56 +01:00
}
}
}
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $user -> default_values [ $relativepathstring ][ 'mandatory' ])) {
foreach ( $user -> default_values [ $relativepathstring ][ 'mandatory' ] as $defkey => $defval ) {
2019-02-03 22:58:56 +01:00
$qualified = 0 ;
2021-02-23 22:03:23 +01:00
if ( $defkey != '_noquery_' ) {
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$foundintru = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpqueryarraytohave as $tmpquerytohave ) {
2020-01-27 22:22:59 +01:00
$tmpquerytohaveparam = explode ( '=' , $tmpquerytohave );
//print "console.log('".$tmpquerytohaveparam[0]." ".$tmpquerytohaveparam[1]." ".GETPOST($tmpquerytohaveparam[0])."');";
2021-02-23 22:03:23 +01:00
if ( ! GETPOSTISSET ( $tmpquerytohaveparam [ 0 ]) || ( $tmpquerytohaveparam [ 1 ] != GETPOST ( $tmpquerytohaveparam [ 0 ]))) {
$foundintru = 1 ;
}
}
if ( ! $foundintru ) {
$qualified = 1 ;
2019-02-03 22:58:56 +01:00
}
//var_dump($defkey.'-'.$qualified);
2021-02-23 22:03:23 +01:00
} else {
$qualified = 1 ;
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $qualified ) {
foreach ( $defval as $paramkey => $paramval ) {
2019-02-03 22:58:56 +01:00
// Add property 'required' on input
print 'jQuery("input[name=\'' . $paramkey . '\']").prop(\'required\',true);' . " \n " ;
print 'jQuery("textarea[name=\'' . $paramkey . '\']").prop(\'required\',true);' . " \n " ;
2021-02-15 15:37:43 +01:00
print '// required on a select works only if key is "", so we add the required attributes but also we reset the key -1 or 0 to an empty string' . " \n " ;
print 'jQuery("select[name=\'' . $paramkey . '\']").prop(\'required\',true);' . " \n " ;
print 'jQuery("select[name=\'' . $paramkey . '\'] option[value=\'-1\']").prop(\'value\', \'\');' . " \n " ;
print 'jQuery("select[name=\'' . $paramkey . '\'] option[value=\'0\']").prop(\'value\', \'\');' . " \n " ;
2019-02-03 22:58:56 +01:00
}
}
}
}
}
print '});' . " \n " ;
// End of tuning
2021-02-23 22:03:23 +01:00
if ( ! empty ( $_SERVER [ 'MAIN_SHOW_TUNING_INFO' ]) || ! empty ( $conf -> global -> MAIN_SHOW_TUNING_INFO )) {
2019-02-03 22:58:56 +01:00
print " \n " ;
print " /* JS CODE TO ENABLE to add memory info */ \n " ;
print 'window.console && console.log("' ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MEMCACHED_SERVER )) {
print 'MEMCACHED_SERVER=' . $conf -> global -> MEMCACHED_SERVER . ' - ' ;
}
2019-11-11 23:59:36 +01:00
print 'MAIN_OPTIMIZE_SPEED=' . ( isset ( $conf -> global -> MAIN_OPTIMIZE_SPEED ) ? $conf -> global -> MAIN_OPTIMIZE_SPEED : 'off' );
2021-02-23 22:03:23 +01:00
if ( ! empty ( $micro_start_time )) { // Works only if MAIN_SHOW_TUNING_INFO is defined at $_SERVER level. Not in global variable.
2019-02-03 22:58:56 +01:00
$micro_end_time = microtime ( true );
2019-11-11 23:59:36 +01:00
print ' - Build time: ' . ceil ( 1000 * ( $micro_end_time - $micro_start_time )) . ' ms' ;
2019-02-03 22:58:56 +01:00
}
2020-02-23 22:05:59 +01:00
if ( function_exists ( " memory_get_usage " )) {
2020-03-12 12:45:44 +01:00
print ' - Mem: ' . memory_get_usage (); // Do not use true here, it seems it takes the peak amount
2019-02-03 22:58:56 +01:00
}
2020-02-23 22:05:59 +01:00
if ( function_exists ( " memory_get_peak_usage " )) {
print ' - Real mem peak: ' . memory_get_peak_usage ( true );
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( function_exists ( " zend_loader_file_encoded " )) {
2019-11-11 23:59:36 +01:00
print ' - Zend encoded file: ' . ( zend_loader_file_encoded () ? 'yes' : 'no' );
2019-02-03 22:58:56 +01:00
}
print '");' . " \n " ;
}
print " \n " . '</script>' . " \n " ;
2020-06-11 16:59:24 +02:00
// Google Analytics
// TODO Add a hook here
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> google -> enabled ) && ! empty ( $conf -> global -> MAIN_GOOGLE_AN_ID )) {
2020-06-11 16:59:24 +02:00
$tmptagarray = explode ( ',' , $conf -> global -> MAIN_GOOGLE_AN_ID );
2020-06-15 04:32:59 +02:00
foreach ( $tmptagarray as $tmptag ) {
2020-06-11 16:59:24 +02:00
print " \n " ;
2020-06-11 17:00:22 +02:00
print " <!-- JS CODE TO ENABLE for google analtics tag --> \n " ;
2020-06-11 16:59:24 +02:00
print "
<!-- Global site tag ( gtag . js ) - Google Analytics -->
< script async src = \ " https://www.googletagmanager.com/gtag/js?id= " . trim ( $tmptag ) . " \" ></script>
< script >
window . dataLayer = window . dataLayer || [];
function gtag (){ dataLayer . push ( arguments );}
gtag ( 'js' , new Date ());
gtag ( 'config' , '".trim($tmptag)."' );
</ script > " ;
print " \n " ;
}
}
2019-02-03 22:58:56 +01:00
}
// Add Xdebug coverage of code
2021-02-23 22:03:23 +01:00
if ( defined ( 'XDEBUGCOVERAGE' )) {
2020-09-07 10:18:17 +02:00
print_r ( xdebug_get_code_coverage ());
2019-02-03 22:58:56 +01:00
}
2019-03-23 14:37:54 +01:00
// Add DebugBar data
2021-02-23 22:03:23 +01:00
if ( ! empty ( $user -> rights -> debugbar -> read ) && is_object ( $debugbar )) {
2020-09-07 10:18:17 +02:00
$debugbar [ 'time' ] -> stopMeasure ( 'pageaftermaster' );
print '<!-- Output debugbar data -->' . " \n " ;
2020-09-07 21:00:40 +02:00
$renderer = $debugbar -> getRenderer ();
2020-09-07 10:18:17 +02:00
print $debugbar -> getRenderer () -> render ();
2021-02-23 22:03:23 +01:00
} elseif ( count ( $conf -> logbuffer )) { // If there is some logs in buffer to show
2019-02-03 22:58:56 +01:00
print " \n " ;
print " <!-- Start of log output \n " ;
//print '<div class="hidden">'."\n";
2021-02-23 22:03:23 +01:00
foreach ( $conf -> logbuffer as $logline ) {
2019-02-03 22:58:56 +01:00
print $logline . " <br> \n " ;
}
//print '</div>'."\n";
print " End of log output --> \n " ;
}
}
}
/**
* Split a string with 2 keys into key array .
* For example : " A=1;B=2;C=2 " is exploded into array ( 'A' => 1 , 'B' => 2 , 'C' => 3 )
*
* @ param string $string String to explode
* @ param string $delimiter Delimiter between each couple of data
* @ param string $kv Delimiter between key and value
* @ return array Array of data exploded
*/
function dolExplodeIntoArray ( $string , $delimiter = ';' , $kv = '=' )
{
2021-02-23 22:03:23 +01:00
if ( $a = explode ( $delimiter , $string )) {
2019-02-03 22:58:56 +01:00
$ka = array ();
foreach ( $a as $s ) { // each part
if ( $s ) {
if ( $pos = strpos ( $s , $kv )) { // key/value delimiter
$ka [ trim ( substr ( $s , 0 , $pos ))] = trim ( substr ( $s , $pos + strlen ( $kv )));
} else { // key delimiter not found
$ka [] = trim ( $s );
}
}
}
return $ka ;
}
return array ();
}
/**
* Set focus onto field with selector ( similar behaviour of 'autofocus' HTML5 tag )
*
* @ param string $selector Selector ( '#id' or 'input[name="ref"]' ) to use to find the HTML input field that must get the autofocus . You must use a CSS selector , so unique id preceding with the '#' char .
2021-10-31 17:22:40 +01:00
* @ return void
2019-02-03 22:58:56 +01:00
*/
function dol_set_focus ( $selector )
{
print " \n " . '<!-- Set focus onto a specific field -->' . " \n " ;
print '<script>jQuery(document).ready(function() { jQuery("' . dol_escape_js ( $selector ) . '").focus(); });</script>' . " \n " ;
}
/**
* Return getmypid () or random PID when function is disabled
* Some web hosts disable this php function for security reasons
* and sometimes we can ' t redeclare function
*
* @ return int
*/
function dol_getmypid ()
{
2019-11-11 23:59:36 +01:00
if ( ! function_exists ( 'getmypid' )) {
2019-02-03 22:58:56 +01:00
return mt_rand ( 1 , 32768 );
} else {
return getmypid ();
}
}
/**
* Generate natural SQL search string for a criteria ( this criteria can be tested on one or several fields )
*
* @ param string | string [] $fields String or array of strings , filled with the name of all fields in the SQL query we must check ( combined with a OR ) . Example : array ( " p.field1 " , " p.field2 " )
* @ param string $value The value to look for .
* If param $mode is 0 , can contains several keywords separated with a space or |
* like " keyword1 keyword2 " = We want record field like keyword1 AND field like keyword2
* or like " keyword1|keyword2 " = We want record field like keyword1 OR field like keyword2
* If param $mode is 1 , can contains an operator < , > or = like " <10 " or " >=100.5 < 1000 "
* If param $mode is 2 , can contains a list of int id separated by comma like " 1,3,4 "
* If param $mode is 3 , can contains a list of string separated by comma like " a,b,c "
* @ param integer $mode 0 = value is list of keyword strings , 1 = value is a numeric test ( Example " >5.5 <10 " ), 2 = value is a list of ID separated with comma ( Example '1,3,4' )
2020-09-25 17:11:54 +02:00
* 3 = value is list of string separated with comma ( Example 'text 1,text 2' ), 4 = value is a list of ID separated with comma ( Example '2,7' ) to be used to search into a multiselect string '1,2,3,4'
2019-02-03 22:58:56 +01:00
* @ param integer $nofirstand 1 = Do not output the first 'AND'
* @ return string $res The statement to append to the SQL query
2022-03-23 13:02:49 +01:00
* @ see dolSqlDateFilter ()
2019-02-03 22:58:56 +01:00
*/
function natural_search ( $fields , $value , $mode = 0 , $nofirstand = 0 )
{
2019-11-11 23:59:36 +01:00
global $db , $langs ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$value = trim ( $value );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $mode == 0 ) {
2019-11-11 23:59:36 +01:00
$value = preg_replace ( '/\*/' , '%' , $value ); // Replace * with %
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $mode == 1 ) {
2019-11-11 23:59:36 +01:00
$value = preg_replace ( '/([<>=]+)\s+([0-9' . preg_quote ( $langs -> trans ( " DecimalSeparator " ), '/' ) . '\-])/' , '\1\2' , $value ); // Clean string '< 10' into '<10' so we can the explode on space to get all tests to do
2019-02-03 22:58:56 +01:00
}
$value = preg_replace ( '/\s*\|\s*/' , '|' , $value );
$crits = explode ( ' ' , $value );
$res = '' ;
2021-02-23 22:03:23 +01:00
if ( ! is_array ( $fields )) {
$fields = array ( $fields );
}
2019-02-03 22:58:56 +01:00
$j = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $crits as $crit ) {
2020-09-25 17:48:04 +02:00
$crit = trim ( $crit );
2021-03-01 20:37:16 +01:00
$i = 0 ;
$i2 = 0 ;
2019-02-03 22:58:56 +01:00
$newres = '' ;
2021-02-23 22:03:23 +01:00
foreach ( $fields as $field ) {
if ( $mode == 1 ) {
2019-11-11 23:59:36 +01:00
$operator = '=' ;
2020-09-25 17:11:54 +02:00
$newcrit = preg_replace ( '/([<>=]+)/' , '' , $crit );
2019-02-03 22:58:56 +01:00
2020-01-09 22:14:39 +01:00
$reg = array ();
2020-09-25 17:11:54 +02:00
preg_match ( '/([<>=]+)/' , $crit , $reg );
2021-02-23 22:03:23 +01:00
if ( $reg [ 1 ]) {
2019-02-03 22:58:56 +01:00
$operator = $reg [ 1 ];
}
2021-02-23 22:03:23 +01:00
if ( $newcrit != '' ) {
2019-02-03 22:58:56 +01:00
$numnewcrit = price2num ( $newcrit );
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $numnewcrit )) {
2021-09-17 10:45:59 +02:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . ' ' . $operator . ' ' . (( float ) $numnewcrit ); // should be a numeric
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . '1 = 2' ; // force false
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$i2 ++ ; // a criteria was added to string
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
} elseif ( $mode == 2 || $mode == - 2 ) {
2020-10-07 15:01:28 +02:00
$crit = preg_replace ( '/[^0-9,]/' , '' , $crit ); // ID are always integer
2020-09-25 17:11:54 +02:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . " " . ( $mode == - 2 ? 'NOT ' : '' );
$newres .= $crit ? " IN ( " . $db -> sanitize ( $db -> escape ( $crit )) . " ) " : " IN (0) " ;
2021-02-23 22:03:23 +01:00
if ( $mode == - 2 ) {
$newres .= ' OR ' . $field . ' IS NULL' ;
}
2019-11-11 23:59:36 +01:00
$i2 ++ ; // a criteria was added to string
2021-02-23 22:03:23 +01:00
} elseif ( $mode == 3 || $mode == - 3 ) {
2020-09-25 17:11:54 +02:00
$tmparray = explode ( ',' , $crit );
2021-02-23 22:03:23 +01:00
if ( count ( $tmparray )) {
2019-11-11 23:59:36 +01:00
$listofcodes = '' ;
2021-02-23 22:03:23 +01:00
foreach ( $tmparray as $val ) {
2020-09-25 17:11:54 +02:00
$val = trim ( $val );
2021-02-23 22:03:23 +01:00
if ( $val ) {
2019-11-11 23:59:36 +01:00
$listofcodes .= ( $listofcodes ? ',' : '' );
2020-09-25 17:11:54 +02:00
$listofcodes .= " ' " . $db -> escape ( $val ) . " ' " ;
2019-02-03 22:58:56 +01:00
}
}
2020-10-06 15:11:45 +02:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . " " . ( $mode == - 3 ? 'NOT ' : '' ) . " IN ( " . $db -> sanitize ( $listofcodes , 1 ) . " ) " ;
2019-11-11 23:59:36 +01:00
$i2 ++ ; // a criteria was added to string
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $mode == - 3 ) {
$newres .= ' OR ' . $field . ' IS NULL' ;
}
} elseif ( $mode == 4 ) {
2020-09-25 17:11:54 +02:00
$tmparray = explode ( ',' , $crit );
2021-02-23 22:03:23 +01:00
if ( count ( $tmparray )) {
2020-09-07 10:18:17 +02:00
$listofcodes = '' ;
2021-02-23 22:03:23 +01:00
foreach ( $tmparray as $val ) {
2020-09-25 17:11:54 +02:00
$val = trim ( $val );
2021-02-23 22:03:23 +01:00
if ( $val ) {
2021-08-28 01:45:53 +02:00
$newres .= ( $i2 > 0 ? " OR ( " : " ( " ) . $field . " LIKE ' " . $db -> escape ( $val ) . " ,%' " ;
$newres .= ' OR ' . $field . " = ' " . $db -> escape ( $val ) . " ' " ;
$newres .= ' OR ' . $field . " LIKE '%, " . $db -> escape ( $val ) . " ' " ;
$newres .= ' OR ' . $field . " LIKE '%, " . $db -> escape ( $val ) . " ,%' " ;
2020-09-07 10:18:17 +02:00
$newres .= ')' ;
$i2 ++ ;
}
}
}
2020-05-21 15:05:19 +02:00
} else // $mode=0
2019-02-03 22:58:56 +01:00
{
$tmpcrits = explode ( '|' , $crit );
$i3 = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmpcrits as $tmpcrit ) {
if ( $tmpcrit !== '0' && empty ( $tmpcrit )) {
continue ;
}
2019-02-03 22:58:56 +01:00
$newres .= (( $i2 > 0 || $i3 > 0 ) ? ' OR ' : '' );
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(id|rowid)$/' , $field )) { // Special case for rowid that is sometimes a ref so used as a search field
2021-09-17 10:45:59 +02:00
$newres .= $field . " = " . ( is_numeric ( trim ( $tmpcrit )) ? (( float ) trim ( $tmpcrit )) : '0' );
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$tmpcrit = trim ( $tmpcrit );
$tmpcrit2 = $tmpcrit ;
2021-03-01 20:37:16 +01:00
$tmpbefore = '%' ;
$tmpafter = '%' ;
2022-02-01 16:18:02 +01:00
if ( preg_match ( '/^!/' , $tmpcrit )) {
2022-01-31 16:09:31 +01:00
$newres .= $field . " NOT LIKE ' " ; // ! as exclude character
$tmpcrit2 = preg_replace ( '/^!/' , '' , $tmpcrit2 );
2022-02-01 16:18:02 +01:00
} else $newres .= $field . " LIKE ' " ;
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^[\^\$]/' , $tmpcrit )) {
2019-11-11 23:59:36 +01:00
$tmpbefore = '' ;
2019-02-03 22:58:56 +01:00
$tmpcrit2 = preg_replace ( '/^[\^\$]/' , '' , $tmpcrit2 );
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/[\^\$]$/' , $tmpcrit )) {
2019-11-11 23:59:36 +01:00
$tmpafter = '' ;
2019-02-03 22:58:56 +01:00
$tmpcrit2 = preg_replace ( '/[\^\$]$/' , '' , $tmpcrit2 );
}
$newres .= $tmpbefore ;
$newres .= $db -> escape ( $tmpcrit2 );
$newres .= $tmpafter ;
$newres .= " ' " ;
2021-02-23 22:03:23 +01:00
if ( $tmpcrit2 == '' ) {
2021-08-28 01:45:53 +02:00
$newres .= " OR " . $field . " IS NULL " ;
2019-02-03 22:58:56 +01:00
}
}
$i3 ++ ;
}
2019-11-11 23:59:36 +01:00
$i2 ++ ; // a criteria was added to string
2019-02-03 22:58:56 +01:00
}
$i ++ ;
}
2021-02-23 22:03:23 +01:00
if ( $newres ) {
$res = $res . ( $res ? ' AND ' : '' ) . ( $i2 > 1 ? '(' : '' ) . $newres . ( $i2 > 1 ? ')' : '' );
}
2019-02-03 22:58:56 +01:00
$j ++ ;
}
2019-11-11 23:59:36 +01:00
$res = ( $nofirstand ? " " : " AND " ) . " ( " . $res . " ) " ;
2019-02-03 22:58:56 +01:00
//print 'xx'.$res.'yy';
return $res ;
}
/**
* Return string with full Url . The file qualified is the one defined by relative path in $object -> last_main_doc
*
* @ param Object $object Object
* @ return string Url string
*/
function showDirectDownloadLink ( $object )
{
global $conf , $langs ;
2019-11-11 23:59:36 +01:00
$out = '' ;
2019-02-03 22:58:56 +01:00
$url = $object -> getLastMainDocLink ( $object -> element );
2021-04-15 17:56:55 +02:00
$out .= img_picto ( $langs -> trans ( " PublicDownloadLinkDesc " ), 'globe' ) . ' <span class="opacitymedium">' . $langs -> trans ( " DirectDownloadLink " ) . '</span><br>' ;
2021-02-23 22:03:23 +01:00
if ( $url ) {
2021-03-26 17:58:00 +01:00
$out .= '<div class="urllink"><input type="text" id="directdownloadlink" class="quatrevingtpercent" value="' . $url . '"></div>' ;
2019-11-11 23:59:36 +01:00
$out .= ajax_autoselect ( " directdownloadlink " , 0 );
2021-04-15 17:09:15 +02:00
} else {
$out .= '<div class="urllink">' . $langs -> trans ( " FileNotShared " ) . '</div>' ;
2019-02-03 22:58:56 +01:00
}
2021-04-15 17:09:15 +02:00
2019-02-03 22:58:56 +01:00
return $out ;
}
/**
* Return the filename of file to get the thumbs
*
* @ param string $file Original filename ( full or relative path )
* @ param string $extName Extension to differenciate thumb file name ( '' , '_small' , '_mini' )
* @ param string $extImgTarget Force image extension for thumbs . Use '' to keep same extension than original image ( default ) .
* @ return string New file name ( full or relative path , including the thumbs / )
*/
function getImageFileNameForSize ( $file , $extName , $extImgTarget = '' )
{
$dirName = dirname ( $file );
2021-02-23 22:03:23 +01:00
if ( $dirName == '.' ) {
$dirName = '' ;
}
2019-02-03 22:58:56 +01:00
2020-06-03 14:05:18 +02:00
$fileName = preg_replace ( '/(\.gif|\.jpeg|\.jpg|\.png|\.bmp|\.webp)$/i' , '' , $file ); // We remove extension, whatever is its case
2019-02-03 22:58:56 +01:00
$fileName = basename ( $fileName );
2021-02-23 22:03:23 +01:00
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.jpg$/i' , $file ) ? '.jpg' : '' );
}
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.jpeg$/i' , $file ) ? '.jpeg' : '' );
}
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.gif$/i' , $file ) ? '.gif' : '' );
}
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.png$/i' , $file ) ? '.png' : '' );
}
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.bmp$/i' , $file ) ? '.bmp' : '' );
}
if ( empty ( $extImgTarget )) {
$extImgTarget = ( preg_match ( '/\.webp$/i' , $file ) ? '.webp' : '' );
}
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( ! $extImgTarget ) {
return $file ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$subdir = '' ;
2021-02-23 22:03:23 +01:00
if ( $extName ) {
$subdir = 'thumbs/' ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
return ( $dirName ? $dirName . '/' : '' ) . $subdir . $fileName . $extName . $extImgTarget ; // New filename for thumb
2019-02-03 22:58:56 +01:00
}
/**
* Return URL we can use for advanced preview links
*
* @ param string $modulepart propal , facture , facture_fourn , ...
* @ param string $relativepath Relative path of docs .
* @ param int $alldata Return array with all components ( 1 is recommended , then use a simple a href link with the class , target and mime attribute added . 'documentpreview' css class is handled by jquery code into main . inc . php )
* @ param string $param More param on http links
* @ return string | array Output string with href link or array with all components of link
*/
function getAdvancedPreviewUrl ( $modulepart , $relativepath , $alldata = 0 , $param = '' )
{
global $conf , $langs ;
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> use_javascript_ajax )) {
return '' ;
}
2019-02-03 22:58:56 +01:00
2020-09-16 14:37:05 +02:00
$isAllowedForPreview = dolIsAllowedForPreview ( $relativepath );
2019-02-03 22:58:56 +01:00
2021-02-23 22:03:23 +01:00
if ( $alldata == 1 ) {
if ( $isAllowedForPreview ) {
return array ( 'target' => '_blank' , 'css' => 'documentpreview' , 'url' => DOL_URL_ROOT . '/document.php?modulepart=' . $modulepart . '&attachment=0&file=' . urlencode ( $relativepath ) . ( $param ? '&' . $param : '' ), 'mime' => dol_mimetype ( $relativepath ));
} else {
return array ();
}
2019-02-03 22:58:56 +01:00
}
2020-09-16 14:37:05 +02:00
// old behavior, return a string
2021-02-23 22:03:23 +01:00
if ( $isAllowedForPreview ) {
return 'javascript:document_preview(\'' . dol_escape_js ( DOL_URL_ROOT . '/document.php?modulepart=' . $modulepart . '&attachment=0&file=' . urlencode ( $relativepath ) . ( $param ? '&' . $param : '' )) . '\', \'' . dol_mimetype ( $relativepath ) . '\', \'' . dol_escape_js ( $langs -> trans ( 'Preview' )) . '\')' ;
} else {
return '' ;
}
2019-02-03 22:58:56 +01:00
}
/**
* Make content of an input box selected when we click into input field .
*
2021-10-19 16:26:43 +02:00
* @ param string $htmlname Id of html object ( '#idvalue' or '.classvalue' )
* @ param string $addlink Add a 'link to' after
* @ param string $textonlink Text to show on link or 'image'
2019-02-03 22:58:56 +01:00
* @ return string
*/
2021-10-19 16:26:43 +02:00
function ajax_autoselect ( $htmlname , $addlink = '' , $textonlink = 'Link' )
2019-02-03 22:58:56 +01:00
{
global $langs ;
$out = ' < script >
jQuery ( document ) . ready ( function () {
2020-03-13 12:53:22 +01:00
jQuery ( " '.((strpos( $htmlname , '.') === 0 ? '' : '#'). $htmlname ).' " ) . click ( function () { jQuery ( this ) . select (); } );
2019-02-03 22:58:56 +01:00
});
</ script > ' ;
2021-02-23 22:03:23 +01:00
if ( $addlink ) {
2021-10-19 16:26:43 +02:00
if ( $textonlink === 'image' ) {
2021-11-22 02:35:55 +01:00
$out .= ' <a href="' . $addlink . '" target="_blank" rel="noopener noreferrer">' . img_picto ( '' , 'globe' ) . '</a>' ;
2021-10-19 16:26:43 +02:00
} else {
2021-11-22 02:35:55 +01:00
$out .= ' <a href="' . $addlink . '" target="_blank" rel="noopener noreferrer">' . $langs -> trans ( " Link " ) . '</a>' ;
2021-10-19 16:26:43 +02:00
}
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
return $out ;
}
2020-09-16 14:37:05 +02:00
/**
* Return if a file is qualified for preview
*
* @ param string $file Filename we looking for information
* @ return int 1 If allowed , 0 otherwise
* @ see dol_mimetype (), image_format_supported () from images . lib . php
*/
2020-09-16 18:51:19 +02:00
function dolIsAllowedForPreview ( $file )
{
2020-09-16 14:37:05 +02:00
global $conf ;
// Check .noexe extension in filename
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.noexe$/i' , $file )) {
return 0 ;
}
2020-09-16 14:37:05 +02:00
// Check mime types
$mime_preview = array ( 'bmp' , 'jpeg' , 'png' , 'gif' , 'tiff' , 'pdf' , 'plain' , 'css' , 'webp' );
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_ALLOW_SVG_FILES_AS_IMAGES )) {
$mime_preview [] = 'svg+xml' ;
}
2020-09-16 14:37:05 +02:00
//$mime_preview[]='vnd.oasis.opendocument.presentation';
//$mime_preview[]='archive';
$num_mime = array_search ( dol_mimetype ( $file , '' , 1 ), $mime_preview );
2021-02-23 22:03:23 +01:00
if ( $num_mime !== false ) {
return 1 ;
}
2020-09-16 14:37:05 +02:00
// By default, not allowed for preview
return 0 ;
}
2019-02-03 22:58:56 +01:00
/**
2022-02-04 15:14:10 +01:00
* Return MIME type of a file from its name with extension .
2019-02-03 22:58:56 +01:00
*
* @ param string $file Filename we looking for MIME type
* @ param string $default Default mime type if extension not found in known list
* @ param int $mode 0 = Return full mime , 1 = otherwise short mime string , 2 = image for mime type , 3 = source language , 4 = css of font fa
* @ return string Return a mime type family ( text / xxx , application / xxx , image / xxx , audio , video , archive )
2020-09-16 14:37:05 +02:00
* @ see dolIsAllowedForPreview (), image_format_supported () from images . lib . php
2019-02-03 22:58:56 +01:00
*/
function dol_mimetype ( $file , $default = 'application/octet-stream' , $mode = 0 )
{
2019-11-11 23:59:36 +01:00
$mime = $default ;
$imgmime = 'other.png' ;
$famime = 'file-o' ;
$srclang = '' ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$tmpfile = preg_replace ( '/\.noexe$/' , '' , $file );
2019-02-03 22:58:56 +01:00
2019-12-02 13:53:28 +01:00
// Plain text files
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.txt$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.rtx$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/richtext' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.csv$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/csv' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.tsv$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/tab-separated-values' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(cf|conf|log)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.ini$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'ini' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.md$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'md' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.css$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/css' ;
$imgmime = 'css.png' ;
$srclang = 'css' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.lang$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'lang' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Certificate files
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(crt|cer|key|pub)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
2019-12-02 13:53:28 +01:00
// XML based (HTML/XML/XAML)
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(html|htm|shtml)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/html' ;
$imgmime = 'html.png' ;
$srclang = 'html' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(xml|xhtml)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/xml' ;
$imgmime = 'other.png' ;
$srclang = 'xml' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xaml$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/xml' ;
$imgmime = 'other.png' ;
$srclang = 'xaml' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Languages
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.bas$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'bas' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(c)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'c' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(cpp)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'cpp' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.cs$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'cs' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(h)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'h' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(java|jsp)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'java' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.php([0-9]{1})?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'php.png' ;
$srclang = 'php' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.phtml$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'php.png' ;
$srclang = 'php' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(pl|pm)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'pl.png' ;
$srclang = 'perl' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.sql$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/plain' ;
$imgmime = 'text.png' ;
$srclang = 'sql' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.js$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/x-javascript' ;
$imgmime = 'jscript.png' ;
$srclang = 'js' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Open office
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.odp$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.oasis.opendocument.presentation' ;
$imgmime = 'ooffice.png' ;
$famime = 'file-powerpoint-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.ods$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.oasis.opendocument.spreadsheet' ;
$imgmime = 'ooffice.png' ;
$famime = 'file-excel-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.odt$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.oasis.opendocument.text' ;
$imgmime = 'ooffice.png' ;
$famime = 'file-word-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// MS Office
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.mdb$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/msaccess' ;
$imgmime = 'mdb.png' ;
$famime = 'file-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.doc(x|m)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/msword' ;
$imgmime = 'doc.png' ;
$famime = 'file-word-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.dot(x|m)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/msword' ;
$imgmime = 'doc.png' ;
$famime = 'file-word-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xlt(x)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.ms-excel' ;
$imgmime = 'xls.png' ;
$famime = 'file-excel-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xla(m)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.ms-excel' ;
$imgmime = 'xls.png' ;
$famime = 'file-excel-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xls$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.ms-excel' ;
$imgmime = 'xls.png' ;
$famime = 'file-excel-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xls(b|m|x)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ;
$imgmime = 'xls.png' ;
$famime = 'file-excel-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.pps(m|x)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/vnd.ms-powerpoint' ;
$imgmime = 'ppt.png' ;
$famime = 'file-powerpoint-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.ppt(m|x)?$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/x-mspowerpoint' ;
$imgmime = 'ppt.png' ;
$famime = 'file-powerpoint-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Other
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.pdf$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/pdf' ;
$imgmime = 'pdf.png' ;
$famime = 'file-pdf-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Scripts
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.bat$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/x-bat' ;
$imgmime = 'script.png' ;
$srclang = 'dos' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.sh$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/x-sh' ;
$imgmime = 'script.png' ;
$srclang = 'bash' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.ksh$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/x-ksh' ;
$imgmime = 'script.png' ;
$srclang = 'bash' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.bash$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/x-bash' ;
$imgmime = 'script.png' ;
$srclang = 'bash' ;
$famime = 'file-code-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Images
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.ico$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/x-icon' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(jpg|jpeg)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/jpeg' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.png$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/png' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.gif$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/gif' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.bmp$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/bmp' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(tif|tiff)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/tiff' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.svg$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/svg+xml' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.webp$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'image/webp' ;
$imgmime = 'image.png' ;
$famime = 'file-image-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Calendar
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.vcs$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/calendar' ;
$imgmime = 'other.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.ics$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'text/calendar' ;
$imgmime = 'other.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Other
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.torrent$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/x-bittorrent' ;
$imgmime = 'other.png' ;
$famime = 'file-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Audio
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(mp3|ogg|au|wav|wma|mid)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'audio' ;
$imgmime = 'audio.png' ;
$famime = 'file-audio-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Video
2021-03-16 14:57:04 +01:00
if ( preg_match ( '/\.mp4$/i' , $tmpfile )) {
$mime = 'video/mp4' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
}
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.ogv$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video/ogg' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.webm$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video/webm' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.avi$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video/x-msvideo' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.divx$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video/divx' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.xvid$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video/xvid' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
if ( preg_match ( '/\.(wmv|mpg|mpeg)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'video' ;
$imgmime = 'video.png' ;
$famime = 'file-video-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Archive
2021-03-16 14:57:04 +01:00
if ( preg_match ( '/\.(zip|rar|gz|tgz|z|cab|bz2|7z|tar|lzh|zst)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'archive' ;
$imgmime = 'archive.png' ;
$famime = 'file-archive-o' ;
2021-02-23 22:03:23 +01:00
} // application/xxx where zzz is zip, ...
2019-02-03 22:58:56 +01:00
// Exe
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(exe|com)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'application/octet-stream' ;
$imgmime = 'other.png' ;
$famime = 'file-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Lib
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(dll|lib|o|so|a)$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'library' ;
$imgmime = 'library.png' ;
$famime = 'file-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Err
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.err$/i' , $tmpfile )) {
2021-03-01 20:37:16 +01:00
$mime = 'error' ;
$imgmime = 'error.png' ;
$famime = 'file-text-o' ;
2021-02-23 22:03:23 +01:00
}
2019-02-03 22:58:56 +01:00
// Return string
2021-02-23 22:03:23 +01:00
if ( $mode == 1 ) {
2019-11-11 23:59:36 +01:00
$tmp = explode ( '/' , $mime );
return ( ! empty ( $tmp [ 1 ]) ? $tmp [ 1 ] : $tmp [ 0 ]);
2019-02-03 22:58:56 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $mode == 2 ) {
2019-02-03 22:58:56 +01:00
return $imgmime ;
}
2021-02-23 22:03:23 +01:00
if ( $mode == 3 ) {
2019-02-03 22:58:56 +01:00
return $srclang ;
}
2021-02-23 22:03:23 +01:00
if ( $mode == 4 ) {
2019-02-03 22:58:56 +01:00
return $famime ;
}
return $mime ;
}
/**
2021-10-20 14:41:40 +02:00
* Return the value of a filed into a dictionary for the record $id .
* This also set all the values into a cache for a next search .
2019-02-03 22:58:56 +01:00
*
2021-10-20 14:41:40 +02:00
* @ param string $tablename Name of dictionary
* @ param string $field The name of field where to find the value to return
* @ param int $id Id of line record
* @ param bool $checkentity Add filter on entity
* @ param string $rowidfield Name of the column rowid ( to use for the filter on $id )
* @ return string The value of field $field . This also set $dictvalues cache .
2019-02-03 22:58:56 +01:00
*/
2021-10-20 14:41:40 +02:00
function getDictionaryValue ( $tablename , $field , $id , $checkentity = false , $rowidfield = 'rowid' )
2019-02-03 22:58:56 +01:00
{
2021-10-20 14:41:40 +02:00
global $conf , $db ;
2019-02-03 22:58:56 +01:00
2021-10-20 14:41:40 +02:00
$dictvalues = ( isset ( $conf -> cache [ 'dictvalues_' . $tablename ]) ? $conf -> cache [ 'dictvalues_' . $tablename ] : null );
if ( is_null ( $dictvalues )) {
$dictvalues = array ();
2021-05-06 17:07:44 +02:00
2021-08-28 01:45:53 +02:00
$sql = " SELECT * FROM " . $tablename . " WHERE 1 = 1 " ; // Here select * is allowed as it is generic code and we don't have list of fields
2021-02-23 22:03:23 +01:00
if ( $checkentity ) {
$sql .= ' AND entity IN (0,' . getEntity ( $tablename ) . ')' ;
}
2019-02-03 22:58:56 +01:00
$resql = $db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
while ( $obj = $db -> fetch_object ( $resql )) {
2021-10-20 14:41:40 +02:00
$dictvalues [ $obj -> { $rowidfield }] = $obj ;
2019-02-03 22:58:56 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2019-02-03 22:58:56 +01:00
dol_print_error ( $db );
}
2021-10-20 14:41:40 +02:00
$conf -> cache [ 'dictvalues_' . $tablename ] = $dictvalues ;
2019-02-03 22:58:56 +01:00
}
2021-10-20 14:41:40 +02:00
if ( ! empty ( $dictvalues [ $id ])) {
// Found
return $dictvalues [ $id ] -> { $field };
} else {
// Not found
2019-02-03 22:58:56 +01:00
return '' ;
}
}
/**
* Return true if the color is light
*
* @ param string $stringcolor String with hex ( FFFFFF ) or comma RGB ( '255,255,255' )
* @ return int - 1 : Error with argument passed | 0 : color is dark | 1 : color is light
*/
function colorIsLight ( $stringcolor )
{
2020-09-07 10:18:17 +02:00
$stringcolor = str_replace ( '#' , '' , $stringcolor );
2019-02-03 22:58:56 +01:00
$res = - 1 ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $stringcolor )) {
2019-02-03 22:58:56 +01:00
$res = 0 ;
2019-11-11 23:59:36 +01:00
$tmp = explode ( ',' , $stringcolor );
2021-02-23 22:03:23 +01:00
if ( count ( $tmp ) > 1 ) { // This is a comma RGB ('255','255','255')
2019-02-03 22:58:56 +01:00
$r = $tmp [ 0 ];
$g = $tmp [ 1 ];
$b = $tmp [ 2 ];
2020-05-21 15:05:19 +02:00
} else {
2019-11-11 23:59:36 +01:00
$hexr = $stringcolor [ 0 ] . $stringcolor [ 1 ];
$hexg = $stringcolor [ 2 ] . $stringcolor [ 3 ];
$hexb = $stringcolor [ 4 ] . $stringcolor [ 5 ];
2019-02-03 22:58:56 +01:00
$r = hexdec ( $hexr );
$g = hexdec ( $hexg );
$b = hexdec ( $hexb );
}
2019-11-11 23:59:36 +01:00
$bright = ( max ( $r , $g , $b ) + min ( $r , $g , $b )) / 510.0 ; // HSL algorithm
2021-02-23 22:03:23 +01:00
if ( $bright > 0.6 ) {
$res = 1 ;
}
2019-02-03 22:58:56 +01:00
}
return $res ;
}
/**
* Function to test if an entry is enabled or not
*
* @ param string $type_user 0 = We test for internal user , 1 = We test for external user
* @ param array $menuentry Array for feature entry to test
* @ param array $listofmodulesforexternal Array with list of modules allowed to external users
* @ return int 0 = Hide , 1 = Show , 2 = Show gray
*/
function isVisibleToUserType ( $type_user , & $menuentry , & $listofmodulesforexternal )
{
global $conf ;
//print 'type_user='.$type_user.' module='.$menuentry['module'].' enabled='.$menuentry['enabled'].' perms='.$menuentry['perms'];
//print 'ok='.in_array($menuentry['module'], $listofmodulesforexternal);
2021-02-23 22:03:23 +01:00
if ( empty ( $menuentry [ 'enabled' ])) {
return 0 ; // Entry disabled by condition
}
if ( $type_user && $menuentry [ 'module' ]) {
2019-11-11 23:59:36 +01:00
$tmploops = explode ( '|' , $menuentry [ 'module' ]);
$found = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $tmploops as $tmploop ) {
2019-02-03 22:58:56 +01:00
if ( in_array ( $tmploop , $listofmodulesforexternal )) {
2021-03-01 20:37:16 +01:00
$found ++ ;
break ;
2019-02-03 22:58:56 +01:00
}
}
2021-02-23 22:03:23 +01:00
if ( ! $found ) {
return 0 ; // Entry is for menus all excluded to external users
}
}
if ( ! $menuentry [ 'perms' ] && $type_user ) {
return 0 ; // No permissions and user is external
}
if ( ! $menuentry [ 'perms' ] && ! empty ( $conf -> global -> MAIN_MENU_HIDE_UNAUTHORIZED )) {
return 0 ; // No permissions and option to hide when not allowed, even for internal user, is on
}
if ( ! $menuentry [ 'perms' ]) {
return 2 ; // No permissions and user is external
2019-02-03 22:58:56 +01:00
}
return 1 ;
}
/**
* Round to next multiple .
*
* @ param double $n Number to round up
* @ param integer $x Multiple . For example 60 to round up to nearest exact minute for a date with seconds .
* @ return integer Value rounded .
*/
function roundUpToNextMultiple ( $n , $x = 5 )
{
2019-11-11 23:59:36 +01:00
return ( ceil ( $n ) % $x === 0 ) ? ceil ( $n ) : round (( $n + $x / 2 ) / $x ) * $x ;
2019-02-03 22:58:56 +01:00
}
2019-03-01 12:01:25 +01:00
/**
2019-03-11 21:03:23 +01:00
* Function dolGetBadge
*
* @ param string $label label of badge no html : use in alt attribute for accessibility
* @ param string $html optional : label of badge with html
* @ param string $type type of badge : Primary Secondary Success Danger Warning Info Light Dark status0 status1 status2 status3 status4 status5 status6 status7 status8 status9
2020-04-07 21:11:18 +02:00
* @ param string $mode default '' , 'pill' , 'dot'
2019-03-11 21:03:23 +01:00
* @ param string $url the url for link
2019-11-01 23:58:14 +01:00
* @ param array $params various params for future : recommended rather than adding more fuction arguments . array ( 'attr' => array ( 'title' => 'abc' ))
2019-03-11 21:03:23 +01:00
* @ return string Html badge
2019-03-01 12:01:25 +01:00
*/
2019-03-05 15:26:19 +01:00
function dolGetBadge ( $label , $html = '' , $type = 'primary' , $mode = '' , $url = '' , $params = array ())
2019-03-01 12:01:25 +01:00
{
2020-09-07 10:18:17 +02:00
$attr = array (
'class' => 'badge ' . ( ! empty ( $mode ) ? ' badge-' . $mode : '' ) . ( ! empty ( $type ) ? ' badge-' . $type : '' ) . ( empty ( $params [ 'css' ]) ? '' : ' ' . $params [ 'css' ])
);
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
if ( empty ( $html )) {
$html = $label ;
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
if ( ! empty ( $url )) {
$attr [ 'href' ] = $url ;
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
if ( $mode === 'dot' ) {
$attr [ 'class' ] .= ' classfortooltip' ;
$attr [ 'title' ] = $html ;
$attr [ 'aria-label' ] = $label ;
$html = '' ;
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
// Override attr
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
2021-02-23 22:03:23 +01:00
foreach ( $params [ 'attr' ] as $key => $value ) {
2019-12-07 17:41:13 +01:00
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
2020-05-21 15:05:19 +02:00
} elseif ( $key == 'classOverride' ) {
2019-12-07 17:41:13 +01:00
$attr [ 'class' ] = $value ;
2020-05-21 15:05:19 +02:00
} else {
2019-12-07 17:41:13 +01:00
$attr [ $key ] = $value ;
}
2020-09-07 10:18:17 +02:00
}
}
2019-03-01 12:01:25 +01:00
2020-09-07 10:18:17 +02:00
// TODO: add hook
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$TCompiledAttr = array ();
foreach ( $attr as $key => $value ) {
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$compiledAttributes = ! empty ( $TCompiledAttr ) ? implode ( ' ' , $TCompiledAttr ) : '' ;
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$tag = ! empty ( $url ) ? 'a' : 'span' ;
2019-03-01 12:01:25 +01:00
2020-09-07 10:18:17 +02:00
return '<' . $tag . ' ' . $compiledAttributes . '>' . $html . '</' . $tag . '>' ;
2019-03-01 12:01:25 +01:00
}
/**
2020-10-08 09:30:15 +02:00
* Output the badge of a status .
2019-03-11 21:03:23 +01:00
*
* @ param string $statusLabel Label of badge no html : use in alt attribute for accessibility
* @ param string $statusLabelShort Short label of badge no html
* @ param string $html Optional : label of badge with html
* @ param string $statusType status0 status1 status2 status3 status4 status5 status6 status7 status8 status9 : image name or badge name
* @ param int $displayMode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto , 6 = Long label + Picto
* @ param string $url The url for link
2020-12-17 11:57:12 +01:00
* @ param array $params Various params . Example : array ( 'tooltip' => 'no|...' , 'badgeParams' =>... )
2019-03-11 21:03:23 +01:00
* @ return string Html status string
2019-03-01 12:01:25 +01:00
*/
2019-03-05 16:58:05 +01:00
function dolGetStatus ( $statusLabel = '' , $statusLabelShort = '' , $html = '' , $statusType = 'status0' , $displayMode = 0 , $url = '' , $params = array ())
2019-03-01 12:01:25 +01:00
{
2020-09-07 10:18:17 +02:00
global $conf ;
$return = '' ;
$dolGetBadgeParams = array ();
if ( ! empty ( $params [ 'badgeParams' ])) {
$dolGetBadgeParams = $params [ 'badgeParams' ];
}
// TODO : add a hook
if ( $displayMode == 0 ) {
$return = ! empty ( $html ) ? $html : ( empty ( $conf -> dol_optimize_smallscreen ) ? $statusLabel : ( empty ( $statusLabelShort ) ? $statusLabel : $statusLabelShort ));
} elseif ( $displayMode == 1 ) {
$return = ! empty ( $html ) ? $html : ( empty ( $statusLabelShort ) ? $statusLabel : $statusLabelShort );
2021-03-01 20:37:16 +01:00
} elseif ( ! empty ( $conf -> global -> MAIN_STATUS_USES_IMAGES )) {
// Use status with images (for backward compatibility)
2020-09-07 10:18:17 +02:00
$return = '' ;
$htmlLabel = ( in_array ( $displayMode , array ( 1 , 2 , 5 )) ? '<span class="hideonsmartphone">' : '' ) . ( ! empty ( $html ) ? $html : $statusLabel ) . ( in_array ( $displayMode , array ( 1 , 2 , 5 )) ? '</span>' : '' );
$htmlLabelShort = ( in_array ( $displayMode , array ( 1 , 2 , 5 )) ? '<span class="hideonsmartphone">' : '' ) . ( ! empty ( $html ) ? $html : ( ! empty ( $statusLabelShort ) ? $statusLabelShort : $statusLabel )) . ( in_array ( $displayMode , array ( 1 , 2 , 5 )) ? '</span>' : '' );
// For small screen, we always use the short label instead of long label.
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen )) {
if ( $displayMode == 0 ) {
$displayMode = 1 ;
} elseif ( $displayMode == 4 ) {
$displayMode = 2 ;
} elseif ( $displayMode == 6 ) {
$displayMode = 5 ;
}
2020-09-07 10:18:17 +02:00
}
// For backward compatibility. Image's filename are still in French, so we use this array to convert
$statusImg = array (
'status0' => 'statut0' ,
'status1' => 'statut1' ,
'status2' => 'statut2' ,
'status3' => 'statut3' ,
'status4' => 'statut4' ,
'status5' => 'statut5' ,
'status6' => 'statut6' ,
'status7' => 'statut7' ,
'status8' => 'statut8' ,
'status9' => 'statut9'
);
if ( ! empty ( $statusImg [ $statusType ])) {
$htmlImg = img_picto ( $statusLabel , $statusImg [ $statusType ]);
} else {
$htmlImg = img_picto ( $statusLabel , $statusType );
}
if ( $displayMode === 2 ) {
$return = $htmlImg . ' ' . $htmlLabelShort ;
} elseif ( $displayMode === 3 ) {
$return = $htmlImg ;
} elseif ( $displayMode === 4 ) {
$return = $htmlImg . ' ' . $htmlLabel ;
} elseif ( $displayMode === 5 ) {
$return = $htmlLabelShort . ' ' . $htmlImg ;
} else { // $displayMode >= 6
$return = $htmlLabel . ' ' . $htmlImg ;
}
2021-03-01 20:37:16 +01:00
} elseif ( empty ( $conf -> global -> MAIN_STATUS_USES_IMAGES ) && ! empty ( $displayMode )) {
// Use new badge
2020-09-07 10:18:17 +02:00
$statusLabelShort = ( empty ( $statusLabelShort ) ? $statusLabel : $statusLabelShort );
2019-03-11 21:03:23 +01:00
2019-12-07 17:41:13 +01:00
$dolGetBadgeParams [ 'attr' ][ 'class' ] = 'badge-status' ;
2020-12-17 11:57:12 +01:00
$dolGetBadgeParams [ 'attr' ][ 'title' ] = empty ( $params [ 'tooltip' ]) ? $statusLabel : ( $params [ 'tooltip' ] != 'no' ? $params [ 'tooltip' ] : '' );
2019-12-07 17:41:13 +01:00
2020-09-07 10:18:17 +02:00
if ( $displayMode == 3 ) {
$return = dolGetBadge (( empty ( $conf -> dol_optimize_smallscreen ) ? $statusLabel : ( empty ( $statusLabelShort ) ? $statusLabel : $statusLabelShort )), '' , $statusType , 'dot' , $url , $dolGetBadgeParams );
} elseif ( $displayMode === 5 ) {
$return = dolGetBadge ( $statusLabelShort , $html , $statusType , '' , $url , $dolGetBadgeParams );
} else {
$return = dolGetBadge (( empty ( $conf -> dol_optimize_smallscreen ) ? $statusLabel : ( empty ( $statusLabelShort ) ? $statusLabel : $statusLabelShort )), $html , $statusType , '' , $url , $dolGetBadgeParams );
}
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
return $return ;
2019-03-01 12:01:25 +01:00
}
2019-03-01 15:33:23 +01:00
/**
2019-03-11 21:03:23 +01:00
* Function dolGetButtonAction
*
2021-06-05 17:48:30 +02:00
* @ param string $label label of button without HTML : use in alt attribute for accessibility $html is not empty
2019-03-11 21:03:23 +01:00
* @ param string $html optional : content with html
* @ param string $actionType default , delete , danger
* @ param string $url the url for link
* @ param string $id attribute id of button
* @ param int $userRight user action right
2021-07-14 10:07:03 +02:00
* // phpcs:disable
* @ param array $params = [ // Various params for future : recommended rather than adding more function arguments
2022-03-16 15:57:04 +01:00
* 'attr' => [ // to add or override button attributes
* 'xxxxx' => '' , // your xxxxx attribute you want
* 'class' => '' , // to add more css class to the button class attribute
* 'classOverride' => '' // to replace class attribute of the button
* ],
* 'confirm' => [
* 'url' => 'http://' , // Overide Url to go when user click on action btn, if empty default url is $url.?confirm=yes, for no js compatibility use $url for fallback confirm.
* 'title' => '' , // Overide title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key
* 'action-btn-label' => '' , // Overide label of action button, if empty default label use "Confirm" lang key
* 'cancel-btn-label' => '' , // Overide label of cancel button, if empty default label use "CloseDialog" lang key
* 'content' => '' , // Overide text of content, if empty default content use "ConfirmBtnCommonContent" lang key
* 'modal' => true , // true|false to display dialog as a modal (with dark background)
* ],
2021-07-14 10:07:03 +02:00
* ]
* // phpcs:enable
2019-03-11 21:03:23 +01:00
* @ return string html button
2019-03-01 15:33:23 +01:00
*/
2019-03-05 15:26:19 +01:00
function dolGetButtonAction ( $label , $html = '' , $actionType = 'default' , $url = '' , $id = '' , $userRight = 1 , $params = array ())
2019-03-01 15:33:23 +01:00
{
2021-07-04 22:59:53 +02:00
global $hookmanager , $action , $object , $langs ;
2020-09-07 10:18:17 +02:00
$class = 'butAction' ;
if ( $actionType == 'danger' || $actionType == 'delete' ) {
$class = 'butActionDelete' ;
2022-02-23 15:36:43 +01:00
if ( ! empty ( $url ) && strpos ( $url , 'token=' ) === false ) $url .= '&token=' . newToken ();
2020-09-07 10:18:17 +02:00
}
$attr = array (
2021-06-05 17:48:30 +02:00
'class' => $class ,
'href' => empty ( $url ) ? '' : $url ,
'title' => $label
2020-09-07 10:18:17 +02:00
);
if ( empty ( $html )) {
$html = $label ;
2022-02-22 12:25:30 +01:00
$attr [ 'title' ] = '' ; // if html not set, leave label on title is redundant
2020-09-07 10:18:17 +02:00
} else {
$attr [ 'aria-label' ] = $label ;
}
if ( empty ( $userRight )) {
$attr [ 'class' ] = 'butActionRefused' ;
$attr [ 'href' ] = '' ;
}
if ( ! empty ( $id )) {
$attr [ 'id' ] = $id ;
}
2022-02-23 16:01:07 +01:00
2020-09-07 10:18:17 +02:00
// Override attr
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
foreach ( $params [ 'attr' ] as $key => $value ) {
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
} elseif ( $key == 'classOverride' ) {
$attr [ 'class' ] = $value ;
} else {
$attr [ $key ] = $value ;
}
}
}
2019-03-11 21:03:23 +01:00
2022-02-23 16:01:07 +01:00
// automatic add tooltip when title is detected
if ( ! empty ( $attr [ 'title' ]) && ! empty ( $attr [ 'class' ]) && strpos ( $attr [ 'class' ], 'classfortooltip' ) === false ) {
$attr [ 'class' ] .= ' classfortooltip' ;
}
2021-07-04 22:59:53 +02:00
// Js Confirm button
2021-07-14 00:02:55 +02:00
if ( $userRight && ! empty ( $params [ 'confirm' ])) {
2021-07-04 23:24:38 +02:00
if ( ! is_array ( $params [ 'confirm' ])) {
$params [ 'confirm' ] = array (
'url' => $url . ( strpos ( $url , '?' ) > 0 ? '&' : '?' ) . 'confirm=yes'
);
}
2021-07-04 22:59:53 +02:00
// for js desabled compatibility set $url as call to confirm action and $params['confirm']['url'] to confirmed action
$attr [ 'data-confirm-url' ] = $params [ 'confirm' ][ 'url' ];
$attr [ 'data-confirm-title' ] = ! empty ( $params [ 'confirm' ][ 'title' ]) ? $params [ 'confirm' ][ 'title' ] : $langs -> trans ( 'ConfirmBtnCommonTitle' , $label );
$attr [ 'data-confirm-content' ] = ! empty ( $params [ 'confirm' ][ 'content' ]) ? $params [ 'confirm' ][ 'content' ] : $langs -> trans ( 'ConfirmBtnCommonContent' , $label );
2021-07-14 00:02:55 +02:00
$attr [ 'data-confirm-content' ] = preg_replace ( " / \r | \n / " , " " , $attr [ 'data-confirm-content' ]);
2021-07-04 22:59:53 +02:00
$attr [ 'data-confirm-action-btn-label' ] = ! empty ( $params [ 'confirm' ][ 'action-btn-label' ]) ? $params [ 'confirm' ][ 'action-btn-label' ] : $langs -> trans ( 'Confirm' );
$attr [ 'data-confirm-cancel-btn-label' ] = ! empty ( $params [ 'confirm' ][ 'cancel-btn-label' ]) ? $params [ 'confirm' ][ 'cancel-btn-label' ] : $langs -> trans ( 'CloseDialog' );
2021-07-14 00:02:55 +02:00
$attr [ 'data-confirm-modal' ] = ! empty ( $params [ 'confirm' ][ 'modal' ]) ? $params [ 'confirm' ][ 'modal' ] : true ;
2021-07-04 22:59:53 +02:00
$attr [ 'class' ] .= ' butActionConfirm' ;
}
2020-09-07 10:18:17 +02:00
if ( isset ( $attr [ 'href' ]) && empty ( $attr [ 'href' ])) {
unset ( $attr [ 'href' ]);
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$TCompiledAttr = array ();
foreach ( $attr as $key => $value ) {
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$compiledAttributes = ! empty ( $TCompiledAttr ) ? implode ( ' ' , $TCompiledAttr ) : '' ;
2019-03-11 21:03:23 +01:00
2020-09-07 10:18:17 +02:00
$tag = ! empty ( $attr [ 'href' ]) ? 'a' : 'span' ;
2019-03-11 21:03:23 +01:00
2021-07-04 22:59:53 +02:00
$parameters = array (
'TCompiledAttr' => $TCompiledAttr ,
'compiledAttributes' => $compiledAttributes ,
'attr' => $attr ,
'tag' => $tag ,
'label' => $label ,
'html' => $html ,
'actionType' => $actionType ,
'url' => $url ,
'id' => $id ,
'userRight' => $userRight ,
'params' => $params
);
$reshook = $hookmanager -> executeHooks ( 'dolGetButtonAction' , $parameters , $object , $action ); // Note that $action and $object may have been modified by some hooks
if ( $reshook < 0 ) setEventMessages ( $hookmanager -> error , $hookmanager -> errors , 'errors' );
if ( empty ( $reshook )) {
return '<' . $tag . ' ' . $compiledAttributes . '>' . $html . '</' . $tag . '>' ;
} else {
return $hookmanager -> resPrint ;
}
2019-03-01 15:33:23 +01:00
}
2019-04-15 00:21:58 +02:00
2021-04-18 20:12:24 +02:00
/**
* Add space between dolGetButtonTitle
*
2021-05-17 23:47:16 +02:00
* @ param string $moreClass more css class label
* @ return string html of title separator
2021-04-18 20:12:24 +02:00
*/
function dolGetButtonTitleSeparator ( $moreClass = " " )
{
return '<span class="button-title-separator ' . $moreClass . '" ></span>' ;
}
2021-06-12 14:16:40 +02:00
/**
* get field error icon
*
2021-06-21 21:54:03 +02:00
* @ param string $fieldValidationErrorMsg message to add in tooltip
* @ return string html output
2021-06-12 14:16:40 +02:00
*/
function getFieldErrorIcon ( $fieldValidationErrorMsg )
{
$out = '' ;
2021-06-21 21:54:03 +02:00
if ( ! empty ( $fieldValidationErrorMsg )) {
$out .= '<span class="field-error-icon classfortooltip" title="' . dol_escape_htmltag ( $fieldValidationErrorMsg , 1 ) . '" role="alert" >' ; // role alert is used for accessibility
2021-06-12 14:16:40 +02:00
$out .= '<span class="fa fa-exclamation-circle" aria-hidden="true" ></span>' ; // For accessibility icon is separated and aria-hidden
$out .= '</span>' ;
}
return $out ;
}
2019-04-15 00:21:58 +02:00
/**
* Function dolGetButtonTitle : this kind of buttons are used in title in list
*
* @ param string $label label of button
* @ param string $helpText optional : content for help tooltip
2019-09-30 17:46:53 +02:00
* @ param string $iconClass class for icon element ( Example : 'fa fa-file' )
2019-04-15 00:21:58 +02:00
* @ param string $url the url for link
* @ param string $id attribute id of button
2021-04-18 20:12:24 +02:00
* @ param int $status 0 no user rights , 1 active , 2 current action or selected , - 1 Feature Disabled , - 2 disable Other reason use helpText as tooltip
2019-04-15 00:21:58 +02:00
* @ param array $params various params for future : recommended rather than adding more function arguments
* @ return string html button
*/
2019-04-16 09:09:25 +02:00
function dolGetButtonTitle ( $label , $helpText = '' , $iconClass = 'fa fa-file' , $url = '' , $id = '' , $status = 1 , $params = array ())
2019-04-15 00:21:58 +02:00
{
2020-09-07 10:18:17 +02:00
global $langs , $conf , $user ;
2019-04-16 21:49:26 +02:00
2020-09-07 10:18:17 +02:00
// Actually this conf is used in css too for external module compatibility and smooth transition to this function
if ( ! empty ( $conf -> global -> MAIN_BUTTON_HIDE_UNAUTHORIZED ) && ( ! $user -> admin ) && $status <= 0 ) {
return '' ;
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
$class = 'btnTitle' ;
2021-10-29 09:40:38 +02:00
if ( in_array ( $iconClass , array ( 'fa fa-plus-circle' , 'fa fa-plus-circle size15x' , 'fa fa-comment-dots' ))) {
2021-02-23 22:03:23 +01:00
$class .= ' btnTitlePlus' ;
}
2020-09-15 02:41:08 +02:00
$useclassfortooltip = 1 ;
2019-12-04 15:09:20 +01:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $params [ 'morecss' ])) {
$class .= ' ' . $params [ 'morecss' ];
}
2019-04-16 21:49:26 +02:00
2020-09-07 10:18:17 +02:00
$attr = array (
2020-09-15 02:41:08 +02:00
'class' => $class ,
'href' => empty ( $url ) ? '' : $url
2020-09-07 10:18:17 +02:00
);
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
if ( ! empty ( $helpText )) {
$attr [ 'title' ] = dol_escape_htmltag ( $helpText );
2020-09-15 02:41:08 +02:00
} elseif ( empty ( $attr [ 'title' ]) && $label ) {
$attr [ 'title' ] = $label ;
$useclassfortooltip = 0 ;
2020-09-07 10:18:17 +02:00
}
2019-04-15 00:21:58 +02:00
2021-04-18 20:12:24 +02:00
if ( $status == 2 ) {
$attr [ 'class' ] .= ' btnTitleSelected' ;
2021-04-18 22:38:18 +02:00
} elseif ( $status <= 0 ) {
2020-09-07 10:18:17 +02:00
$attr [ 'class' ] .= ' refused' ;
2019-04-16 21:49:26 +02:00
2020-09-07 10:18:17 +02:00
$attr [ 'href' ] = '' ;
2019-04-16 21:49:26 +02:00
2020-09-07 10:18:17 +02:00
if ( $status == - 1 ) { // disable
$attr [ 'title' ] = dol_escape_htmltag ( $langs -> transnoentitiesnoconv ( " FeatureDisabled " ));
} elseif ( $status == 0 ) { // Not enough permissions
$attr [ 'title' ] = dol_escape_htmltag ( $langs -> transnoentitiesnoconv ( " NotEnoughPermissions " ));
}
}
2019-04-15 00:21:58 +02:00
2020-09-15 02:41:08 +02:00
if ( ! empty ( $attr [ 'title' ]) && $useclassfortooltip ) {
2020-09-07 10:18:17 +02:00
$attr [ 'class' ] .= ' classfortooltip' ;
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
if ( ! empty ( $id )) {
$attr [ 'id' ] = $id ;
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
// Override attr
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
foreach ( $params [ 'attr' ] as $key => $value ) {
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
} elseif ( $key == 'classOverride' ) {
$attr [ 'class' ] = $value ;
} else {
$attr [ $key ] = $value ;
}
}
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
if ( isset ( $attr [ 'href' ]) && empty ( $attr [ 'href' ])) {
unset ( $attr [ 'href' ]);
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
// TODO : add a hook
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
$TCompiledAttr = array ();
foreach ( $attr as $key => $value ) {
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
$compiledAttributes = ( empty ( $TCompiledAttr ) ? '' : implode ( ' ' , $TCompiledAttr ));
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
$tag = ( empty ( $attr [ 'href' ]) ? 'span' : 'a' );
2019-04-15 00:21:58 +02:00
2020-09-15 14:45:51 +02:00
$button = '<' . $tag . ' ' . $compiledAttributes . '>' ;
2020-09-07 10:18:17 +02:00
$button .= '<span class="' . $iconClass . ' valignmiddle btnTitle-icon"></span>' ;
2020-09-15 02:41:08 +02:00
if ( ! empty ( $params [ 'forcenohideoftext' ])) {
$button .= '<span class="valignmiddle text-plus-circle btnTitle-label' . ( empty ( $params [ 'forcenohideoftext' ]) ? ' hideonsmartphone' : '' ) . '">' . $label . '</span>' ;
}
2020-09-07 10:18:17 +02:00
$button .= '</' . $tag . '>' ;
2019-04-15 00:21:58 +02:00
2020-09-07 10:18:17 +02:00
return $button ;
2019-04-15 00:21:58 +02:00
}
2019-05-21 15:13:25 +02:00
2020-03-07 15:06:14 +01:00
/**
* Get an array with properties of an element .
* Called by fetchObjectByElement .
*
* @ param string $element_type Element type ( Value of $object -> element ) . Example : 'action' , 'facture' , 'project_task' or 'object@mymodule' ...
* @ return array ( module , classpath , element , subelement , classfile , classname )
*/
function getElementProperties ( $element_type )
{
$regs = array ();
$classfile = $classname = $classpath = '' ;
// Parse element/subelement (ex: project_task)
$module = $element_type ;
$element = $element_type ;
$subelement = $element_type ;
// If we ask an resource form external module (instead of default path)
if ( preg_match ( '/^([^@]+)@([^@]+)$/i' , $element_type , $regs )) {
$element = $subelement = $regs [ 1 ];
$module = $regs [ 2 ];
}
//print '<br>1. element : '.$element.' - module : '.$module .'<br>';
if ( preg_match ( '/^([^_]+)_([^_]+)/i' , $element , $regs )) {
$module = $element = $regs [ 1 ];
$subelement = $regs [ 2 ];
}
// For compat
if ( $element_type == " action " ) {
$classpath = 'comm/action/class' ;
$subelement = 'Actioncomm' ;
$module = 'agenda' ;
}
// To work with non standard path
if ( $element_type == 'facture' || $element_type == 'invoice' ) {
$classpath = 'compta/facture/class' ;
$module = 'facture' ;
$subelement = 'facture' ;
}
if ( $element_type == 'commande' || $element_type == 'order' ) {
$classpath = 'commande/class' ;
$module = 'commande' ;
$subelement = 'commande' ;
}
if ( $element_type == 'propal' ) {
$classpath = 'comm/propal/class' ;
}
if ( $element_type == 'supplier_proposal' ) {
$classpath = 'supplier_proposal/class' ;
}
if ( $element_type == 'shipping' ) {
$classpath = 'expedition/class' ;
$subelement = 'expedition' ;
$module = 'expedition_bon' ;
}
if ( $element_type == 'delivery' ) {
2020-10-06 12:05:24 +02:00
$classpath = 'delivery/class' ;
$subelement = 'delivery' ;
2020-10-06 15:57:50 +02:00
$module = 'delivery_note' ;
2020-03-07 15:06:14 +01:00
}
if ( $element_type == 'contract' ) {
$classpath = 'contrat/class' ;
$module = 'contrat' ;
$subelement = 'contrat' ;
}
if ( $element_type == 'member' ) {
$classpath = 'adherents/class' ;
$module = 'adherent' ;
$subelement = 'adherent' ;
}
if ( $element_type == 'cabinetmed_cons' ) {
$classpath = 'cabinetmed/class' ;
$module = 'cabinetmed' ;
$subelement = 'cabinetmedcons' ;
}
if ( $element_type == 'fichinter' ) {
$classpath = 'fichinter/class' ;
$module = 'ficheinter' ;
$subelement = 'fichinter' ;
}
if ( $element_type == 'dolresource' || $element_type == 'resource' ) {
$classpath = 'resource/class' ;
$module = 'resource' ;
$subelement = 'dolresource' ;
}
if ( $element_type == 'propaldet' ) {
$classpath = 'comm/propal/class' ;
$module = 'propal' ;
$subelement = 'propaleligne' ;
}
if ( $element_type == 'order_supplier' ) {
$classpath = 'fourn/class' ;
$module = 'fournisseur' ;
$subelement = 'commandefournisseur' ;
$classfile = 'fournisseur.commande' ;
}
if ( $element_type == 'invoice_supplier' ) {
$classpath = 'fourn/class' ;
$module = 'fournisseur' ;
$subelement = 'facturefournisseur' ;
$classfile = 'fournisseur.facture' ;
}
if ( $element_type == " service " ) {
$classpath = 'product/class' ;
$subelement = 'product' ;
}
2021-02-23 22:03:23 +01:00
if ( empty ( $classfile )) {
$classfile = strtolower ( $subelement );
}
if ( empty ( $classname )) {
$classname = ucfirst ( $subelement );
}
if ( empty ( $classpath )) {
$classpath = $module . '/class' ;
}
2020-03-07 15:06:14 +01:00
$element_properties = array (
'module' => $module ,
'classpath' => $classpath ,
'element' => $element ,
'subelement' => $subelement ,
'classfile' => $classfile ,
'classname' => $classname
);
return $element_properties ;
}
/**
* Fetch an object from its id and element_type
* Inclusion of classes is automatic
*
* @ param int $element_id Element id
* @ param string $element_type Element type
* @ param string $element_ref Element ref ( Use this or element_id but not both )
* @ return int | object object || 0 || - 1 if error
*/
function fetchObjectByElement ( $element_id , $element_type , $element_ref = '' )
{
global $conf , $db ;
$element_prop = getElementProperties ( $element_type );
2021-02-23 22:03:23 +01:00
if ( is_array ( $element_prop ) && $conf -> { $element_prop [ 'module' ]} -> enabled ) {
2020-03-07 15:06:14 +01:00
dol_include_once ( '/' . $element_prop [ 'classpath' ] . '/' . $element_prop [ 'classfile' ] . '.class.php' );
$objecttmp = new $element_prop [ 'classname' ]( $db );
$ret = $objecttmp -> fetch ( $element_id , $element_ref );
2021-02-23 22:03:23 +01:00
if ( $ret >= 0 ) {
2020-03-07 15:06:14 +01:00
return $objecttmp ;
}
}
return 0 ;
}
2019-05-21 13:53:12 +02:00
/**
* Return if a file can contains executable content
*
2020-06-17 13:42:38 +02:00
* @ param string $filename File name to test
2019-05-21 13:53:12 +02:00
* @ return boolean True if yes , False if no
*/
function isAFileWithExecutableContent ( $filename )
{
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/\.(htm|html|js|phar|php|php\d+|phtml|pht|pl|py|cgi|ksh|sh|shtml|bash|bat|cmd|wpk|exe|dmg)$/i' , $filename )) {
2020-09-07 10:18:17 +02:00
return true ;
}
2020-06-17 14:45:15 +02:00
2020-09-07 10:18:17 +02:00
return false ;
2019-05-21 13:53:12 +02:00
}
2019-12-01 10:20:11 +01:00
/**
2020-03-19 10:52:07 +01:00
* Return the value of token currently saved into session with name 'newtoken' .
* This token must be send by any POST as it will be used by next page for comparison with value in session .
2019-12-01 10:20:11 +01:00
*
* @ return string
*/
2019-12-01 12:51:01 +01:00
function newToken ()
{
2022-03-16 20:12:01 +01:00
return empty ( $_SESSION [ 'newtoken' ]) ? '' : $_SESSION [ 'newtoken' ];
2019-12-01 10:20:11 +01:00
}
2020-03-19 10:52:07 +01:00
/**
* Return the value of token currently saved into session with name 'token' .
2022-02-18 16:24:11 +01:00
* For ajax call , you must use this token as a parameter of the call into the js calling script ( the called ajax php page must also set constant NOTOKENRENEWAL ) .
2020-03-19 10:52:07 +01:00
*
* @ return string
*/
function currentToken ()
{
2021-07-28 18:22:26 +02:00
return isset ( $_SESSION [ 'token' ]) ? $_SESSION [ 'token' ] : '' ;
2020-03-19 10:52:07 +01:00
}
2020-09-04 15:24:45 +02:00
/**
2020-09-16 18:51:19 +02:00
* Start a table with headers and a optinal clickable number ( don ' t forget to use " finishSimpleTable() " after the last table row )
2020-09-10 11:26:17 +02:00
*
2020-09-08 11:15:33 +02:00
* @ param string $header The first left header of the table ( automatic translated )
* @ param string $link ( optional ) The link to a internal dolibarr page , when click on the number ( without the first " / " )
* @ param string $arguments ( optional ) Additional arguments for the link ( e . g . " search_status=0 " )
* @ param integer $emptyRows ( optional ) The count of empty rows after the first header
* @ param integer $number ( optional ) The number that is shown right after the first header , when not set the link is shown on the right side of the header as " FullList "
2020-09-04 15:24:45 +02:00
* @ return void
2020-09-16 18:51:19 +02:00
*
* @ see finishSimpleTable ()
2020-09-04 15:24:45 +02:00
*/
2020-09-10 11:04:41 +02:00
function startSimpleTable ( $header , $link = " " , $arguments = " " , $emptyRows = 0 , $number = - 1 )
2020-09-04 15:24:45 +02:00
{
global $langs ;
print '<div class="div-table-responsive-no-min">' ;
print '<table class="noborder centpercent">' ;
print '<tr class="liste_titre">' ;
2020-09-08 11:15:33 +02:00
2020-09-04 15:24:45 +02:00
print $emptyRows < 1 ? '<th>' : '<th colspan="' . ( $emptyRows + 1 ) . '">' ;
2020-09-08 11:15:33 +02:00
print $langs -> trans ( $header );
2020-09-04 15:24:45 +02:00
2020-09-09 08:16:26 +02:00
// extra space between the first header and the number
if ( $number > - 1 ) {
2020-09-04 15:24:45 +02:00
print ' ' ;
}
2020-09-09 08:16:26 +02:00
if ( ! empty ( $link )) {
if ( ! empty ( $arguments )) {
2020-09-08 11:15:33 +02:00
print '<a href="' . DOL_URL_ROOT . '/' . $link . '?' . $arguments . '">' ;
2020-09-09 08:16:26 +02:00
} else {
2020-09-08 11:15:33 +02:00
print '<a href="' . DOL_URL_ROOT . '/' . $link . '">' ;
}
2020-09-04 15:24:45 +02:00
}
2020-09-09 08:16:26 +02:00
if ( $number > - 1 ) {
2020-09-04 15:24:45 +02:00
print '<span class="badge">' . $number . '</span>' ;
}
2020-09-09 08:16:26 +02:00
if ( ! empty ( $link )) {
2020-09-04 15:24:45 +02:00
print '</a>' ;
}
print '</th>' ;
2020-09-09 08:16:26 +02:00
if ( $number < 0 && ! empty ( $link )) {
2020-09-08 11:15:33 +02:00
print '<th class="right">' ;
2020-09-04 15:24:45 +02:00
2020-09-09 08:16:26 +02:00
if ( ! empty ( $arguments )) {
2020-09-08 11:15:33 +02:00
print '<a class="commonlink" href="' . DOL_URL_ROOT . '/' . $link . '?' . $arguments . '">' ;
2020-09-09 08:16:26 +02:00
} else {
2020-09-08 11:15:33 +02:00
print '<a class="commonlink" href="' . DOL_URL_ROOT . '/' . $link . '">' ;
}
print $langs -> trans ( " FullList " );
print '</a>' ;
2020-09-04 15:24:45 +02:00
print '</th>' ;
}
print '</tr>' ;
}
2020-09-10 11:04:41 +02:00
/**
2020-09-16 18:51:19 +02:00
* Add the correct HTML close tags for " startSimpleTable(...) " ( use after the last table line )
2020-09-10 11:26:17 +02:00
*
2020-09-16 18:51:19 +02:00
* @ param bool $addLineBreak ( optional ) Add a extra line break after the complete table ( \ < br\ > )
* @ return void
2020-09-10 11:04:41 +02:00
*
2020-09-16 18:51:19 +02:00
* @ see startSimpleTable ()
2020-09-10 11:04:41 +02:00
*/
function finishSimpleTable ( $addLineBreak = false )
{
print '</table>' ;
print '</div>' ;
2020-09-10 11:25:35 +02:00
if ( $addLineBreak ) {
2020-09-10 11:04:41 +02:00
print '<br>' ;
}
}
2020-09-10 11:25:35 +02:00
/**
* Add a summary line to the current open table ( " None " , " XMoreLines " or " Total xxx " )
*
2020-09-10 12:29:01 +02:00
* @ param integer $tableColumnCount The complete count columns of the table
2020-09-10 11:25:35 +02:00
* @ param integer $num The count of the rows of the table , when it is zero ( 0 ) the " $noneWord " is shown instead
* @ param integer $nbofloop ( optional ) The maximum count of rows thaht the table show ( when it is zero ( 0 ) no summary line will show , expect " $noneWord " when $num === 0 )
* @ param integer $total ( optional ) The total value thaht is shown after when the table has minimum of one entire
* @ param string $noneWord ( optional ) The word that is shown when the table has no entires ( $num === 0 )
* @ param boolean $extraRightColumn ( optional ) Add a addtional column after the summary word and total number
* @ return void
*/
2020-09-10 11:04:41 +02:00
function addSummaryTableLine ( $tableColumnCount , $num , $nbofloop = 0 , $total = 0 , $noneWord = " None " , $extraRightColumn = false )
{
global $langs ;
2020-09-10 11:25:35 +02:00
if ( $num === 0 ) {
2020-09-10 11:04:41 +02:00
print '<tr class="oddeven">' ;
2020-09-10 12:29:01 +02:00
print '<td colspan="' . $tableColumnCount . '" class="opacitymedium">' . $langs -> trans ( $noneWord ) . '</td>' ;
2020-09-10 11:04:41 +02:00
print '</tr>' ;
return ;
}
2021-02-23 22:03:23 +01:00
if ( $nbofloop === 0 ) {
2020-09-10 11:04:41 +02:00
// don't show a summary line
return ;
}
if ( $num === 0 ) {
$colspan = $tableColumnCount ;
2021-02-23 22:03:23 +01:00
} elseif ( $num > $nbofloop ) {
2020-09-10 11:04:41 +02:00
$colspan = $tableColumnCount ;
} else {
$colspan = $tableColumnCount - 1 ;
}
2020-09-10 11:25:35 +02:00
if ( $extraRightColumn ) {
2020-09-10 11:04:41 +02:00
$colspan -- ;
}
print '<tr class="liste_total">' ;
2020-09-10 11:25:35 +02:00
if ( $nbofloop > 0 && $num > $nbofloop ) {
2020-09-10 11:04:41 +02:00
print '<td colspan="' . $colspan . '" class="right">' . $langs -> trans ( " XMoreLines " , ( $num - $nbofloop )) . '</td>' ;
} else {
print '<td colspan="' . $colspan . '" class="right"> ' . $langs -> trans ( " Total " ) . '</td>' ;
print '<td class="right" width="100">' . price ( $total ) . '</td>' ;
}
2020-09-10 11:25:35 +02:00
if ( $extraRightColumn ) {
2020-09-10 11:04:41 +02:00
print '<td></td>' ;
}
print '</tr>' ;
}
2020-10-03 14:02:53 +02:00
/**
2020-10-27 02:19:43 +01:00
* Return a file on output using a low memory . It can return very large files with no need of memory .
2020-10-03 14:11:47 +02:00
* WARNING : This close output buffers .
2020-10-03 14:02:53 +02:00
*
* @ param string $fullpath_original_file_osencoded Full path of file to return .
* @ param int $method - 1 automatic , 0 = readfile , 1 = fread , 2 = stream_copy_to_stream
2020-10-03 14:56:04 +02:00
* @ return void
2020-10-03 14:02:53 +02:00
*/
function readfileLowMemory ( $fullpath_original_file_osencoded , $method = - 1 )
{
global $conf ;
if ( $method == - 1 ) {
$method = 0 ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> MAIN_FORCE_READFILE_WITH_FREAD )) {
$method = 1 ;
}
if ( ! empty ( $conf -> global -> MAIN_FORCE_READFILE_WITH_STREAM_COPY )) {
$method = 2 ;
}
2020-10-03 14:02:53 +02:00
}
2020-10-03 14:11:47 +02:00
// Be sure we don't have output buffering enabled to have readfile working correctly
2021-02-23 22:03:23 +01:00
while ( ob_get_level ()) {
ob_end_flush ();
}
2020-10-03 14:11:47 +02:00
2020-10-03 14:02:53 +02:00
// Solution 0
if ( $method == 0 ) {
readfile ( $fullpath_original_file_osencoded );
2021-03-01 20:37:16 +01:00
} elseif ( $method == 1 ) {
// Solution 1
2020-10-03 14:02:53 +02:00
$handle = fopen ( $fullpath_original_file_osencoded , " rb " );
while ( ! feof ( $handle )) {
print fread ( $handle , 8192 );
}
fclose ( $handle );
2021-03-01 20:37:16 +01:00
} elseif ( $method == 2 ) {
// Solution 2
2020-10-03 14:02:53 +02:00
$handle1 = fopen ( $fullpath_original_file_osencoded , " rb " );
$handle2 = fopen ( " php://output " , " wb " );
stream_copy_to_stream ( $handle1 , $handle2 );
fclose ( $handle1 );
fclose ( $handle2 );
}
}
2021-01-22 09:09:46 +01:00
/**
2021-05-19 11:47:58 +02:00
* Create a button to copy $valuetocopy in the clipboard .
2021-08-24 13:19:53 +02:00
* Code that handle the click is inside lib_foot . jsp . php .
2021-01-28 12:34:54 +01:00
*
2021-05-12 11:51:39 +02:00
* @ param string $valuetocopy The value to print
* @ param int $showonlyonhover Show the copy - paste button only on hover
* @ param string $texttoshow Replace the value to show with this text
2021-01-28 12:34:54 +01:00
* @ return string The string to print for the button
2021-01-22 09:09:46 +01:00
*/
2021-05-12 11:51:39 +02:00
function showValueWithClipboardCPButton ( $valuetocopy , $showonlyonhover = 1 , $texttoshow = '' )
2021-01-22 16:58:47 +01:00
{
2021-06-30 17:14:19 +02:00
/*
2021-05-19 11:47:58 +02:00
global $conf ;
2021-06-30 17:14:19 +02:00
if ( ! empty ( $conf -> dol_no_mouse_hover )) {
2021-05-19 11:47:58 +02:00
$showonlyonhover = 0 ;
} */
2021-08-24 13:19:53 +02:00
$tag = 'span' ; // Using div does not work when using the js copy code.
2021-05-12 11:51:39 +02:00
if ( $texttoshow ) {
2021-10-24 16:35:42 +02:00
$result = '<span class="clipboardCP' . ( $showonlyonhover ? ' clipboardCPShowOnHover' : '' ) . '"><' . $tag . ' class="clipboardCPValue hidewithsize">' . dol_escape_htmltag ( $valuetocopy , 1 , 1 ) . '</' . $tag . '><span class="clipboardCPValueToPrint">' . dol_escape_htmltag ( $texttoshow , 1 , 1 ) . '</span><span class="clipboardCPButton far fa-clipboard opacitymedium paddingleft paddingright"></span><span class="clipboardCPText"></span></span>' ;
2021-05-12 11:51:39 +02:00
} else {
2021-10-24 16:35:42 +02:00
$result = '<span class="clipboardCP' . ( $showonlyonhover ? ' clipboardCPShowOnHover' : '' ) . '"><' . $tag . ' class="clipboardCPValue">' . dol_escape_htmltag ( $valuetocopy , 1 , 1 ) . '</' . $tag . '><span class="clipboardCPButton far fa-clipboard opacitymedium paddingleft paddingright"></span><span class="clipboardCPText"></span></span>' ;
2021-05-12 11:51:39 +02:00
}
2021-01-28 11:15:11 +01:00
return $result ;
2021-01-22 09:13:04 +01:00
}
2021-06-30 17:14:19 +02:00
/**
* Decode an encode string . The string can be encoded in json format ( recommended ) or with serialize ( avoid this )
*
2021-06-30 17:27:20 +02:00
* @ param string $stringtodecode String to decode ( json or serialize coded )
* @ return mixed The decoded object .
2021-06-30 17:14:19 +02:00
*/
function jsonOrUnserialize ( $stringtodecode )
{
$result = json_decode ( $stringtodecode );
if ( $result === null ) {
$result = unserialize ( $stringtodecode );
}
return $result ;
}
2022-01-01 21:46:16 +01:00
/**
* Return if a $sqlfilters parameter is valid and will pass the preg_replace_callback () to replace Generic filter string with SQL filter string
* Example of usage :
* if ( $sqlfilters ) {
* $errormessage = '' ;
* if ( dolCheckFilters ( $sqlfilters , $errormessage )) {
* $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)' ;
* $sql .= " AND ( " . preg_replace_callback ( '/' . $regexstring . '/' , 'dolForgeCriteriaCallback' , $sqlfilters ) . " ) " ;
* }
* }
*
* @ param string $sqlfilters sqlfilter string
* @ param string $error Error message
* @ return boolean True if valid , False if not valid ( $error is filled with the reason in such a case )
*/
function dolCheckFilters ( $sqlfilters , & $error = '' )
{
//$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
//$tmp=preg_replace_all('/'.$regexstring.'/', '', $sqlfilters);
$tmp = $sqlfilters ;
$i = 0 ; $nb = strlen ( $tmp );
$counter = 0 ;
while ( $i < $nb ) {
if ( $tmp [ $i ] == '(' ) {
$counter ++ ;
}
if ( $tmp [ $i ] == ')' ) {
$counter -- ;
}
if ( $counter < 0 ) {
$error = " Bad sqlfilters= " . $sqlfilters ;
dol_syslog ( $error , LOG_WARNING );
return false ;
}
$i ++ ;
}
return true ;
}
/**
* Function to forge a SQL criteria from a Generic filter string .
* Example of usage :
* if ( $sqlfilters ) {
* $errormessage = '' ;
* if ( dolCheckFilters ( $sqlfilters , $errormessage )) {
* $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)' ;
* $sql .= " AND ( " . preg_replace_callback ( '/' . $regexstring . '/' , 'dolForgeCriteriaCallback' , $sqlfilters ) . " ) " ;
* }
* }
*
* @ param array $matches Array of found string by regex search .
* Example : " t.ref:like:'SO-%' " or " t.date_creation:<:'20160101' " or " t.date_creation:<:'2016-01-01 12:30:00' " or " t.nature:is:NULL "
* @ return string Forged criteria . Example : " t.field like 'abc%' "
*/
function dolForgeCriteriaCallback ( $matches )
{
global $db ;
2022-02-15 11:03:48 +01:00
dol_syslog ( " Convert matches " . $matches [ 1 ]);
2022-01-01 21:46:16 +01:00
if ( empty ( $matches [ 1 ])) {
return '' ;
}
$tmp = explode ( ':' , $matches [ 1 ], 3 );
if ( count ( $tmp ) < 3 ) {
return '' ;
}
$operand = preg_replace ( '/[^a-z0-9\._]/i' , '' , trim ( $tmp [ 0 ]));
$operator = strtoupper ( preg_replace ( '/[^a-z<>=]/i' , '' , trim ( $tmp [ 1 ])));
2022-02-28 22:30:17 +01:00
if ( $operator == 'NOTLIKE' ) {
$operator = 'NOT LIKE' ;
}
2022-01-01 21:46:16 +01:00
$tmpescaped = trim ( $tmp [ 2 ]);
$regbis = array ();
if ( $operator == 'IN' ) {
$tmpescaped = " ( " . $db -> sanitize ( $tmpescaped , 1 ) . " ) " ;
} elseif ( preg_match ( '/^\'(.*)\'$/' , $tmpescaped , $regbis )) {
$tmpescaped = " ' " . $db -> escape ( $regbis [ 1 ]) . " ' " ;
} else {
$tmpescaped = $db -> sanitize ( $db -> escape ( $tmpescaped ));
}
return $db -> escape ( $operand ) . ' ' . $db -> escape ( $operator ) . " " . $tmpescaped ;
}