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 >
2019-01-28 21:39:22 +01:00
* Copyright ( C ) 2013 - 2017 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 >
2020-04-12 18:03:51 +02:00
* Copyright ( C ) 2018 - 2020 Frédéric France < frederic . france @ netlogic . fr >
2019-03-27 11:05:43 +01:00
* Copyright ( C ) 2019 Thibault Foucart < support @ ptibogxiv . net >
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
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
{
global $conf , $mc ;
2012-01-15 02:39:43 +01:00
2012-01-11 14:14:14 +01:00
if ( is_object ( $mc ))
{
2018-10-26 18:23:48 +02:00
return $mc -> getEntity ( $element , $shared , $currentobject );
2012-01-11 14:14:14 +01: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' );
2019-11-11 23:59:36 +01:00
if ( in_array ( $element , $addzero )) $out .= '0,' ;
$out .= $conf -> entity ;
2012-01-11 15:07:17 +01: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 ;
2019-08-29 00:19:46 +02:00
if ( is_object ( $mc ) && method_exists ( $mc , 'setEntity' ))
2019-06-03 11:13:26 +02:00
{
return $mc -> setEntity ( $currentobject );
}
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
}
}
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
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
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/firefox(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) { $name = 'firefox' ; $version = $reg [ 2 ]; }
elseif ( preg_match ( '/edge(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) { $name = 'edge' ; $version = $reg [ 2 ]; }
elseif ( preg_match ( '/chrome(\/|\s)([\d\.]+)/i' , $user_agent , $reg )) { $name = 'chrome' ; $version = $reg [ 2 ]; } // we can have 'chrome (Mozilla...) chrome x.y' in one string
elseif ( preg_match ( '/chrome/i' , $user_agent , $reg )) { $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 )) { $name = 'safari' ; $version = $reg [ 2 ]; } // Safari is often present in string for mobile but its not.
elseif ( preg_match ( '/opera(\/|\s)([\d\.]*)/i' , $user_agent , $reg )) { $name = 'opera' ; $version = $reg [ 2 ]; }
elseif ( preg_match ( '/(MSIE\s([0-9]+\.[0-9]))|.*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i' , $user_agent , $reg )) { $name = 'ie' ; $version = end ( $reg ); } // MS products at end
elseif ( preg_match ( '/(Windows NT\s([0-9]+\.[0-9])).*(Trident\/[0-9]+.[0-9];.*rv:([0-9]+\.[0-9]+))/i' , $user_agent , $reg )) { $name = 'ie' ; $version = end ( $reg ); } // MS products at end
elseif ( preg_match ( '/l(i|y)n(x|ks)(\(|\/|\s)*([\d\.]+)/i' , $user_agent , $reg )) { $name = 'lynxlinks' ; $version = $reg [ 4 ]; }
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 ;
$disconnectdone = false ; $depth = 0 ;
if ( is_object ( $db ) && ! empty ( $db -> connected )) { $depth = $db -> transaction_opened ; $disconnectdone = $db -> close (); }
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
/**
* Return true if we are in a context of submitting a parameter
*
* @ 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-01-31 19:46:03 +01:00
$isset = 0 ;
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
if ( constant ( 'DOL_URL_ROOT' )) $relativepathstring = preg_replace ( '/^' . preg_quote ( constant ( 'DOL_URL_ROOT' ), '/' ) . '/' , '' , $relativepathstring );
$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
if ( ! empty ( $_GET [ 'restore_lastsearch_values' ])) // Use $_GET here and not GETPOST
{
if ( ! empty ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ])) // If there is saved values
{
$tmp = json_decode ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ], true );
if ( is_array ( $tmp ))
{
foreach ( $tmp as $key => $val )
{
if ( $key == $paramname ) // We are on the requested parameter
{
$isset = 1 ;
break ;
}
}
}
}
// If there is saved contextpage, page or limit
if ( $paramname == 'contextpage' && ! empty ( $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ]))
{
$isset = 1 ;
}
elseif ( $paramname == 'page' && ! empty ( $_SESSION [ 'lastsearch_page_' . $relativepathstring ]))
{
$isset = 1 ;
}
elseif ( $paramname == 'limit' && ! empty ( $_SESSION [ 'lastsearch_limit_' . $relativepathstring ]))
{
$isset = 1 ;
}
}
else {
$isset = ( isset ( $_POST [ $paramname ]) || isset ( $_GET [ $paramname ]));
}
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 .
* Use the property $user -> default_values [ path ][ 'creatform' ] 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 )
* 'none' = no check ( only for param that should have very rich content )
* 'int' = check it ' s numeric ( integer or float )
* 'intcomma' = check it 's integer+comma (' 1 , 2 , 3 , 4. .. ' )
* 'alpha' = check it ' s text and sign
* 'aZ' = check it ' s a - z only
* 'aZ09' = check it ' s simple alpha string ( recommended for keys )
* 'array' = check it ' s array
* 'san_alpha' = Use filter_var with FILTER_SANITIZE_STRING ( do not use this for free text string )
* 'nohtml' , 'alphanohtml' = check there is no html content
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
2017-10-13 13:28:26 +02:00
if ( empty ( $paramname )) return 'BadFirstParameterForGETPOST' ;
if ( empty ( $check ))
{
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
2019-11-11 23:59:36 +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 ] : '' );
2013-07-29 17:32:43 +02:00
else return 'BadThirdParameterForGETPOST' ;
2017-05-25 08:48:59 +02:00
2017-05-05 18:42:11 +02:00
if ( empty ( $method ) || $method == 3 || $method == 4 )
{
2017-10-13 13:28:26 +02:00
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
2019-01-27 11:55:16 +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
2019-11-11 23:59:36 +01:00
if ( ! empty ( $_GET [ 'restore_lastsearch_values' ])) // Use $_GET here and not GETPOST
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ])) // If there is saved values
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$tmp = json_decode ( $_SESSION [ 'lastsearch_values_' . $relativepathstring ], true );
2018-06-23 11:55:04 +02:00
if ( is_array ( $tmp ))
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
foreach ( $tmp as $key => $val )
2017-10-13 13:28:26 +02:00
{
2018-06-23 11:55:04 +02:00
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
2019-11-11 23:59:36 +01:00
if ( $paramname == 'contextpage' && ! empty ( $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ]))
2018-06-23 11:55:04 +02:00
{
2018-12-14 10:31:09 +01:00
$out = $_SESSION [ 'lastsearch_contextpage_' . $relativepathstring ];
}
2019-11-11 23:59:36 +01:00
elseif ( $paramname == 'page' && ! empty ( $_SESSION [ 'lastsearch_page_' . $relativepathstring ]))
2018-12-14 10:31:09 +01:00
{
$out = $_SESSION [ 'lastsearch_page_' . $relativepathstring ];
}
2019-11-11 23:59:36 +01:00
elseif ( $paramname == 'limit' && ! empty ( $_SESSION [ 'lastsearch_limit_' . $relativepathstring ]))
2018-12-14 10:31:09 +01:00
{
$out = $_SESSION [ 'lastsearch_limit_' . $relativepathstring ];
2018-06-23 11:55:04 +02:00
}
2017-10-13 13:28:26 +02:00
}
// Else, retreive default values if we are not doing a sort
2019-11-11 23:59:36 +01:00
elseif ( ! isset ( $_GET [ 'sortfield' ])) // 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
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $_GET [ 'action' ]) && $_GET [ 'action' ] == 'create' && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ]))
2017-10-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
// Search default value from $object->field
global $object ;
if ( is_object ( $object ) && isset ( $object -> fields [ $paramname ][ 'default' ]))
2017-10-13 13:28:26 +02:00
{
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
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_ENABLE_DEFAULT_VALUES ))
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $_GET [ 'action' ]) && ( preg_match ( '/^create/' , $_GET [ 'action' ]) || preg_match ( '/^presend/' , $_GET [ 'action' ])) && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ]))
2017-10-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
// Now search in setup to overwrite default values
2019-11-11 23:59:36 +01:00
if ( ! empty ( $user -> default_values )) // $user->default_values defined from menu 'Setup - Default values'
2017-10-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
if ( isset ( $user -> default_values [ $relativepathstring ][ 'createform' ]))
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'createform' ] as $defkey => $defval )
2017-10-13 13:28:26 +02:00
{
$qualified = 0 ;
if ( $defkey != '_noquery_' )
{
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
foreach ( $tmpqueryarraytohave as $tmpquerytohave )
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) $foundintru = 1 ;
2017-10-13 13:28:26 +02:00
}
2019-11-11 23:59:36 +01:00
if ( ! $foundintru ) $qualified = 1 ;
2017-10-13 13:28:26 +02:00
//var_dump($defkey.'-'.$qualified);
}
else $qualified = 1 ;
if ( $qualified )
{
2017-10-25 22:02:07 +02:00
//var_dump($user->default_values[$relativepathstring][$defkey]['createform']);
if ( isset ( $user -> default_values [ $relativepathstring ][ 'createform' ][ $defkey ][ $paramname ]))
2017-10-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
$out = $user -> default_values [ $relativepathstring ][ 'createform' ][ $defkey ][ $paramname ];
break ;
}
}
}
}
}
}
// Management of default search_filters and sort order
//elseif (preg_match('/list.php$/', $_SERVER["PHP_SELF"]) && ! empty($paramname) && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname]))
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $paramname ) && ! isset ( $_GET [ $paramname ]) && ! isset ( $_POST [ $paramname ]))
2017-10-25 22:02:07 +02:00
{
2019-11-11 23:59:36 +01:00
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]);
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...']
{
2019-11-11 23:59:36 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'sortorder' ] as $defkey => $defval )
2017-10-25 22:02:07 +02:00
{
$qualified = 0 ;
if ( $defkey != '_noquery_' )
{
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
foreach ( $tmpqueryarraytohave as $tmpquerytohave )
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) $foundintru = 1 ;
2017-10-13 13:28:26 +02:00
}
2019-11-11 23:59:36 +01:00
if ( ! $foundintru ) $qualified = 1 ;
2017-10-25 22:02:07 +02:00
//var_dump($defkey.'-'.$qualified);
}
else $qualified = 1 ;
if ( $qualified )
{
2019-11-11 23:59:36 +01:00
$forbidden_chars_to_replace = array ( " " , " ' " , " / " , " \\ " , " : " , " * " , " ? " , " \" " , " < " , " > " , " | " , " [ " , " ] " , " ; " , " = " ); // we accept _, -, . and ,
foreach ( $user -> default_values [ $relativepathstring ][ 'sortorder' ][ $defkey ] as $key => $val )
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
if ( $out ) $out .= ', ' ;
2017-10-25 22:02:07 +02:00
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
}
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
}
}
}
2017-09-11 00:02:52 +02:00
}
2017-10-25 22:02:07 +02:00
elseif ( isset ( $user -> default_values [ $relativepathstring ][ 'filters' ]))
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
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-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
$qualified = 0 ;
if ( $defkey != '_noquery_' )
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$tmpqueryarraywehave = explode ( '&' , dol_string_nohtmltag ( $_SERVER [ 'QUERY_STRING' ]));
$foundintru = 0 ;
foreach ( $tmpqueryarraytohave as $tmpquerytohave )
2017-10-25 22:02:07 +02:00
{
2019-11-11 23:59:36 +01:00
if ( ! in_array ( $tmpquerytohave , $tmpqueryarraywehave )) $foundintru = 1 ;
2017-10-25 22:02:07 +02:00
}
2019-11-11 23:59:36 +01:00
if ( ! $foundintru ) $qualified = 1 ;
2017-10-25 22:02:07 +02:00
//var_dump($defkey.'-'.$qualified);
2017-10-13 13:28:26 +02:00
}
2017-10-25 22:02:07 +02:00
else $qualified = 1 ;
2017-10-01 14:54:17 +02:00
2017-10-25 22:02:07 +02:00
if ( $qualified )
2017-10-13 13:28:26 +02:00
{
2017-10-25 22:02:07 +02:00
if ( isset ( $_POST [ 'sall' ]) || isset ( $_POST [ 'search_all' ]) || isset ( $_GET [ 'sall' ]) || isset ( $_GET [ 'search_all' ]))
{
// We made a search from quick search menu, do we still use default filter ?
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 );
}
}
else
2017-10-13 13:28:26 +02:00
{
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.
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ) && empty ( $_POST [ $paramname ]) && empty ( $noreplace ))
2017-10-01 14:54:17 +02:00
{
2020-03-19 11:59:57 +01:00
$reg = array ();
2019-11-11 23:59:36 +01:00
$maxloop = 20 ; $loopnb = 0 ; // Protection against infinite loop
2017-10-13 13:28:26 +02: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.
{
2019-10-20 11:17:54 +02:00
$loopnb ++ ; $newout = '' ;
2019-11-11 23:59:36 +01: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 ); }
2019-10-20 11:17:54 +02:00
elseif ( $reg [ 1 ] == 'MYCOMPANY_COUNTRY_ID' || $reg [ 1 ] == 'MYCOUNTRY_ID' || $reg [ 1 ] == 'MYCOUNTRYID' )
{
$newout = $mysoc -> country_id ;
}
elseif ( $reg [ 1 ] == 'USER_ID' || $reg [ 1 ] == 'USERID' )
{
$newout = $user -> id ;
}
elseif ( $reg [ 1 ] == 'USER_SUPERVISOR_ID' || $reg [ 1 ] == 'SUPERVISOR_ID' || $reg [ 1 ] == 'SUPERVISORID' )
{
$newout = $user -> fk_user ;
}
elseif ( $reg [ 1 ] == 'ENTITY_ID' || $reg [ 1 ] == 'ENTITYID' )
{
$newout = $conf -> entity ;
}
2019-11-11 23:59:36 +01: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
}
}
// Check is done after replacement
switch ( $check )
{
case 'none' :
break ;
case 'int' : // Check param is a numeric value (integer but also float or hexadecimal)
2019-11-11 23:59:36 +01:00
if ( ! is_numeric ( $out )) { $out = '' ; }
2017-10-13 13:28:26 +02:00
break ;
case 'intcomma' :
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/[^0-9,-]+/i' , $out )) $out = '' ;
2017-10-13 13:28:26 +02:00
break ;
case 'alpha' :
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ))
2017-11-02 09:58:22 +01:00
{
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
2020-02-19 11:33:45 +01:00
$out = str_replace ( array ( '"' , '../' ), '' , trim ( $out ));
2017-11-02 09:58:22 +01:00
}
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 ;
case 'aZ' :
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ))
2017-11-02 09:58:22 +01:00
{
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
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' :
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ))
2017-11-02 09:58:22 +01:00
{
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
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
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ))
2018-04-25 15:47:42 +02:00
{
2019-11-11 23:59:36 +01:00
$out = trim ( $out );
if ( preg_match ( '/[^a-z0-9_\-\.,]+/i' , $out )) $out = '' ;
2018-04-25 15:47:42 +02:00
}
break ;
2017-10-13 13:28:26 +02:00
case 'array' :
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ) || empty ( $out )) $out = array ();
2017-10-13 13:28:26 +02:00
break ;
2020-02-19 11:33:45 +01:00
case 'nohtml' :
2019-11-11 23:59:36 +01:00
$out = dol_string_nohtmltag ( $out , 0 );
2017-10-01 14:54:17 +02:00
break ;
2020-02-19 11:33:45 +01:00
case 'alphanohtml' : // Recommended for most scalar parameters and search parameters
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $out ))
2017-11-02 09:58:22 +01:00
{
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
2020-02-19 11:33:45 +01:00
$out = str_replace ( array ( '"' , '../' ), '' , trim ( $out ));
2020-07-30 14:47:51 +02:00
$out = dol_string_nohtmltag ( $out , 0 );
2017-11-02 09:58:22 +01:00
}
2017-10-01 14:54:17 +02:00
break ;
2019-10-04 14:04:31 +02:00
case 'restricthtml' : // Recommended for most html textarea
2019-11-11 23:59:36 +01:00
$out = dol_string_onlythesehtmltags ( $out , 0 );
2019-10-04 14:04:31 +02:00
break ;
2017-10-01 14:54:17 +02:00
case 'custom' :
2017-10-13 13:28:26 +02: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
2017-10-13 13:28:26 +02:00
// Code for search criteria persistence.
2017-05-16 23:38:23 +02:00
// Save data into session if key start with 'search_' or is 'smonth', 'syear', 'month', 'year'
if ( empty ( $method ) || $method == 3 || $method == 4 )
{
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/^search_/' , $paramname ) || in_array ( $paramname , array ( 'sortorder' , 'sortfield' )))
2017-10-13 13:28:26 +02:00
{
//var_dump($paramname.' - '.$out.' '.$user->default_values[$relativepathstring]['filters'][$paramname]);
2017-05-19 15:34:38 +02:00
2018-04-25 16:01:06 +02:00
// 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).
2017-05-25 08:48:59 +02:00
2018-09-27 16:38:18 +02:00
if ( $out != '' ) // $out = '0' or 'abc', it is a search criteria to keep
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$user -> lastsearch_values_tmp [ $relativepathstring ][ $paramname ] = $out ;
2017-10-13 13:28:26 +02:00
}
}
2017-05-16 23:38:23 +02:00
}
2017-05-25 08:48:59 +02: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
2019-11-11 23:59:36 +01:00
if ( ! function_exists ( 'dol_getprefix' ))
2010-12-27 20:13:06 +01:00
{
2018-08-31 21:39:23 +02:00
/**
* Return a prefix to use for this Dolibarr instance , for session / cookie names or email id .
2019-04-07 15:44:17 +02:00
* 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 .
2018-08-31 21:39:23 +02:00
*
* @ param string $mode '' ( prefix for session name ) or 'email' ( prefix for email id )
* @ return string A calculated prefix
*/
2019-01-27 15:20:16 +01:00
function dol_getprefix ( $mode = '' )
2018-08-31 21:39:23 +02:00
{
2019-04-07 15:44:17 +02:00
global $conf ;
2016-12-15 12:11:39 +01:00
2018-11-16 16:43:13 +01:00
// If prefix is for email
if ( $mode == 'email' )
2017-12-19 00:15:22 +01:00
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID )) // If MAIL_PREFIX_FOR_EMAIL_ID is set (a value initialized with a random value is recommended)
2018-11-16 16:43:13 +01:00
{
if ( $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME' ) return $conf -> global -> MAIL_PREFIX_FOR_EMAIL_ID ;
2019-01-27 10:49:34 +01:00
elseif ( isset ( $_SERVER [ " SERVER_NAME " ])) return $_SERVER [ " SERVER_NAME " ];
2018-11-16 16:43:13 +01:00
}
2019-04-07 15:44:17 +02:00
// The recommended value (may be not defined for old versions)
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> file -> instance_unique_id )) return $conf -> file -> instance_unique_id ;
2019-04-07 15:44:17 +02:00
// For backward compatibility
2019-01-19 16:14:45 +01:00
return dol_hash ( DOL_DOCUMENT_ROOT . DOL_URL_ROOT , '3' );
2017-12-19 00:15:22 +01:00
}
2019-04-07 15:44:17 +02:00
// The recommended value (may be not defined for old versions)
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> file -> instance_unique_id )) return $conf -> file -> instance_unique_id ;
2019-04-07 15:44:17 +02:00
// For backward compatibility
2017-12-19 00:15:22 +01:00
if ( isset ( $_SERVER [ " SERVER_NAME " ]) && isset ( $_SERVER [ " DOCUMENT_ROOT " ]))
{
2019-01-19 16:14:45 +01:00
return dol_hash ( $_SERVER [ " SERVER_NAME " ] . $_SERVER [ " DOCUMENT_ROOT " ] . DOL_DOCUMENT_ROOT . DOL_URL_ROOT , '3' );
2017-12-19 00:15:22 +01:00
}
2019-04-07 15:44:17 +02:00
2019-01-19 16:14:45 +01:00
return dol_hash ( DOL_DOCUMENT_ROOT . DOL_URL_ROOT , '3' );
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
{
2019-11-11 23:59:36 +01:00
global $conf , $langs , $user , $mysoc ; // Do not remove this. They must be defined for files we include. Other globals var must be retreived 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
2012-08-03 23:29:08 +02:00
if ( empty ( $type )) // For a filesystem path
{
2019-11-11 23:59:36 +01:00
$res = DOL_DOCUMENT_ROOT . '/' . $path ; // Standard default path
2019-05-15 18:59:46 +02:00
if ( is_array ( $conf -> file -> dol_document_root ))
2013-07-07 13:17:48 +02:00
{
2019-05-15 18:59:46 +02:00
foreach ( $conf -> file -> dol_document_root as $key => $dirroot ) // ex: array("main"=>"/home/main/htdocs", "alt0"=>"/home/dirmod/htdocs", ...)
2018-11-05 15:31:41 +01:00
{
2019-05-15 18:59:46 +02:00
if ( $key == 'main' )
{
continue ;
}
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
}
}
2017-11-05 18:15:59 +01:00
if ( $returnemptyifnotfound ) // Not found into alternate dir
2017-09-23 01:24:31 +02:00
{
2019-11-11 23:59:36 +01:00
if ( $returnemptyifnotfound == 1 || ! file_exists ( $res )) return '' ;
2017-09-23 01:24:31 +02:00
}
2012-08-03 23:29:08 +02:00
}
else // For an url path
{
// 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 = '' ;
if ( $type == 1 ) $res = DOL_URL_ROOT . '/' . $path ; // Standard value
if ( $type == 2 ) $res = DOL_MAIN_URL_ROOT . '/' . $path ; // Standard value
2016-08-02 14:33:46 +02:00
if ( $type == 3 ) $res = DOL_URL_ROOT . '/' . $path ;
2016-11-16 09:40:29 +01:00
2013-07-07 13:17:48 +02:00
foreach ( $conf -> file -> dol_document_root as $key => $dirroot ) // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
2012-08-03 23:29:08 +02:00
{
2016-11-16 09:40:29 +01:00
if ( $key == 'main' )
2016-10-31 10:37:58 +01:00
{
2017-10-13 13:28:26 +02:00
if ( $type == 3 )
{
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 '?'
if ( ! empty ( $regs [ 1 ]))
2012-08-03 23:29:08 +02:00
{
2013-07-07 03:26:51 +02:00
//print $key.'-'.$dirroot.'/'.$path.'-'.$conf->file->dol_url_root[$type].'<br>'."\n";
2013-07-09 14:19:05 +02:00
if ( file_exists ( $dirroot . '/' . $regs [ 1 ]))
2013-07-07 13:17:48 +02:00
{
2013-07-07 23:37:56 +02:00
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
}
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
}
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
{
2017-07-23 20:27:30 +02:00
if ( empty ( $native ))
{
2019-11-11 23:59:36 +01:00
$myclone = unserialize ( serialize ( $object ));
2017-07-23 20:27:30 +02:00
}
else
{
2019-11-11 23:59:36 +01:00
$myclone = clone $object ; // PHP clone is a shallow copy only, not a real clone, so properties of references will keep references (refer 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 ;
2013-04-03 15:20:56 +02:00
if ( empty ( $conf -> dol_optimize_smallscreen )) return $size ;
2012-08-03 23:29:08 +02:00
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
/**
2011-08-17 18:18:12 +02:00
* Clean a string to use it as a file name
*
2011-09-17 02:47:01 +02:00
* @ param string $str String to clean
* @ 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.
$filesystem_forbidden_chars = array ( '<' , '>' , '/' , '\\' , '?' , '*' , '|' , '"' , ':' , '°' , '$' , ';' );
2019-11-11 23:59:36 +01:00
return dol_string_nospecial ( $unaccent ? dol_string_unaccent ( $str ) : $str , $newstr , $filesystem_forbidden_chars );
2008-10-25 23:35:27 +02:00
}
2016-09-08 11:05:47 +02:00
/**
* Clean a string to use it as a path name
*
* @ 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
{
2019-11-11 23:59:36 +01:00
$filesystem_forbidden_chars = array ( '<' , '>' , '?' , '*' , '|' , '"' , '°' );
2020-01-13 13:20:58 +01:00
return dol_string_nospecial ( $unaccent ? dol_string_unaccent ( $str ) : $str , $newstr , $filesystem_forbidden_chars );
2016-09-08 11:05:47 +02:00
}
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
{
2012-08-03 23:29:08 +02:00
if ( utf8_check ( $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' ,
'%C3%88' => 'E' , '%C3%89' => 'E' , '%C3%8A' => 'E' , '%C3%8B' => 'E' ,
'%C3%8C' => 'I' , '%C3%8D' => 'I' , '%C3%8E' => 'I' , '%C3%8F' => 'I' ,
'%C3%92' => 'O' , '%C3%93' => 'O' , '%C3%94' => 'O' , '%C3%95' => 'O' , '%C3%96' => 'O' ,
'%C3%99' => 'U' , '%C3%9A' => 'U' , '%C3%9B' => 'U' , '%C3%9C' => 'U' ,
'%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' ,
'%C3%B9' => 'u' , '%C3%BA' => 'u' , '%C3%BB' => 'u' , '%C3%BC' => 'u' ,
2014-09-06 14:40:43 +02:00
'%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 );
2012-08-03 23:29:08 +02:00
}
else
{
2014-09-06 14:40:43 +02:00
// See http://www.ascii-code.com/
2019-10-20 11:17:54 +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
*
2015-02-20 22:51:47 +01:00
* @ param string $str String to clean
* @ param string $newstr String to replace forbidden chars with
* @ param array $badcharstoreplace List of forbidden characters
* @ return string Cleaned string
2011-09-20 13:43:14 +02:00
*
2019-03-11 01:01:15 +01:00
* @ see dol_sanitizeFilename (), dol_string_unaccent ()
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_string_nospecial ( $str , $newstr = '_' , $badcharstoreplace = '' )
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 ();
if ( is_array ( $badcharstoreplace )) $forbidden_chars_to_replace = $badcharstoreplace ;
2012-08-03 23:29:08 +02:00
//$forbidden_chars_to_remove=array("(",")");
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
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.
2019-11-11 23:59:36 +01:00
if ( empty ( $noescapebackslashn )) { $substitjs [ " \n " ] = '\\n' ; $substitjs [ '\\' ] = '\\\\' ; }
if ( empty ( $mode )) { $substitjs [ " ' " ] = " \\ ' " ; $substitjs [ '"' ] = " \\ ' " ; }
elseif ( $mode == 1 ) $substitjs [ " ' " ] = " \\ ' " ;
elseif ( $mode == 2 ) { $substitjs [ '"' ] = '\\"' ; }
elseif ( $mode == 3 ) { $substitjs [ " ' " ] = " \\ ' " ; $substitjs [ '"' ] = " \\ \" " ; }
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
* @ param int $keepb 1 = Preserve b tags ( otherwise , remove them )
* @ param int $keepn 1 = Preserve \r\n strings ( otherwise , replace them with escaped value ) . Set to 1 when escaping for a < textarea >.
* @ param string $keepmoretags '' or 'common' or list of tags
* @ 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
*/
2020-03-12 16:15:48 +01:00
function dol_escape_htmltag ( $stringtoescape , $keepb = 0 , $keepn = 0 , $keepmoretags = '' , $escapeonlyhtmltags = 0 )
2009-01-28 10:00:29 +01:00
{
2019-08-30 16:22:24 +02:00
if ( $keepmoretags == 'common' ) $keepmoretags = 'html,body,a,em,i,u,ul,li,br,div,img,font,p,span,strong,table,tr,td,th,tbody' ;
// TODO Implement $keepmoretags
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' );
}
2019-11-11 23:59:36 +01:00
if ( ! $keepb ) $tmp = strtr ( $tmp , array ( " <b> " => '' , '</b>' => '' ));
if ( ! $keepn ) $tmp = strtr ( $tmp , array ( " \r " => '\\r' , " \n " => '\\n' ));
2020-03-12 16:15:48 +01:00
if ( $escapeonlyhtmltags ) {
return htmlspecialchars ( $tmp , ENT_COMPAT , 'UTF-8' );
} else {
return htmlentities ( $tmp , ENT_COMPAT , 'UTF-8' );
}
2009-01-28 10:00:29 +01:00
}
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 lower . Never use strtolower because it does not works with UTF8 strings .
2012-10-23 09:30:48 +02:00
*
2012-10-18 16:30:12 +02:00
* @ param string $utf8_string String to encode
2012-10-23 09:30:48 +02:00
* @ return string String converted
2012-10-18 16:30:12 +02:00
*/
function dol_strtolower ( $utf8_string )
{
return mb_strtolower ( $utf8_string , " UTF-8 " );
}
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
*
2012-10-18 16:30:12 +02:00
* @ param string $utf8_string String to encode
2012-10-23 09:30:48 +02:00
* @ return string String converted
2012-10-18 16:30:12 +02:00
*/
2012-10-28 13:57:21 +01:00
function dol_strtoupper ( $utf8_string )
{
return mb_strtoupper ( $utf8_string , " UTF-8 " );
}
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
* On Linux LOG_ERR = 3 , LOG_WARNING = 4 , LOG_INFO = 6 , LOG_DEBUG = 7
* @ 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
{
2019-03-23 14:37:54 +01:00
global $conf , $user , $debugbar ;
2012-10-16 02:01:37 +02:00
// If syslog module enabled
2015-02-25 18:24:36 +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
if ( defined ( 'USEEXTERNALSERVER' ) && ! defined ( 'USEDOLIBARRSERVER' ) && ! defined ( 'USEDOLIBARREDITOR' )) {
global $website , $websitekey ;
if ( is_object ( $website ) && ! empty ( $website -> ref )) $suffixinfilename .= '_website_' . $website -> ref ;
elseif ( ! empty ( $websitekey )) $suffixinfilename .= '_website_' . $websitekey ;
}
2018-06-04 12:55:55 +02:00
if ( $ident < 0 )
{
foreach ( $conf -> loghandlers as $loghandlerinstance )
{
$loghandlerinstance -> setIdent ( $ident );
}
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $message ))
2012-10-16 02:01:37 +02:00
{
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' );
2019-11-11 23:59:36 +01:00
if ( ! array_key_exists ( $level , $logLevels ))
2017-10-13 13:28:26 +02:00
{
throw new Exception ( 'Incorrect log level' );
}
if ( $level > $conf -> global -> SYSLOG_LEVEL ) return ;
2019-11-11 23:59:36 +01:00
$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 ))
|| ( ! empty ( $user -> rights -> debugbar -> read ) && is_object ( $debugbar )))
2017-10-13 13:28:26 +02:00
{
2019-03-23 14:37:54 +01: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
2019-11-11 23:59:36 +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 " ;
print $message . " \n " ;
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
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' ];
}
2017-10-13 13:28:26 +02:00
// This is when PHP session is ran inside a web server but not inside a client request (example: init code of apache)
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $_SERVER [ 'SERVER_ADDR' ])) $data [ 'ip' ] = $_SERVER [ 'SERVER_ADDR' ];
2017-10-13 13:28:26 +02:00
// 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).
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $_SERVER [ 'COMPUTERNAME' ])) $data [ 'ip' ] = $_SERVER [ 'COMPUTERNAME' ] . ( empty ( $_SERVER [ 'USERNAME' ]) ? '' : '@' . $_SERVER [ 'USERNAME' ]);
2017-10-13 13:28:26 +02:00
// 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).
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $_SERVER [ 'LOGNAME' ])) $data [ 'ip' ] = '???@' . $_SERVER [ 'LOGNAME' ];
2017-10-13 13:28:26 +02:00
// Loop on each log handler and send output
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
2018-06-04 12:55:55 +02:00
if ( $ident > 0 )
2012-10-16 02:01:37 +02:00
{
2012-12-05 11:18:45 +01:00
foreach ( $conf -> loghandlers as $loghandlerinstance )
{
$loghandlerinstance -> setIdent ( $ident );
}
2012-08-03 23:29:08 +02:00
}
2008-08-06 16:50:06 +02:00
}
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
2019-03-02 18:20:13 +01:00
* @ param int $notab - 1 or 0 = Add tab header , 1 = no tab header ( if you set this to 1 , using dol_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 .
2011-09-17 02:47:01 +02:00
* @ return void
2008-08-06 16:50:06 +02:00
*/
2020-02-24 20:41:29 +01:00
function dol_fiche_head ( $links = array (), $active = '0' , $title = '' , $notab = 0 , $picto = '' , $pictoisfullpath = 0 , $morehtmlright = '' , $morecss = '' , $limittoshow = 0 )
2008-08-06 16:50:06 +02:00
{
2020-02-24 20:41:29 +01:00
print dol_get_fiche_head ( $links , $active , $title , $notab , $picto , $pictoisfullpath , $morehtmlright , $morecss , $limittoshow );
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
*
2013-03-10 13:23:55 +01:00
* @ param array $links Array of tabs
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
2019-03-02 18:20:13 +01:00
* @ param int $notab - 1 or 0 = Add tab header , 1 = no tab header ( if you set this to 1 , using dol_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 .
2015-02-10 10:45:48 +01:00
* @ return string
2011-07-08 15:07:44 +02:00
*/
2020-02-24 20:41:29 +01:00
function dol_get_fiche_head ( $links = array (), $active = '' , $title = '' , $notab = 0 , $picto = '' , $pictoisfullpath = 0 , $morehtmlright = '' , $morecss = '' , $limittoshow = 0 )
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 ;
if ( ! empty ( $conf -> dol_optimize_smallscreen )) $showtitle = 0 ;
2012-08-03 23:29:08 +02:00
2019-11-01 23:16:08 +01:00
$out = " \n " . '<!-- 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
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
if ( ! empty ( $title ) && $showtitle )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$limittitle = 30 ;
$out .= '<a class="tabTitle">' ;
2020-06-10 12:35:39 +02:00
if ( $picto && empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) $out .= img_picto ( $title , ( $pictoisfullpath ? '' : 'object_' ) . $picto , '' , $pictoisfullpath , 0 , 0 , '' , 'imgTabTitle' ) . ' ' ;
2019-11-11 23:59:36 +01:00
$out .= '<span class="tabTitleText">' . dol_trunc ( $title , $limittitle ) . '</span>' ;
$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 ;
if ( is_array ( $links ) && ! empty ( $links ))
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$keys = array_keys ( $links );
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 );
}
if ( ! empty ( $conf -> dol_optimize_smallscreen )) $limittoshow = 2 ;
2019-11-11 23:59:36 +01:00
$displaytab = 0 ;
$nbintab = 0 ;
$popuptab = 0 ;
$outmore = '' ;
for ( $i = 0 ; $i <= $maxkey ; $i ++ )
{
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
if ( $i >= $limittoshow ) $limittoshow -- ;
2015-11-17 14:42:34 +01:00
}
}
2015-11-01 17:27:41 +01:00
2019-11-11 23:59:36 +01:00
for ( $i = 0 ; $i <= $maxkey ; $i ++ )
2012-08-03 23:29:08 +02:00
{
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 ;
2014-12-22 12:26:04 +01:00
}
2019-11-01 23:16:08 +01: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
2015-11-17 14:42:34 +01:00
if ( $i < $limittoshow || $isactive )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$out .= '<div class="inline-block tabsElem' . ( $isactive ? ' tabsElemActive' : '' ) . (( ! $isactive && ! empty ( $conf -> global -> MAIN_HIDE_INACTIVETAB_ON_PRINT )) ? ' hideonprint' : '' ) . '"><!-- id tab = ' . ( empty ( $links [ $i ][ 2 ]) ? '' : $links [ $i ][ 2 ]) . ' -->' ;
2014-12-22 12:26:04 +01:00
if ( isset ( $links [ $i ][ 2 ]) && $links [ $i ][ 2 ] == 'image' )
2012-08-03 23:29:08 +02:00
{
2014-12-22 12:26:04 +01:00
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 " ;
2014-12-22 12:26:04 +01: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
}
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $links [ $i ][ 1 ]))
2012-08-03 23:29:08 +02:00
{
2014-12-22 12:26:04 +01:00
//print "x $i $active ".$links[$i][2]." z";
if ( $isactive )
{
2019-11-11 23:59:36 +01:00
$out .= '<a' . ( ! empty ( $links [ $i ][ 2 ]) ? ' id="' . $links [ $i ][ 2 ] . '"' : '' ) . ' class="tabactive tab inline-block' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '">' ;
$out .= $links [ $i ][ 1 ];
$out .= '</a>' . " \n " ;
2014-12-22 12:26:04 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
$out .= '<a' . ( ! empty ( $links [ $i ][ 2 ]) ? ' id="' . $links [ $i ][ 2 ] . '"' : '' ) . ' class="tabunactive tab inline-block' . ( $morecss ? ' ' . $morecss : '' ) . '" href="' . $links [ $i ][ 0 ] . '">' ;
$out .= $links [ $i ][ 1 ];
$out .= '</a>' . " \n " ;
2014-12-22 12:26:04 +01:00
}
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
$out .= '</div>' ;
2012-08-03 23:29:08 +02:00
}
2014-12-22 12:26:04 +01:00
else
2012-08-03 23:29:08 +02:00
{
2017-10-13 13:28:26 +02:00
// The popup with the other tabs
2019-11-11 23:59:36 +01:00
if ( ! $popuptab )
2015-10-15 13:31:44 +02:00
{
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;">' ;
2014-12-22 12:26:04 +01:00
if ( isset ( $links [ $i ][ 2 ]) && $links [ $i ][ 2 ] == 'image' )
2012-08-03 23:29:08 +02:00
{
2014-12-22 12:26:04 +01:00
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 " ;
2014-12-22 12:26:04 +01:00
else
2019-11-11 23:59:36 +01:00
$outmore .= '<span class="tabspan">' . $links [ $i ][ 1 ] . '</span>' . " \n " ;
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $links [ $i ][ 1 ]))
2017-11-24 14:23:25 +01:00
{
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
}
2019-11-11 23:59:36 +01:00
if ( $popuptab ) $outmore .= '</div>' ;
2015-11-01 17:27:41 +01:00
2019-08-22 11:47:03 +02:00
if ( $popuptab ) // If there is some tabs not shown
2014-12-22 12:26:04 +01:00
{
2019-11-11 23:59:36 +01:00
$left = ( $langs -> trans ( " DIRECTION " ) == 'rtl' ? 'right' : 'left' );
$right = ( $langs -> trans ( " DIRECTION " ) == 'rtl' ? 'left' : 'right' );
2017-11-24 14:23:25 +01:00
2019-11-11 23:59:36 +01:00
$tabsname = str_replace ( " @ " , " " , $picto );
$out .= '<div id="moretabs' . $tabsname . '" class="inline-block tabsElem">' ;
$out .= '<a href="#" class="tab moretab inline-block tabunactive reposition">' . $langs -> trans ( " More " ) . '... (' . $nbintab . ')</a>' ;
2020-02-23 23:37:46 +01:00
$out .= '<div id="moretabsList' . $tabsname . '" style="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> " ;
$out .= " $ ('#moretabs " . $tabsname . " ').mouseenter( function() { console.log('mouseenter " . $left . " '); $ ('#moretabsList " . $tabsname . " ').css(' " . $left . " ','auto');}); " ;
$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
2019-11-11 23:59:36 +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"
2016-11-12 14:36:52 +01:00
if ( $reshook > 0 )
{
$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
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
{
2019-11-11 23:59:36 +01:00
if ( ! $notab || $notab == - 1 ) return " \n </div> \n " ;
2012-08-03 23:29:08 +02:00
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
* @ param string $morehtmlref More html to show after ref
* @ param string $moreparam More param to add in nav link url .
* @ param int $nodbprefix Do not include DB prefix to forge table name
* @ param string $morehtmlleft More html code to show before ref
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
{
2015-10-11 12:27:04 +02:00
global $conf , $form , $user , $langs ;
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 );
$showbarcode = empty ( $conf -> barcode -> enabled ) ? 0 : ( $object -> barcode ? 1 : 0 );
if ( ! empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && empty ( $user -> rights -> barcode -> lire_advance )) $showbarcode = 0 ;
$modulepart = 'unknown' ;
2017-02-13 01:36:02 +01:00
2019-11-11 23:59:36 +01:00
if ( $object -> element == 'societe' ) $modulepart = 'societe' ;
if ( $object -> element == 'contact' ) $modulepart = 'contact' ;
if ( $object -> element == 'member' ) $modulepart = 'memberphoto' ;
if ( $object -> element == 'user' ) $modulepart = 'userphoto' ;
if ( $object -> element == 'product' ) $modulepart = 'product' ;
if ( $object -> element == 'ticket' ) $modulepart = 'ticket' ;
2017-05-05 12:33:49 +02:00
2017-04-17 13:02:40 +02:00
if ( class_exists ( " Imagick " ))
{
2019-11-11 23:59:36 +01:00
if ( $object -> element == 'propal' ) $modulepart = 'propal' ;
if ( $object -> element == 'commande' ) $modulepart = 'commande' ;
if ( $object -> element == 'facture' ) $modulepart = 'facture' ;
if ( $object -> element == 'fichinter' ) $modulepart = 'ficheinter' ;
if ( $object -> element == 'contrat' ) $modulepart = 'contract' ;
if ( $object -> element == 'supplier_proposal' ) $modulepart = 'supplier_proposal' ;
if ( $object -> element == 'order_supplier' ) $modulepart = 'supplier_order' ;
if ( $object -> element == 'invoice_supplier' ) $modulepart = 'supplier_invoice' ;
if ( $object -> element == 'expensereport' ) $modulepart = 'expensereport' ;
2017-04-17 13:02:40 +02:00
}
2015-11-06 18:57:35 +01:00
if ( $object -> element == 'product' )
{
2019-11-11 23:59:36 +01:00
$width = 80 ; $cssclass = 'photoref' ;
$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 );
if ( $conf -> browser -> layout == 'phone' ) $maxvisiblephotos = 1 ;
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>' ;
2017-10-13 13:28:26 +02:00
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>' ;
2016-06-04 16:34:26 +02:00
}
2019-06-17 18:38:14 +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
}
2015-11-06 18:57:35 +01:00
}
2018-06-04 21:49:29 +02:00
elseif ( $object -> element == 'ticket' )
2018-03-18 20:01:11 +01:00
{
2019-11-11 23:59:36 +01:00
$width = 80 ; $cssclass = 'photoref' ;
$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 );
if ( $conf -> browser -> layout == 'phone' ) $maxvisiblephotos = 1 ;
2019-10-01 12:02:28 +02:00
if ( $showimage )
{
$showphoto = $object -> show_photos ( 'ticket' , $conf -> ticket -> multidir_output [ $entity ], 'small' , $maxvisiblephotos , 0 , 0 , 0 , $width , 0 );
if ( $object -> nbphoto > 0 )
{
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $showphoto . '</div>' ;
2019-10-01 12:02:28 +02:00
}
else
{
$showimage = 0 ;
}
}
2019-11-11 23:59:36 +01:00
if ( ! $showimage )
2018-03-18 20:01:11 +01:00
{
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>' ;
2018-03-18 20:01:11 +01:00
}
2019-06-17 18:38:14 +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" border="0"' . ( $width ? ' style="width: ' . $width . 'px"' : '' ) . ' src="' . DOL_URL_ROOT . $nophoto . '"></div>' ;
2019-06-17 18:38:14 +02:00
}
2018-03-18 20:01:11 +01:00
}
}
2016-11-16 09:40:29 +01:00
else
2015-11-06 18:57:35 +01:00
{
2017-04-17 13:02:40 +02:00
if ( $showimage )
2017-10-13 13:28:26 +02:00
{
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
if ( in_array ( $modulepart , array ( 'propal' , 'commande' , 'facture' , 'ficheinter' , 'contract' , 'supplier_order' , 'supplier_proposal' , 'supplier_invoice' , 'expensereport' )) && class_exists ( " Imagick " ))
{
$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 ]) . " / " ;
2017-10-13 13:28:26 +02: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
2017-10-13 13:28:26 +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
}
2019-11-11 23:59:36 +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
2019-03-24 14:53:26 +01:00
if ( $pdfexists )
2017-10-13 13:28:26 +02:00
{
// Conversion du PDF en image png si fichier png non existant
2019-11-11 23:59:36 +01:00
if ( ! file_exists ( $fileimage ) || ( filemtime ( $fileimage ) < filemtime ( $filepdf )))
2017-10-13 13:28:26 +02:00
{
2019-03-24 13:27:26 +01:00
if ( empty ( $conf -> global -> MAIN_DISABLE_PDF_THUMBS )) // If you experience trouble with pdf thumb generation and imagick, you can disable here.
2017-10-13 13:28:26 +02:00
{
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
2017-10-13 13:28:26 +02:00
if ( $ret < 0 ) $error ++ ;
}
}
2019-03-24 14:53:26 +01:00
}
2017-10-13 13:28:26 +02:00
2019-11-11 23:59:36 +01:00
if ( $pdfexists && ! $error )
2019-03-24 14:53:26 +01:00
{
2019-11-11 23:59:36 +01:00
$heightforphotref = 70 ;
if ( ! empty ( $conf -> dol_optimize_smallscreen )) $heightforphotref = 60 ;
2019-03-24 14:54:04 +01:00
// If the preview file is found
2017-10-13 13:28:26 +02:00
if ( file_exists ( $fileimage ))
{
$phototoshow = '<div class="floatleft inline-block valignmiddle divphotoref"><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 ) . '">' ;
$phototoshow .= '</div></div>' ;
2017-10-13 13:28:26 +02:00
}
}
}
2019-11-11 23:59:36 +01:00
elseif ( ! $phototoshow )
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$phototoshow .= $form -> showphoto ( $modulepart , $object , 0 , 0 , 0 , 'photoref' , 'small' , 1 , 0 , $maxvisiblephotos );
2017-10-13 13:28:26 +02: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
}
}
2020-04-13 04:14:28 +02:00
if ( ! $phototoshow ) // Show No photo link (picto of object)
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' ;
2017-10-13 13:28:26 +02: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' );
2017-10-13 13:28:26 +02:00
}
else
{
2019-11-11 23:59:36 +01:00
$width = 14 ; $cssclass = 'photorefcenter' ;
2017-10-13 13:28:26 +02:00
$picto = $object -> picto ;
2019-11-11 23:59:36 +01:00
if ( $object -> element == 'project' && ! $object -> public ) $picto = 'project' ; // instead of projectpub
2020-04-13 04:14:28 +02:00
$nophoto = img_picto ( 'No photo' , 'object_' . $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
2019-11-11 23:59:36 +01:00
$morehtmlleft .= '</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
2019-11-11 23:59:36 +01:00
if ( $showbarcode ) $morehtmlleft .= '<div class="floatleft inline-block valignmiddle divphotoref">' . $form -> showbarcode ( $object ) . '</div>' ;
2017-05-25 08:48:59 +02:00
2017-03-10 16:26:43 +01:00
if ( $object -> element == 'societe' )
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> use_javascript_ajax ) && $user -> rights -> societe -> creer && ! empty ( $conf -> global -> MAIN_DIRECT_STATUS_UPDATE ))
2017-10-13 13:28:26 +02:00
{
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= ajax_object_onoff ( $object , 'status' , 'status' , 'InActivity' , 'ActivityCeased' );
2017-10-13 13:28:26 +02:00
}
2017-11-18 01:29:42 +01:00
else {
2019-11-11 23:59:36 +01:00
$morehtmlstatus .= $object -> getLibStatut ( 6 );
2017-11-18 01:29:42 +01:00
}
2016-11-16 09:40:29 +01:00
}
2015-11-06 18:57:35 +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
}
2015-11-06 18:57:35 +01:00
}
2017-04-13 15:15:44 +02:00
elseif ( in_array ( $object -> element , array ( 'facture' , 'invoice' , 'invoice_supplier' , 'chargesociales' , 'loan' )))
2016-09-21 01:25:34 +02:00
{
2019-11-11 23:59:36 +01:00
$tmptxt = $object -> getLibStatut ( 6 , $object -> totalpaye );
if ( empty ( $tmptxt ) || $tmptxt == $object -> getLibStatut ( 3 )) $tmptxt = $object -> getLibStatut ( 5 , $object -> totalpaye );
$morehtmlstatus .= $tmptxt ;
2016-09-21 01:25:34 +02:00
}
2017-05-25 08:48:59 +02:00
elseif ( $object -> element == 'contrat' || $object -> element == 'contract' )
2016-10-04 12:31:45 +02:00
{
2019-11-11 23:59:36 +01:00
if ( $object -> statut == 0 ) $morehtmlstatus .= $object -> getLibStatut ( 5 );
else $morehtmlstatus .= $object -> getLibStatut ( 4 );
2016-10-04 12:31:45 +02:00
}
2017-09-10 20:47:45 +02:00
elseif ( $object -> element == 'facturerec' )
{
2019-11-11 23:59:36 +01:00
if ( $object -> frequency == 0 ) $morehtmlstatus .= $object -> getLibStatut ( 2 );
else $morehtmlstatus .= $object -> getLibStatut ( 5 );
2017-09-10 20:47:45 +02:00
}
2018-03-06 21:51:43 +01:00
elseif ( $object -> element == 'project_task' )
{
$object -> fk_statut = 1 ;
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
2018-03-06 21:51:43 +01:00
}
2016-11-11 23:17:37 +01:00
else { // Generic case
2019-11-11 23:59:36 +01:00
$tmptxt = $object -> getLibStatut ( 6 );
if ( empty ( $tmptxt ) || $tmptxt == $object -> getLibStatut ( 3 )) $tmptxt = $object -> getLibStatut ( 5 );
$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"
2020-01-10 02:43:24 +01:00
if ( ! empty ( $conf -> accounting -> enabled ) && in_array ( $object -> element , array ( 'bank' , 'facture' , 'invoice' , 'invoice_supplier' , 'expensereport' , 'payment_various' )))
2018-01-22 03:07:11 +01:00
{
if ( method_exists ( $object , 'getVentilExportCompta' ))
{
$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
2019-11-11 23:59:36 +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
2020-04-01 18:11:28 +02:00
if ( in_array ( $object -> element , array ( 'product' , 'bank_account' , 'project_task' )))
2017-02-09 05:58:39 +01:00
{
2019-11-11 23:59:36 +01:00
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
2020-04-01 18:11:28 +02:00
if ( method_exists ( $object , 'getBannerAddress' ) && ! in_array ( $object -> element , array ( 'product' , 'bookmark' , 'ecm_directories' , 'ecm_files' )))
2015-11-06 18:57:35 +01:00
{
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
}
2020-04-10 10:59:32 +02: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 ))
2015-10-11 12:27:04 +02:00
{
2019-11-11 23:59:36 +01:00
$morehtmlref .= '<div style="clear: both;"></div><div class="refidno">' ;
$morehtmlref .= $langs -> trans ( " TechnicalID " ) . ': ' . $object -> id ;
$morehtmlref .= '</div>' ;
2015-10-11 12:27:04 +02:00
}
2017-05-25 08:48:59 +02:00
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 = '' ;
if ( $fieldrequired ) $ret .= '<span class="fieldrequired">' ;
$ret .= '<label for="' . $fieldkey . '">' ;
$ret .= $langs -> trans ( $langkey );
$ret .= '</label>' ;
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 ];
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 = '' ;
$countriesusingstate = array ( 'AU' , 'CA' , 'US' , 'IN' , 'GB' , 'ES' , 'UK' , 'TR' ); // 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 )) {
2020-04-01 18:11:28 +02:00
$ret .= ( $extralangcode ? $object -> array_languages [ 'address' ][ $extralangcode ] : $object -> address );
2017-11-22 09:51:46 +01:00
}
2011-10-12 19:24:27 +02:00
// Zip/Town/State
2019-11-11 23:59:36 +01:00
if ( in_array ( $object -> country_code , array ( 'AU' , 'CA' , 'US' )) || ! empty ( $conf -> global -> MAIN_FORCE_STATE_INTO_ADDRESS )) // US: title firstname name \n address lines \n town, state, zip \n country
2011-10-12 19:24:27 +02:00
{
2020-04-01 18:11:28 +02:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : $object -> town );
$ret .= ( $ret ? $sep : '' ) . $town ;
2016-02-22 13:28:08 +01:00
if ( $object -> state )
2011-10-12 19:24:27 +02:00
{
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2011-10-12 19:24:27 +02:00
}
2019-11-11 23:59:36 +01:00
if ( $object -> zip ) $ret .= ( $ret ? " , " : '' ) . $object -> zip ;
2011-10-12 19:24:27 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( in_array ( $object -> country_code , array ( 'GB' , 'UK' ))) // UK: title firstname name \n address lines \n town state \n zip \n country
2012-09-12 17:39:02 +02:00
{
2020-04-01 18:11:28 +02:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : $object -> town );
$ret .= ( $ret ? $sep : '' ) . $town ;
2016-02-22 13:28:08 +01:00
if ( $object -> state )
2012-09-15 09:02:20 +02:00
{
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2012-09-15 09:02:20 +02:00
}
2019-11-11 23:59:36 +01:00
if ( $object -> zip ) $ret .= ( $ret ? $sep : '' ) . $object -> zip ;
2012-09-12 17:39:02 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( in_array ( $object -> country_code , array ( 'ES' , 'TR' ))) // ES: title firstname name \n address lines \n zip town \n state \n country
2013-02-19 16:02:58 +01:00
{
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? $sep : '' ) . $object -> zip ;
2020-04-01 18:11:28 +02:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : $object -> town );
$ret .= ( $town ? (( $object -> zip ? ' ' : '' ) . $town ) : '' );
2016-02-22 13:28:08 +01:00
if ( $object -> state )
2013-02-19 16:02:58 +01:00
{
2019-11-11 23:59:36 +01:00
$ret .= " \n " . $object -> state ;
2013-02-19 16:02:58 +01:00
}
}
2019-01-27 23:23:38 +01:00
elseif ( in_array ( $object -> country_code , array ( 'IT' ))) // IT: tile firstname name\n address lines \n zip (Code Departement) \n country
2017-11-08 11:42:02 +01:00
{
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? $sep : '' ) . $object -> zip ;
2020-04-01 18:11:28 +02:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : $object -> town );
$ret .= ( $town ? (( $object -> zip ? ' ' : '' ) . $town ) : '' );
2020-01-13 14:25:48 +01:00
$ret .= ( $object -> state_code ? ( ' ' . ( $object -> state_code )) : '' );
2017-11-08 11:42:02 +01:00
}
2012-09-12 17:39:02 +02:00
else // Other: title firstname name \n address lines \n zip town \n country
2011-10-12 19:24:27 +02:00
{
2020-04-01 18:11:28 +02:00
$town = ( $extralangcode ? $object -> array_languages [ 'town' ][ $extralangcode ] : $object -> town );
2019-11-11 23:59:36 +01:00
$ret .= $object -> zip ? (( $ret ? $sep : '' ) . $object -> zip ) : '' ;
2020-04-01 18:11:28 +02:00
$ret .= ( $town ? (( $object -> zip ? ' ' : ( $ret ? $sep : '' )) . $town ) : '' );
2019-01-27 11:55:16 +01:00
if ( $object -> state && in_array ( $object -> country_code , $countriesusingstate ))
2011-10-12 19:24:27 +02:00
{
2019-11-11 23:59:36 +01:00
$ret .= ( $ret ? " , " : '' ) . $object -> state ;
2011-10-12 19:24:27 +02:00
}
}
2019-11-11 23:59:36 +01:00
if ( ! is_object ( $outputlangs )) $outputlangs = $langs ;
2018-05-21 19:37:47 +02:00
if ( $withcountry )
{
$langs -> load ( " dict " );
2019-11-11 23:59:36 +01:00
$ret .= ( $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 );
2013-01-18 15:57:11 +01:00
}
2013-01-19 16:29:16 +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
2016-09-23 10:32:19 +02:00
* " day " , " daytext " , " dayhour " , " dayhourldap " , " dayhourtext " , " dayrfc " , " dayhourrfc " , " ...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
*/
2019-01-27 15:20:16 +01:00
function dol_print_date ( $time , $format = '' , $tzoutput = 'tzserver' , $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
2013-04-03 15:20:56 +02:00
// Clean parameters
2019-11-11 23:59:36 +01:00
$to_gmt = false ;
$offsettz = $offsetdst = 0 ;
2012-08-03 23:29:08 +02:00
if ( $tzoutput )
{
2019-11-11 23:59:36 +01:00
$to_gmt = true ; // For backward compatibility
2012-08-03 23:29:08 +02: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'
$offsettz = 0 ;
$offsetdst = 0 ;
2012-08-03 23:29:08 +02:00
}
2017-10-12 18:14:02 +02:00
elseif ( $tzoutput == 'tzuser' || $tzoutput == 'tzuserrel' )
2012-08-03 23:29:08 +02:00
{
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'
$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
}
}
}
2019-11-11 23:59:36 +01:00
if ( ! is_object ( $outputlangs )) $outputlangs = $langs ;
if ( ! $format ) $format = 'daytextshort' ;
$reduceformat = ( ! empty ( $conf -> dol_optimize_smallscreen ) && in_array ( $format , array ( 'day' , 'dayhour' ))) ? 1 : 0 ;
2019-01-27 11:55:16 +01:00
$formatwithoutreduce = preg_replace ( '/reduceformat/' , '' , $format );
2019-11-11 23:59:36 +01:00
if ( $formatwithoutreduce != $format ) { $format = $formatwithoutreduce ; $reduceformat = 1 ; } // 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
2019-11-11 23:59:36 +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 );
2012-08-03 23:29:08 +02:00
// Format not sensitive to language
2019-11-11 23:59:36 +01:00
elseif ( $format == 'dayhourlog' ) $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' ;
2012-08-03 23:29:08 +02:00
2013-04-21 17:56:29 +02:00
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
2012-08-03 23:29:08 +02:00
// If date undefined or "", we return ""
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $time ) == 0 ) return '' ; // $time=0 allowed (it means 01/01/1970 00:00:00)
2012-08-03 23:29:08 +02:00
2013-04-03 15:20:56 +02:00
// Clean format
2019-01-27 11:55:16 +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
}
2019-01-27 11:55:16 +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 ();
2019-04-01 22:09:24 +02: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
2012-08-03 23:29:08 +02:00
{
2019-04-01 19:27:34 +02:00
dol_print_error ( " Functions.lib::dol_print_date function called with a bad value from page " . $_SERVER [ " PHP_SELF " ]);
return '' ;
2012-08-03 23:29:08 +02:00
}
2019-04-01 22:09:24 +02: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
{
// This part of code should not be used.
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'
2019-11-11 23:59:36 +01:00
$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 ] : '' );
2019-04-01 22:09:24 +02:00
2019-11-11 23:59:36 +01:00
$time = dol_mktime ( $shour , $smin , $ssec , $smonth , $sday , $syear , true );
$ret = adodb_strftime ( $format , $time + $offsettz + $offsetdst , $to_gmt );
2019-04-01 22:09:24 +02:00
}
2012-08-03 23:29:08 +02:00
else
{
// Date is a timestamps
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
2019-11-11 23:59:36 +01:00
$ret = adodb_strftime ( $format , $timetouse , $to_gmt );
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
else $ret = 'Bad value ' . $time . ' for date' ;
2012-08-03 23:29:08 +02:00
}
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/__b__/i' , $format ))
2012-08-03 23:29:08 +02:00
{
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.
2019-11-11 23:59:36 +01:00
$month = adodb_strftime ( '%m' , $timetouse );
$month = sprintf ( " %02d " , $month ); // $month may be return with format '06' on some installation and '6' on other, so we force it to '06'.
2012-08-03 23:29:08 +02:00
if ( $encodetooutput )
{
2019-11-11 23:59:36 +01:00
$monthtext = $outputlangs -> transnoentities ( 'Month' . $month );
$monthtextshort = $outputlangs -> transnoentities ( 'MonthShort' . $month );
2012-08-03 23:29:08 +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;
}
2019-01-27 11:55:16 +01:00
if ( preg_match ( '/__a__/i' , $format ))
2012-08-03 23:29:08 +02:00
{
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
2019-11-11 23:59:36 +01:00
$w = adodb_strftime ( '%w' , $timetouse ); // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring.
$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 .
2011-09-03 01:57:26 +02:00
* PHP getdate is restricted to the years 1901 - 2038 on Unix and 1970 - 2038 on Windows
2015-02-03 11:25:51 +01:00
* WARNING : This function always use PHP server timezone to return locale informations !!!
2012-01-22 02:12:11 +01:00
* Usage must be avoid .
2015-02-03 11:25:51 +01:00
* FIXME : Replace this with PHP date function and a parameter $gm
2012-01-22 02:12:11 +01:00
*
2013-11-07 21:12:11 +01:00
* @ param int $timestamp Timestamp
2012-04-02 18:37:37 +02:00
* @ param boolean $fast Fast mode
2011-10-03 18:10:50 +02:00
* @ return array Array of informations
* If no fast mode :
* '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 ,
* 'yday' => floor ( $secsInYear / $_day_power ),
* 'weekday' => gmdate ( 'l' , $_day_power * ( 3 + $dow )),
* 'month' => gmdate ( 'F' , mktime ( 0 , 0 , 0 , $month , 2 , 1971 )),
* If fast mode :
* 'seconds' => $secs ,
* 'minutes' => $min ,
* 'hours' => $hour ,
* 'mday' => $day ,
* 'mon' => $month ,
* 'year' => $year ,
* 'yday' => floor ( $secsInYear / $_day_power ),
* 'leap' => $leaf ,
* 'ndays' => $ndays
2019-03-11 01:01:15 +01:00
* @ see dol_print_date (), dol_stringtotime (), dol_mktime ()
2008-08-06 16:50:06 +02:00
*/
2019-01-27 15:20:16 +01:00
function dol_getdate ( $timestamp , $fast = false )
2008-08-06 16:50:06 +02:00
{
2014-12-06 11:00:49 +01:00
global $conf ;
2014-12-18 10:09:47 +01:00
2019-11-11 23:59:36 +01:00
$usealternatemethod = false ;
if ( $timestamp <= 0 ) $usealternatemethod = true ; // <= 1970
if ( $timestamp >= 2145913200 ) $usealternatemethod = true ; // >= 2038
2012-08-03 23:29:08 +02:00
if ( $usealternatemethod )
{
2019-11-11 23:59:36 +01:00
$arrayinfo = adodb_getdate ( $timestamp , $fast );
2012-08-03 23:29:08 +02:00
}
else
{
2019-11-11 23:59:36 +01:00
$arrayinfo = getdate ( $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
* False or 0 or 'server' = local to server TZ
* 'user' = local to user TZ
* '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
*/
2019-01-27 15:20:16 +01:00
function dol_mktime ( $hour , $minute , $second , $month , $day , $year , $gm = false , $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"]." -";
// Clean parameters
2019-11-11 23:59:36 +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
if ( $check )
{
2019-11-11 23:59:36 +01:00
if ( ! $month || ! $day ) return '' ;
if ( $day > 31 ) return '' ;
2012-08-03 23:29:08 +02:00
if ( $month > 12 ) return '' ;
2019-11-11 23:59:36 +01:00
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
}
2019-11-01 15:21:21 +01:00
if ( empty ( $gm ) || $gm === 'server' )
2012-08-03 23:29:08 +02:00
{
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 );
}
elseif ( $gm === 'user' )
{
// 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 );
}
2019-11-11 23:59:36 +01:00
catch ( Exception $e )
2014-03-21 10:13:29 +01:00
{
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
}
2019-11-01 15:21:21 +01:00
}
elseif ( strrpos ( $gm , " tz, " ) !== false )
{
2019-11-11 23:59:36 +01:00
$timezone = str_replace ( " tz, " , " " , $gm ); // Example 'tz,Europe/Berlin'
2019-11-01 15:21:21 +01:00
try
2016-02-22 22:00:59 +01:00
{
2019-11-01 15:21:21 +01:00
$localtz = new DateTimeZone ( $timezone );
2016-02-22 22:00:59 +01:00
}
2019-11-11 23:59:36 +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
*
2019-10-17 20:24:04 +02:00
* @ param string $mode 'gmt' => we return GMT timestamp ,
2012-02-06 05:31:19 +01:00
* 'tzserver' => we add the PHP server timezone
* 'tzref' => we add the company timezone
* 'tzuser' => 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
*/
2019-01-27 15:20:16 +01:00
function dol_now ( $mode = 'gmt' )
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
2019-11-11 23:59:36 +01:00
if ( $mode == 'gmt' ) $ret = time (); // Time for now at greenwich.
2019-01-27 10:49:34 +01:00
elseif ( $mode == 'tzserver' ) // Time for now with PHP server timezone added
2012-08-03 23:29:08 +02:00
{
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 ));
2012-08-03 23:29:08 +02:00
}
2020-01-27 02:13:12 +01:00
/* elseif ( $mode == 'tzref' ) // Time for now with parent company timezone is added
2012-08-03 23:29:08 +02:00
{
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2012-08-03 23:29:08 +02:00
$tzsecond = getParentCompanyTimeZoneInt (); // Contains tz+dayling saving time
$ret = dol_now ( 'gmt' ) + ( $tzsecond * 3600 );
} */
2019-01-27 10:49:34 +01:00
elseif ( $mode == 'tzuser' ) // Time for now with user timezone added
2012-08-03 23:29:08 +02:00
{
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
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
if ( empty ( $shortvalue ) || $size < ( $level * 10 ))
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$ret = $size ;
$textunitshort = $langs -> trans ( " b " );
$textunitlong = $langs -> trans ( " Bytes " );
2012-08-03 23:29:08 +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
2019-11-11 23:59:36 +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
2012-08-03 23:29:08 +02:00
if ( empty ( $url )) return '' ;
2019-11-11 23:59:36 +01:00
$link = '<a href="' ;
if ( ! preg_match ( '/^http/i' , $url )) $link .= 'http://' ;
$link .= $url ;
$link .= '"' ;
if ( $target ) $link .= ' target="' . $target . '"' ;
$link .= '>' ;
if ( ! preg_match ( '/^http/i' , $url )) $link .= 'http://' ;
$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
}
/**
2011-07-04 10:38:51 +02:00
* Show EMail link
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
2019-11-11 23:59:36 +01:00
$newemail = $email ;
2012-08-03 23:29:08 +02:00
2020-06-10 12:35:39 +02:00
if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER ) && $withpicto ) $withpicto = 0 ;
2012-08-03 23:29:08 +02:00
if ( empty ( $email )) return ' ' ;
2019-11-11 23:59:36 +01:00
if ( ! empty ( $addlink ))
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$newemail = '<a style="text-overflow: ellipsis;" href="' ;
if ( ! preg_match ( '/^mailto:/i' , $email )) $newemail .= 'mailto:' ;
$newemail .= $email ;
$newemail .= '">' ;
$newemail .= dol_trunc ( $email , $max );
$newemail .= '</a>' ;
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
}
2019-11-11 23:59:36 +01:00
if (( $cid || $socid ) && ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$type = 'AC_EMAIL' ; $link = '' ;
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
}
}
else
{
2019-11-11 23:59:36 +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 ()
{
global $conf , $db ;
$sql = " SELECT rowid, code, label, url, icon, active FROM " . MAIN_DB_PREFIX . " c_socialnetworks " ;
2019-11-11 23:59:36 +01:00
$sql .= " WHERE entity= " . $conf -> entity ;
2019-09-12 20:44:24 +02:00
$socialnetworks = array ();
$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 ,
);
}
}
return $socialnetworks ;
}
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
*
2018-10-12 11:02:03 +02:00
* @ param string $value Skype to show ( only skype , without 'Name of recipient' before )
2015-01-04 20:17:49 +01:00
* @ param int $cid Id of contact if known
* @ param int $socid Id of third party if known
2018-10-12 11:02:03 +02:00
* @ param string $type 'skype' , 'facebook' , ...
2015-01-04 20:17:49 +01:00
* @ return string HTML Link
2013-11-04 21:41:36 +01:00
*/
2019-01-27 15:20:16 +01:00
function dol_print_socialnetworks ( $value , $cid , $socid , $type )
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
2018-10-12 11:02:03 +02:00
if ( empty ( $value )) return ' ' ;
2013-11-04 21:41:36 +01:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $type ))
2013-11-04 21:41:36 +01:00
{
2019-10-17 20:24:04 +02:00
$htmllink = '<div class="divsocialnetwork inline-block valignmiddle">' ;
$htmllink .= img_picto ( $langs -> trans ( strtoupper ( $type )), $type . '.png' , '' , false , 0 , 0 , '' , 'paddingright' , 0 );
$htmllink .= $value ;
2018-10-12 11:02:03 +02:00
if ( $type == 'skype' )
{
2019-11-11 23:59:36 +01:00
$htmllink .= ' ' ;
$htmllink .= '<a href="skype:' ;
$htmllink .= $value ;
$htmllink .= '?call" alt="' . $langs -> trans ( " Call " ) . ' ' . $value . '" title="' . $langs -> trans ( " Call " ) . ' ' . $value . '">' ;
$htmllink .= '<img src="' . DOL_URL_ROOT . '/theme/common/skype_callbutton.png" border="0">' ;
$htmllink .= '</a><a href="skype:' ;
$htmllink .= $value ;
$htmllink .= '?chat" alt="' . $langs -> trans ( " Chat " ) . ' ' . $value . '" title="' . $langs -> trans ( " Chat " ) . ' ' . $value . '">' ;
$htmllink .= '<img class="paddingleft" src="' . DOL_URL_ROOT . '/theme/common/skype_chatbutton.png" border="0">' ;
$htmllink .= '</a>' ;
2018-10-12 11:02:03 +02:00
}
2019-11-11 23:59:36 +01:00
if (( $cid || $socid ) && ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create && $type == 'skype' )
2013-11-04 21:41:36 +01:00
{
2019-11-11 23:59:36 +01:00
$addlink = 'AC_SKYPE' ;
$link = '' ;
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>' ;
$htmllink .= ( $link ? ' ' . $link : '' );
2013-11-04 21:41:36 +01:00
}
2019-11-11 23:59:36 +01:00
$htmllink .= '</div>' ;
2013-11-04 21:41:36 +01:00
}
else
{
$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
}
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
* @ param string $withpicto Show picto
* @ 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 ));
2012-08-03 23:29:08 +02:00
if ( empty ( $phone )) { return '' ; }
2020-04-08 15:13:19 +02:00
if ( $conf -> global -> MAIN_PHONE_SEPAR ) $separ = $conf -> global -> MAIN_PHONE_SEPAR ;
2019-11-11 23:59:36 +01:00
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
2019-11-11 23:59:36 +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 ;
2015-10-16 16:14:33 +02: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 );
2012-08-03 23:29:08 +02:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 7 )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$newphone = substr ( $newphone , 0 , 3 ) . $separ . substr ( $newphone , 3 , 2 ) . $separ . substr ( $newphone , 5 , 2 );
2012-08-03 23:29:08 +02:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 9 )
2012-08-03 23:29:08 +02:00
{
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 );
2012-08-03 23:29:08 +02:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 11 )
2012-08-03 23:29:08 +02:00
{
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 );
2012-08-03 23:29:08 +02:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 12 )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +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 );
2012-08-03 23:29:08 +02:00
}
}
2018-02-15 10:47:32 +01:00
elseif ( strtoupper ( $countrycode ) == " CA " )
2016-08-01 20:18:31 +02:00
{
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
}
2016-08-01 20:18:31 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( strtoupper ( $countrycode ) == " PT " )
2018-02-17 01:16:52 +01:00
{ //Portugal
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2019-11-11 23:59:36 +01:00
elseif ( strtoupper ( $countrycode ) == " SR " )
2018-02-15 10:47:32 +01:00
{ //Suriname
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 10 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 11 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2019-11-11 23:59:36 +01:00
elseif ( strtoupper ( $countrycode ) == " DE " )
2018-02-15 10:47:32 +01:00
{ //Allemagne
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 14 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " ES " )
2018-02-15 10:47:32 +01:00
{ //Espagne
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " BF " )
2018-02-15 10:47:32 +01:00
{ // Burkina Faso
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " RO " )
2018-02-15 10:47:32 +01:00
{ // Roumanie
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " TR " )
2018-02-17 01:16:52 +01:00
{ //Turquie
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " US " )
2018-02-15 10:47:32 +01:00
{ //Etat-Unis
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " MX " )
2018-02-15 10:47:32 +01:00
{ //Mexique
2018-02-17 01:16:52 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 11 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2018-02-17 01:16:52 +01:00
elseif ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " ML " )
2018-02-15 10:47:32 +01:00
{ //Mali
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " TH " )
2018-02-15 10:47:32 +01:00
{ //Thaïlande
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 11 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
2019-02-03 14:29:45 +01:00
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " MU " )
2019-02-03 14:29:45 +01:00
{
//Maurice
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 11 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " ZA " )
2018-02-15 10:47:32 +01:00
{ //Afrique du sud
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " SY " )
2018-02-15 10:47:32 +01:00
{ //Syrie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " AE " )
2018-02-15 10:47:32 +01:00
{ //Emirats Arabes Unis
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 14 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " DZ " )
2018-02-15 10:47:32 +01:00
{ //Algérie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " BE " )
2018-02-15 10:47:32 +01:00
{ //Belgique
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 11 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " PF " )
2018-02-15 10:47:32 +01:00
{ //Polynésie française
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " CO " )
2018-02-15 10:47:32 +01:00
{ //Colombie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " JO " )
2018-02-15 10:47:32 +01:00
{ //Jordanie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2019-08-01 15:46:34 +02:00
elseif ( strtoupper ( $countrycode ) == " JM " )
{ //Jamaïque
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $newphone ) == 12 )
2019-08-01 15:46:34 +02:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " MG " )
2018-02-15 10:47:32 +01:00
{ //Madagascar
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-17 01:16:52 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " GB " )
2018-02-15 10:47:32 +01:00
{ //Royaume uni
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " CH " )
2018-02-15 10:47:32 +01:00
{ //Suisse
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 15 )
2018-02-15 10:47:32 +01:00
{ // +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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " TN " )
2018-02-15 10:47:32 +01:00
{ //Tunisie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " GF " )
2018-02-15 10:47:32 +01:00
{ //Guyane francaise
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " GP " )
2018-02-15 10:47:32 +01:00
{ //Guadeloupe
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " MQ " )
2018-02-15 10:47:32 +01:00
{ //Martinique
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2018-02-15 13:38:21 +01:00
elseif ( strtoupper ( $countrycode ) == " IT " )
2018-02-15 10:47:32 +01:00
{ //Italie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2018-02-15 10:47:32 +01:00
{ //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 );
2018-02-15 10:47:32 +01:00
}
2019-11-11 23:59:36 +01:00
elseif ( dol_strlen ( $phone ) == 13 )
2018-02-15 10:47:32 +01:00
{ //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
}
}
2019-11-11 23:59:36 +01:00
elseif ( strtoupper ( $countrycode ) == " AU " )
2019-02-03 14:29:45 +01:00
{
//Australie
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $phone ) == 12 )
2019-02-03 14:29:45 +01: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
}
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $addlink )) // Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set)
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
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
2013-04-16 01:13:20 +02:00
{
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>' ;
2013-04-16 01:13:20 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $conf -> clicktodial -> enabled ) && $addlink == 'AC_TEL' ) // If click to dial, we use click to dial url
2012-08-03 23:29:08 +02:00
{
if ( empty ( $user -> clicktodial_loaded )) $user -> fetch_clicktodial ();
2013-03-31 16:44:24 +02:00
// Define urlmask
2019-11-11 23:59:36 +01:00
$urlmask = 'ErrorClickToDialModuleNotConfigured' ;
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 ;
$newphone = '<a href="' . $url . '"' ;
if ( ! empty ( $conf -> global -> CLICKTODIAL_FORCENEWTARGET )) $newphone .= ' target="_blank"' ;
$newphone .= '>' . $newphonesav . '</a>' ;
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)
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> agenda -> enabled ) && $user -> rights -> agenda -> myactions -> create )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$type = 'AC_TEL' ; $link = '' ;
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
}
}
2015-10-11 12:27:04 +02: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
}
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' ;
2019-11-11 23:59:36 +01:00
} elseif ( $withpicto == 'phone' ) {
2018-01-02 11:24:28 +01:00
$picto = 'phoning' ;
2019-11-11 23:59:36 +01: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
}
2019-11-11 23:59:36 +01:00
if ( $adddivfloat ) $rep .= '<div class="nospan float" style="margin-right: 10px">' ;
else $rep .= '<span style="margin-right: 10px;">' ;
$rep .= ( $withpicto ? img_picto ( $titlealt , 'object_' . $picto . '.png' ) . ' ' : '' ) . $newphone ;
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
2019-11-11 23:59:36 +01:00
if ( empty ( $mode )) $ret .= $ip ;
2012-08-03 23:29:08 +02:00
2017-10-28 13:36:23 +02:00
if ( $mode != 2 )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$countrycode = dolGetCountryCodeFromIp ( $ip );
2012-08-03 23:29:08 +02: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 );
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
else $ret .= ' (' . $countrycode . ')' ;
2012-08-03 23:29:08 +02:00
}
2019-08-21 17:28:54 +02:00
else
{
// 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 ()
{
2019-11-11 23:59:36 +01:00
$ip = empty ( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ]) ? ( empty ( $_SERVER [ 'HTTP_CLIENT_IP' ]) ? ( empty ( $_SERVER [ 'REMOTE_ADDR' ]) ? '' : $_SERVER [ 'REMOTE_ADDR' ]) : $_SERVER [ 'HTTP_CLIENT_IP' ]) : $_SERVER [ 'HTTP_X_FORWARDED_FOR' ];
2018-11-21 15:40:15 +01:00
return $ip ;
}
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
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> geoipmaxmind -> enabled ))
2017-10-28 13:36:23 +02:00
{
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 = '' ;
if ( ! empty ( $conf -> geoipmaxmind -> enabled ))
2012-08-03 23:29:08 +02:00
{
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
2012-08-03 23:29:08 +02: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
}
if ( empty ( $reshook ))
{
2019-11-11 23:59:36 +01:00
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 ;
2020-04-01 18:11:28 +02: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 ;
2017-10-13 13:28:26 +02:00
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
}
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
}
2015-10-10 01:51:12 +02: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
/**
2011-09-03 01:57:26 +02:00
* Return true if email syntax is ok
*
2015-06-08 17:13:23 +02:00
* @ param string $address email ( Ex : " toto@examle.com " , " John Do <johndo@example.com> " )
2015-03-19 11:47:30 +01:00
* @ param int $acceptsupervisorkey If 1 , the special string '__SUPERVISOREMAIL__' is also accepted as valid
* @ return boolean true if email syntax is OK , false if KO or empty string
2009-08-11 19:58:25 +02:00
*/
2019-01-27 15:20:16 +01:00
function isValidEmail ( $address , $acceptsupervisorkey = 0 )
2009-08-11 19:58:25 +02:00
{
2015-03-19 11:47:30 +01:00
if ( $acceptsupervisorkey && $address == '__SUPERVISOREMAIL__' ) return true ;
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
*/
function isValidMXRecord ( $domain )
{
if ( function_exists ( 'idn_to_ascii' ) && function_exists ( 'checkdnsrr' ))
{
2019-11-11 23:59:36 +01:00
if ( ! checkdnsrr ( idn_to_ascii ( $domain ), 'MX' ))
2018-07-04 11:07:28 +02:00
{
return 0 ;
}
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 );
if ( count ( $mxhosts ) > 1 ) return 1 ;
2019-11-11 23:59:36 +01:00
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
{
2019-01-27 11:55:16 +01:00
if ( function_exists ( 'mb_strlen' )) return mb_strlen ( $string , $stringencoding );
2012-08-03 23:29:08 +02:00
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 ;
2019-11-11 23:59:36 +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 = '' ;
2018-11-15 13:39:12 +01:00
if ( empty ( $trunconbytes ))
2012-08-03 23:29:08 +02:00
{
2018-11-15 13:39:12 +01:00
if ( function_exists ( 'mb_substr' ))
{
2019-11-11 23:59:36 +01:00
$ret = mb_substr ( $string , $start , $length , $stringencoding );
2018-11-15 13:39:12 +01: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
}
else
{
2018-11-15 13:39:12 +01:00
if ( function_exists ( 'mb_strcut' ))
{
2019-11-11 23:59:36 +01:00
$ret = mb_strcut ( $string , $start , $length , $stringencoding );
2018-11-15 13:39:12 +01: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
/**
2011-05-13 20:08:55 +02: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 '...' .
* 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
2017-06-30 18:30:01 +02: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 or max + 2 or max + 3 so it does not worse to replace with ... )
2011-12-17 16:44:48 +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
2011-12-17 16:44:48 +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 ;
2019-11-11 23:59:36 +01:00
if ( $size == 0 || ! empty ( $conf -> global -> MAIN_DISABLE_TRUNC )) return $string ;
2016-11-16 09:40:29 +01:00
2019-11-11 23:59:36 +01:00
if ( empty ( $stringencoding )) $stringencoding = 'UTF-8' ;
2014-12-09 20:17:13 +01:00
// reduce for small screen
2019-11-11 23:59:36 +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
if ( $trunc == 'right' )
{
2019-11-11 23:59:36 +01:00
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
if ( dol_strlen ( $newstring , $stringencoding ) > ( $size + ( $nodot ? 0 : 3 ))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ...
return dol_substr ( $newstring , 0 , $size , $stringencoding ) . ( $nodot ? '' : '...' );
2012-08-03 23:29:08 +02:00
else
2017-06-30 18:30:01 +02:00
//return 'u'.$size.'-'.$newstring.'-'.dol_strlen($newstring,$stringencoding).'-'.$string;
2012-08-03 23:29:08 +02:00
return $string ;
}
elseif ( $trunc == 'middle' )
{
2019-11-11 23:59:36 +01:00
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
if ( dol_strlen ( $newstring , $stringencoding ) > 2 && dol_strlen ( $newstring , $stringencoding ) > ( $size + 1 ))
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$size1 = round ( $size / 2 );
$size2 = round ( $size / 2 );
2019-01-27 11:55:16 +01:00
return dol_substr ( $newstring , 0 , $size1 , $stringencoding ) . '...' . dol_substr ( $newstring , dol_strlen ( $newstring , $stringencoding ) - $size2 , $size2 , $stringencoding );
2012-08-03 23:29:08 +02:00
}
else
return $string ;
}
elseif ( $trunc == 'left' )
{
2019-11-11 23:59:36 +01:00
$newstring = dol_textishtml ( $string ) ? dol_string_nohtmltag ( $string , 1 ) : $string ;
if ( dol_strlen ( $newstring , $stringencoding ) > ( $size + ( $nodot ? 0 : 3 ))) // If nodot is 0 and size is 1,2 or 3 chars more, we don't trunc and don't add ...
2019-01-27 11:55:16 +01:00
return '...' . dol_substr ( $newstring , dol_strlen ( $newstring , $stringencoding ) - $size , $size , $stringencoding );
2012-08-03 23:29:08 +02:00
else
return $string ;
}
elseif ( $trunc == 'wrap' )
{
2019-11-11 23:59:36 +01:00
$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 );
2012-08-03 23:29:08 +02:00
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 )
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
* @ 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 ;
2012-08-03 23:29:08 +02:00
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 ;
$theme = $conf -> theme ;
$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 )) {
2019-11-11 23:59:36 +01:00
$morecss .= ( $morecss ? ' ' : '' ) . $reg [ 1 ];
2019-02-20 06:01:13 +01:00
$moreatt = str_replace ( 'class="' . $reg [ 1 ] . '"' , '' , $moreatt );
}
2019-02-10 10:45:49 +01:00
} else {
2019-09-30 17:08:57 +02:00
$pictowithouttext = preg_replace ( '/(\.png|\.gif|\.svg)$/' , '' , $picto );
2018-03-14 20:08:44 +01:00
2019-09-30 17:08:57 +02:00
if ( empty ( $srconly ) && in_array ( $pictowithouttext , array (
2019-10-02 18:36:36 +02:00
'1downarrow' , '1uparrow' , '1leftarrow' , '1rightarrow' , '1uparrow_selected' , '1downarrow_selected' , '1leftarrow_selected' , '1rightarrow_selected' ,
2020-04-25 13:49:44 +02:00
'accountancy' , 'address' , 'bank_account' , 'barcode' , 'bank' , 'bill' , 'bookmark' , 'bom' , 'building' ,
2020-05-15 16:07:39 +02:00
'cash-register' , 'category' , 'check' , 'close_title' , 'company' , 'contact' , 'contract' , 'cubes' ,
2020-04-20 15:57:15 +02:00
'delete' , 'dolly' , 'dollyrevert' , 'edit' , 'ellipsis-h' , 'external-link-alt' , 'external-link-square-alt' ,
2020-04-25 13:49:44 +02:00
'filter' , 'file-code' , 'file-export' , 'file-import' , 'file-upload' , 'folder' , 'folder-open' , 'globe' , 'globe-americas' , 'grip' , 'grip_title' , 'help' ,
2020-04-30 14:46:49 +02:00
'intervention' , 'label' , 'language' , 'list' , 'listlight' , 'lot' ,
2020-04-25 17:18:57 +02:00
'map-marker-alt' , 'money-bill-alt' , 'mrp' , 'note' ,
2020-04-25 03:31:47 +02:00
'object_accounting' , 'object_action' , 'object_account' , 'object_barcode' , 'object_bill' , 'object_billa' , 'object_billd' , 'object_bom' ,
2020-05-07 22:52:32 +02:00
'object_category' , 'object_conversation' , 'object_bookmark' , 'object_bug' , 'object_dolly' , 'object_dollyrevert' , 'object_generic' , 'object_folder' ,
2020-04-20 19:39:34 +02:00
'object_list-alt' , 'object_calendar' , 'object_calendarweek' , 'object_calendarmonth' , 'object_calendarday' , 'object_calendarperuser' ,
2020-04-24 23:56:57 +02:00
'object_cash-register' , 'object_company' , 'object_contact' , 'object_contract' , 'object_donation' , 'object_dynamicprice' ,
2020-05-11 19:00:27 +02:00
'object_globe' , 'object_holiday' , 'object_hrm' , 'object_invoice' , 'object_intervention' , 'object_label' ,
2020-04-30 14:46:49 +02:00
'object_margin' , 'object_money-bill-alt' , 'object_multicurrency' , 'object_order' , 'object_payment' ,
2020-04-24 23:56:57 +02:00
'object_lot' , 'object_mrp' , 'object_payment' , 'object_product' , 'object_propal' ,
2020-04-25 13:49:44 +02:00
'object_other' , 'object_paragraph' , 'object_poll' , 'object_printer' , 'object_project' , 'object_projectpub' , 'object_propal' , 'object_resource' , 'object_rss' , 'object_projecttask' ,
2020-05-19 23:22:40 +02:00
'object_shipment' , 'object_supplier_invoice' , 'object_supplier_invoicea' , 'object_supplier_invoiced' , 'object_supplier_order' , 'object_supplier_proposal' , 'object_service' , 'object_stock' ,
2020-04-25 13:49:44 +02:00
'object_technic' , 'object_ticket' , 'object_trip' , 'object_user' , 'object_group' , 'object_member' ,
2020-05-11 19:00:27 +02:00
'object_phoning' , 'object_phoning_mobile' , 'object_phoning_fax' , 'object_email' , 'object_website' ,
2020-04-25 13:49:44 +02:00
'off' , 'on' , 'order' ,
2020-05-02 03:39:56 +02:00
'paiment' , 'play' , 'playdisabled' , 'poll' , 'printer' , 'product' , 'propal' , 'projecttask' , 'stock' , 'resize' , 'service' , 'stats' , 'trip' ,
2020-05-27 00:26:04 +02:00
'setup' , 'sign-out' , 'split' , 'stripe-s' , 'switch_off' , 'switch_on' , 'tools' , 'unlink' , 'uparrow' , 'user' , 'vcard' , 'wrench' ,
2020-03-02 17:35:49 +01:00
'jabber' , 'skype' , 'twitter' , 'facebook' , 'linkedin' , 'instagram' , 'snapchat' , 'youtube' , 'google-plus-g' , 'whatsapp' ,
2019-11-11 23:59:36 +01:00
'chevron-left' , 'chevron-right' , 'chevron-down' , 'chevron-top' ,
2020-07-26 20:51:49 +02:00
'home' , 'hrm' , 'companies' , 'products' , 'commercial' , 'invoicing' , 'pencil-ruler' , 'preview' , 'project' , 'projectpub' , 'supplier_invoice' , 'members' , 'ticket' , 'generic' ,
2020-04-25 13:49:44 +02:00
'error' , 'warning' , 'supplier_proposal' , 'supplier_order' , 'supplier_invoice' ,
2019-10-02 19:04:24 +02:00
'title_setup' , 'title_accountancy' , 'title_bank' , 'title_hrm' , 'title_agenda'
2018-10-12 11:02:03 +02:00
)
)) {
2019-11-05 09:52:33 +01:00
$fakey = $pictowithouttext ;
$facolor = '' ; $fasize = '' ;
2019-11-11 23:59:36 +01:00
$fa = 'fas' ;
2020-05-17 13:34:16 +02:00
if ( in_array ( $pictowithouttext , array ( 'object_generic' , '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
}
2020-05-27 00:26:04 +02:00
if ( in_array ( $pictowithouttext , array ( 'skype' , 'twitter' , 'facebook' , 'linkedin' , 'instagram' , 'snapchat' , '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-04-06 15:34:28 +02:00
$pictowithouttext = str_replace ( 'object_' , '' , $pictowithouttext );
2019-11-05 09:52:33 +01:00
2019-09-30 17:08:57 +02:00
$arrayconvpictotofa = array (
2020-04-25 03:31:47 +02:00
'account' => 'university' , 'accountancy' => 'money-check-alt' , 'action' => 'calendar-alt' , 'address' => 'address-book' ,
2020-05-19 23:22:40 +02:00
'bank_account' => 'university' , 'bill' => 'file-invoice-dollar' , 'billa' => 'file-excel' , 'supplier_invoicea' => 'file-excel' , 'billd' => 'file-medical' , 'supplier_invoiced' => 'file-medical' , 'bom' => 'cubes' ,
2020-05-07 22:52:32 +02:00
'company' => 'building' , 'contact' => 'address-book' , 'contract' => 'suitcase' , 'conversation' => 'comments' , 'donation' => 'file-alt' , 'dynamicprice' => 'hand-holding-usd' ,
2020-04-25 03:00:41 +02:00
'setup' => 'cog' , 'companies' => 'building' , 'products' => 'cube' , 'commercial' => 'suitcase' , 'invoicing' => 'coins' ,
2020-04-20 15:57:15 +02:00
'accounting' => 'chart-line' , 'category' => 'tag' , 'dollyrevert' => 'dolly' ,
2020-07-26 20:51:49 +02:00
'hrm' => 'user-tie' , 'margin' => 'calculator' , 'members' => 'users' , 'ticket' => 'ticket-alt' , 'globe' => 'external-link-alt' , 'lot' => 'barcode' ,
2020-04-07 16:45:08 +02:00
'email' => 'at' ,
2020-04-09 13:40:26 +02:00
'edit' => 'pencil-alt' , 'grip_title' => 'arrows-alt' , 'grip' => 'arrows-alt' , 'help' => 'info-circle' ,
2020-04-30 14:46:49 +02:00
'generic' => 'file' , 'holiday' => 'umbrella-beach' , 'label' => 'layer-group' ,
'member' => 'users' , 'mrp' => 'cubes' , 'trip' => 'wallet' , 'group' => 'users' ,
2020-04-07 16:45:08 +02:00
'sign-out' => 'sign-out-alt' ,
2020-04-20 02:14:43 +02:00
'switch_off' => 'toggle-off' , 'switch_on' => 'toggle-on' , 'check' => 'check' , 'bookmark' => 'star' , 'bookmark' => 'star' ,
'bank' => 'university' , 'close_title' => 'window-close' , 'delete' => 'trash' , 'edit' => 'pencil-alt' , 'filter' => 'filter' ,
2020-04-06 23:38:30 +02:00
'list-alt' => 'list-alt' , 'calendar' => 'calendar-alt' , 'calendarweek' => 'calendar-week' , 'calendarmonth' => 'calendar-alt' , 'calendarday' => 'calendar-day' , 'calendarperuser' => 'table' ,
2020-05-02 00:41:27 +02:00
'intervention' => 'ambulance' , 'invoice' => 'file-invoice-dollar' , 'multicurrency' => 'dollar-sign' , 'order' => 'file-invoice' ,
2019-10-09 18:07:00 +02:00
'error' => 'exclamation-triangle' , 'warning' => 'exclamation-triangle' ,
2020-04-20 02:48:05 +02:00
'other' => 'square' ,
2020-04-20 18:38:25 +02:00
'playdisabled' => 'play' , 'poll' => 'check-double' , 'preview' => 'binoculars' , 'project' => 'sitemap' , 'projectpub' => 'sitemap' , 'projecttask' => 'tasks' , 'propal' => 'file-signature' ,
2020-04-24 23:56:57 +02:00
'resize' => 'crop' , 'supplier_order' => 'dol-order_supplier' , 'supplier_proposal' => 'file-signature' ,
2020-04-22 17:59:54 +02:00
'payment' => 'money-check-alt' , 'phoning' => 'phone' , 'phoning_mobile' => 'mobile-alt' , 'phoning_fax' => 'fax' , 'printer' => 'print' , 'product' => 'cube' , 'service' => 'concierge-bell' ,
2020-04-20 02:14:43 +02:00
'resource' => 'laptop-house' ,
2020-05-10 15:45:07 +02:00
'shipment' => 'dolly' , 'stock' => 'box-open' , 'stats' => 'chart-bar' , 'split' => 'code-branch' , 'supplier_invoice' => 'file-invoice-dollar' , 'technic' => 'cogs' , 'ticket' => 'ticket-alt' ,
2020-04-09 16:36:39 +02:00
'title_setup' => 'tools' , 'title_accountancy' => 'money-check-alt' , 'title_bank' => 'university' , 'title_hrm' => 'umbrella-beach' ,
'title_agenda' => 'calendar-alt' ,
2020-05-17 13:34:16 +02:00
'uparrow' => 'mail-forward' , 'vcard' => 'address-card' ,
2020-05-11 19:00:27 +02:00
'jabber' => 'comment-o' ,
'website' => 'globe-americas'
2019-09-30 17:08:57 +02:00
);
2020-04-07 16:45:08 +02:00
if ( $pictowithouttext == 'off' ) {
2019-10-03 20:42:02 +02:00
$fakey = 'fa-square' ;
2018-04-03 13:13:40 +02:00
$fasize = '1.3em' ;
}
2019-09-30 17:08:57 +02:00
elseif ( $pictowithouttext == 'on' ) {
2019-10-03 20:42:02 +02:00
$fakey = 'fa-check-square' ;
2018-04-03 13:13:40 +02:00
$fasize = '1.3em' ;
}
2019-09-30 17:08:57 +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 ;
2018-10-01 00:20:47 +02:00
}
2019-09-30 17:08:57 +02:00
elseif ( $pictowithouttext == 'printer' ) {
2018-04-03 13:13:40 +02:00
$fakey = 'fa-print' ;
$fasize = '1.2em' ;
2020-04-06 18:21:13 +02:00
}
2019-09-30 17:08:57 +02:00
elseif ( $pictowithouttext == 'note' ) {
2019-10-03 20:42:02 +02:00
$fakey = 'fa-sticky-note' ;
2019-11-11 23:59:36 +01:00
$marginleftonlyshort = 1 ;
2018-10-01 00:20:47 +02:00
}
2019-09-30 17:08:57 +02:00
elseif ( in_array ( $pictowithouttext , array ( '1uparrow' , '1downarrow' , '1leftarrow' , '1rightarrow' , '1uparrow_selected' , '1downarrow_selected' , '1leftarrow_selected' , '1rightarrow_selected' ))) {
2019-11-11 23:59:36 +01: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' );
2019-09-30 17:08:57 +02:00
$fakey = 'fa-' . $convertarray [ $pictowithouttext ];
if ( preg_match ( '/selected/' , $pictowithouttext )) $facolor = '#888' ;
2018-09-12 21:57:32 +02:00
$marginleftonlyshort = 1 ;
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $arrayconvpictotofa [ $pictowithouttext ]))
2019-09-30 17:08:57 +02:00
{
$fakey = 'fa-' . $arrayconvpictotofa [ $pictowithouttext ];
2019-01-04 15:22:59 +01:00
}
2018-04-03 13:13:40 +02:00
else {
2019-09-30 17:08:57 +02:00
$fakey = 'fa-' . $pictowithouttext ;
2020-04-07 16:45:08 +02:00
}
// Define $marginleftonlyshort
$arrayconvpictotomarginleftonly = array (
'bank' , 'check' , 'delete' , 'generic' , 'grip' , 'grip_title' , 'jabber' ,
'grip_title' , 'grip' , 'listlight' , 'note' , 'on' , 'off' , 'playdisabled' , 'printer' , 'resize' , 'sign-out' , 'stats' , 'switch_on' , 'switch_off' ,
'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 (
2020-05-26 22:30:11 +02:00
'action' => 'infobox-action' , 'account' => 'infobox-bank_account' , 'accountancy' => 'infobox-bank_account' ,
2020-05-19 23:22:40 +02:00
'bank_account' => 'bg-infobox-bank_account' ,
2020-05-26 22:30:11 +02:00
'bill' => 'infobox-commande' , 'billa' => 'infobox-commande' , 'billd' => 'infobox-commande' ,
'cash-register' => 'infobox-bank_account' , 'contract' => 'infobox-contrat' , 'check' => 'font-status4' , 'conversation' => 'infobox-contrat' ,
'donation' => 'infobox-commande' , 'dollyrevert' => 'flip' , 'ecm' => 'infobox-action' ,
'hrm' => 'infobox-adherent' , 'group' => 'infobox-adherent' , 'intervention' => 'infobox-contrat' ,
'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' ,
2020-04-07 16:45:08 +02:00
'error' => 'pictoerror' , 'warning' => 'pictowarning' , 'switch_on' => 'font-status4' ,
2020-05-26 22:30:11 +02:00
'holiday' => 'infobox-holiday' , 'invoice' => 'infobox-commande' ,
'payment' => 'infobox-bank_account' , 'poll' => 'infobox-adherent' , 'project' => 'infobox-project' , 'projecttask' => 'infobox-project' , 'propal' => 'infobox-propal' ,
'resource' => 'infobox-action' ,
'supplier_invoice' => 'infobox-order_supplier' , 'supplier_invoicea' => 'infobox-order_supplier' , 'supplier_invoiced' => 'infobox-order_supplier' ,
'supplier_order' => 'infobox-order_supplier' , 'supplier_proposal' => 'infobox-supplier_proposal' ,
'ticket' => 'infobox-contrat' , 'title_accountancy' => 'infobox-bank_account' , 'title_hrm' => 'infobox-holiday' , 'trip' => 'infobox-expensereport' , 'title_agenda' => 'infobox-action' ,
//'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-04-13 01:42:10 +02:00
'address' => '#37a' , 'building' => '#37a' , 'bom' => '#a69944' ,
'companies' => '#37a' , 'company' => '#37a' , 'contact' => '#37a' , 'dynamicprice' => '#a69944' ,
2020-04-12 21:36:57 +02:00
'edit' => '#444' , 'note' => '#999' , 'error' => '' , 'listlight' => '#999' ,
2020-04-22 17:59:54 +02:00
'dolly' => '#a69944' , 'dollyrevert' => '#a69944' , 'lot' => '#a69944' ,
'map-marker-alt' => '#aaa' , 'mrp' => '#a69944' , 'product' => '#a69944' , 'service' => '#a69944' , 'stock' => '#a69944' ,
2020-04-07 21:11:18 +02:00
'other' => '#ddd' ,
2020-04-20 02:14:43 +02:00
'playdisabled' => '#ccc' , 'printer' => '#444' , 'projectpub' => '#986c6a' , 'resize' => '#444' , 'rss' => '#cba' ,
2020-05-11 19:00:27 +02:00
'shipment' => '#a69944' , 'stats' => '#444' , 'switch_off' => '#999' , 'uparrow' => '#555' , 'globe-americas' => '#aaa' ,
'website' => '#304'
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.
// class/style need to be extracted to avoid duplicate class/style validation errors when $moreatt is added to the end of the attributes.
2019-11-11 23:59:36 +01:00
$reg = array ();
2018-04-03 13:13:40 +02:00
if ( preg_match ( '/class="([^"]+)"/' , $moreatt , $reg )) {
2019-11-11 23:59:36 +01:00
$morecss .= ( $morecss ? ' ' : '' ) . $reg [ 1 ];
2019-01-27 11:55:16 +01:00
$moreatt = str_replace ( 'class="' . $reg [ 1 ] . '"' , '' , $moreatt );
2019-01-21 16:19:31 +01:00
}
if ( preg_match ( '/style="([^"]+)"/' , $moreatt , $reg )) {
2019-11-11 23:59:36 +01:00
$morestyle = ' ' . $reg [ 1 ];
2019-01-27 11:55:16 +01:00
$moreatt = str_replace ( 'style="' . $reg [ 1 ] . '"' , '' , $moreatt );
2019-01-21 16:19:31 +01:00
}
2019-11-11 23:59:36 +01:00
$moreatt = trim ( $moreatt );
2019-01-21 16:19:31 +01:00
2019-11-11 23:59:36 +01: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 : '' ) . '>' ;
if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER )) {
$enabledisablehtml .= $titlealt ;
2018-04-03 13:13:40 +02: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
2018-04-03 13:13:40 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $conf -> global -> MAIN_OVERWRITE_THEME_RES )) {
$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
2018-04-03 13:13:40 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $conf -> modules_parts [ 'theme' ]) && array_key_exists ( $theme , $conf -> modules_parts [ 'theme' ])) {
$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
2019-11-11 23:59:36 +01:00
return '<img src="' . $fullpathpicto . '" 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
{
2020-04-20 18:38:25 +02: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 ;
2019-08-18 03:42:38 +02:00
if ( is_numeric ( $picto ))
{
2019-11-11 23:59:36 +01:00
$leveltopicto = array ( 0 => 'weather-clear.png' , 1 => 'weather-few-clouds.png' , 2 => 'weather-clouds.png' , 3 => 'weather-many-clouds.png' , 4 => 'weather-storm.png' );
2019-08-18 03:42:38 +02:00
//return '<i class="fa fa-weather-level'.$picto.'"></i>';
$picto = $leveltopicto [ $picto ];
}
2019-11-11 23:59:36 +01: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
* @ 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
*/
2017-03-31 14:21:51 +02:00
function img_picto_common ( $titlealt , $picto , $moreatt = '' , $pictoisfullpath = 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
2019-11-11 23:59:36 +01:00
if ( ! preg_match ( '/(\.png|\.gif)$/i' , $picto )) $picto .= '.png' ;
2012-07-30 23:23:58 +02:00
2012-08-03 23:29:08 +02:00
if ( $pictoisfullpath ) $path = $picto ;
else
{
$path = DOL_URL_ROOT . '/theme/common/' . $picto ;
2012-08-04 08:45:38 +02:00
2019-11-11 23:59:36 +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
2012-08-04 09:56:25 +02:00
if ( file_exists ( $themepath )) $path = $themepath ;
2012-08-03 23:29:08 +02:00
}
}
2012-07-30 23:23:58 +02:00
2017-03-31 14:21:51 +02:00
return img_picto ( $titlealt , $path , $moreatt , 1 );
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
* @ return string Return an img tag
2008-08-06 16:50:06 +02:00
*/
2014-07-29 21:34:23 +02:00
function img_action ( $titlealt , $numaction )
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
2015-05-06 23:13:07 +02:00
if ( empty ( $titlealt ) || $titlealt == 'default' )
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01: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' ); }
2015-05-06 23:13:07 +02:00
else { $titlealt = $langs -> transnoentitiesnoconv ( 'ChangeStatus ' . $numaction ); $numaction = 0 ; }
2012-08-03 23:29:08 +02:00
}
2019-11-11 23:59:36 +01:00
if ( ! is_numeric ( $numaction )) $numaction = 0 ;
2012-08-03 23:29:08 +02:00
2014-07-29 21:34:23 +02:00
return img_picto ( $titlealt , '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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
*/
2014-07-29 21:34:23 +02:00
function img_view ( $titlealt = 'default' , $float = 0 , $other = '' )
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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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 ;
2019-11-11 23:59:36 +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
if ( $titlealt == 'default' ) $titlealt = $langs -> trans ( 'Split' );
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
2012-08-03 23:29:08 +02:00
if ( $usealttitle )
{
2012-09-16 15:04:55 +02:00
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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +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
2014-07-29 21:34:23 +02: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
2014-07-29 21:34:23 +02:00
if ( $titlealt == 'default' ) $titlealt = $langs -> trans ( 'Active' );
2012-07-30 22:36:43 +02:00
2014-07-29 21:34:23 +02: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
*
* @ param string $brand Brand name of credit card
2020-03-24 21:40:25 +01:00
* @ 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
{
2020-03-24 21:40:25 +01:00
if ( is_null ( $morecss )) $morecss = 'fa-2x' ;
2019-11-11 23:59:36 +01: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
2014-07-29 21:34:23 +02: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.'"');
2019-06-02 19:47:19 +02:00
return '<i class="fa fa-' . $mimefa . ' paddingright"' . ( $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 ;
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 ;
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
* @ param string $admin '1' = Info for admin users . '0' = Info for standard users ( change only the look ), 'error' , 'xxx' = Other
* @ 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 ;
if ( $infoonimgalt )
{
2020-02-11 10:38:09 +01:00
$result = img_picto ( $text , 'info' , 'class="hideonsmartphone' . ( $morecss ? ' ' . $morecss : '' ) . '"' );
}
else {
if ( empty ( $conf -> use_javascript_ajax )) $textfordropdown = '' ;
$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 ) {
$tmpresult .= '<span class="' . $class . 'text opacitymedium">' . $langs -> trans ( $textfordropdown ) . ' ' . img_picto ( $langs -> trans ( $textfordropdown ), '1downarrow' ) . '</span>' ;
$tmpresult .= ' < script type = " text/javascript " language = " javascript " >
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
*
2014-03-16 17:37:54 +01:00
* @ param DoliDB $db Database handler
* @ param mixed $error String or array of errors strings to show
2015-05-03 20:07:16 +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 = '' ;
// Si erreur intervenue avant chargement langue
2019-11-11 23:59:36 +01:00
if ( ! $langs )
2012-08-03 23:29:08 +02:00
{
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 " );
}
2018-09-14 10:20:21 +02:00
// Load translation files required by the page
$langs -> loadLangs ( array ( 'main' , 'errors' ));
2012-08-03 23:29:08 +02:00
if ( $_SERVER [ 'DOCUMENT_ROOT' ]) // Mode web
{
2019-11-11 23:59:36 +01:00
$out .= $langs -> trans ( " DolibarrHasDetectedError " ) . " .<br> \n " ;
if ( ! empty ( $conf -> global -> MAIN_FEATURES_LEVEL )) $out .= " You use an experimental or develop level of features, so please do NOT report any bugs, except if problem is confirmed moving option MAIN_FEATURES_LEVEL back to 0.<br> \n " ;
$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 " ;
2019-11-11 23:59:36 +01:00
if ( isset ( $conf -> global -> MAIN_FEATURES_LEVEL )) $out .= " <b> " . $langs -> trans ( " LevelOfFeature " ) . " :</b> " . $conf -> global -> MAIN_FEATURES_LEVEL . " <br> \n " ;
2012-08-03 23:29:08 +02: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
}
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " Server " ) . " :</b> " . $_SERVER [ " SERVER_SOFTWARE " ] . " <br> \n " ;
2015-01-17 16:22:37 +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
}
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " UserAgent " ) . " :</b> " . $_SERVER [ " HTTP_USER_AGENT " ] . " <br> \n " ;
$out .= " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " RequestedUrl " ) . " :</b> " . dol_htmlentities ( $_SERVER [ " REQUEST_URI " ], ENT_COMPAT , 'UTF-8' ) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " Referer " ) . " :</b> " . ( isset ( $_SERVER [ " HTTP_REFERER " ]) ? dol_htmlentities ( $_SERVER [ " HTTP_REFERER " ], ENT_COMPAT , 'UTF-8' ) : '' ) . " <br> \n " ;
$out .= " <b> " . $langs -> trans ( " MenuManager " ) . " :</b> " . ( isset ( $conf -> standard_menu ) ? $conf -> standard_menu : '' ) . " <br> \n " ;
$out .= " <br> \n " ;
$syslog .= " url= " . dol_escape_htmltag ( $_SERVER [ " REQUEST_URI " ]);
$syslog .= " , query_string= " . dol_escape_htmltag ( $_SERVER [ " QUERY_STRING " ]);
2012-08-03 23:29:08 +02:00
}
else // Mode CLI
{
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
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> modules ))
2019-04-23 10:24:05 +02:00
{
2019-11-11 23:59:36 +01:00
$out .= " <b> " . $langs -> trans ( " Modules " ) . " :</b> " . join ( ', ' , $conf -> modules ) . " <br> \n " ;
2019-04-23 10:24:05 +02:00
}
2012-08-03 23:29:08 +02: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 " ;
$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 " ;
$out .= " <br> \n " ;
2012-08-03 23:29:08 +02:00
}
else // Mode CLI
{
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
}
2015-05-03 20:07:16 +02: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
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
foreach ( $errors as $msg )
2012-08-03 23:29:08 +02:00
{
2016-05-07 16:38:32 +02:00
if ( empty ( $msg )) continue ;
2012-08-03 23:29:08 +02:00
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 " ;
2012-08-03 23:29:08 +02:00
}
2015-05-03 20:07:16 +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
}
}
if ( empty ( $dolibarr_main_prod ) && $_SERVER [ 'DOCUMENT_ROOT' ] && function_exists ( 'xdebug_print_function_stack' ) && function_exists ( 'xdebug_call_file' ))
{
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
}
if ( empty ( $dolibarr_main_prod )) print $out ;
2019-11-21 18:17:40 +01:00
else // This should not happen, except if there is a bug somewhere. Enabled and check log in such case.
2017-09-06 11:39:30 +02:00
{
2019-12-15 17:48:30 +01:00
print 'This website or feature is currently temporarly not available.<br><br>This may be due to a maintenance operation. Current status of operation are on next line...<br><br>' . " \n " ;
2019-08-31 19:39:39 +02:00
$langs -> load ( " errors " );
2017-09-06 11:39:30 +02:00
print $langs -> trans ( " DolibarrHasDetectedError " ) . '. ' ;
print $langs -> trans ( " YouCanSetOptionDolibarrMainProdToZero " );
define ( " MAIN_CORE_ERROR " , 1 );
}
2012-08-03 23:29:08 +02:00
//else print 'Sorry, an error occured but the parameter $dolibarr_main_prod is defined in conf file so no message is reported to your browser. Please read the log file for error message.';
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
2019-11-11 23:59:36 +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' ));
2017-06-02 09:13:04 +02:00
if ( $errormessage ) print '<br><br>' . $errormessage ;
2017-12-19 18:26:27 +01:00
if ( is_array ( $errormessages ) && count ( $errormessages ))
{
2019-11-11 23:59:36 +01:00
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
2012-02-04 14:39:47 +01:00
* @ return void
2011-07-06 11:25:05 +02:00
*/
2019-01-27 15:20:16 +01:00
function print_liste_field_titre ( $name , $file = " " , $field = " " , $begin = " " , $moreparam = " " , $moreattrib = " " , $sortfield = " " , $sortorder = " " , $prefix = " " , $tooltip = " " )
2011-08-30 19:56:45 +02:00
{
2017-09-16 10:12:44 +02:00
print getTitleFieldOfList ( $name , 0 , $file , $field , $begin , $moreparam , $moreattrib , $sortfield , $sortorder , $prefix , 0 , $tooltip );
2011-08-30 19:56:45 +02:00
}
/**
* Get title line of an array
2011-09-02 23:56:37 +02:00
*
2017-08-31 18:29:57 +02:00
* @ param string $name Translation key of field
* @ 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
2015-02-10 10:52:48 +01:00
* @ return string
2011-08-30 19:56:45 +02:00
*/
2019-01-27 15:20:16 +01:00
function getTitleFieldOfList ( $name , $thead = 0 , $file = " " , $field = " " , $begin = " " , $moreparam = " " , $moreattrib = " " , $sortfield = " " , $sortorder = " " , $prefix = " " , $disablesortlink = 0 , $tooltip = '' )
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
2019-11-11 23:59:36 +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' ;
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-02-24 21:18:49 +01:00
if ( empty ( $conf -> global -> MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE )) {
$prefix = 'wrapcolumntitle ' . $prefix ;
}
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-02-24 21:18:49 +01:00
if ( $field1 && ( $sortfield1 == $field1 || $sortfield1 == preg_replace ( " /^[^ \ .]+ \ ./ " , " " , $field1 ))) {
$out .= '<' . $tag . ' class="' . $prefix . 'liste_titre_sel" ' . $moreattrib ;
2020-02-24 21:33:28 +01:00
$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-02-24 21:18:49 +01:00
$out .= '>' ;
}
else {
$out .= '<' . $tag . ' class="' . $prefix . 'liste_titre" ' . $moreattrib ;
2020-02-24 21:33:28 +01:00
$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-02-24 21:18:49 +01:00
$out .= '>' ;
}
2013-04-14 02:09:41 +02:00
2017-07-16 12:07:59 +02:00
if ( empty ( $thead ) && $field && empty ( $disablesortlink )) // If this is a sort field
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$options = preg_replace ( '/sortfield=([a-zA-Z0-9,\s\.]+)/i' , '' , $moreparam );
$options = preg_replace ( '/sortorder=([a-zA-Z0-9,\s\.]+)/i' , '' , $options );
$options = preg_replace ( '/&+/i' , '&' , $options );
if ( ! preg_match ( '/^&/' , $options )) $options = '&' . $options ;
2013-04-14 02:09:41 +02:00
2019-11-11 23:59:36 +01:00
$sortordertouseinlink = '' ;
2018-04-28 19:54:41 +02:00
if ( $field1 != $sortfield1 ) // We are on another field than current sorted field
2015-10-09 13:01:50 +02:00
{
2018-04-28 19:54:41 +02:00
if ( preg_match ( '/^DESC/i' , $sortorder ))
{
2019-11-11 23:59:36 +01:00
$sortordertouseinlink .= str_repeat ( 'desc,' , count ( explode ( ',' , $field )));
2018-04-28 19:54:41 +02:00
}
else // We reverse the var $sortordertouseinlink
{
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
}
2018-04-28 19:54:41 +02:00
else // We are on field that is the first current sorting criteria
2015-10-09 13:01:50 +02:00
{
2018-04-28 19:54:41 +02: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 )));
2018-04-28 19:54:41 +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
}
2013-04-14 02:09:41 +02:00
2019-11-11 23:59:36 +01:00
if ( $tooltip ) $out .= $form -> textwithpicto ( $langs -> trans ( $name ), $langs -> trans ( $tooltip ));
else $out .= $langs -> trans ( $name );
2013-04-14 02:09:41 +02:00
2017-07-16 12:07:59 +02:00
if ( empty ( $thead ) && $field && empty ( $disablesortlink )) // If this is a sort field
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$out .= '</a>' ;
2012-08-03 23:29:08 +02:00
}
2015-10-09 13:01:50 +02:00
if ( empty ( $thead ) && $field ) // If this is a sort field
2012-08-03 23:29:08 +02:00
{
2019-11-11 23:59:36 +01:00
$options = preg_replace ( '/sortfield=([a-zA-Z0-9,\s\.]+)/i' , '' , $moreparam );
$options = preg_replace ( '/sortorder=([a-zA-Z0-9,\s\.]+)/i' , '' , $options );
$options = preg_replace ( '/&+/i' , '&' , $options );
if ( ! preg_match ( '/^&/' , $options )) $options = '&' . $options ;
2012-08-03 23:29:08 +02:00
2019-11-11 23:59:36 +01:00
if ( ! $sortorder || $field1 != $sortfield1 )
2012-08-03 23:29:08 +02:00
{
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>';
2012-08-03 23:29:08 +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
* @ return string Title to show
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
2019-11-11 23:59:36 +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">' ;
2020-04-11 14:13:16 +02: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>' ;
2019-02-03 22:58:56 +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
}
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-03-13 12:53:22 +01:00
* @ param string $morehtmlright More html to show
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 .
2019-02-03 22:58:56 +01:00
* @ return void
*/
2020-03-13 12:53:22 +01: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 )
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 ;
2019-11-11 23:59:36 +01:00
$totalnboflines = abs ( $totalnboflines );
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( $picto == 'setup' ) $picto = 'title_setup.png' ;
if (( $conf -> browser -> name == 'ie' ) && $picto == 'generic' ) $picto = 'title.gif' ;
2019-02-03 22:58:56 +01:00
if ( $limit < 0 ) $limit = $conf -> liste_limit ;
if ( $savlimit != 0 && (( $num > $limit ) || ( $num == - 1 ) || ( $limit == 0 )))
{
$nextpage = 1 ;
}
else
{
$nextpage = 0 ;
}
//print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage;
print " \n " ;
print " <!-- Begin title ' " . $titre . " ' --> \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
2020-04-11 14:13:16 +02: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 ;
2020-02-24 21:48:46 +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
if ( $morehtmlcenter )
{
print '<td class="nobordernopadding center valignmiddle">' . $morehtmlcenter . '</td>' ;
}
// Right
print '<td class="nobordernopadding valignmiddle right">' ;
if ( $sortfield ) $options .= " &sortfield= " . urlencode ( $sortfield );
if ( $sortorder ) $options .= " &sortorder= " . urlencode ( $sortorder );
// Show navigation bar
$pagelist = '' ;
if ( $savlimit != 0 && ( $page > 0 || $num > $limit ))
{
if ( $totalnboflines ) // If we know total nb of lines
{
// 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
2019-11-11 23:59:36 +01:00
if ( $limit > 0 ) $nbpages = ceil ( $totalnboflines / $limit );
else $nbpages = 1 ;
$cpt = ( $page - $maxnbofpage );
if ( $cpt < 0 ) { $cpt = 0 ; }
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( $cpt >= 1 )
2019-02-03 22:58:56 +01:00
{
2020-03-13 12:53:22 +01:00
if ( empty ( $pagenavastextinput )) {
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=0' . $options . '">1</a></li>' ;
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>' ;
}
2019-02-03 22:58:56 +01:00
}
do
{
2020-03-13 12:53:22 +01:00
if ( $pagenavastextinput ) {
if ( $cpt == $page )
{
$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 .= '/' ;
//if (($cpt + 1) < $nbpages) $pagelist .= '/';
2020-03-13 12:53:22 +01:00
}
} else {
if ( $cpt == $page )
{
$pagelist .= '<li class="pagination"><span class="active">' . ( $page + 1 ) . '</span></li>' ;
}
else
{
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . $cpt . $options . '">' . ( $cpt + 1 ) . '</a></li>' ;
}
2019-02-03 22:58:56 +01:00
}
$cpt ++ ;
}
2020-03-13 12:53:22 +01: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 )) {
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>' ;
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . ( $nbpages - 1 ) . $options . '">' . $nbpages . '</a></li>' ;
}
} else {
//var_dump($page.' '.$cpt.' '.$nbpages);
2020-03-17 03:24:24 +01:00
//if (($page + 1) < $nbpages) {
2020-03-13 12:53:22 +01:00
$pagelist .= '<li class="pagination"><a href="' . $file . '?page=' . ( $nbpages - 1 ) . $options . '">' . $nbpages . '</a></li>' ;
2020-03-17 03:24:24 +01:00
//}
2019-02-03 22:58:56 +01: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
}
}
2019-11-14 11:53:28 +01:00
if ( $savlimit || $morehtmlright ) {
2019-11-14 11:00:49 +01:00
print_fleche_navigation ( $page , $file , $options , $nextpage , $pagelist , $morehtmlright , $savlimit , $totalnboflines , $hideselectlimit ); // output the div and ul for previous/last completed with page numbers into $pagelist
}
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
* @ return void
*/
function print_fleche_navigation ( $page , $file , $options = '' , $nextpage = 0 , $betweenarrows = '' , $afterarrows = '' , $limit = - 1 , $totalnboflines = 0 , $hideselectlimit = 0 )
{
global $conf , $langs ;
print '<div class="pagination"><ul>' ;
2019-11-14 11:53:28 +01:00
if (( int ) $limit > 0 && empty ( $hideselectlimit ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +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' ;
2019-02-03 22:58:56 +01:00
//$pagesizechoices.=',0:'.$langs->trans("All"); // Not yet supported
//$pagesizechoices.=',2:2';
2019-11-11 23:59:36 +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 ;
if ( ! in_array ( $tmpkey , $tmpchoice )) $tmpchoice [] = $tmpkey ;
$tmpkey = $conf -> liste_limit . ':' . $conf -> liste_limit ;
if ( ! in_array ( $tmpkey , $tmpchoice )) $tmpchoice [] = $tmpkey ;
2019-02-03 22:58:56 +01:00
asort ( $tmpchoice , SORT_NUMERIC );
2019-11-11 23:59:36 +01:00
foreach ( $tmpchoice as $val )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$selected = '' ;
$tmp = explode ( ':' , $val );
$key = $tmp [ 0 ];
$val = $tmp [ 1 ];
2019-02-03 22:58:56 +01:00
if ( $key != '' && $val != '' )
{
if (( int ) $key == ( int ) $limit )
{
$selected = ' selected="selected"' ;
}
print '<option name="' . $key . '"' . $selected . '>' . dol_escape_htmltag ( $val ) . '</option>' . " \n " ;
}
}
print '</select>' ;
if ( $conf -> use_javascript_ajax )
{
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>' ;
}
if ( $page > 0 )
{
2020-05-11 11:53:13 +02:00
print '<li class="pagination paginationpage"><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
}
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
}
if ( $nextpage > 0 )
{
2020-05-11 11:53:13 +02:00
print '<li class="pagination paginationpage"><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
}
if ( $afterarrows )
{
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
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
}
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
}
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()
2019-11-11 23:59:36 +01:00
if ( ! preg_match ( '/\//' , $rate )) $ret = price ( $rate , 0 , '' , 0 , 0 ) . ( $addpercent ? '%' : '' );
2019-02-03 22:58:56 +01:00
else
{
// 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
}
2019-11-11 23:59:36 +01:00
if (( $info_bits & 1 ) && $usestarfornpr >= 0 ) $ret .= ' *' ;
$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
*
* @ param float $amount Amount to format
* @ param integer $form Type of format , HTML or not ( not by default )
* @ param Translate $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 Chaine avec montant formate
*
* @ see price2num () Revert function of price
*/
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
2019-11-11 23:59:36 +01:00
if ( empty ( $amount )) $amount = 0 ; // To have a numeric value if amount not defined or = ''
$amount = ( is_numeric ( $amount ) ? $amount : 0 ); // Check if amount is numeric, for example, an error occured when amount value = o (letter) instead 0 (number)
if ( $rounding < 0 ) $rounding = min ( $conf -> global -> MAIN_MAX_DECIMALS_UNIT , $conf -> global -> MAIN_MAX_DECIMALS_TOT );
$nbdecimal = $rounding ;
2019-02-03 22:58:56 +01:00
// Output separators by default (french)
2019-11-11 23:59:36 +01:00
$dec = ',' ; $thousand = ' ' ;
2019-02-03 22:58:56 +01:00
// If $outlangs not forced, we use use language
2019-11-11 23:59:36 +01:00
if ( ! is_object ( $outlangs )) $outlangs = $langs ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +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)
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $decpart ) > $nbdecimal ) $nbdecimal = dol_strlen ( $decpart );
2019-02-03 22:58:56 +01:00
// Si on depasse max
if ( $trunc && $nbdecimal > $conf -> global -> MAIN_MAX_DECIMALS_SHOWN )
{
2019-11-11 23:59:36 +01:00
$nbdecimal = $conf -> global -> MAIN_MAX_DECIMALS_SHOWN ;
2019-02-03 22:58:56 +01:00
if ( preg_match ( '/\.\.\./i' , $conf -> global -> MAIN_MAX_DECIMALS_SHOWN ))
{
// 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
if ( $forcerounding >= 0 ) $nbdecimal = $forcerounding ;
// Format number
2019-11-11 23:59:36 +01:00
$output = number_format ( $amount , $nbdecimal , $dec , $thousand );
2019-02-03 22:58:56 +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 = '' ;
2019-02-03 22:58:56 +01:00
if ( $currency_code )
{
2019-11-11 23:59:36 +01:00
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' );
2019-02-03 22:58:56 +01:00
if ( in_array ( $currency_code , $listofcurrenciesbefore ) || in_array ( $outlangs -> defaultlang , $listoflanguagesbefore ))
{
2019-11-11 23:59:36 +01:00
$cursymbolbefore .= $outlangs -> getCurrencySymbol ( $currency_code );
2019-02-03 22:58:56 +01: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-04-22 12:40:11 +02:00
* @ param float $amount Amount to convert / clean or round
2019-02-03 22:58:56 +01:00
* @ param string $rounding '' = No rounding
* 'MU' = Round to Max unit price ( MAIN_MAX_DECIMALS_UNIT )
* 'MT' = Round to Max for totals with Tax ( MAIN_MAX_DECIMALS_TOT )
* 'MS' = Round to Max for stock quantity ( MAIN_MAX_DECIMALS_STOCK )
2020-03-25 17:41:39 +01:00
* 'CR' = Currency rate
2019-02-03 22:58:56 +01:00
* Numeric = Nb of digits for rounding
* @ param int $alreadysqlnb Put 1 if you know that content is already universal format number
2019-09-24 14:20:29 +02:00
* @ return string Amount with universal numeric format ( Example : '99.99999' ) .
* If conversion fails , it return text unchanged if $rounding = '' or '0' if $rounding is defined .
* If amount is null or '' , it returns '' if $rounding = '' or '0' if $rounding is defined ..
2019-02-03 22:58:56 +01:00
*
2019-03-11 01:01:15 +01:00
* @ see price () Opposite function of price2num
2019-02-03 22:58:56 +01:00
*/
function price2num ( $amount , $rounding = '' , $alreadysqlnb = 0 )
{
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 '.'
2019-11-11 23:59:36 +01:00
$dec = ',' ; $thousand = ' ' ;
if ( $langs -> transnoentitiesnoconv ( " SeparatorDecimal " ) != " SeparatorDecimal " ) $dec = $langs -> transnoentitiesnoconv ( " SeparatorDecimal " );
if ( $langs -> transnoentitiesnoconv ( " SeparatorThousand " ) != " SeparatorThousand " ) $thousand = $langs -> transnoentitiesnoconv ( " SeparatorThousand " );
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)
if ( $alreadysqlnb != 1 ) // If not a PHP number or unknown, we change format
{
//print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'<br>';
// 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.
if ( is_numeric ( $amount ))
{
// 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
}
//print "QQ".$amount.'<br>';
// Now make replace (the main goal of function)
2019-11-11 23:59:36 +01:00
if ( $thousand != ',' && $thousand != '.' ) $amount = str_replace ( ',' , '.' , $amount ); // To accept 2 notations for french users
$amount = str_replace ( ' ' , '' , $amount ); // To avoid spaces
$amount = str_replace ( $thousand , '' , $amount ); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount = str_replace ( $dec , '.' , $amount );
2019-02-03 22:58:56 +01:00
}
// Now, make a rounding if required
if ( $rounding )
{
2019-11-11 23:59:36 +01:00
$nbofdectoround = '' ;
if ( $rounding == 'MU' ) $nbofdectoround = $conf -> global -> MAIN_MAX_DECIMALS_UNIT ;
elseif ( $rounding == 'MT' ) $nbofdectoround = $conf -> global -> MAIN_MAX_DECIMALS_TOT ;
elseif ( $rounding == 'MS' ) $nbofdectoround = empty ( $conf -> global -> MAIN_MAX_DECIMALS_STOCK ) ? 5 : $conf -> global -> MAIN_MAX_DECIMALS_STOCK ;
2020-03-25 17:41:39 +01:00
elseif ( $rounding == 'CR' ) $nbofdectoround = 8 ;
2019-11-11 23:59:36 +01:00
elseif ( is_numeric ( $rounding )) $nbofdectoround = $rounding ;
2019-02-03 22:58:56 +01:00
//print "RR".$amount.' - '.$nbofdectoround.'<br>';
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $nbofdectoround )) $amount = round ( $amount , $nbofdectoround ); // $nbofdectoround can be 0.
2019-02-03 22:58:56 +01:00
else return 'ErrorBadParameterProvidedToFunction' ;
//print 'SS'.$amount.' - '.$nbofdec.' - '.$dec.' - '.$thousand.' - '.$nbofdectoround.'<br>';
// 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.
if ( is_numeric ( $amount ))
{
// 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
2019-11-11 23:59:36 +01:00
if ( $thousand != ',' && $thousand != '.' ) $amount = str_replace ( ',' , '.' , $amount ); // To accept 2 notations for french users
$amount = str_replace ( ' ' , '' , $amount ); // To avoid spaces
$amount = str_replace ( $thousand , '' , $amount ); // Replace of thousand before replace of dec to avoid pb if thousand is .
$amount = str_replace ( $dec , '.' , $amount );
2019-02-03 22:58:56 +01:00
}
return $amount ;
}
/**
* Output a dimension with best unit
*
* @ param float $dimension Dimension
2019-09-27 19:45:33 +02:00
* @ param int $unit Unit scale of dimension ( Example : 0 = kg , - 3 = g , - 6 = mg , 98 = ounce , 99 = pound , ... )
2019-02-03 22:58:56 +01:00
* @ param string $type 'weight' , 'volume' , ...
* @ param Translate $outputlangs Translate language object
* @ param int $round - 1 = non rounding , x = number of decimal
* @ 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 )
* @ return string String to show dimensions
*/
function showDimensionInBestUnit ( $dimension , $unit , $type , $outputlangs , $round = - 1 , $forceunitoutput = 'no' )
{
require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php' ;
2019-11-11 23:59:36 +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 ;
}
2019-11-11 23:59:36 +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 ;
}
elseif (( $forceunitoutput == 'no' && $dimension > 100000000 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == 6 ))
{
$dimension = $dimension / 1000000 ;
$unit = $unit + 6 ;
}
elseif (( $forceunitoutput == 'no' && $dimension > 100000 && $unit < 90 ) || ( is_numeric ( $forceunitoutput ) && $forceunitoutput == 3 ))
{
$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 ))
{
$dimension = // convert dimension from standard unit into ounce or pound
$unit = $forceunitoutput ;
}
if ( $unit > 90 && $type == 'weight' && is_numeric ( $forceunitoutput ) && $forceunitoutput < 90 )
{
$dimension = // convert dimension from standard unit into ounce or pound
$unit = $forceunitoutput ;
} */
2019-11-11 23:59:36 +01:00
$ret = price ( $dimension , 0 , $outputlangs , 0 , 0 , $round ) . ' ' . measuringUnitString ( 0 , $type , $unit );
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 ;
2019-11-11 23:59:36 +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 ();
2019-02-03 22:58:56 +01:00
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) // If vat is "xx (yy)"
{
$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
if ( $mysoc -> country_code == 'ES' ) // For spain localtaxes 1 and 2, tax is qualified if buyer use local tax
{
if ( $local == 1 )
{
2019-11-11 23:59:36 +01:00
if ( ! $mysoc -> localtax1_assuj || ( string ) $vatratecleaned == " 0 " ) return 0 ;
2019-02-03 22:58:56 +01:00
if ( $thirdparty_seller -> id == $mysoc -> id )
{
2019-11-11 23:59:36 +01:00
if ( ! $thirdparty_buyer -> localtax1_assuj ) return 0 ;
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
if ( ! $thirdparty_seller -> localtax1_assuj ) return 0 ;
2019-02-03 22:58:56 +01:00
}
}
if ( $local == 2 )
{
//if (! $mysoc->localtax2_assuj || (string) $vatratecleaned == "0") return 0;
2019-11-11 23:59:36 +01:00
if ( ! $mysoc -> localtax2_assuj ) return 0 ; // If main vat is 0, IRPF may be different than 0.
2019-02-03 22:58:56 +01:00
if ( $thirdparty_seller -> id == $mysoc -> id )
{
2019-11-11 23:59:36 +01:00
if ( ! $thirdparty_buyer -> localtax2_assuj ) return 0 ;
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
if ( ! $thirdparty_seller -> localtax2_assuj ) return 0 ;
2019-02-03 22:58:56 +01:00
}
}
}
else
{
2019-11-11 23:59:36 +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.
if ( in_array ( $mysoc -> country_code , array ( 'ES' )))
{
$conf -> global -> MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY = 1 ;
}
// Search local taxes
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
if ( $local == 1 )
2019-02-03 22:58:56 +01:00
{
if ( $thirdparty_seller != $mysoc )
{
if ( ! isOnlyOneLocalTax ( $local )) // TODO We should provide $vatrate to search on correct line and not always on line with highest vat rate
{
return $thirdparty_seller -> localtax1_value ;
}
}
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.
{
return $conf -> global -> MAIN_INFO_VALUE_LOCALTAX1 ;
}
}
}
2019-11-11 23:59:36 +01:00
if ( $local == 2 )
2019-02-03 22:58:56 +01:00
{
if ( $thirdparty_seller != $mysoc )
{
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
{
return $thirdparty_seller -> localtax2_value ;
}
}
else // i am the seller
{
if ( in_array ( $mysoc -> country_code , array ( 'ES' )))
{
return $thirdparty_buyer -> localtax2_value ;
}
else
{
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 " ;
2019-02-03 22:58:56 +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 = ' " . $thirdparty_seller -> country_code . " ' " ;
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
2019-11-11 23:59:36 +01:00
if ( $vatratecode ) $sql .= " AND t.code =' " . $vatratecode . " ' " ; // If we have the code, we use it in priority
else $sql .= " AND t.recuperableonly =' " . $vatnpr . " ' " ;
2019-02-03 22:58:56 +01:00
dol_syslog ( " get_localtax " , LOG_DEBUG );
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
$obj = $db -> fetch_object ( $resql );
2019-11-11 23:59:36 +01:00
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
2019-11-11 23:59:36 +01:00
if ( count ( $valors ) > 1 )
2019-02-03 22:58:56 +01:00
{
return false ;
}
else
{
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 " ;
$sql .= " WHERE c.code = ' " . $mysoc -> country_code . " ' AND t.active = 1 AND t.taux=( " ;
$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 " ;
$sql .= " WHERE c.code = ' " . $mysoc -> country_code . " ' AND tt.active = 1 " ;
$sql .= " ) " ;
$resql = $db -> query ( $sql );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
$obj = $db -> fetch_object ( $resql );
2019-11-11 23:59:36 +01:00
if ( $local == 1 ) return $obj -> localtax1 ;
elseif ( $local == 2 ) return $obj -> localtax2 ;
2019-02-03 22:58:56 +01:00
}
return 0 ;
}
/**
* Get vat main information from Id .
* You can call getLocalTaxesFromRate after to get other fields .
*
* @ 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
$sql = " SELECT t.rowid, t.code, t.taux as rate, t.recuperableonly as npr, t.accountancy_code_sell, t.accountancy_code_buy " ;
2019-11-11 23:59:36 +01:00
$sql .= " FROM " . MAIN_DB_PREFIX . " c_tva as t " ;
if ( $firstparamisid ) $sql .= " WHERE t.rowid = " . ( int ) $vatrate ;
2019-02-03 22:58:56 +01:00
else
{
$vatratecleaned = $vatrate ;
$vatratecode = '' ;
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) // If vat is "xx (yy)"
{
$vatratecleaned = $reg [ 1 ];
$vatratecode = $reg [ 2 ];
}
2019-11-11 23:59:36 +01:00
$sql .= " , " . MAIN_DB_PREFIX . " c_country as c " ;
2019-02-03 22:58:56 +01:00
/* if ( $mysoc -> country_code == 'ES' ) $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $buyer -> country_code . " ' " ; // vat in spain use the buyer country ??
else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $seller -> country_code . " ' " ; */
2019-11-11 23:59:36 +01:00
$sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $seller -> country_code . " ' " ;
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
if ( $vatratecode ) $sql .= " AND t.code = ' " . $vatratecode . " ' " ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
$obj = $db -> fetch_object ( $resql );
if ( $obj ) return array ( 'rowid' => $obj -> rowid , 'code' => $obj -> code , 'rate' => $obj -> rate , 'npr' => $obj -> npr , 'accountancy_code_sell' => $obj -> accountancy_code_sell , 'accountancy_code_buy' => $obj -> accountancy_code_buy );
else return array ();
}
else dol_print_error ( $db );
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 .
* 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 localtax and type , and then
* provide it to the function calcul_price_total .
*
* @ 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 )
* @ return array array ( localtax_type1 ( 1 - 6 / 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 " ;
2019-11-11 23:59:36 +01:00
if ( $firstparamisid ) $sql .= " WHERE t.rowid = " . ( int ) $vatrate ;
2019-02-03 22:58:56 +01:00
else
{
$vatratecleaned = $vatrate ;
$vatratecode = '' ;
2020-01-01 22:27:47 +01:00
$reg = array ();
2019-02-03 22:58:56 +01:00
if ( preg_match ( '/^(.*)\s*\((.*)\)$/' , $vatrate , $reg )) // If vat is "x.x (yy)"
{
$vatratecleaned = $reg [ 1 ];
$vatratecode = $reg [ 2 ];
}
2019-11-11 23:59:36 +01:00
$sql .= " , " . MAIN_DB_PREFIX . " c_country as c " ;
if ( $mysoc -> country_code == 'ES' ) $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $buyer -> country_code . " ' " ; // local tax in spain use the buyer country ??
2019-02-03 22:58:56 +01:00
else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = ' " . $seller -> country_code . " ' " ;
2019-11-11 23:59:36 +01:00
$sql .= " AND t.taux = " . (( float ) $vatratecleaned ) . " AND t.active = 1 " ;
if ( $vatratecode ) $sql .= " AND t.code = ' " . $vatratecode . " ' " ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
$resql = $db -> query ( $sql );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
$obj = $db -> fetch_object ( $resql );
2020-01-01 22:27:47 +01:00
$vateratestring = $obj -> rate . ( $obj -> code ? ' (' . $obj -> code . ')' : '' );
2019-02-03 22:58:56 +01:00
if ( $local == 1 )
{
2020-01-01 22:27:47 +01:00
return array ( $obj -> localtax1_type , get_localtax ( $vateratestring , $local , $buyer , $seller ), $obj -> accountancy_code_sell , $obj -> accountancy_code_buy );
2019-02-03 22:58:56 +01:00
}
elseif ( $local == 2 )
{
2020-01-01 22:27:47 +01:00
return array ( $obj -> localtax2_type , get_localtax ( $vateratestring , $local , $buyer , $seller ), $obj -> accountancy_code_sell , $obj -> accountancy_code_buy );
2019-02-03 22:58:56 +01:00
}
else
{
2020-01-01 22:27:47 +01:00
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
}
}
return 0 ;
}
/**
* Return vat rate of a product in a particular selling country or default country vat if product is unknown
* Function called by get_default_tva
*
* @ param int $idprod Id of product or 0 if not a predefined product
* @ param Societe $thirdparty_seller Thirdparty with a -> country_code defined ( FR , US , IT , ... )
* @ 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
*/
function get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice = 0 )
{
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
if ( $idprod > 0 )
{
// 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
if ( $mysoc -> country_code == $thirdparty_seller -> country_code ) // If selling country is ours
{
if ( $idprodfournprice > 0 ) // We want vat for product for a "supplier" object
{
$product -> get_buyprice ( $idprodfournprice , 0 , 0 , 0 );
2019-11-11 23:59:36 +01:00
$ret = $product -> vatrate_supplier ;
if ( $product -> default_vat_code ) $ret .= ' (' . $product -> default_vat_code . ')' ;
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
$ret = $product -> tva_tx ; // Default vat of product we defined
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 ;
2019-02-03 22:58:56 +01:00
}
else
{
// TODO Read default product vat according to countrycode and product. Vat for couple countrycode/product is a feature not implemeted yet.
// May be usefull/required if hidden option SERVICE_ARE_ECOMMERCE_200238EC is on
}
}
2019-11-11 23:59:36 +01:00
if ( ! $found )
2019-02-03 22:58:56 +01:00
{
if ( empty ( $conf -> global -> MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS ))
{
// 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 " ;
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code=' " . $thirdparty_seller -> country_code . " ' " ;
$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 );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
2019-11-11 23:59:36 +01:00
$obj = $db -> fetch_object ( $resql );
2019-02-03 22:58:56 +01:00
if ( $obj )
{
2019-11-11 23:59:36 +01:00
$ret = $obj -> vat_rate ;
if ( $obj -> default_vat_code ) $ret .= ' (' . $obj -> default_vat_code . ')' ;
2019-02-03 22:58:56 +01:00
}
$db -> free ( $sql );
}
else dol_print_error ( $db );
}
2019-11-11 23:59:36 +01:00
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 ;
}
/**
* Return localtax vat rate of a product in a particular selling country or default country vat if product is unknown
*
* @ param int $idprod Id of product
* @ param int $local 1 for localtax1 , 2 for localtax 2
* @ param Societe $thirdparty_seller Thirdparty with a -> country_code defined ( FR , US , IT , ... )
* @ 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
*/
function get_product_localtax_for_country ( $idprod , $local , $thirdparty_seller )
{
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
if ( $idprod > 0 )
{
// 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
if ( $mysoc -> country_code == $thirdparty_seller -> country_code ) // If selling country is ours
{
/* 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 ;
*/
}
else
{
// TODO Read default product vat according to countrycode and product
}
}
2019-11-11 23:59:36 +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 " ;
$sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code=' " . $thirdparty_seller -> country_code . " ' " ;
$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 );
2019-02-03 22:58:56 +01:00
if ( $resql )
{
2019-11-11 23:59:36 +01:00
$obj = $db -> fetch_object ( $resql );
2019-02-03 22:58:56 +01:00
if ( $obj )
{
2019-11-11 23:59:36 +01:00
if ( $local == 1 ) $ret = $obj -> localtax1 ;
elseif ( $local == 2 ) $ret = $obj -> localtax2 ;
2019-02-03 22:58:56 +01:00
}
}
else dol_print_error ( $db );
}
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 )
* 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 .
* 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 .
* Si ( vendeur et acheteur dans Communaute europeenne ) et ( acheteur = particulier ou entreprise sans num TVA intra ) alors TVA par defaut = TVA du produit vendu . Fin de regle
* Si ( vendeur et acheteur dans Communaute europeenne ) et ( acheteur = entreprise avec num TVA ) intra alors TVA par defaut = 0. Fin de regle
* Sinon TVA proposee par defaut = 0. Fin de regle .
*
* @ 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.
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> SERVICE_ARE_ECOMMERCE_200238EC ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
if ( $seller_in_cee && $buyer_in_cee && ! $thirdparty_buyer -> isACompany ())
2019-02-03 22:58:56 +01:00
{
//print 'VATRULE 0';
return get_product_vat_for_country ( $idprod , $thirdparty_buyer , $idprodfournprice );
}
}
// If seller does not use VAT
2019-11-11 23:59:36 +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 )
2019-11-11 23:59:36 +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.
// Not supported
// 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
if (( $seller_in_cee && $buyer_in_cee ))
{
2019-11-11 23:59:36 +01:00
$isacompany = $thirdparty_buyer -> isACompany ();
2019-02-03 22:58:56 +01:00
if ( $isacompany )
{
//print 'VATRULE 3';
return 0 ;
}
else
{
//print 'VATRULE 4';
return get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice );
}
}
// Si (vendeur en France et acheteur hors Communaute europeenne et acheteur particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC ) && empty ( $buyer_in_cee ) && ! $thirdparty_buyer -> isACompany ()) {
2019-02-03 22:58:56 +01:00
return get_product_vat_for_country ( $idprod , $thirdparty_seller , $idprodfournprice );
}
// 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
//print 'VATRULE 5';
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 ;
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 ;
}
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 ;
if ( ! is_object ( $thirdparty_seller )) return - 1 ;
if ( ! is_object ( $thirdparty_buyer )) return - 1 ;
2019-11-11 23:59:36 +01:00
if ( $local == 1 ) // Localtax 1
2019-02-03 22:58:56 +01:00
{
if ( $mysoc -> country_code == 'ES' )
{
2019-11-11 23:59:36 +01:00
if ( is_numeric ( $thirdparty_buyer -> localtax1_assuj ) && ! $thirdparty_buyer -> localtax1_assuj ) return 0 ;
2019-02-03 22:58:56 +01:00
}
else
{
// Si vendeur non assujeti a Localtax1, localtax1 par default=0
2019-11-11 23:59:36 +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
}
}
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +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
}
if ( $thirdparty_seller -> country_code == $thirdparty_buyer -> country_code )
{
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 ;
2019-11-11 23:59:36 +01:00
$result = 'unknown' ; $classname = '' ;
2019-02-03 22:58:56 +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' );
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' ;
2019-02-03 22:58:56 +01:00
}
elseif ( $yesno == 0 || strtolower ( $yesno ) == 'no' || strtolower ( $yesno ) == 'false' )
{
2019-11-11 23:59:36 +01:00
$result = $langs -> trans ( " no " );
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
2019-11-11 23:59:36 +01:00
if ( $color == 2 ) $classname = 'ok' ;
else $classname = 'error' ;
2019-03-27 11:05:43 +01:00
}
if ( $color ) return '<font class="' . $classname . '">' . $result . '</font>' ;
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 .
* New usage : $conf -> module -> multidir_output [ $object -> entity ] . '/' . get_exdir ( 0 , 0 , 0 , 1 , $object , $modulepart )
* or : $conf -> module -> dir_output . '/' . get_exdir ( 0 , 0 , 0 , 1 , $object , $modulepart ) if multidir_output not defined .
* Example our with new usage : $object is invoice -> 'INYYMM-ABCD'
* Example our with old usage : '015' with level 3 -> " 0/1/5/ " , '015' with level 1 -> " 5/ " , 'ABC-1' with level 3 -> " 0/0/1/ "
*
* @ param string $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
* @ param string $modulepart Type of object ( 'invoice_supplier, ' donation ', ' invoice ', ...' )
* @ return string Dir to use ending . Example '' or '1/' or '1/2/'
*/
function get_exdir ( $num , $level , $alpha , $withoutslash , $object , $modulepart )
{
global $conf ;
$path = '' ;
2019-11-11 23:59:36 +01:00
$arrayforoldpath = array ( 'cheque' , 'user' , 'category' , 'holiday' , 'supplier_invoice' , 'invoice_supplier' , 'mailing' , 'supplier_payment' );
if ( ! empty ( $conf -> global -> PRODUCT_USE_OLD_PATH_FOR_PHOTO )) $arrayforoldpath [] = 'product' ;
if ( ! empty ( $level ) && in_array ( $modulepart , $arrayforoldpath ))
2019-02-03 22:58:56 +01:00
{
// This part should be removed once all code is using "get_exdir" to forge path, with all parameters provided.
if ( empty ( $alpha )) $num = preg_replace ( '/([^0-9])/i' , '' , $num );
else $num = preg_replace ( '/^.*\-/i' , '' , $num );
$num = substr ( " 000 " . $num , - $level );
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 );
}
else
{
// TODO
// We will enhance here a common way of forging path for document storage
// Here, object->id, object->ref and modulepart are required.
//var_dump($modulepart);
2019-11-11 23:59:36 +01:00
if ( in_array ( $modulepart , array ( 'thirdparty' , 'contact' , 'member' , 'propal' , 'proposal' , 'commande' , 'order' , 'facture' , 'invoice' ,
'supplier_order' , 'supplier_proposal' , 'shipment' , 'contract' , 'expensereport' , 'ficheinter' )))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$path = ( $object -> ref ? $object -> ref : $object -> id );
2019-02-03 22:58:56 +01:00
}
}
2019-11-11 23:59:36 +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 );
2019-02-03 22:58:56 +01:00
if ( @ is_dir ( $dir_osencoded )) return 0 ;
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 );
2019-02-03 22:58:56 +01:00
for ( $i = 0 ; $i < $num ; $i ++ )
{
if ( $i > 0 ) $ccdir .= '/' . $cdir [ $i ];
else $ccdir .= $cdir [ $i ];
2019-11-11 23:59:36 +01:00
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)
if ( $ccdir )
{
2019-11-11 23:59:36 +01:00
$ccdir_osencoded = dol_osencode ( $ccdir );
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
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 ++ ;
}
else
{
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 ++ ;
}
}
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
* @ 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 )
* @ return string String cleaned
*
2019-03-11 01:01:15 +01:00
* @ see dol_escape_htmltag () strip_tags () dol_string_onlythesehtmltags () dol_string_neverthesehtmltags ()
2019-02-03 22:58:56 +01:00
*/
function dol_string_nohtmltag ( $stringtoclean , $removelinefeed = 1 , $pagecodeto = 'UTF-8' , $strip_tags = 0 )
{
2019-12-23 15:45:08 +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 );
if ( $strip_tags ) {
$temp = strip_tags ( $temp );
} else {
$pattern = " /<[^<>]+>/ " ;
// Exemple of $temp: <a href="/myurl" title="<u>A title</u>">0000-021</a>
2019-11-11 23:59:36 +01:00
$temp = preg_replace ( $pattern , " " , $temp ); // pass 1
2019-02-03 22:58:56 +01:00
// $temp after pass 1: <a href="/myurl" title="A title">0000-021
2019-11-11 23:59:36 +01:00
$temp = preg_replace ( $pattern , " " , $temp ); // pass 2
2019-02-03 22:58:56 +01:00
// $temp after pass 2: 0000-021
}
$temp = dol_html_entity_decode ( $temp , ENT_COMPAT , $pagecodeto );
// Supprime aussi les retours
2019-11-11 23:59:36 +01:00
if ( $removelinefeed == 1 ) $temp = str_replace ( array ( " \r \n " , " \r " , " \n " ), " " , $temp );
2019-02-03 22:58:56 +01:00
// et les espaces doubles
while ( strpos ( $temp , " " ))
{
$temp = str_replace ( " " , " " , $temp );
}
return trim ( $temp );
}
/**
* Clean a string to keep only desirable HTML tags .
*
2020-02-09 18:28:34 +01:00
* @ param string $stringtoclean String to clean
* @ param string $cleanalsosomestyles Clean also some tags
* @ 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
*/
2020-02-09 18:28:34 +01:00
function dol_string_onlythesehtmltags ( $stringtoclean , $cleanalsosomestyles = 1 )
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 " ,
2020-07-25 00:57:40 +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 "
2019-02-03 22:58:56 +01:00
);
$allowed_tags_string = join ( " >< " , $allowed_tags );
$allowed_tags_string = preg_replace ( '/^>/' , '' , $allowed_tags_string );
$allowed_tags_string = preg_replace ( '/<$/' , '' , $allowed_tags_string );
2020-02-09 18:28:34 +01:00
$allowed_tags_string = '<' . $allowed_tags_string . '>' ;
if ( $cleanalsosomestyles ) {
2020-04-10 10:59:32 +02:00
$stringtoclean = preg_replace ( '/position\s*:\s*(absolute|fixed)\s*!\s*important/' , '' , $stringtoclean ); // 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-02-09 18:28:34 +01:00
}
2019-02-03 22:58:56 +01:00
$temp = strip_tags ( $stringtoclean , $allowed_tags_string );
return $temp ;
}
/**
* Clean a string from some undesirable HTML tags .
2020-02-09 18:28:34 +01:00
* Note . Not enough 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
*
2019-03-11 01:01:15 +01:00
* @ see dol_escape_htmltag () strip_tags () dol_string_nohtmltag () dol_string_onlythesehtmltags ()
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 ;
2019-11-11 23:59:36 +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
{
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
2019-02-03 22:58:56 +01: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 )) ? '...' : '' );
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
$ishtml = 0 ;
2019-02-03 22:58:56 +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 " => " " );
}
else
{
$repTable = array ( " \t " => " " , " \n " => " <br> " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
}
$text = strtr ( $text , $repTable );
if ( $charset == 'UTF-8' ) { $pattern = '/(<br[^>]*>)/Uu' ; } // /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support
2019-11-11 23:59:36 +01:00
else $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
2019-02-03 22:58:56 +01:00
while (( $i < $nba ) && ( $i < ( $nboflines * 2 )))
{
if ( $i % 2 == 0 ) $firstline .= $a [ $i ];
2019-11-11 23:59:36 +01:00
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 ;
2019-02-03 22:58:56 +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.
if ( $removelasteolbr ) $newstring = preg_replace ( '/<br>$/i' , '' , $newstring ); // Remove last <br> (remove only last one)
$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__' => '"' ));
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
if ( $removelasteolbr ) $newstring = preg_replace ( '/(\r\n|\r|\n)$/i' , '' , $newstring ); // Remove last \n (may remove several)
$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' )
{
2019-11-11 23:59:36 +01:00
$ret = dol_html_entity_decode ( $stringtodecode , ENT_COMPAT , $pagecodeto );
$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 )
{
2019-11-11 23:59:36 +01:00
$ret = preg_replace ( '/(<br>|<br(\s[\sa-zA-Z_="]*)?\/?>|' . " \n " . '|' . " \r " . ')+$/i' , " " , $stringtodecode );
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
* @ param string $b Operand b ( ENT_QUOTES = convert simple and double quotes )
* @ param string $c Operand c
* @ param string $keepsomeentities Entities but & amp ;, < , > , " are not converted.
* @ 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 ;
if ( $keepsomeentities ) $newstring = strtr ( $newstring , array ( '&' => '__andamp__' , '<' => '__andlt__' , '>' => '__andgt__' , '"' => '__dquot__' ));
$newstring = html_entity_decode ( $newstring , $b , $c );
if ( $keepsomeentities ) $newstring = strtr ( $newstring , array ( '__andamp__' => '&' , '__andlt__' => '<' , '__andgt__' => '>' , '__dquot__' => '"' ));
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
*/
function dol_htmlentities ( $string , $flags = null , $encoding = 'UTF-8' , $double_encode = false )
{
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 ;
for ( $scursor = 0 ; $scursor < $len ; $scursor ++ )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$ordchar = ord ( $s [ $scursor ]);
2019-02-03 22:58:56 +01:00
//print $scursor.'-'.$ordchar.'<br>';
2019-11-11 23:59:36 +01:00
if ( $ordchar < 32 && $ordchar != 13 && $ordchar != 10 ) { $ok = 0 ; break ; }
elseif ( $ordchar > 126 && $ordchar < 160 ) { $ok = 0 ; break ; }
2019-08-29 13:17:14 +02: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
}
2019-08-29 13:17:14 +02: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 )
{
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 " => " " );
if ( dol_textishtml ( $text )) $repTable = array ( " \t " => " " , " \n " => " " , " \r " => " " , " \0 " => " " , " \x0B " => " " );
$text = strtr ( $text , $repTable );
if ( $charset == 'UTF-8' ) { $pattern = '/(<br[^>]*>)/Uu' ; } // /U is to have UNGREEDY regex to limit to one html tag. /u is for UTF8 support
2019-11-11 23:59:36 +01:00
else $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
2019-11-11 23:59:36 +01:00
if ( $maxlinesize )
2019-02-03 22:58:56 +01:00
{
foreach ( $a as $line )
{
2019-11-11 23:59:36 +01:00
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 );
2019-11-11 23:59:36 +01:00
if ( dol_strlen ( $line_dec ) > $maxlinesize )
2019-02-03 22:58:56 +01:00
{
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 )
{
if ( $option == 1 )
{
if ( preg_match ( '/<html/i' , $msg )) return true ;
elseif ( preg_match ( '/<body/i' , $msg )) return true ;
2020-03-12 16:15:48 +01:00
elseif ( preg_match ( '/<\/textarea/i' , $msg )) return true ;
2019-02-03 22:58:56 +01:00
elseif ( preg_match ( '/<br/i' , $msg )) return true ;
return false ;
}
else
{
if ( preg_match ( '/<html/i' , $msg )) return true ;
elseif ( preg_match ( '/<body/i' , $msg )) return true ;
2020-03-12 16:15:48 +01:00
elseif ( preg_match ( '/<\/textarea/i' , $msg )) return true ;
2019-02-03 22:58:56 +01:00
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 ;
elseif ( preg_match ( '/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i' , $msg )) return true ;
elseif ( preg_match ( '/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/>/i' , $msg )) return true ;
2019-11-11 23:59:36 +01:00
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" />
2019-02-03 22:58:56 +01:00
elseif ( preg_match ( '/<h[0-9]>/i' , $msg )) return true ;
2019-11-11 23:59:36 +01:00
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 )
{
2019-03-11 01:01:15 +01:00
if ( ! empty ( $invert ))
{
$tmp = $text1 ;
$text1 = $text2 ;
$text2 = $tmp ;
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$ret = '' ;
2020-05-14 14:10:04 +02:00
$ret .= ( ! dol_textishtml ( $text1 ) && dol_textishtml ( $text2 )) ? dol_nl2br ( dol_escape_htmltag ( $text1 , 0 , 1 , '' , 1 ), 0 , $forxml ) : $text1 ;
2019-11-11 23:59:36 +01:00
$ret .= ( ! empty ( $text1 ) && ! empty ( $text2 )) ? (( dol_textishtml ( $text1 ) || dol_textishtml ( $text2 )) ? ( $forxml ? " <br \ > \n " : " <br> \n " ) : " \n " ) : " " ;
2020-05-14 14:10:04 +02:00
$ret .= ( dol_textishtml ( $text1 ) && ! dol_textishtml ( $text2 )) ? dol_nl2br ( dol_escape_htmltag ( $text2 , 0 , 1 , '' , 1 ), 0 , $forxml ) : $text2 ;
2019-03-11 01:01:15 +01:00
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
2019-11-11 23:59:36 +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 ;
2019-11-11 23:59:36 +01:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__USER_SIGNATURE__' => ( string ) (( $signature && empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN )) ? ( $onlykey == 2 ? dol_trunc ( dol_string_nohtmltag ( $signature ), 30 ) : $signature ) : '' )
)
);
// For backward compatibility
if ( $onlykey != 2 )
{
$substitutionarray [ '__SIGNATURE__' ] = ( string ) (( $signature && empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN )) ? ( $onlykey == 2 ? dol_trunc ( dol_string_nohtmltag ( $signature ), 30 ) : $signature ) : '' );
}
2019-11-11 23:59:36 +01:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__USER_ID__' => ( string ) $user -> id ,
'__USER_LOGIN__' => ( string ) $user -> login ,
2020-03-11 16:28:00 +01:00
'__USER_EMAIL__' => ( string ) $user -> email ,
'__USER_LASTNAME__' => ( string ) $user -> lastname ,
2019-02-03 22:58:56 +01:00
'__USER_FIRSTNAME__' => ( string ) $user -> firstname ,
'__USER_FULLNAME__' => ( string ) $user -> getFullName ( $outputlangs ),
'__USER_SUPERVISOR_ID__' => ( string ) ( $user -> fk_user ? $user -> fk_user : '0' ),
'__USER_REMOTE_IP__' => ( string ) getUserRemoteIP ()
)
);
}
2019-11-11 23:59:36 +01:00
if (( empty ( $exclude ) || ! in_array ( 'mycompany' , $exclude )) && is_object ( $mysoc ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__MYCOMPANY_NAME__' => $mysoc -> name ,
'__MYCOMPANY_EMAIL__' => $mysoc -> email ,
'__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 ,
'__MYCOMPANY_FULLADDRESS__' => $mysoc -> getFullAddress ( 1 , ', ' ),
'__MYCOMPANY_ADDRESS__' => $mysoc -> address ,
'__MYCOMPANY_ZIP__' => $mysoc -> zip ,
'__MYCOMPANY_TOWN__' => $mysoc -> town ,
'__MYCOMPANY_COUNTRY__' => $mysoc -> country ,
'__MYCOMPANY_COUNTRY_ID__' => $mysoc -> country_id ,
2020-01-28 02:50:11 +01:00
'__MYCOMPANY_COUNTRY_CODE__' => $mysoc -> country_code ,
'__MYCOMPANY_CURRENCY_CODE__' => $conf -> currency
2019-02-03 22:58:56 +01:00
));
}
2019-11-11 23:59:36 +01:00
if (( $onlykey || is_object ( $object )) && ( empty ( $exclude ) || ! in_array ( 'object' , $exclude )))
2019-02-03 22:58:56 +01:00
{
if ( $onlykey )
{
$substitutionarray [ '__ID__' ] = '__ID__' ;
$substitutionarray [ '__REF__' ] = '__REF__' ;
$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__' ;
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> societe -> enabled ))
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
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> adherent -> enabled ))
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__' ;
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
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> projet -> enabled ))
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
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> contrat -> enabled ))
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' ;
$substitutionarray [ '__SECUREKEYPAYMENT_CONTRACTLINE__' ] = 'Security key for payment on a a service' ;
$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' ;
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> expedition -> enabled ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__SHIPPINGTRACKNUM__' ] = 'Shipping tacking number' ;
$substitutionarray [ '__SHIPPINGTRACKNUMURL__' ] = 'Shipping tracking url' ;
2019-02-03 22:58:56 +01:00
}
}
else
{
$substitutionarray [ '__ID__' ] = $object -> id ;
$substitutionarray [ '__REF__' ] = $object -> ref ;
$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 ) : '' );
2019-10-22 14:39:33 +02:00
2019-02-03 22:58:56 +01:00
// For backward compatibility
$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-10-22 14:39:33 +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-02-13 10:44:08 +01:00
$substitutionarray [ '__SUPPLIER_ORDER_DELAY_DELIVERY__' ] = $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
2019-02-03 22:58:56 +01:00
$birthday = dol_print_date ( $object -> birth , 'day' );
if ( $object -> id > 0 )
{
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__MEMBER_ID__' ] = $object -> id ;
2019-02-03 22:58:56 +01:00
if ( method_exists ( $object , 'getCivilityLabel' )) $substitutionarray [ '__MEMBER_CIVILITY__' ] = $object -> getCivilityLabel ();
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__MEMBER_FIRSTNAME__' ] = $object -> firstname ;
$substitutionarray [ '__MEMBER_LASTNAME__' ] = $object -> lastname ;
if ( method_exists ( $object , 'getFullName' )) $substitutionarray [ '__MEMBER_FULLNAME__' ] = $object -> getFullName ( $outputlangs );
$substitutionarray [ '__MEMBER_COMPANY__' ] = $object -> societe ;
$substitutionarray [ '__MEMBER_ADDRESS__' ] = $object -> address ;
$substitutionarray [ '__MEMBER_ZIP__' ] = $object -> zip ;
$substitutionarray [ '__MEMBER_TOWN__' ] = $object -> town ;
$substitutionarray [ '__MEMBER_COUNTRY__' ] = $object -> country ;
$substitutionarray [ '__MEMBER_EMAIL__' ] = $object -> email ;
$substitutionarray [ '__MEMBER_BIRTH__' ] = $birthday ;
$substitutionarray [ '__MEMBER_PHOTO__' ] = $object -> photo ;
$substitutionarray [ '__MEMBER_LOGIN__' ] = $object -> login ;
$substitutionarray [ '__MEMBER_PASSWORD__' ] = $object -> pass ;
$substitutionarray [ '__MEMBER_PHONE__' ] = $object -> phone ;
$substitutionarray [ '__MEMBER_PHONEPRO__' ] = $object -> phone_perso ;
$substitutionarray [ '__MEMBER_PHONEMOBILE__' ] = $object -> phone_mobile ;
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' );
}
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 : '' );
$substitutionarray [ '__THIRDPARTY_PHONE__' ] = ( is_object ( $object ) ? $object -> phone : '' );
$substitutionarray [ '__THIRDPARTY_FAX__' ] = ( is_object ( $object ) ? $object -> fax : '' );
$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 : '' );
$substitutionarray [ '__THIRDPARTY_NOTE_PUBLIC__' ] = ( is_object ( $object ) ? dol_htmlentitiesbr ( $object -> note_public ) : '' );
$substitutionarray [ '__THIRDPARTY_NOTE_PRIVATE__' ] = ( is_object ( $object ) ? dol_htmlentitiesbr ( $object -> note_private ) : '' );
2019-02-03 22:58:56 +01:00
}
elseif ( is_object ( $object -> thirdparty ) && $object -> thirdparty -> id > 0 )
{
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 : '' );
$substitutionarray [ '__THIRDPARTY_PHONE__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> phone : '' );
$substitutionarray [ '__THIRDPARTY_FAX__' ] = ( is_object ( $object -> thirdparty ) ? $object -> thirdparty -> fax : '' );
$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 : '' );
$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 ) : '' );
2019-02-03 22:58:56 +01:00
}
2019-09-23 13:04:22 +02:00
if ( is_object ( $object -> project ) && $object -> project -> id > 0 )
{
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
}
if ( is_object ( $object -> projet ) && $object -> projet -> id > 0 ) // Deprecated, for backward compatibility
2019-02-03 22:58:56 +01:00
{
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
}
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
}
if ( is_object ( $object ) && $object -> element == 'contrat' && is_array ( $object -> lines ))
{
if ( $object -> id > 0 )
{
2019-11-11 23:59:36 +01:00
$dateplannedstart = '' ;
$datenextexpiration = '' ;
foreach ( $object -> lines as $line )
2019-02-03 22:58:56 +01:00
{
if ( $line -> date_ouverture_prevue > $dateplannedstart ) $dateplannedstart = $line -> date_ouverture_prevue ;
2019-11-11 23:59:36 +01:00
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
}
$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' );
}
}
// Create dynamic tags for __EXTRAFIELD_FIELD__
if ( $object -> table_element && $object -> id > 0 )
{
2019-11-11 23:59:36 +01:00
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 );
if ( $object -> fetch_optionals () > 0 )
{
if ( is_array ( $extrafields -> attributes [ $object -> table_element ][ 'label' ]) && count ( $extrafields -> attributes [ $object -> table_element ][ 'label' ]) > 0 )
{
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-05-07 15:37:32 +02:00
if ( $extrafields -> attribute_type [ $key ] == 'date' ) {
$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 );
2020-05-07 15:41:21 +02:00
$substitutionarray [ '__EXTRAFIELD_' . strtoupper ( $key ) . '_RFC__' ] = dol_print_date ( $object -> array_options [ 'options_' . $key ], 'dayrfc' );
2020-05-07 15:37:32 +02:00
} elseif ( $extrafields -> attribute_type [ $key ] == 'datetime' ) {
$datetime = $object -> array_options [ 'options_' . $key ];
2020-05-07 15:41:21 +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 ) : '' );
2020-05-07 15:37:32 +02:00
$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' ) : '' );
}
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 = '' ;
2019-02-03 22:58:56 +01:00
if ( empty ( $substitutionarray [ '__REF__' ]))
{
2019-11-11 23:59:36 +01:00
$paymenturl = '' ;
2019-02-03 22:58:56 +01:00
}
else
{
// 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' ;
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' ;
$url = getOnlinePaymentUrl ( 0 , $typeforonlinepayment , $substitutionarray [ '__REF__' ]);
$paymenturl = $url ;
2019-02-03 22:58:56 +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 ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +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 );
}
else $substitutionarray [ '__DIRECTDOWNLOAD_URL_PROPOSAL__' ] = '' ;
2019-11-11 23:59:36 +01:00
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 );
}
else $substitutionarray [ '__DIRECTDOWNLOAD_URL_ORDER__' ] = '' ;
2019-11-11 23:59:36 +01:00
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 );
}
else $substitutionarray [ '__DIRECTDOWNLOAD_URL_INVOICE__' ] = '' ;
2020-03-02 19:23:45 +01:00
2020-03-12 12:45:44 +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 ;
2019-02-03 22:58:56 +01:00
}
}
}
2019-11-11 23:59:36 +01:00
if ( empty ( $exclude ) || ! in_array ( 'objectamount' , $exclude ))
2019-02-03 22:58:56 +01:00
{
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
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__AMOUNT__' ] = is_object ( $object ) ? $object -> total_ttc : '' ;
$substitutionarray [ '__AMOUNT_EXCL_TAX__' ] = is_object ( $object ) ? $object -> total_ht : '' ;
$substitutionarray [ '__AMOUNT_VAT__' ] = is_object ( $object ) ? ( $object -> total_vat ? $object -> total_vat : $object -> total_tva ) : '' ;
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
2019-11-11 23:59:36 +01:00
$substitutionarray [ '__AMOUNT_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_ttc ? price ( $object -> total_ttc , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : null ) : '' ;
$substitutionarray [ '__AMOUNT_EXCL_TAX_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_ht ? price ( $object -> total_ht , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : null ) : '' ;
$substitutionarray [ '__AMOUNT_VAT_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_vat ? price ( $object -> total_vat , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : ( $object -> total_tva ? price ( $object -> total_tva , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : null )) : '' ;
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 1 )) $substitutionarray [ '__AMOUNT_TAX2_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_localtax1 ? price ( $object -> total_localtax1 , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : null ) : '' ;
if ( $onlykey != 2 || $mysoc -> useLocalTax ( 2 )) $substitutionarray [ '__AMOUNT_TAX3_FORMATED__' ] = is_object ( $object ) ? ( $object -> total_localtax2 ? price ( $object -> total_localtax2 , 0 , $outputlangs , 0 , 0 , - 1 , $conf -> currency ) : null ) : '' ;
2019-02-03 22:58:56 +01:00
// TODO Add keys for foreign multicurrency
// For backward compatibility
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 : '' ;
$substitutionarray [ '__TOTAL_VAT__' ] = is_object ( $object ) ? ( $object -> total_vat ? $object -> total_vat : $object -> total_tva ) : '' ;
2019-02-03 22:58:56 +01:00
}
}
//var_dump($substitutionarray['__AMOUNT_FORMATED__']);
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
$substitutionarray = array_merge ( $substitutionarray , array (
2019-02-03 22:58:56 +01:00
'__DAY__' => ( string ) $tmp [ 'mday' ],
2019-11-11 23:59:36 +01:00
'__DAY_TEXT__' => $outputlangs -> trans ( 'Day' . $tmp [ 'wday' ]), // Monday
'__DAY_TEXT_SHORT__' => $outputlangs -> trans ( $tmp [ 'weekday' ] . 'Min' ), // Mon
'__DAY_TEXT_MIN__' => $outputlangs -> trans ( 'Short' . $tmp [ 'weekday' ]), // 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 ),
));
}
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> multicompany -> enabled ))
2019-02-03 22:58:56 +01:00
{
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
}
2019-11-11 23:59:36 +01:00
if ( empty ( $exclude ) || ! in_array ( 'system' , $exclude ))
2019-02-03 22:58:56 +01:00
{
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 );
*
* @ 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
* @ 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
*/
function make_substitutions ( $text , $substitutionarray , $outputlangs = null )
{
global $conf , $langs ;
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $substitutionarray )) return 'ErrorBadParameterSubstitutionArrayWhenCalling_make_substitutions' ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( empty ( $outputlangs )) $outputlangs = $langs ;
2019-02-03 22:58:56 +01:00
2019-04-25 17:37:54 +02:00
// Make substitution for language keys: __(AnyTranslationKey)__ or __(AnyTranslationKey|langfile)__
2019-02-03 22:58:56 +01:00
if ( is_object ( $outputlangs ))
{
2020-03-17 13:33:21 +01:00
$reg = array ();
2019-02-03 22:58:56 +01:00
while ( preg_match ( '/__\(([^\)]+)\)__/' , $text , $reg ))
{
$msgishtml = 0 ;
if ( dol_textishtml ( $text , 1 )) $msgishtml = 1 ;
// If key is __(TranslationKey|langfile)__, then force load of langfile.lang
2019-11-11 23:59:36 +01:00
$tmp = explode ( '|' , $reg [ 1 ]);
if ( ! empty ( $tmp [ 1 ])) $outputlangs -> load ( $tmp [ 1 ]);
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$text = preg_replace ( '/__\(' . preg_quote ( $reg [ 1 ], '/' ) . '\)__/' , $msgishtml ? dol_htmlentitiesbr ( $outputlangs -> transnoentitiesnoconv ( $reg [ 1 ])) : $outputlangs -> transnoentitiesnoconv ( $reg [ 1 ]), $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 ();
2019-02-03 22:58:56 +01:00
while ( preg_match ( '/__\[([^\]]+)\]__/' , $text , $reg ))
{
$msgishtml = 0 ;
if ( dol_textishtml ( $text , 1 )) $msgishtml = 1 ;
$keyfound = $reg [ 1 ];
2020-05-06 04:03:07 +02:00
if ( preg_match ( '/(_pass|_pw|password|secret|_key|key$)/i' , $keyfound )) $newval = '*****forbidden*****' ;
2019-11-11 23:59:36 +01:00
else $newval = empty ( $conf -> global -> $keyfound ) ? '' : $conf -> global -> $keyfound ;
$text = preg_replace ( '/__\[' . preg_quote ( $keyfound , '/' ) . '\]__/' , $msgishtml ? dol_htmlentitiesbr ( $newval ) : $newval , $text );
2019-02-03 22:58:56 +01:00
}
// Make substitition for array $substitutionarray
foreach ( $substitutionarray as $key => $value )
{
2019-11-11 23:59:36 +01:00
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
2019-11-11 23:59:36 +01:00
if ( $key == '__SIGNATURE__' && ( ! empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN ))) $value = '' ; // Protection
if ( $key == '__USER_SIGNATURE__' && ( ! empty ( $conf -> global -> MAIN_MAIL_DO_NOT_USE_SIGN ))) $value = '' ; // Protection
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$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' ;
// Add a substitution key for each extrafields, using key __EXTRA_XXX__
// TODO Remove this. Already available into the getCommonSubstitutionArray used to build the substitution array.
/* if ( is_object ( $object ) && is_array ( $object -> array_options ))
{
foreach ( $object -> array_options as $key => $val )
{
$keyshort = preg_replace ( '/^(options|extra)_/' , '' , $key );
$substitutionarray [ '__EXTRAFIELD_' . $keyshort . '__' ] = $val ;
// For backward compatibiliy
$substitutionarray [ '%EXTRA_' . $keyshort . '%' ] = $val ;
}
} */
// 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
2019-11-11 23:59:36 +01:00
foreach ( $dirsubstitutions as $reldir )
2019-02-03 22:58:56 +01:00
{
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
2019-11-11 23:59:36 +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_' );
foreach ( $substitfiles as $substitfile )
2019-02-03 22:58:56 +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 ;
2019-02-03 22:58:56 +01:00
if ( function_exists ( $function_name )) $function_name ( $substitutionarray , $outputlangs , $object , $parameters );
}
}
}
}
/**
* 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
* @ param integer $withparenthesis 1 = Add parenthesis , 0 = non parenthesis
* @ 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
2019-11-11 23:59:36 +01:00
if ( ! is_object ( $outputlangs )) $outputlangs = $langs ;
2019-02-03 22:58:56 +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
}
2019-11-11 23:59:36 +01:00
if ( $date_start && ! $date_end )
2019-02-03 22:58:56 +01:00
{
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
}
2019-11-11 23:59:36 +01:00
if ( ! $date_start && $date_end )
2019-02-03 22:58:56 +01:00
{
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
* @ param int $nameorder - 1 = Auto , 0 = Lastname + Firstname , 1 = Firstname + Lastname , 2 = Firstname , 3 = Firstname if defined else lastname
* @ 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
2019-11-11 23:59:36 +01:00
if ( $nameorder < 0 ) $nameorder = ( empty ( $conf -> global -> MAIN_FIRSTNAME_NAME_POSITION ) ? 1 : 0 );
2019-02-03 22:58:56 +01:00
if ( $nameorder && $nameorder != 2 && $nameorder != 3 )
{
2019-11-11 23:59:36 +01:00
$ret .= $firstname ;
if ( $firstname && $lastname ) $ret .= ' ' ;
$ret .= $lastname ;
2019-02-03 22:58:56 +01:00
}
elseif ( $nameorder == 2 || $nameorder == 3 )
{
2019-11-11 23:59:36 +01:00
$ret .= $firstname ;
2019-10-20 11:17:54 +02:00
if ( empty ( $ret ) && $nameorder == 3 )
{
2019-11-11 23:59:36 +01:00
$ret .= $lastname ;
2019-10-20 11:17:54 +02:00
}
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
$ret .= $lastname ;
if ( $firstname && $lastname ) $ret .= ' ' ;
$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 .
*
* @ param mixed $mesgs Message string or array
* @ param string $style Which style to use ( 'mesgs' by default , 'warnings' , 'errors' )
* @ 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
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $mesgs )) // If mesgs is a string
2019-02-03 22:58:56 +01:00
{
if ( $mesgs ) $_SESSION [ 'dol_events' ][ $style ][] = $mesgs ;
}
else // If mesgs is an array
{
2019-11-11 23:59:36 +01:00
foreach ( $mesgs as $mesg )
2019-02-03 22:58:56 +01:00
{
if ( $mesg ) $_SESSION [ 'dol_events' ][ $style ][] = $mesg ;
}
}
}
/**
* 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
{
if ( empty ( $mesg ) && empty ( $mesgs ))
{
dol_syslog ( " Try to add a message in stack with empty message " , LOG_WARNING );
}
else
{
2019-08-18 18:36:18 +02:00
if ( $messagekey )
{
// 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
}
if ( empty ( $messagekey ) || empty ( $_COOKIE [ " DOLHIDEMESSAGE " . $messagekey ]))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
if ( ! in_array (( string ) $style , array ( 'mesgs' , 'warnings' , 'errors' ))) dol_print_error ( '' , 'Bad parameter style=' . $style . ' for setEventMessages' );
2019-08-18 18:36:18 +02:00
if ( empty ( $mesgs )) setEventMessage ( $mesg , $style );
else
{
2019-11-11 23:59:36 +01:00
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' ])) {
if ( empty ( $disabledoutputofmessages )) dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'mesgs' ]);
unset ( $_SESSION [ 'dol_events' ][ 'mesgs' ]);
}
// Show errors
if ( isset ( $_SESSION [ 'dol_events' ][ 'errors' ])) {
if ( empty ( $disabledoutputofmessages )) dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'errors' ], 'error' );
unset ( $_SESSION [ 'dol_events' ][ 'errors' ]);
}
// Show warnings
if ( isset ( $_SESSION [ 'dol_events' ][ 'warnings' ])) {
if ( empty ( $disabledoutputofmessages )) dol_htmloutput_mesg ( '' , $_SESSION [ 'dol_events' ][ 'warnings' ], 'warning' );
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 ;
2019-11-11 23:59:36 +01:00
$ret = 0 ; $return = '' ;
$out = '' ;
$divstart = $divend = '' ;
2019-02-03 22:58:56 +01:00
// If inline message with no format, we add it.
2019-11-11 23:59:36 +01:00
if (( empty ( $conf -> use_javascript_ajax ) || ! empty ( $conf -> global -> MAIN_DISABLE_JQUERY_JNOTIFY ) || $keepembedded ) && ! preg_match ( '/<div class=".*">/i' , $out ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$divstart = '<div class="' . $style . ' clearboth">' ;
$divend = '</div>' ;
2019-02-03 22:58:56 +01:00
}
if (( is_array ( $mesgarray ) && count ( $mesgarray )) || $mesgstring )
{
$langs -> load ( " errors " );
2019-11-11 23:59:36 +01:00
$out .= $divstart ;
2019-02-03 22:58:56 +01:00
if ( is_array ( $mesgarray ) && count ( $mesgarray ))
{
2019-11-11 23:59:36 +01:00
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 );
if ( $ret < count ( $mesgarray )) $out .= " <br> \n " ;
2019-02-03 22:58:56 +01:00
}
}
if ( $mesgstring )
{
$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
}
if ( $out )
{
2019-11-11 23:59:36 +01:00
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 > ' ;
}
else
{
$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 )
{
2019-11-11 23:59:36 +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 ;
2019-02-03 22:58:56 +01:00
if ( is_array ( $mesgarray ))
{
2019-11-11 23:59:36 +01:00
foreach ( $mesgarray as $val )
2019-02-03 22:58:56 +01:00
{
if ( $val && preg_match ( '/class="error"/i' , $val )) { $iserror ++ ; break ; }
if ( $val && preg_match ( '/class="warning"/i' , $val )) { $iswarning ++ ; break ; }
}
}
elseif ( $mesgstring && preg_match ( '/class="error"/i' , $mesgstring )) $iserror ++ ;
elseif ( $mesgstring && preg_match ( '/class="warning"/i' , $mesgstring )) $iswarning ++ ;
2019-11-11 23:59:36 +01:00
if ( $style == 'error' ) $iserror ++ ;
if ( $style == 'warning' ) $iswarning ++ ;
2019-02-03 22:58:56 +01:00
if ( $iserror || $iswarning )
{
// 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
if ( is_array ( $mesgarray ))
{
2019-11-11 23:59:36 +01:00
$newmesgarray = array ();
foreach ( $mesgarray as $val )
2019-02-03 22:58:56 +01:00
{
2019-08-01 15:42:44 +02:00
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 ;
2019-08-01 15:42:44 +02:00
}
else
{
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 );
2019-02-03 22:58:56 +01:00
}
else print get_htmloutput_mesg ( $mesgstring , $mesgarray , 'ok' , $keepembedded );
}
/**
* 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' )
* @ param int $natsort 1 = use " natural " sort ( natsort ), 0 = use " standard " sort ( asort )
* @ 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
if ( is_array ( $array ))
{
2019-11-11 23:59:36 +01:00
$sizearray = count ( $array );
if ( $sizearray > 0 )
2019-02-03 22:58:56 +01:00
{
$temp = array ();
2019-11-11 23:59:36 +01:00
foreach ( array_keys ( $array ) as $key )
2019-05-16 12:25:14 +02:00
{
if ( is_object ( $array [ $key ]))
{
2019-11-11 23:59:36 +01:00
$temp [ $key ] = $array [ $key ] -> $index ;
2019-05-16 12:25:14 +02:00
}
else
{
2019-11-11 23:59:36 +01:00
$temp [ $key ] = $array [ $key ][ $index ];
2019-05-16 12:25:14 +02:00
}
}
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( ! $natsort ) {
( $order == 'asc' ) ? asort ( $temp ) : arsort ( $temp );
2019-02-24 20:06:55 +01:00
} else {
( $case_sensitive ) ? natsort ( $temp ) : natcasesort ( $temp );
2019-11-11 23:59:36 +01:00
if ( $order != 'asc' ) $temp = array_reverse ( $temp , true );
2019-02-24 20:06:55 +01:00
}
2019-02-03 22:58:56 +01:00
$sorted = array ();
2019-11-11 23:59:36 +01:00
foreach ( array_keys ( $temp ) as $key )
2019-02-03 22:58:56 +01:00
{
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 )
{
// We must use here a binary strlen function (so not dol_strlen)
$strLength = dol_strlen ( $str );
2019-11-11 23:59:36 +01:00
for ( $i = 0 ; $i < $strLength ; $i ++ )
2019-02-03 22:58:56 +01:00
{
if ( ord ( $str [ $i ]) < 0x80 ) continue ; // 0bbbbbbb
2019-11-11 23:59:36 +01:00
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
2019-02-03 22:58:56 +01:00
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 ?
2019-02-03 22:58:56 +01:00
if (( ++ $i == strlen ( $str )) || (( ord ( $str [ $i ]) & 0xC0 ) != 0x80 ))
return false ;
}
}
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;
2020-02-13 10:44:08 +01:00
if ( ! mb_check_encoding ( $str , 'ASCII' )) return false ;
2020-02-06 12:58:02 +01:00
} else {
2020-02-13 10:44:08 +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
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
if ( $tmp == 'iso-8859-1' ) return utf8_decode ( $str );
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
if ( $key == '' ) return '' ;
// Check in cache
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 ) . " ' " ;
if ( ! empty ( $entityfilter ))
$sql .= " AND entity IN ( " . getEntity ( $tablename ) . " ) " ;
2019-02-03 22:58:56 +01:00
$resql = $db -> query ( $sql );
if ( $resql )
{
$obj = $db -> fetch_object ( $resql );
2019-11-11 23:59:36 +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 ];
}
else
{
return - 1 ;
}
}
/**
* Verify if condition in string is ok or not
*
* @ param string $strRights String with condition to check
* @ return boolean True or False . Return True if strRights is ''
*/
function verifCond ( $strRights )
{
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
//print $strRights."<br>\n";
$rights = true ;
if ( $strRights != '' )
{
2019-11-11 23:59:36 +01:00
$str = 'if(!(' . $strRights . ')) { $rights = false; }' ;
dol_eval ( $str ); // The dol_eval must contains all the global $xxx used into a condition
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 () .
*
* @ 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
* @ return mixed Nothing or return of eval
*/
function dol_eval ( $s , $returnvalue = 0 , $hideerrors = 1 )
{
// 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
//print $s."<br>\n";
if ( $returnvalue )
{
if ( $hideerrors ) return @ eval ( 'return ' . $s . ';' );
else return eval ( 'return ' . $s . ';' );
}
else
{
if ( $hideerrors ) @ eval ( $s );
else eval ( $s );
}
}
/**
* 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 ) != '' );
}
/**
* Return img flag of country for a language code or country code
*
* @ param string $codelang Language code ( en_IN , fr_CA ... ) or Country code ( IN , FR )
* @ param string $moreatt Add more attribute on img tag ( For example 'style="float: right"' )
* @ return string HTML img string with flag .
*/
function picto_from_langcode ( $codelang , $moreatt = '' )
{
global $langs ;
if ( empty ( $codelang )) return '' ;
if ( $codelang == 'auto' )
{
return '<span class="fa fa-globe"></span>' ;
}
$langtocountryflag = array (
'ar_AR' => '' ,
'ca_ES' => 'catalonia' ,
'da_DA' => 'dk' ,
'fr_CA' => 'mq' ,
'sv_SV' => 'se'
);
if ( isset ( $langtocountryflag [ $codelang ])) $flagImage = $langtocountryflag [ $codelang ];
else
{
$tmparray = explode ( '_' , $codelang );
$flagImage = empty ( $tmparray [ 1 ]) ? $tmparray [ 0 ] : $tmparray [ 1 ];
}
return img_picto_common ( $codelang , 'flags/' . strtolower ( $flagImage ) . '.png' , $moreatt );
}
/**
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
*
* @ param string $countrycode Country code like 'US' , 'FR' , 'CA' , ...
* @ return string Value of locale like 'en_US' , 'fr_FR' , ...
*/
function getLanguageCodeFromCountryCode ( $countrycode )
{
global $mysoc ;
2019-02-28 13:11:14 +01:00
if ( empty ( $countrycode )) return null ;
2019-02-03 22:58:56 +01:00
if ( strtoupper ( $countrycode ) == 'MQ' ) return 'fr_CA' ;
2019-11-11 23:59:36 +01:00
if ( strtoupper ( $countrycode ) == 'SE' ) return 'sv_SE' ; // se_SE is Sami/Sweden, and we want in priority sv_SE for SE country
2019-02-03 22:58:56 +01:00
if ( strtoupper ( $countrycode ) == 'CH' )
{
if ( $mysoc -> country_code == 'FR' ) return 'fr_CH' ;
if ( $mysoc -> country_code == 'DE' ) return 'de_CH' ;
}
// 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' ,
'as-IN' ,
'ba-RU' ,
'be-BY' ,
'bg-BG' ,
'bn-BD' ,
'bn-IN' ,
'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' ,
'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' ,
'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 );
if ( in_array ( $buildprimarykeytotest , $locales )) return strtolower ( $countrycode ) . '_' . strtoupper ( $countrycode );
2019-06-30 16:19:26 +02:00
if ( function_exists ( 'locale_get_primary_language' ) && function_exists ( 'locale_get_region' )) // Need extension php-intl
2019-04-03 18:38:27 +02:00
{
foreach ( $locales as $locale )
{
$locale_language = locale_get_primary_language ( $locale );
$locale_region = locale_get_region ( $locale );
if ( strtoupper ( $countrycode ) == $locale_region )
{
//var_dump($locale.'-'.$locale_language.'-'.$locale_region);
return strtolower ( $locale_language ) . '_' . strtoupper ( $locale_region );
}
}
2018-11-21 15:40:15 +01:00
}
2019-04-03 18:39:27 +02:00
else
2019-02-03 22:58:56 +01:00
{
2019-04-03 18:39:27 +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' )
{
global $hookmanager ;
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
2019-11-11 23:59:36 +01:00
if ( $mode == 'add' && ! preg_match ( '/^\-/' , $values [ 1 ]))
2019-02-03 22:58:56 +01:00
{
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 );
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +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 [ 5 ]), 1 );
2019-02-03 22:58:56 +01:00
$head [ $h ][ 1 ] = $label ;
$head [ $h ][ 2 ] = str_replace ( '+' , '' , $values [ 1 ]);
$h ++ ;
}
}
elseif ( count ( $values ) == 5 ) // deprecated
{
dol_syslog ( 'Passing 5 values in tabs module_parts is deprecated. Please update to 6 with permissions.' , LOG_WARNING );
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 );
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +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 ++ ;
}
}
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 ]);
foreach ( $head as $key => $val )
2019-02-03 22:58:56 +01:00
{
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);
2019-11-11 23:59:36 +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
2019-11-11 23:59:36 +01:00
if ( ! empty ( $hookmanager ))
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$parameters = array ( 'object' => $object , 'mode' => $mode , 'head' => $head );
$reshook = $hookmanager -> executeHooks ( 'completeTabsHead' , $parameters );
2019-02-03 22:58:56 +01:00
if ( $reshook > 0 )
{
$head = $hookmanager -> resArray ;
$h = count ( $head );
}
}
}
/**
* 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 ;
if ( $zone == 'private' ) print " \n " . '<!-- Common footer for private page -->' . " \n " ;
else print " \n " . '<!-- Common footer for public page -->' . " \n " ;
// 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 " ;
2019-02-03 22:58:56 +01:00
print '<div id="page_y" style="display: none;">' . $_POST [ 'page_y' ] . '</div>' . " \n " ;
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
2019-02-03 22:58:56 +01:00
if ( empty ( $reshook ))
{
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_HTML_FOOTER )) print $conf -> global -> MAIN_HTML_FOOTER . " \n " ;
2019-02-03 22:58:56 +01:00
print " \n " ;
2019-11-11 23:59:36 +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 " ;
if ( $zone == 'private' && empty ( $conf -> dol_use_jmobile ))
{
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
if ( $action == 'create' || $action == 'edit' || ( empty ( $action ) && ( preg_match ( '/new\.php/' , $_SERVER [ " PHP_SELF " ]))))
{
print '/* JS CODE TO ENABLE to manage focus and mandatory form fields */' . " \n " ;
$relativepathstring = $_SERVER [ " PHP_SELF " ];
// Clean $relativepathstring
if ( constant ( 'DOL_URL_ROOT' )) $relativepathstring = preg_replace ( '/^' . preg_quote ( constant ( 'DOL_URL_ROOT' ), '/' ) . '/' , '' , $relativepathstring );
$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']));
2019-02-03 22:58:56 +01:00
if ( ! empty ( $user -> default_values [ $relativepathstring ][ 'focus' ]))
{
2019-11-11 23:59:36 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'focus' ] as $defkey => $defval )
2019-02-03 22:58:56 +01:00
{
$qualified = 0 ;
if ( $defkey != '_noquery_' )
{
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$foundintru = 0 ;
foreach ( $tmpqueryarraytohave as $tmpquerytohave )
2019-02-03 22:58:56 +01:00
{
2020-01-27 22:22:59 +01:00
$tmpquerytohaveparam = explode ( '=' , $tmpquerytohave );
//print "console.log('".$tmpquerytohaveparam[0]." ".$tmpquerytohaveparam[1]." ".GETPOST($tmpquerytohaveparam[0])."');";
if ( ! GETPOSTISSET ( $tmpquerytohaveparam [ 0 ]) || ( $tmpquerytohaveparam [ 1 ] != GETPOST ( $tmpquerytohaveparam [ 0 ]))) $foundintru = 1 ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
if ( ! $foundintru ) $qualified = 1 ;
2019-02-03 22:58:56 +01:00
//var_dump($defkey.'-'.$qualified);
}
else $qualified = 1 ;
if ( $qualified )
{
2019-11-11 23:59:36 +01:00
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
}
}
}
}
if ( ! empty ( $user -> default_values [ $relativepathstring ][ 'mandatory' ]))
{
2019-11-11 23:59:36 +01:00
foreach ( $user -> default_values [ $relativepathstring ][ 'mandatory' ] as $defkey => $defval )
2019-02-03 22:58:56 +01:00
{
$qualified = 0 ;
if ( $defkey != '_noquery_' )
{
2019-11-11 23:59:36 +01:00
$tmpqueryarraytohave = explode ( '&' , $defkey );
$foundintru = 0 ;
foreach ( $tmpqueryarraytohave as $tmpquerytohave )
2019-02-03 22:58:56 +01:00
{
2020-01-27 22:22:59 +01:00
$tmpquerytohaveparam = explode ( '=' , $tmpquerytohave );
//print "console.log('".$tmpquerytohaveparam[0]." ".$tmpquerytohaveparam[1]." ".GETPOST($tmpquerytohaveparam[0])."');";
if ( ! GETPOSTISSET ( $tmpquerytohaveparam [ 0 ]) || ( $tmpquerytohaveparam [ 1 ] != GETPOST ( $tmpquerytohaveparam [ 0 ]))) $foundintru = 1 ;
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
if ( ! $foundintru ) $qualified = 1 ;
2019-02-03 22:58:56 +01:00
//var_dump($defkey.'-'.$qualified);
}
else $qualified = 1 ;
if ( $qualified )
{
2019-11-11 23:59:36 +01:00
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 " ;
2019-11-11 23:59:36 +01:00
print 'jQuery("select[name=\'' . $paramkey . '\']").prop(\'required\',true);' . " \n " ; // required on a select works only if key is "", this does not happen in Dolibarr
2019-02-03 22:58:56 +01:00
}
}
}
}
}
print '});' . " \n " ;
// End of tuning
2019-11-11 23:59:36 +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("' ;
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MEMCACHED_SERVER )) print 'MEMCACHED_SERVER=' . $conf -> global -> MEMCACHED_SERVER . ' - ' ;
print 'MAIN_OPTIMIZE_SPEED=' . ( isset ( $conf -> global -> MAIN_OPTIMIZE_SPEED ) ? $conf -> global -> MAIN_OPTIMIZE_SPEED : 'off' );
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
}
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
if ( ! empty ( $conf -> google -> enabled ) && ! empty ( $conf -> global -> MAIN_GOOGLE_AN_ID ))
{
$tmptagarray = explode ( ',' , $conf -> global -> MAIN_GOOGLE_AN_ID );
foreach ( $tmptagarray as $tmptag ) {
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
if ( defined ( 'XDEBUGCOVERAGE' ))
{
2019-03-23 14:37:54 +01: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
2019-11-11 23:59:36 +01:00
if ( ! empty ( $user -> rights -> debugbar -> read ) && is_object ( $debugbar ))
2019-03-23 14:37:54 +01:00
{
$debugbar [ 'time' ] -> stopMeasure ( 'pageaftermaster' );
print '<!-- Output debugbar data -->' . " \n " ;
print $debugbar -> getRenderer () -> render ();
}
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";
2019-11-11 23:59:36 +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 = '=' )
{
if ( $a = explode ( $delimiter , $string ))
{
$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 .
* @ return string HTML code to set focus
*/
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' )
* 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 '1,3,4' ) for search into a multiselect string ( '1,2' )
* @ param integer $nofirstand 1 = Do not output the first 'AND'
* @ return string $res The statement to append to the SQL query
*/
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
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
}
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 = '' ;
2019-11-11 23:59:36 +01:00
if ( ! is_array ( $fields )) $fields = array ( $fields );
2019-02-03 22:58:56 +01:00
$nboffields = count ( $fields );
$end2 = count ( $crits );
$j = 0 ;
foreach ( $crits as $crit )
{
$i = 0 ; $i2 = 0 ;
$newres = '' ;
foreach ( $fields as $field )
{
if ( $mode == 1 )
{
2019-11-11 23:59:36 +01:00
$operator = '=' ;
2019-02-03 22:58:56 +01:00
$newcrit = preg_replace ( '/([<>=]+)/' , '' , trim ( $crit ));
2020-01-09 22:14:39 +01:00
$reg = array ();
2019-02-03 22:58:56 +01:00
preg_match ( '/([<>=]+)/' , trim ( $crit ), $reg );
if ( $reg [ 1 ])
{
$operator = $reg [ 1 ];
}
if ( $newcrit != '' )
{
$numnewcrit = price2num ( $newcrit );
if ( is_numeric ( $numnewcrit ))
{
2019-11-11 23:59:36 +01:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . ' ' . $operator . ' ' . $numnewcrit ;
2019-02-03 22:58:56 +01: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
}
}
2019-08-28 16:06:19 +02:00
elseif ( $mode == 2 || $mode == - 2 )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . " " . ( $mode == - 2 ? 'NOT ' : '' ) . " IN ( " . $db -> escape ( trim ( $crit )) . " ) " ;
2019-08-28 16:06:19 +02:00
if ( $mode == - 2 ) $newres .= ' OR ' . $field . ' IS NULL' ;
2019-11-11 23:59:36 +01:00
$i2 ++ ; // a criteria was added to string
2019-02-03 22:58:56 +01:00
}
2019-08-28 16:06:19 +02:00
elseif ( $mode == 3 || $mode == - 3 )
2019-02-03 22:58:56 +01:00
{
2019-11-11 23:59:36 +01:00
$tmparray = explode ( ',' , trim ( $crit ));
2019-02-03 22:58:56 +01:00
if ( count ( $tmparray ))
{
2019-11-11 23:59:36 +01:00
$listofcodes = '' ;
foreach ( $tmparray as $val )
2019-02-03 22:58:56 +01:00
{
if ( $val )
{
2019-11-11 23:59:36 +01:00
$listofcodes .= ( $listofcodes ? ',' : '' );
$listofcodes .= " ' " . $db -> escape ( trim ( $val )) . " ' " ;
2019-02-03 22:58:56 +01:00
}
}
2019-11-11 23:59:36 +01:00
$newres .= ( $i2 > 0 ? ' OR ' : '' ) . $field . " " . ( $mode == - 3 ? 'NOT ' : '' ) . " IN ( " . $listofcodes . " ) " ;
$i2 ++ ; // a criteria was added to string
2019-02-03 22:58:56 +01:00
}
2019-08-28 16:06:19 +02:00
if ( $mode == - 3 ) $newres .= ' OR ' . $field . ' IS NULL' ;
2019-02-03 22:58:56 +01:00
}
elseif ( $mode == 4 )
{
2019-11-11 23:59:36 +01:00
$tmparray = explode ( ',' , trim ( $crit ));
2019-02-03 22:58:56 +01:00
if ( count ( $tmparray ))
{
2019-11-11 23:59:36 +01:00
$listofcodes = '' ;
foreach ( $tmparray as $val )
2019-02-03 22:58:56 +01:00
{
if ( $val )
{
2019-11-11 23:59:36 +01:00
$newres .= ( $i2 > 0 ? ' OR (' : '(' ) . $field . ' LIKE \'' . $db -> escape ( trim ( $val )) . ',%\'' ;
$newres .= ' OR ' . $field . ' = \'' . $db -> escape ( trim ( $val )) . '\'' ;
$newres .= ' OR ' . $field . ' LIKE \'%,' . $db -> escape ( trim ( $val )) . '\'' ;
$newres .= ' OR ' . $field . ' LIKE \'%,' . $db -> escape ( trim ( $val )) . ',%\'' ;
2019-02-03 22:58:56 +01:00
$newres .= ')' ;
$i2 ++ ;
}
}
}
}
else // $mode=0
{
$tmpcrits = explode ( '|' , $crit );
$i3 = 0 ;
2019-11-11 23:59:36 +01:00
foreach ( $tmpcrits as $tmpcrit )
2019-02-03 22:58:56 +01:00
{
2020-02-29 12:51:33 +01:00
if ( $tmpcrit !== '0' && empty ( $tmpcrit )) continue ;
2019-02-03 22:58:56 +01:00
$newres .= (( $i2 > 0 || $i3 > 0 ) ? ' OR ' : '' );
if ( preg_match ( '/\.(id|rowid)$/' , $field )) // Special case for rowid that is sometimes a ref so used as a search field
{
2019-11-11 23:59:36 +01:00
$newres .= $field . " = " . ( is_numeric ( trim ( $tmpcrit )) ? trim ( $tmpcrit ) : '0' );
2019-02-03 22:58:56 +01:00
}
else
{
2019-11-11 23:59:36 +01:00
$newres .= $field . " LIKE ' " ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$tmpcrit = trim ( $tmpcrit );
$tmpcrit2 = $tmpcrit ;
$tmpbefore = '%' ; $tmpafter = '%' ;
2019-02-03 22:58:56 +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 );
}
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 .= " ' " ;
if ( $tmpcrit2 == '' )
{
2019-11-11 23:59:36 +01: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 ++ ;
}
2019-11-11 23:59:36 +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 );
if ( $url )
{
2019-11-11 23:59:36 +01:00
$out .= img_picto ( '' , 'globe' ) . ' ' . $langs -> trans ( " DirectDownloadLink " ) . '<br>' ;
$out .= '<input type="text" id="directdownloadlink" class="quatrevingtpercent" value="' . $url . '">' ;
$out .= ajax_autoselect ( " directdownloadlink " , 0 );
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 );
2019-11-11 23:59:36 +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 );
2019-11-11 23:59:36 +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' : '' );
2020-06-03 14:05:18 +02:00
if ( empty ( $extImgTarget )) $extImgTarget = ( preg_match ( '/\.webp$/i' , $file ) ? '.webp' : '' );
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
if ( ! $extImgTarget ) return $file ;
2019-02-03 22:58:56 +01:00
2019-11-11 23:59:36 +01:00
$subdir = '' ;
2019-02-03 22:58:56 +01:00
if ( $extName ) $subdir = 'thumbs/' ;
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 ;
if ( empty ( $conf -> use_javascript_ajax )) return '' ;
2020-06-03 14:05:18 +02:00
$mime_preview = array ( 'bmp' , 'jpeg' , 'png' , 'gif' , 'tiff' , 'pdf' , 'plain' , 'css' , 'svg+xml' , 'webp' );
2019-02-03 22:58:56 +01:00
//$mime_preview[]='vnd.oasis.opendocument.presentation';
//$mime_preview[]='archive';
$num_mime = array_search ( dol_mimetype ( $relativepath , '' , 1 ), $mime_preview );
if ( $alldata == 1 )
{
2019-11-11 23:59:36 +01:00
if ( $num_mime !== false ) 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 ),);
2019-02-03 22:58:56 +01:00
else return array ();
}
// old behavior
2019-11-11 23:59:36 +01:00
if ( $num_mime !== false ) 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' )) . '\')' ;
2019-02-03 22:58:56 +01:00
else return '' ;
}
/**
* Make content of an input box selected when we click into input field .
*
2020-03-13 12:53:22 +01:00
* @ param string $htmlname Id of html object ( '#idvalue' or '.classvalue' )
2019-02-03 22:58:56 +01:00
* @ param string $addlink Add a 'link to' after
* @ return string
*/
function ajax_autoselect ( $htmlname , $addlink = '' )
{
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 > ' ;
2019-11-11 23:59:36 +01:00
if ( $addlink ) $out .= ' <a href="' . $addlink . '" target="_blank">' . $langs -> trans ( " Link " ) . '</a>' ;
2019-02-03 22:58:56 +01:00
return $out ;
}
/**
* Return mime type of a file
*
* @ 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 )
2019-03-11 01:01:15 +01:00
* @ see 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
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.txt$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.rtx$/i' , $tmpfile )) { $mime = 'text/richtext' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.csv$/i' , $tmpfile )) { $mime = 'text/csv' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.tsv$/i' , $tmpfile )) { $mime = 'text/tab-separated-values' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.(cf|conf|log)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.ini$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'ini' ; $famime = 'file-text-o' ; }
2019-12-02 13:53:28 +01:00
if ( preg_match ( '/\.md$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'md' ; $famime = 'file-text-o' ; }
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.css$/i' , $tmpfile )) { $mime = 'text/css' ; $imgmime = 'css.png' ; $srclang = 'css' ; $famime = 'file-text-o' ; }
2019-02-03 22:58:56 +01:00
// Certificate files
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(crt|cer|key|pub)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $famime = 'file-text-o' ; }
2019-12-02 13:53:28 +01:00
// XML based (HTML/XML/XAML)
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(html|htm|shtml)$/i' , $tmpfile )) { $mime = 'text/html' ; $imgmime = 'html.png' ; $srclang = 'html' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.(xml|xhtml)$/i' , $tmpfile )) { $mime = 'text/xml' ; $imgmime = 'other.png' ; $srclang = 'xml' ; $famime = 'file-text-o' ; }
2019-12-02 13:53:28 +01:00
if ( preg_match ( '/\.xaml$/i' , $tmpfile )) { $mime = 'text/xml' ; $imgmime = 'other.png' ; $srclang = 'xaml' ; $famime = 'file-text-o' ; }
2019-02-03 22:58:56 +01:00
// Languages
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.bas$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'bas' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.(c)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'c' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.(cpp)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'cpp' ; $famime = 'file-code-o' ; }
2020-02-13 10:44:08 +01:00
if ( preg_match ( '/\.cs$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'cs' ; $famime = 'file-code-o' ; }
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(h)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'h' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.(java|jsp)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'java' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.php([0-9]{1})?$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'php.png' ; $srclang = 'php' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.phtml$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'php.png' ; $srclang = 'php' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.(pl|pm)$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'pl.png' ; $srclang = 'perl' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.sql$/i' , $tmpfile )) { $mime = 'text/plain' ; $imgmime = 'text.png' ; $srclang = 'sql' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.js$/i' , $tmpfile )) { $mime = 'text/x-javascript' ; $imgmime = 'jscript.png' ; $srclang = 'js' ; $famime = 'file-code-o' ; }
2019-02-03 22:58:56 +01:00
// Open office
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.odp$/i' , $tmpfile )) { $mime = 'application/vnd.oasis.opendocument.presentation' ; $imgmime = 'ooffice.png' ; $famime = 'file-powerpoint-o' ; }
if ( preg_match ( '/\.ods$/i' , $tmpfile )) { $mime = 'application/vnd.oasis.opendocument.spreadsheet' ; $imgmime = 'ooffice.png' ; $famime = 'file-excel-o' ; }
if ( preg_match ( '/\.odt$/i' , $tmpfile )) { $mime = 'application/vnd.oasis.opendocument.text' ; $imgmime = 'ooffice.png' ; $famime = 'file-word-o' ; }
2019-02-03 22:58:56 +01:00
// MS Office
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.mdb$/i' , $tmpfile )) { $mime = 'application/msaccess' ; $imgmime = 'mdb.png' ; $famime = 'file-o' ; }
if ( preg_match ( '/\.doc(x|m)?$/i' , $tmpfile )) { $mime = 'application/msword' ; $imgmime = 'doc.png' ; $famime = 'file-word-o' ; }
if ( preg_match ( '/\.dot(x|m)?$/i' , $tmpfile )) { $mime = 'application/msword' ; $imgmime = 'doc.png' ; $famime = 'file-word-o' ; }
if ( preg_match ( '/\.xlt(x)?$/i' , $tmpfile )) { $mime = 'application/vnd.ms-excel' ; $imgmime = 'xls.png' ; $famime = 'file-excel-o' ; }
if ( preg_match ( '/\.xla(m)?$/i' , $tmpfile )) { $mime = 'application/vnd.ms-excel' ; $imgmime = 'xls.png' ; $famime = 'file-excel-o' ; }
if ( preg_match ( '/\.xls$/i' , $tmpfile )) { $mime = 'application/vnd.ms-excel' ; $imgmime = 'xls.png' ; $famime = 'file-excel-o' ; }
if ( preg_match ( '/\.xls(b|m|x)$/i' , $tmpfile )) { $mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ; $imgmime = 'xls.png' ; $famime = 'file-excel-o' ; }
if ( preg_match ( '/\.pps(m|x)?$/i' , $tmpfile )) { $mime = 'application/vnd.ms-powerpoint' ; $imgmime = 'ppt.png' ; $famime = 'file-powerpoint-o' ; }
if ( preg_match ( '/\.ppt(m|x)?$/i' , $tmpfile )) { $mime = 'application/x-mspowerpoint' ; $imgmime = 'ppt.png' ; $famime = 'file-powerpoint-o' ; }
2019-02-03 22:58:56 +01:00
// Other
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.pdf$/i' , $tmpfile )) { $mime = 'application/pdf' ; $imgmime = 'pdf.png' ; $famime = 'file-pdf-o' ; }
2019-02-03 22:58:56 +01:00
// Scripts
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.bat$/i' , $tmpfile )) { $mime = 'text/x-bat' ; $imgmime = 'script.png' ; $srclang = 'dos' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.sh$/i' , $tmpfile )) { $mime = 'text/x-sh' ; $imgmime = 'script.png' ; $srclang = 'bash' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.ksh$/i' , $tmpfile )) { $mime = 'text/x-ksh' ; $imgmime = 'script.png' ; $srclang = 'bash' ; $famime = 'file-code-o' ; }
if ( preg_match ( '/\.bash$/i' , $tmpfile )) { $mime = 'text/x-bash' ; $imgmime = 'script.png' ; $srclang = 'bash' ; $famime = 'file-code-o' ; }
2019-02-03 22:58:56 +01:00
// Images
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.ico$/i' , $tmpfile )) { $mime = 'image/x-icon' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.(jpg|jpeg)$/i' , $tmpfile )) { $mime = 'image/jpeg' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.png$/i' , $tmpfile )) { $mime = 'image/png' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.gif$/i' , $tmpfile )) { $mime = 'image/gif' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.bmp$/i' , $tmpfile )) { $mime = 'image/bmp' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.(tif|tiff)$/i' , $tmpfile )) { $mime = 'image/tiff' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
if ( preg_match ( '/\.svg$/i' , $tmpfile )) { $mime = 'image/svg+xml' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
2020-06-03 14:05:18 +02:00
if ( preg_match ( '/\.webp$/i' , $tmpfile )) { $mime = 'image/webp' ; $imgmime = 'image.png' ; $famime = 'file-image-o' ; }
2019-02-03 22:58:56 +01:00
// Calendar
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.vcs$/i' , $tmpfile )) { $mime = 'text/calendar' ; $imgmime = 'other.png' ; $famime = 'file-text-o' ; }
if ( preg_match ( '/\.ics$/i' , $tmpfile )) { $mime = 'text/calendar' ; $imgmime = 'other.png' ; $famime = 'file-text-o' ; }
2019-02-03 22:58:56 +01:00
// Other
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.torrent$/i' , $tmpfile )) { $mime = 'application/x-bittorrent' ; $imgmime = 'other.png' ; $famime = 'file-o' ; }
2019-02-03 22:58:56 +01:00
// Audio
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(mp3|ogg|au|wav|wma|mid)$/i' , $tmpfile )) { $mime = 'audio' ; $imgmime = 'audio.png' ; $famime = 'file-audio-o' ; }
2019-02-03 22:58:56 +01:00
// Video
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.ogv$/i' , $tmpfile )) { $mime = 'video/ogg' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
if ( preg_match ( '/\.webm$/i' , $tmpfile )) { $mime = 'video/webm' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
if ( preg_match ( '/\.avi$/i' , $tmpfile )) { $mime = 'video/x-msvideo' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
if ( preg_match ( '/\.divx$/i' , $tmpfile )) { $mime = 'video/divx' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
if ( preg_match ( '/\.xvid$/i' , $tmpfile )) { $mime = 'video/xvid' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
if ( preg_match ( '/\.(wmv|mpg|mpeg)$/i' , $tmpfile )) { $mime = 'video' ; $imgmime = 'video.png' ; $famime = 'file-video-o' ; }
2019-02-03 22:58:56 +01:00
// Archive
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(zip|rar|gz|tgz|z|cab|bz2|7z|tar|lzh)$/i' , $tmpfile )) { $mime = 'archive' ; $imgmime = 'archive.png' ; $famime = 'file-archive-o' ; } // application/xxx where zzz is zip, ...
2019-02-03 22:58:56 +01:00
// Exe
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(exe|com)$/i' , $tmpfile )) { $mime = 'application/octet-stream' ; $imgmime = 'other.png' ; $famime = 'file-o' ; }
2019-02-03 22:58:56 +01:00
// Lib
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.(dll|lib|o|so|a)$/i' , $tmpfile )) { $mime = 'library' ; $imgmime = 'library.png' ; $famime = 'file-o' ; }
2019-02-03 22:58:56 +01:00
// Err
2019-11-11 23:59:36 +01:00
if ( preg_match ( '/\.err$/i' , $tmpfile )) { $mime = 'error' ; $imgmime = 'error.png' ; $famime = 'file-text-o' ; }
2019-02-03 22:58:56 +01:00
// Return string
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
}
if ( $mode == 2 )
{
return $imgmime ;
}
if ( $mode == 3 )
{
return $srclang ;
}
if ( $mode == 4 )
{
return $famime ;
}
return $mime ;
}
/**
* Return value from dictionary
*
* @ param string $tablename name of dictionary
* @ param string $field the value to return
* @ param int $id id of line
* @ param bool $checkentity add filter on entity
* @ param string $rowidfield name of the column rowid
* @ return string
*/
function getDictvalue ( $tablename , $field , $id , $checkentity = false , $rowidfield = 'rowid' )
{
2019-11-11 23:59:36 +01:00
global $dictvalues , $db , $langs ;
2019-02-03 22:58:56 +01:00
if ( ! isset ( $dictvalues [ $tablename ]))
{
$dictvalues [ $tablename ] = array ();
2019-11-11 23:59:36 +01:00
$sql = 'SELECT * FROM ' . $tablename . ' WHERE 1' ; // Here select * is allowed as it is generic code and we don't have list of fields
if ( $checkentity ) $sql .= ' AND entity IN (0,' . getEntity ( $tablename ) . ')' ;
2019-02-03 22:58:56 +01:00
$resql = $db -> query ( $sql );
if ( $resql )
{
while ( $obj = $db -> fetch_object ( $resql ))
{
$dictvalues [ $tablename ][ $obj -> { $rowidfield }] = $obj ;
}
}
else
{
dol_print_error ( $db );
}
}
if ( ! empty ( $dictvalues [ $tablename ][ $id ])) return $dictvalues [ $tablename ][ $id ] -> { $field }; // Found
else // Not found
{
if ( $id > 0 ) return $id ;
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 )
{
2019-02-26 17:44:16 +01:00
$stringcolor = str_replace ( '#' , '' , $stringcolor );
2019-02-03 22:58:56 +01:00
$res = - 1 ;
if ( ! empty ( $stringcolor ))
{
$res = 0 ;
2019-11-11 23:59:36 +01:00
$tmp = explode ( ',' , $stringcolor );
2019-02-03 22:58:56 +01:00
if ( count ( $tmp ) > 1 ) // This is a comma RGB ('255','255','255')
{
$r = $tmp [ 0 ];
$g = $tmp [ 1 ];
$b = $tmp [ 2 ];
}
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
2019-02-03 22:58:56 +01:00
if ( $bright > 0.6 ) $res = 1 ;
}
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);
2019-11-11 23:59:36 +01:00
if ( empty ( $menuentry [ 'enabled' ])) return 0 ; // Entry disabled by condition
2019-02-03 22:58:56 +01:00
if ( $type_user && $menuentry [ 'module' ])
{
2019-11-11 23:59:36 +01:00
$tmploops = explode ( '|' , $menuentry [ 'module' ]);
$found = 0 ;
foreach ( $tmploops as $tmploop )
2019-02-03 22:58:56 +01:00
{
if ( in_array ( $tmploop , $listofmodulesforexternal )) {
$found ++ ; break ;
}
}
2019-11-11 23:59:36 +01:00
if ( ! $found ) return 0 ; // Entry is for menus all excluded to external users
2019-02-03 22:58:56 +01:00
}
2019-11-11 23:59:36 +01:00
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
{
2019-11-11 23:59:36 +01:00
$attr = array (
2019-12-07 17:41:13 +01:00
'class' => 'badge ' . ( ! empty ( $mode ) ? ' badge-' . $mode : '' ) . ( ! empty ( $type ) ? ' badge-' . $type : '' ) . ( empty ( $params [ 'css' ]) ? '' : ' ' . $params [ 'css' ])
2019-03-01 12:01:25 +01:00
);
2019-03-11 21:03:23 +01:00
2019-11-01 15:53:57 +01:00
if ( empty ( $html )) {
2019-03-01 15:33:23 +01:00
$html = $label ;
}
2019-03-11 21:03:23 +01:00
2019-11-01 15:53:57 +01:00
if ( ! empty ( $url )) {
2019-03-01 12:01:25 +01:00
$attr [ 'href' ] = $url ;
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
if ( $mode === 'dot' ) {
$attr [ 'class' ] .= ' classfortooltip' ;
2019-03-01 12:01:25 +01:00
$attr [ 'title' ] = $html ;
2019-03-01 15:33:23 +01:00
$attr [ 'aria-label' ] = $label ;
2019-11-11 23:59:36 +01:00
$html = '' ;
2019-03-01 12:01:25 +01:00
}
2019-03-11 21:03:23 +01:00
2019-03-01 12:01:25 +01:00
// Override attr
2019-11-01 15:53:57 +01:00
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
2019-11-11 23:59:36 +01:00
foreach ( $params [ 'attr' ] as $key => $value ) {
2019-12-07 17:41:13 +01:00
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
}
elseif ( $key == 'classOverride' ) {
$attr [ 'class' ] = $value ;
}
else {
$attr [ $key ] = $value ;
}
2019-03-01 12:01:25 +01:00
}
}
2019-03-01 15:33:23 +01:00
// TODO: add hook
2019-03-11 21:03:23 +01:00
2019-03-01 12:01:25 +01:00
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
2019-03-11 21:03:23 +01:00
2019-03-01 12:01:25 +01:00
$TCompiledAttr = array ();
2019-11-11 23:59:36 +01:00
foreach ( $attr as $key => $value ) {
2019-03-01 12:01:25 +01:00
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
$compiledAttributes = ! empty ( $TCompiledAttr ) ? implode ( ' ' , $TCompiledAttr ) : '' ;
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
$tag = ! empty ( $url ) ? 'a' : 'span' ;
2019-03-01 12:01:25 +01:00
return '<' . $tag . ' ' . $compiledAttributes . '>' . $html . '</' . $tag . '>' ;
}
/**
2019-03-11 21:03:23 +01:00
* Function dolGetStatus
*
* @ 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
* @ param array $params Various params for future : recommended rather than adding more function arguments
* @ 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
{
2019-03-01 15:33:23 +01:00
global $conf ;
2019-03-01 12:01:25 +01:00
2019-05-18 15:53:07 +02:00
$return = '' ;
2019-10-03 21:34:01 +02:00
$dolGetBadgeParams = array ();
2019-10-23 17:31:54 +02:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $params [ 'badgeParams' ])) {
2019-10-03 21:34:01 +02:00
$dolGetBadgeParams = $params [ 'badgeParams' ];
}
2019-03-01 15:33:23 +01:00
// TODO : add a hook
2019-03-11 21:03:23 +01:00
if ( $displayMode == 0 ) {
2019-11-11 23:59:36 +01:00
$return = ! empty ( $html ) ? $html : $statusLabel ;
2019-03-01 12:01:25 +01:00
}
2019-03-11 21:03:23 +01:00
elseif ( $displayMode == 1 ) {
2019-11-11 23:59:36 +01:00
$return = ! empty ( $html ) ? $html : ( ! empty ( $statusLabelShort ) ? $statusLabelShort : $statusLabel );
2019-03-05 16:58:05 +01:00
}
2019-11-01 15:53:57 +01:00
// Use status with images (for backward compatibility)
2019-11-11 23:59:36 +01:00
elseif ( ! empty ( $conf -> global -> MAIN_STATUS_USES_IMAGES )) {
2019-03-01 12:01:25 +01:00
$return = '' ;
2019-11-11 23:59:36 +01:00
$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>' : '' );
2019-03-11 21:03:23 +01:00
2019-11-01 15:53:57 +01:00
// For small screen, we always use the short label instead of long label.
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> dol_optimize_smallscreen ))
2019-10-23 17:31:54 +02:00
{
if ( $displayMode == 0 ) $displayMode = 1 ;
elseif ( $displayMode == 4 ) $displayMode = 2 ;
elseif ( $displayMode == 6 ) $displayMode = 5 ;
}
2019-11-01 12:52:03 +01:00
// For backward compatibility. Image's filename are still in French, so we use this array to convert
2019-11-11 23:59:36 +01:00
$statusImg = array (
2020-03-24 19:06:37 +01:00
'status0' => 'statut0' ,
'status1' => 'statut1' ,
'status2' => 'statut2' ,
'status3' => 'statut3' ,
'status4' => 'statut4' ,
'status5' => 'statut5' ,
'status6' => 'statut6' ,
'status7' => 'statut7' ,
'status8' => 'statut8' ,
'status9' => 'statut9'
2019-10-23 17:31:54 +02:00
);
2019-11-11 23:59:36 +01:00
if ( ! empty ( $statusImg [ $statusType ])) {
2019-03-01 12:01:25 +01:00
$htmlImg = img_picto ( $statusLabel , $statusImg [ $statusType ]);
2019-11-11 23:59:36 +01:00
} else {
2019-03-01 12:01:25 +01:00
$htmlImg = img_picto ( $statusLabel , $statusType );
}
2019-03-11 21:03:23 +01:00
if ( $displayMode === 2 ) {
2019-11-11 23:59:36 +01:00
$return = $htmlImg . ' ' . $htmlLabelShort ;
2019-03-01 12:01:25 +01:00
}
2019-03-11 21:03:23 +01:00
elseif ( $displayMode === 3 ) {
2019-03-01 12:01:25 +01:00
$return = $htmlImg ;
}
2019-03-11 21:03:23 +01:00
elseif ( $displayMode === 4 ) {
2019-11-11 23:59:36 +01:00
$return = $htmlImg . ' ' . $htmlLabel ;
2019-03-01 12:01:25 +01:00
}
2019-03-11 21:03:23 +01:00
elseif ( $displayMode === 5 ) {
2019-11-11 23:59:36 +01:00
$return = $htmlLabelShort . ' ' . $htmlImg ;
2019-03-05 16:58:05 +01:00
}
2019-03-11 21:03:23 +01:00
else { // $displayMode >= 6
2019-11-11 23:59:36 +01:00
$return = $htmlLabel . ' ' . $htmlImg ;
2019-03-01 12:01:25 +01:00
}
}
// Use new badge
2019-11-01 15:53:57 +01:00
elseif ( empty ( $conf -> global -> MAIN_STATUS_USES_IMAGES ) && ! empty ( $displayMode )) {
2019-11-11 23:59:36 +01:00
$statusLabelShort = ! empty ( $statusLabelShort ) ? $statusLabelShort : $statusLabel ;
2019-03-11 21:03:23 +01:00
2019-12-07 17:41:13 +01:00
$dolGetBadgeParams [ 'attr' ][ 'class' ] = 'badge-status' ;
2020-04-07 21:11:18 +02:00
$dolGetBadgeParams [ 'attr' ][ 'title' ] = $statusLabel ;
2019-12-07 17:41:13 +01:00
2019-03-15 20:39:55 +01:00
if ( $displayMode == 3 ) {
2019-10-03 21:34:01 +02:00
$return = dolGetBadge ( $statusLabel , '' , $statusType , 'dot' , $url , $dolGetBadgeParams );
2019-03-05 16:58:05 +01:00
}
2019-03-15 20:39:55 +01:00
elseif ( $displayMode === 5 ) {
2019-10-03 21:34:01 +02:00
$return = dolGetBadge ( $statusLabelShort , $html , $statusType , '' , $url , $dolGetBadgeParams );
2019-03-05 16:58:05 +01:00
}
2019-03-15 20:39:55 +01:00
else {
2019-10-03 21:34:01 +02:00
$return = dolGetBadge ( $statusLabel , $html , $statusType , '' , $url , $dolGetBadgeParams );
2019-03-05 16:58:05 +01:00
}
2019-03-01 12:01:25 +01:00
}
2019-03-11 21:03:23 +01:00
2019-03-05 17:16:38 +01: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
*
* @ param string $label label of button no html : use in alt attribute for accessibility $html is not empty
* @ 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
* @ param array $params various params for future : recommended rather than adding more function arguments
* @ 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
{
2019-11-11 23:59:36 +01:00
$class = 'butAction' ;
if ( $actionType == 'danger' || $actionType == 'delete' ) {
$class = 'butActionDelete' ;
2019-03-01 15:33:23 +01:00
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
$attr = array (
2019-03-01 15:33:23 +01:00
'class' => $class
2019-11-11 23:59:36 +01:00
, 'href' => empty ( $url ) ? '' : $url
2019-03-01 15:33:23 +01:00
);
2019-11-11 23:59:36 +01:00
if ( empty ( $html )) {
2019-03-01 15:33:23 +01:00
$html = $label ;
2019-11-11 23:59:36 +01:00
} else {
2019-03-01 15:33:23 +01:00
$attr [ 'aria-label' ] = $label ;
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
if ( empty ( $userRight )) {
2019-03-01 15:33:23 +01:00
$attr [ 'class' ] = 'butActionRefused' ;
$attr [ 'href' ] = '' ;
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $id )) {
2019-03-01 15:33:23 +01:00
$attr [ 'id' ] = $id ;
}
2019-03-11 21:03:23 +01:00
2019-03-01 15:33:23 +01:00
// Override attr
2019-11-11 23:59:36 +01:00
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
foreach ( $params [ 'attr' ] as $key => $value ) {
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
2019-06-13 22:11:47 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( $key == 'classOverride' ) {
2019-06-13 22:11:47 +02:00
$attr [ 'class' ] = $value ;
}
2019-11-11 23:59:36 +01:00
else {
2019-06-13 22:11:47 +02:00
$attr [ $key ] = $value ;
}
2019-03-01 15:33:23 +01:00
}
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
if ( isset ( $attr [ 'href' ]) && empty ( $attr [ 'href' ])) {
2019-03-01 15:33:23 +01:00
unset ( $attr [ 'href' ]);
}
2019-03-11 21:03:23 +01:00
2019-03-01 15:33:23 +01:00
// TODO : add a hook
2019-03-11 21:03:23 +01:00
2019-03-01 15:33:23 +01:00
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
2019-03-11 21:03:23 +01:00
2019-03-01 15:33:23 +01:00
$TCompiledAttr = array ();
2019-11-11 23:59:36 +01:00
foreach ( $attr as $key => $value ) {
2019-03-01 15:33:23 +01:00
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
$compiledAttributes = ! empty ( $TCompiledAttr ) ? implode ( ' ' , $TCompiledAttr ) : '' ;
2019-03-11 21:03:23 +01:00
2019-11-11 23:59:36 +01:00
$tag = ! empty ( $attr [ 'href' ]) ? 'a' : 'span' ;
2019-03-11 21:03:23 +01:00
2019-03-01 15:33:23 +01:00
return '<div class="inline-block divButAction"><' . $tag . ' ' . $compiledAttributes . '>' . $html . '</' . $tag . '></div>' ;
}
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
2019-04-16 21:49:26 +02:00
* @ param int $status 0 no user rights , 1 active , - 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
{
2019-04-16 21:49:26 +02:00
global $langs , $conf , $user ;
// Actually this conf is used in css too for external module compatibility and smooth transition to this function
2019-11-11 23:59:36 +01:00
if ( ! empty ( $conf -> global -> MAIN_BUTTON_HIDE_UNAUTHORIZED ) && ( ! $user -> admin ) && $status <= 0 ) {
2019-04-16 21:49:26 +02:00
return '' ;
}
2019-04-15 00:21:58 +02:00
2019-09-30 17:46:53 +02:00
$class = 'btnTitle' ;
2020-05-11 11:53:13 +02:00
if ( $iconClass == 'fa fa-plus-circle' ) $class .= ' btnTitlePlus' ;
2019-12-04 15:09:20 +01:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $params [ 'morecss' ])) $class .= ' ' . $params [ 'morecss' ];
2019-04-16 21:49:26 +02:00
2019-11-11 23:59:36 +01:00
$attr = array (
2019-04-15 00:21:58 +02:00
'class' => $class
2019-11-11 23:59:36 +01:00
, 'href' => empty ( $url ) ? '' : $url
2019-04-15 00:21:58 +02:00
);
2019-11-11 23:59:36 +01:00
if ( ! empty ( $helpText )) {
2019-04-15 00:21:58 +02:00
$attr [ 'title' ] = dol_escape_htmltag ( $helpText );
}
2019-11-11 23:59:36 +01:00
if ( $status <= 0 ) {
2019-04-16 22:02:23 +02:00
$attr [ 'class' ] .= ' refused' ;
2019-04-16 21:49:26 +02:00
2019-04-16 09:09:25 +02:00
$attr [ 'href' ] = '' ;
2019-04-16 21:49:26 +02:00
2019-11-11 23:59:36 +01:00
if ( $status == - 1 ) { // disable
2019-04-16 21:49:26 +02:00
$attr [ 'title' ] = dol_escape_htmltag ( $langs -> transnoentitiesnoconv ( " FeatureDisabled " ));
}
2019-11-11 23:59:36 +01:00
elseif ( $status == 0 ) { // Not enough permissions
2019-04-16 21:49:26 +02:00
$attr [ 'title' ] = dol_escape_htmltag ( $langs -> transnoentitiesnoconv ( " NotEnoughPermissions " ));
}
2019-04-16 09:09:25 +02:00
}
2019-04-15 00:21:58 +02:00
2019-11-11 23:59:36 +01:00
if ( ! empty ( $attr [ 'title' ])) {
2019-04-15 00:21:58 +02:00
$attr [ 'class' ] .= ' classfortooltip' ;
}
2019-11-11 23:59:36 +01:00
if ( empty ( $id )) {
2019-04-15 00:21:58 +02:00
$attr [ 'id' ] = $id ;
}
// Override attr
2019-11-11 23:59:36 +01:00
if ( ! empty ( $params [ 'attr' ]) && is_array ( $params [ 'attr' ])) {
foreach ( $params [ 'attr' ] as $key => $value ) {
if ( $key == 'class' ) {
$attr [ 'class' ] .= ' ' . $value ;
2019-04-15 00:21:58 +02:00
}
2019-11-11 23:59:36 +01:00
elseif ( $key == 'classOverride' ) {
2019-04-15 00:21:58 +02:00
$attr [ 'class' ] = $value ;
}
2019-11-11 23:59:36 +01:00
else {
2019-04-15 00:21:58 +02:00
$attr [ $key ] = $value ;
}
}
}
2019-11-11 23:59:36 +01:00
if ( isset ( $attr [ 'href' ]) && empty ( $attr [ 'href' ])) {
2019-04-15 00:21:58 +02:00
unset ( $attr [ 'href' ]);
}
// TODO : add a hook
// escape all attribute
$attr = array_map ( 'dol_escape_htmltag' , $attr );
$TCompiledAttr = array ();
2019-11-11 23:59:36 +01:00
foreach ( $attr as $key => $value ) {
2019-04-15 00:21:58 +02:00
$TCompiledAttr [] = $key . '="' . $value . '"' ;
}
2019-09-30 17:46:53 +02:00
$compiledAttributes = ( empty ( $TCompiledAttr ) ? '' : implode ( ' ' , $TCompiledAttr ));
2019-04-15 00:21:58 +02:00
2019-09-30 17:46:53 +02:00
$tag = ( empty ( $attr [ 'href' ]) ? 'span' : 'a' );
2019-04-15 00:21:58 +02:00
2020-05-11 11:53:13 +02:00
$button = '' ;
$button .= '<' . $tag . ' ' . $compiledAttributes . ' >' ;
2019-11-11 23:59:36 +01:00
$button .= '<span class="' . $iconClass . ' valignmiddle btnTitle-icon"></span>' ;
2019-12-04 15:09:20 +01:00
$button .= '<span class="valignmiddle text-plus-circle btnTitle-label' . ( empty ( $params [ 'forcenohideoftext' ]) ? ' hideonsmartphone' : '' ) . '">' . $label . '</span>' ;
2019-11-11 23:59:36 +01:00
$button .= '</' . $tag . '>' ;
2019-04-15 00:21:58 +02:00
return $button ;
}
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' ) {
$classpath = 'livraison/class' ;
$subelement = 'livraison' ;
$module = 'livraison_bon' ;
}
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' ;
}
if ( empty ( $classfile )) $classfile = strtolower ( $subelement );
if ( empty ( $classname )) $classname = ucfirst ( $subelement );
if ( empty ( $classpath )) $classpath = $module . '/class' ;
$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 );
if ( is_array ( $element_prop ) && $conf -> { $element_prop [ 'module' ]} -> enabled )
{
dol_include_once ( '/' . $element_prop [ 'classpath' ] . '/' . $element_prop [ 'classfile' ] . '.class.php' );
$objecttmp = new $element_prop [ 'classname' ]( $db );
$ret = $objecttmp -> fetch ( $element_id , $element_ref );
if ( $ret >= 0 )
{
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 )
{
2020-06-17 13:42:38 +02: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 ))
2019-05-21 13:53:12 +02:00
{
return true ;
}
2020-06-17 14:45:15 +02:00
2019-05-21 13:53:12 +02:00
return false ;
}
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 ()
{
2019-12-01 10:20:11 +01:00
return $_SESSION [ 'newtoken' ];
}
2020-03-19 10:52:07 +01:00
/**
* Return the value of token currently saved into session with name 'token' .
*
* @ return string
*/
function currentToken ()
{
return $_SESSION [ 'token' ];
}