PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/core/lib/functions2.lib.php

https://github.com/asterix14/dolibarr
PHP | 1195 lines | 753 code | 138 blank | 304 comment | 199 complexity | 41ad5d7e0d98393eed79fa4815d13c19 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2008-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2008-2011 Regis Houssin <regis@dolibarr.fr>
  4. * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. * or see http://www.gnu.org/
  19. */
  20. /**
  21. * \file htdocs/core/lib/functions2.lib.php
  22. * \brief A set of functions for Dolibarr
  23. * This file contains all rare functions.
  24. */
  25. /**
  26. * Try to guess default paper format according to language into $langs
  27. *
  28. * @return string Defautl paper format code
  29. */
  30. function dol_getDefaultFormat()
  31. {
  32. global $langs;
  33. $selected='EUA4';
  34. if ($langs->defaultlang == 'ca_CA') $selected='CAP4'; // Canada
  35. if ($langs->defaultlang == 'en_US') $selected='USLetter'; // US
  36. return $selected;
  37. }
  38. /**
  39. * Output content of a file $filename in version of current language (otherwise may use an alternate language)
  40. *
  41. * @param langs Object language to use for output
  42. * @param filename Relative filename to output
  43. * @param searchalt 1=Search also in alternative languages
  44. * @return boolean
  45. */
  46. function dol_print_file($langs,$filename,$searchalt=0)
  47. {
  48. global $conf;
  49. // Test if file is in lang directory
  50. foreach($langs->dir as $searchdir)
  51. {
  52. $formfile=($searchdir."/langs/".$langs->defaultlang."/".$filename);
  53. dol_syslog('functions2::dol_print_file search file '.$formfile, LOG_DEBUG);
  54. if (is_readable($formfile))
  55. {
  56. $content=file_get_contents($formfile);
  57. $isutf8=utf8_check($content);
  58. if (! $isutf8 && $conf->file->character_set_client == 'UTF-8') print utf8_encode($content);
  59. elseif ($isutf8 && $conf->file->character_set_client == 'ISO-8859-1') print utf8_decode($content);
  60. else print $content;
  61. return true;
  62. }
  63. else dol_syslog('functions2::dol_print_file not found', LOG_DEBUG);
  64. if ($searchalt) {
  65. // Test si fichier dans repertoire de la langue alternative
  66. if ($langs->defaultlang != "en_US") $formfilealt = $searchdir."/langs/en_US/".$filename;
  67. else $formfilealt = $searchdir."/langs/fr_FR/".$filename;
  68. dol_syslog('functions2::dol_print_file search alt file '.$formfilealt, LOG_DEBUG);
  69. //print 'getcwd='.getcwd().' htmlfilealt='.$formfilealt.' X '.file_exists(getcwd().'/'.$formfilealt);
  70. if (is_readable($formfilealt))
  71. {
  72. $content=file_get_contents($formfilealt);
  73. $isutf8=utf8_check($content);
  74. if (! $isutf8 && $conf->file->character_set_client == 'UTF-8') print utf8_encode($content);
  75. elseif ($isutf8 && $conf->file->character_set_client == 'ISO-8859-1') print utf8_decode($content);
  76. else print $content;
  77. return true;
  78. }
  79. else dol_syslog('functions2::dol_print_file not found', LOG_DEBUG);
  80. }
  81. }
  82. return false;
  83. }
  84. /**
  85. * Show informations on an object
  86. *
  87. * @param object Objet to show
  88. */
  89. function dol_print_object_info($object)
  90. {
  91. global $langs,$db;
  92. $langs->load("other");
  93. // Import key
  94. if (isset($object->import_key))
  95. print $langs->trans("ImportedWithSet")." : " . $object->import_key . '<br>';
  96. // User creation
  97. if (isset($object->user_creation))
  98. {
  99. print $langs->trans("CreatedBy")." : ";
  100. if (is_object($object->user_creation))
  101. {
  102. print $object->user_creation->getNomUrl(1);
  103. }
  104. else
  105. {
  106. $userstatic=new User($db);
  107. $userstatic->fetch($object->user_creation);
  108. print $userstatic->getNomUrl(1);
  109. }
  110. print '<br>';
  111. }
  112. // Date
  113. if (isset($object->date_creation))
  114. print $langs->trans("DateCreation")." : " . dol_print_date($object->date_creation,"dayhourtext") . '<br>';
  115. // User change
  116. if (isset($object->user_modification))
  117. {
  118. print $langs->trans("ModifiedBy")." : ";
  119. if (is_object($object->user_modification))
  120. {
  121. print $object->user_modification->getNomUrl(1);
  122. }
  123. else
  124. {
  125. $userstatic=new User($db);
  126. $userstatic->fetch($object->user_modification);
  127. print $userstatic->getNomUrl(1);
  128. }
  129. print '<br>';
  130. }
  131. // Date
  132. if (isset($object->date_modification))
  133. print $langs->trans("DateLastModification")." : " . dol_print_date($object->date_modification,"dayhourtext") . '<br>';
  134. // User validation
  135. if (isset($object->user_validation))
  136. {
  137. print $langs->trans("ValidatedBy")." : ";
  138. if (is_object($object->user_validation))
  139. {
  140. print $object->user_validation->getNomUrl(1);
  141. }
  142. else
  143. {
  144. $userstatic=new User($db);
  145. $userstatic->fetch($object->user_validation);
  146. print $userstatic->getNomUrl(1);
  147. }
  148. print '<br>';
  149. }
  150. // Date
  151. if (isset($object->date_validation))
  152. print $langs->trans("DateValidation")." : " . dol_print_date($object->date_validation,"dayhourtext") . '<br>';
  153. // User close
  154. if (isset($object->user_cloture))
  155. {
  156. print $langs->trans("ClosedBy")." : ";
  157. if (is_object($object->user_cloture))
  158. {
  159. print $object->user_cloture->getNomUrl(1);
  160. }
  161. else
  162. {
  163. $userstatic=new User($db);
  164. $userstatic->fetch($object->user_cloture);
  165. print $userstatic->getNomUrl(1);
  166. }
  167. print '<br>';
  168. }
  169. // Date
  170. if (isset($object->date_cloture))
  171. print $langs->trans("DateClosing")." : " . dol_print_date($object->date_cloture,"dayhourtext") . '<br>';
  172. // User conciliate
  173. if (isset($object->user_rappro))
  174. {
  175. print $langs->trans("ConciliatedBy")." : ";
  176. if (is_object($object->user_rappro))
  177. {
  178. print $object->user_rappro->getNomUrl(1);
  179. }
  180. else
  181. {
  182. $userstatic=new User($db);
  183. $userstatic->fetch($object->user_rappro);
  184. print $userstatic->getNomUrl(1);
  185. }
  186. print '<br>';
  187. }
  188. // Date
  189. if (isset($object->date_rappro))
  190. print $langs->trans("DateConciliating")." : " . dol_print_date($object->date_rappro,"dayhourtext") . '<br>';
  191. //Date send
  192. if (isset($object->date_envoi))
  193. print $langs->trans("DateLastSend")." : " . dol_print_date($object->date_envoi,"dayhourtext") . '<br>';
  194. }
  195. /**
  196. * Return true if email has a domain name that can't be resolved
  197. *
  198. * @param mail adresse email (Ex: "toto@titi.com", "John Do <johndo@titi.com>")
  199. * @return boolean true if domain email is OK, false if KO
  200. */
  201. function isValidMailDomain($mail)
  202. {
  203. list($user, $domain) = explode("@", $mail, 2);
  204. if (checkdnsrr($domain, "MX"))
  205. {
  206. return true;
  207. }
  208. else
  209. {
  210. return false;
  211. }
  212. }
  213. /**
  214. * Url string validation
  215. * <http[s]> :// [user[:pass]@] hostname [port] [/path] [?getquery] [anchor]
  216. *
  217. * @param url Url
  218. * @param http 1: verify http, 0: not verify http
  219. * @param pass 1: verify user and pass, 0: not verify user and pass
  220. * @param port 1: verify port, 0: not verify port
  221. * @param path 1: verify path, 0: not verify path
  222. * @param query 1: verify query, 0: not verify query
  223. * @param anchor 1: verify anchor, 0: not verify anchor
  224. * @return int 1=Check is OK, 0=Check is KO
  225. */
  226. function isValidUrl($url,$http=0,$pass=0,$port=0,$path=0,$query=0,$anchor=0)
  227. {
  228. $ValidUrl = 0;
  229. $urlregex = '';
  230. // SCHEME
  231. if ($http) $urlregex .= "^(http:\/\/|https:\/\/)";
  232. // USER AND PASS
  233. if ($pass) $urlregex .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)";
  234. // HOSTNAME OR IP
  235. //$urlregex .= "[a-z0-9+\$_-]+(\.[a-z0-9+\$_-]+)*"; // http://x = allowed (ex. http://localhost, http://routerlogin)
  236. //$urlregex .= "[a-z0-9+\$_-]+(\.[a-z0-9+\$_-]+)+"; // http://x.x = minimum
  237. $urlregex .= "([a-z0-9+\$_-]+\.)*[a-z0-9+\$_-]{2,3}"; // http://x.xx(x) = minimum
  238. //use only one of the above
  239. // PORT
  240. if ($port) $urlregex .= "(\:[0-9]{2,5})";
  241. // PATH
  242. if ($path) $urlregex .= "(\/([a-z0-9+\$_-]\.?)+)*\/";
  243. // GET Query
  244. if ($query) $urlregex .= "(\?[a-z+&\$_.-][a-z0-9;:@\/&%=+\$_.-]*)";
  245. // ANCHOR
  246. if ($anchor) $urlregex .= "(#[a-z_.-][a-z0-9+\$_.-]*)$";
  247. // check
  248. if (preg_match('/'.$urlregex.'/i', $url))
  249. {
  250. $ValidUrl = 1;
  251. }
  252. //print $urlregex.' - '.$url.' - '.$ValidUrl;exit;
  253. return $ValidUrl;
  254. }
  255. /**
  256. * Clean an url string
  257. *
  258. * @param url Url
  259. * @param http 1: keep http://, 0: remove also http://
  260. * @return string Cleaned url
  261. */
  262. function clean_url($url,$http=1)
  263. {
  264. // Fixed by Matelli (see http://matelli.fr/showcases/patchs-dolibarr/fix-cleaning-url.html)
  265. // To include the minus sign in a char class, we must not escape it but put it at the end of the class
  266. // Also, there's no need of escape a dot sign in a class
  267. if (preg_match('/^(https?:[\\/]+)?([0-9A-Z.-]+\.[A-Z]{2,4})(:[0-9]+)?/i',$url,$regs))
  268. {
  269. $proto=$regs[1];
  270. $domain=$regs[2];
  271. $port=$regs[3];
  272. //print $url." -> ".$proto." - ".$domain." - ".$port;
  273. //$url = dol_string_nospecial(trim($url));
  274. $url = trim($url);
  275. // Si http: defini on supprime le http (Si https on ne supprime pas)
  276. $newproto=$proto;
  277. if ($http==0)
  278. {
  279. if (preg_match('/^http:[\\/]+/i',$url))
  280. {
  281. $url = preg_replace('/^http:[\\/]+/i','',$url);
  282. $newproto = '';
  283. }
  284. }
  285. // On passe le nom de domaine en minuscule
  286. $CleanUrl = preg_replace('/^'.preg_quote($proto.$domain,'/').'/i', $newproto.strtolower($domain), $url);
  287. return $CleanUrl;
  288. }
  289. }
  290. /**
  291. * Return lines of an html table from an array
  292. * Used by array2table function only
  293. */
  294. function array2tr($data,$troptions='',$tdoptions=''){
  295. $text = '<tr '.$troptions.'>' ;
  296. foreach($data as $key => $item){
  297. $text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
  298. }
  299. $text.= '</tr>' ;
  300. return $text ;
  301. }
  302. /**
  303. * Return an html table from an array
  304. */
  305. function array2table($data,$tableMarkup=1,$tableoptions='',$troptions='',$tdoptions=''){
  306. $text='' ;
  307. if($tableMarkup) $text = '<table '.$tableoptions.'>' ;
  308. foreach($data as $key => $item){
  309. if(is_array($item)){
  310. $text.=array2tr($item,$troptions,$tdoptions);
  311. } else {
  312. $text.= '<tr '.$troptions.'>' ;
  313. $text.= '<td '.$tdoptions.'>'.$key.'</td>' ;
  314. $text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
  315. $text.= '</tr>' ;
  316. }
  317. }
  318. if($tableMarkup) $text.= '</table>' ;
  319. return $text ;
  320. }
  321. /**
  322. * Return next value for a mask
  323. *
  324. * @param $db Database handler
  325. * @param $mask Mask to use
  326. * @param $table Table containing field with counter
  327. * @param $field Field containing already used values of counter
  328. * @param $where To add a filter on selection (for exemple to filter on invoice types)
  329. * @param $objsoc The company that own the object we need a counter for
  330. * @param $date Date to use for the {y},{m},{d} tags.
  331. * @param $mode 'next' for next value or 'last' for last value
  332. * @return string New value
  333. */
  334. function get_next_value($db,$mask,$table,$field,$where='',$objsoc='',$date='',$mode='next')
  335. {
  336. global $conf;
  337. if (! is_object($objsoc)) $valueforccc=$objsoc;
  338. else $valueforccc=$objsoc->code_client;
  339. // Clean parameters
  340. if ($date == '') $date=mktime(); // We use local year and month of PHP server to search numbers
  341. // but we should use local year and month of user
  342. // Extract value for mask counter, mask raz and mask offset
  343. if (! preg_match('/\{(0+)([@\+][0-9]+)?([@\+][0-9]+)?\}/i',$mask,$reg)) return 'ErrorBadMask';
  344. $masktri=$reg[1].$reg[2].$reg[3];
  345. $maskcounter=$reg[1];
  346. $maskraz=-1;
  347. $maskoffset=0;
  348. if (dol_strlen($maskcounter) < 3) return 'CounterMustHaveMoreThan3Digits';
  349. // Extract value for third party mask counter
  350. if (preg_match('/\{(c+)(0*)\}/i',$mask,$regClientRef))
  351. {
  352. $maskrefclient=$regClientRef[1].$regClientRef[2];
  353. $maskrefclient_maskclientcode=$regClientRef[1];
  354. $maskrefclient_maskcounter=$regClientRef[2];
  355. $maskrefclient_maskoffset=0; //default value of maskrefclient_counter offset
  356. $maskrefclient_clientcode=substr($valueforccc,0,dol_strlen($maskrefclient_maskclientcode));//get n first characters of client code where n is length in mask
  357. $maskrefclient_clientcode=str_pad($maskrefclient_clientcode,dol_strlen($maskrefclient_maskclientcode),"#",STR_PAD_RIGHT);//padding maskrefclient_clientcode for having exactly n characters in maskrefclient_clientcode
  358. $maskrefclient_clientcode=dol_string_nospecial($maskrefclient_clientcode);//sanitize maskrefclient_clientcode for sql insert and sql select like
  359. if (dol_strlen($maskrefclient_maskcounter) > 0 && dol_strlen($maskrefclient_maskcounter) < 3) return 'CounterMustHaveMoreThan3Digits';
  360. }
  361. else $maskrefclient='';
  362. // Extract value for third party type
  363. if (preg_match('/\{(t+)\}/i',$mask,$regType))
  364. {
  365. $masktype=$regType[1];
  366. $masktype_value=substr(preg_replace('/^TE_/','',$objsoc->typent_code),0,dol_strlen($regType[1]));//get n first characters of client code where n is length in mask
  367. $masktype_value=str_pad($masktype_value,dol_strlen($regType[1]),"#",STR_PAD_RIGHT);
  368. }
  369. else $masktype='';
  370. $maskwithonlyymcode=$mask;
  371. $maskwithonlyymcode=preg_replace('/\{(0+)([@\+][0-9]+)?([@\+][0-9]+)?\}/i',$maskcounter,$maskwithonlyymcode);
  372. $maskwithonlyymcode=preg_replace('/\{dd\}/i','dd',$maskwithonlyymcode);
  373. $maskwithonlyymcode=preg_replace('/\{(c+)(0*)\}/i',$maskrefclient,$maskwithonlyymcode);
  374. $maskwithonlyymcode=preg_replace('/\{(t+)\}/i',$masktype_value,$maskwithonlyymcode);
  375. $maskwithnocode=$maskwithonlyymcode;
  376. $maskwithnocode=preg_replace('/\{yyyy\}/i','yyyy',$maskwithnocode);
  377. $maskwithnocode=preg_replace('/\{yy\}/i','yy',$maskwithnocode);
  378. $maskwithnocode=preg_replace('/\{y\}/i','y',$maskwithnocode);
  379. $maskwithnocode=preg_replace('/\{mm\}/i','mm',$maskwithnocode);
  380. // Now maskwithnocode = 0000ddmmyyyyccc for example
  381. // and maskcounter = 0000 for example
  382. //print "maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode."\n<br>";
  383. // If an offset is asked
  384. if (! empty($reg[2]) && preg_match('/^\+/',$reg[2])) $maskoffset=preg_replace('/^\+/','',$reg[2]);
  385. if (! empty($reg[3]) && preg_match('/^\+/',$reg[3])) $maskoffset=preg_replace('/^\+/','',$reg[3]);
  386. // Define $sqlwhere
  387. // If a restore to zero after a month is asked we check if there is already a value for this year.
  388. if (! empty($reg[2]) && preg_match('/^@/',$reg[2])) $maskraz=preg_replace('/^@/','',$reg[2]);
  389. if (! empty($reg[3]) && preg_match('/^@/',$reg[3])) $maskraz=preg_replace('/^@/','',$reg[3]);
  390. if ($maskraz >= 0)
  391. {
  392. if ($maskraz > 12) return 'ErrorBadMaskBadRazMonth';
  393. // Define posy, posm and reg
  394. if ($maskraz > 1)
  395. {
  396. if (! preg_match('/^(.*)\{(y+)\}\{(m+)\}/i',$maskwithonlyymcode)
  397. && ! preg_match('/^(.*)\{(m+)\}\{(y+)\}/i',$maskwithonlyymcode)) return 'ErrorCantUseRazInStartedYearIfNoYearMonthInMask';
  398. if (preg_match('/^(.*)\{(y+)\}\{(m+)\}/i',$maskwithonlyymcode,$reg)) { $posy=2; $posm=3; }
  399. elseif (preg_match('/^(.*)\{(m+)\}\{(y+)\}/i',$maskwithonlyymcode,$reg)) { $posy=3; $posm=2; }
  400. if (dol_strlen($reg[$posy]) < 2) return 'ErrorCantUseRazWithYearOnOneDigit';
  401. }
  402. else
  403. {
  404. if (! preg_match('/^(.*)\{(y+)\}/i',$maskwithonlyymcode)) return 'ErrorCantUseRazIfNoYearInMask';
  405. if (preg_match('/^(.*)\{(y+)\}/i',$maskwithonlyymcode,$reg)) { $posy=2; $posm=0; }
  406. }
  407. //print "x".$maskwithonlyymcode." ".$maskraz." ".$posy." ".$posm;
  408. // Define $yearcomp and $monthcomp (that will be use in the select where to search max number)
  409. $monthcomp=$maskraz;
  410. $yearoffset=0;
  411. $yearcomp=0;
  412. if (date("m",$date) < $maskraz) { $yearoffset=-1; } // If current month lower that month of return to zero, year is previous year
  413. if (dol_strlen($reg[$posy]) == 4) $yearcomp=sprintf("%04d",date("Y",$date)+$yearoffset);
  414. if (dol_strlen($reg[$posy]) == 2) $yearcomp=sprintf("%02d",date("y",$date)+$yearoffset);
  415. if (dol_strlen($reg[$posy]) == 1) $yearcomp=substr(date("y",$date),2,1)+$yearoffset;
  416. $sqlwhere='';
  417. $sqlwhere.='( (SUBSTRING('.$field.', '.(dol_strlen($reg[1])+1).', '.dol_strlen($reg[2]).') >= '.$yearcomp;
  418. if ($monthcomp > 1) // Test useless if monthcomp = 1 (or 0 is same as 1)
  419. {
  420. if (dol_strlen($reg[$posy]) == 4) $yearcomp1=sprintf("%04d",date("Y",$date)+$yearoffset+1);
  421. if (dol_strlen($reg[$posy]) == 2) $yearcomp1=sprintf("%02d",date("y",$date)+$yearoffset+1);
  422. // FIXME If mask is {mm}{yy}, sqlwhere is wrong here
  423. $sqlwhere.=' AND SUBSTRING('.$field.', '.(dol_strlen($reg[1])+dol_strlen($reg[2])+1).', '.dol_strlen($reg[3]).') >= '.$monthcomp.')';
  424. $sqlwhere.=' OR SUBSTRING('.$field.', '.(dol_strlen($reg[1])+1).', '.dol_strlen($reg[2]).') >= '.$yearcomp1.' )';
  425. }
  426. else
  427. {
  428. $sqlwhere.=') )';
  429. }
  430. }
  431. //print $sqlwhere;
  432. //print "masktri=".$masktri." maskcounter=".$maskcounter." maskraz=".$maskraz." maskoffset=".$maskoffset." yearcomp=".$yearcomp."<br>\n";
  433. // Define $sqlstring
  434. $posnumstart=strpos($maskwithnocode,$maskcounter); // Pos of counter in final string (from 0 to ...)
  435. if ($posnumstart < 0) return 'ErrorBadMaskFailedToLocatePosOfSequence';
  436. $sqlstring='SUBSTRING('.$field.', '.($posnumstart+1).', '.dol_strlen($maskcounter).')';
  437. //print "x".$sqlstring;
  438. // Define $maskLike
  439. $maskLike = dol_string_nospecial($mask);
  440. $maskLike = str_replace("%","_",$maskLike);
  441. // Replace protected special codes with matching number of _ as wild card caracter
  442. $maskLike = preg_replace('/\{yyyy\}/i','____',$maskLike);
  443. $maskLike = preg_replace('/\{yy\}/i','__',$maskLike);
  444. $maskLike = preg_replace('/\{y\}/i','_',$maskLike);
  445. $maskLike = preg_replace('/\{mm\}/i','__',$maskLike);
  446. $maskLike = preg_replace('/\{dd\}/i','__',$maskLike);
  447. $maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),str_pad("",dol_strlen($maskcounter),"_"),$maskLike);
  448. if ($maskrefclient) $maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),str_pad("",dol_strlen($maskrefclient),"_"),$maskLike);
  449. //if ($masktype) $maskLike = str_replace(dol_string_nospecial('{'.$masktype.'}'),str_pad("",dol_strlen($masktype),"_"),$maskLike);
  450. if ($masktype) $maskLike = str_replace(dol_string_nospecial('{'.$masktype.'}'),$masktype_value,$maskLike);
  451. // Get counter in database
  452. $counter=0;
  453. $sql = "SELECT MAX(".$sqlstring.") as val";
  454. $sql.= " FROM ".MAIN_DB_PREFIX.$table;
  455. // $sql.= " WHERE ".$field." not like '(%'";
  456. $sql.= " WHERE ".$field." LIKE '".$maskLike."'";
  457. $sql.= " AND ".$field." NOT LIKE '%PROV%'";
  458. $sql.= " AND entity = ".$conf->entity;
  459. if ($where) $sql.=$where;
  460. if ($sqlwhere) $sql.=' AND '.$sqlwhere;
  461. //print $sql.'<br>';
  462. dol_syslog("functions2::get_next_value sql=".$sql, LOG_DEBUG);
  463. $resql=$db->query($sql);
  464. if ($resql)
  465. {
  466. $obj = $db->fetch_object($resql);
  467. $counter = $obj->val;
  468. }
  469. else dol_print_error($db);
  470. if (empty($counter) || preg_match('/[^0-9]/i',$counter)) $counter=$maskoffset;
  471. if ($mode == 'last')
  472. {
  473. $counterpadded=str_pad($counter,dol_strlen($maskcounter),"0",STR_PAD_LEFT);
  474. // Define $maskLike
  475. $maskLike = dol_string_nospecial($mask);
  476. $maskLike = str_replace("%","_",$maskLike);
  477. // Replace protected special codes with matching number of _ as wild card caracter
  478. $maskLike = preg_replace('/\{yyyy\}/i','____',$maskLike);
  479. $maskLike = preg_replace('/\{yy\}/i','__',$maskLike);
  480. $maskLike = preg_replace('/\{y\}/i','_',$maskLike);
  481. $maskLike = preg_replace('/\{mm\}/i','__',$maskLike);
  482. $maskLike = preg_replace('/\{dd\}/i','__',$maskLike);
  483. $maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),$counterpadded,$maskLike);
  484. if ($maskrefclient) $maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),str_pad("",dol_strlen($maskrefclient),"_"),$maskLike);
  485. //if ($masktype) $maskLike = str_replace(dol_string_nospecial('{'.$masktype.'}'),str_pad("",dol_strlen($masktype),"_"),$maskLike);
  486. if ($masktype) $maskLike = str_replace(dol_string_nospecial('{'.$masktype.'}'),$masktype_value,$maskLike);
  487. $ref='';
  488. $sql = "SELECT facnumber as ref";
  489. $sql.= " FROM ".MAIN_DB_PREFIX."facture";
  490. $sql.= " WHERE facnumber LIKE '".$maskLike."'";
  491. $sql.= " AND entity = ".$conf->entity;
  492. dol_syslog("mod_facture_terre::getNextValue sql=".$sql);
  493. $resql=$db->query($sql);
  494. if ($resql)
  495. {
  496. $obj = $db->fetch_object($resql);
  497. if ($obj) $ref = $obj->ref;
  498. }
  499. else dol_print_error($db);
  500. $numFinal=$ref;
  501. }
  502. else if ($mode == 'next')
  503. {
  504. $counter++;
  505. if ($maskrefclient_maskcounter)
  506. {
  507. //print "maskrefclient_maskcounter=".$maskrefclient_maskcounter." maskwithnocode=".$maskwithnocode." maskrefclient=".$maskrefclient."\n<br>";
  508. // Define $sqlstring
  509. $maskrefclient_posnumstart=strpos($maskwithnocode,$maskrefclient_maskcounter,strpos($maskwithnocode,$maskrefclient)); // Pos of counter in final string (from 0 to ...)
  510. if ($maskrefclient_posnumstart <= 0) return 'ErrorBadMask';
  511. $maskrefclient_sqlstring='SUBSTRING('.$field.', '.($maskrefclient_posnumstart+1).', '.dol_strlen($maskrefclient_maskcounter).')';
  512. //print "x".$sqlstring;
  513. // Define $maskrefclient_maskLike
  514. $maskrefclient_maskLike = dol_string_nospecial($mask);
  515. $maskrefclient_maskLike = str_replace("%","_",$maskrefclient_maskLike);
  516. // Replace protected special codes with matching number of _ as wild card caracter
  517. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{yyyy}'),'____',$maskrefclient_maskLike);
  518. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{yy}'),'__',$maskrefclient_maskLike);
  519. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{y}'),'_',$maskrefclient_maskLike);
  520. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{mm}'),'__',$maskrefclient_maskLike);
  521. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{dd}'),'__',$maskrefclient_maskLike);
  522. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),str_pad("",dol_strlen($maskcounter),"_"),$maskrefclient_maskLike);
  523. $maskrefclient_maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),$maskrefclient_clientcode.str_pad("",dol_strlen($maskrefclient_maskcounter),"_"),$maskrefclient_maskLike);
  524. // Get counter in database
  525. $maskrefclient_counter=0;
  526. $maskrefclient_sql = "SELECT MAX(".$maskrefclient_sqlstring.") as val";
  527. $maskrefclient_sql.= " FROM ".MAIN_DB_PREFIX.$table;
  528. //$sql.= " WHERE ".$field." not like '(%'";
  529. $maskrefclient_sql.= " WHERE ".$field." LIKE '".$maskrefclient_maskLike."'";
  530. $maskrefclient_sql.= " AND entity = ".$conf->entity;
  531. if ($where) $maskrefclient_sql.=$where; //use the same optional where as general mask
  532. if ($sqlwhere) $maskrefclient_sql.=' AND '.$sqlwhere; //use the same sqlwhere as general mask
  533. $maskrefclient_sql.=' AND (SUBSTRING('.$field.', '.(strpos($maskwithnocode,$maskrefclient)+1).', '.dol_strlen($maskrefclient_maskclientcode).")='".$maskrefclient_clientcode."')";
  534. dol_syslog("functions2::get_next_value maskrefclient_sql=".$maskrefclient_sql, LOG_DEBUG);
  535. $maskrefclient_resql=$db->query($maskrefclient_sql);
  536. if ($maskrefclient_resql)
  537. {
  538. $maskrefclient_obj = $db->fetch_object($maskrefclient_resql);
  539. $maskrefclient_counter = $maskrefclient_obj->val;
  540. }
  541. else dol_print_error($db);
  542. if (empty($maskrefclient_counter) || preg_match('/[^0-9]/i',$maskrefclient_counter)) $maskrefclient_counter=$maskrefclient_maskoffset;
  543. $maskrefclient_counter++;
  544. }
  545. // Build numFinal
  546. $numFinal = $mask;
  547. // We replace special codes except refclient
  548. $numFinal = preg_replace('/\{yyyy\}/i',date("Y",$date),$numFinal);
  549. $numFinal = preg_replace('/\{yy\}/i',date("y",$date),$numFinal);
  550. $numFinal = preg_replace('/\{y\}/i' ,substr(date("y",$date),2,1),$numFinal);
  551. $numFinal = preg_replace('/\{mm\}/i',date("m",$date),$numFinal);
  552. $numFinal = preg_replace('/\{dd\}/i',date("d",$date),$numFinal);
  553. // Now we replace the counter
  554. $maskbefore='{'.$masktri.'}';
  555. $maskafter=str_pad($counter,dol_strlen($maskcounter),"0",STR_PAD_LEFT);
  556. //print 'x'.$maskbefore.'-'.$maskafter.'y';
  557. $numFinal = str_replace($maskbefore,$maskafter,$numFinal);
  558. // Now we replace the refclient
  559. if ($maskrefclient)
  560. {
  561. //print "maskrefclient=".$maskrefclient." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode."\n<br>";
  562. $maskrefclient_maskbefore='{'.$maskrefclient.'}';
  563. $maskrefclient_maskafter=$maskrefclient_clientcode.str_pad($maskrefclient_counter,dol_strlen($maskrefclient_maskcounter),"0",STR_PAD_LEFT);
  564. $numFinal = str_replace($maskrefclient_maskbefore,$maskrefclient_maskafter,$numFinal);
  565. }
  566. // Now we replace the type
  567. if ($masktype)
  568. {
  569. $masktype_maskbefore='{'.$masktype.'}';
  570. $masktype_maskafter=$masktype_value;
  571. $numFinal = str_replace($masktype_maskbefore,$masktype_maskafter,$numFinal);
  572. }
  573. }
  574. dol_syslog("functions2::get_next_value return ".$numFinal,LOG_DEBUG);
  575. return $numFinal;
  576. }
  577. /**
  578. * Check value
  579. *
  580. * @param $mask Mask to use
  581. * @param $value Value
  582. * @return int <0 if KO, 0 if OK
  583. */
  584. function check_value($mask,$value)
  585. {
  586. $result=0;
  587. // Extract value for mask counter, mask raz and mask offset
  588. if (! preg_match('/\{(0+)([@\+][0-9]+)?([@\+][0-9]+)?\}/i',$mask,$reg)) return 'ErrorBadMask';
  589. $masktri=$reg[1].(isset($reg[2])?$reg[2]:'').(isset($reg[3])?$reg[3]:'');
  590. $maskcounter=$reg[1];
  591. $maskraz=-1;
  592. $maskoffset=0;
  593. if (dol_strlen($maskcounter) < 3) return 'CounterMustHaveMoreThan3Digits';
  594. // Extract value for third party mask counter
  595. if (preg_match('/\{(c+)(0*)\}/i',$mask,$regClientRef))
  596. {
  597. $maskrefclient=$regClientRef[1].$regClientRef[2];
  598. $maskrefclient_maskclientcode=$regClientRef[1];
  599. $maskrefclient_maskcounter=$regClientRef[2];
  600. $maskrefclient_maskoffset=0; //default value of maskrefclient_counter offset
  601. $maskrefclient_clientcode=substr($valueforccc,0,dol_strlen($maskrefclient_maskclientcode));//get n first characters of client code to form maskrefclient_clientcode
  602. $maskrefclient_clientcode=str_pad($maskrefclient_clientcode,dol_strlen($maskrefclient_maskclientcode),"#",STR_PAD_RIGHT);//padding maskrefclient_clientcode for having exactly n characters in maskrefclient_clientcode
  603. $maskrefclient_clientcode=dol_string_nospecial($maskrefclient_clientcode);//sanitize maskrefclient_clientcode for sql insert and sql select like
  604. if (dol_strlen($maskrefclient_maskcounter) > 0 && dol_strlen($maskrefclient_maskcounter) < 3) return 'CounterMustHaveMoreThan3Digits';
  605. }
  606. else $maskrefclient='';
  607. $maskwithonlyymcode=$mask;
  608. $maskwithonlyymcode=preg_replace('/\{(0+)([@\+][0-9]+)?([@\+][0-9]+)?\}/i',$maskcounter,$maskwithonlyymcode);
  609. $maskwithonlyymcode=preg_replace('/\{dd\}/i','dd',$maskwithonlyymcode);
  610. $maskwithonlyymcode=preg_replace('/\{(c+)(0*)\}/i',$maskrefclient,$maskwithonlyymcode);
  611. $maskwithnocode=$maskwithonlyymcode;
  612. $maskwithnocode=preg_replace('/\{yyyy\}/i','yyyy',$maskwithnocode);
  613. $maskwithnocode=preg_replace('/\{yy\}/i','yy',$maskwithnocode);
  614. $maskwithnocode=preg_replace('/\{y\}/i','y',$maskwithnocode);
  615. $maskwithnocode=preg_replace('/\{mm\}/i','mm',$maskwithnocode);
  616. // Now maskwithnocode = 0000ddmmyyyyccc for example
  617. // and maskcounter = 0000 for example
  618. //print "maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode."\n<br>";
  619. // If an offset is asked
  620. if (! empty($reg[2]) && preg_match('/^\+/',$reg[2])) $maskoffset=preg_replace('/^\+/','',$reg[2]);
  621. if (! empty($reg[3]) && preg_match('^\+',$reg[3])) $maskoffset=preg_replace('/^\+/','',$reg[3]);
  622. // Define $sqlwhere
  623. // If a restore to zero after a month is asked we check if there is already a value for this year.
  624. if (! empty($reg[2]) && preg_match('/^@/',$reg[2])) $maskraz=preg_replace('/^@/','',$reg[2]);
  625. if (! empty($reg[3]) && preg_match('/^@/',$reg[3])) $maskraz=preg_replace('/^@/','',$reg[3]);
  626. if ($maskraz >= 0)
  627. {
  628. if ($maskraz > 12) return 'ErrorBadMaskBadRazMonth';
  629. // Define reg
  630. if ($maskraz > 1 && ! preg_match('/^(.*)\{(y+)\}\{(m+)\}/i',$maskwithonlyymcode,$reg)) return 'ErrorCantUseRazInStartedYearIfNoYearMonthInMask';
  631. if ($maskraz <= 1 && ! preg_match('/^(.*)\{(y+)\}/i',$maskwithonlyymcode,$reg)) return 'ErrorCantUseRazIfNoYearInMask';
  632. //print "x".$maskwithonlyymcode." ".$maskraz;
  633. }
  634. //print "masktri=".$masktri." maskcounter=".$maskcounter." maskraz=".$maskraz." maskoffset=".$maskoffset."<br>\n";
  635. // Check we have a number in ($posnumstart+1).', '.dol_strlen($maskcounter)
  636. //
  637. // Check length
  638. $len=dol_strlen($maskwithnocode);
  639. if (dol_strlen($value) != $len) $result=-1;
  640. // Define $maskLike
  641. $maskLike = dol_string_nospecial($mask);
  642. $maskLike = str_replace("%","_",$maskLike);
  643. // Replace protected special codes with matching number of _ as wild card caracter
  644. $maskLike = str_replace(dol_string_nospecial('{yyyy}'),'____',$maskLike);
  645. $maskLike = str_replace(dol_string_nospecial('{yy}'),'__',$maskLike);
  646. $maskLike = str_replace(dol_string_nospecial('{y}'),'_',$maskLike);
  647. $maskLike = str_replace(dol_string_nospecial('{mm}'),'__',$maskLike);
  648. $maskLike = str_replace(dol_string_nospecial('{dd}'),'__',$maskLike);
  649. $maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),str_pad("",dol_strlen($maskcounter),"_"),$maskLike);
  650. if ($maskrefclient) $maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),str_pad("",strlen($maskrefclient),"_"),$maskLike);
  651. dol_syslog("functions2::check_value result=".$result,LOG_DEBUG);
  652. return $result;
  653. }
  654. /**
  655. * Convert a binary data to string that represent hexadecimal value
  656. *
  657. * @param bin Value to convert
  658. * @param pad Add 0
  659. * @param upper Convert to tupper
  660. * @return string x
  661. */
  662. function binhex($bin, $pad=false, $upper=false)
  663. {
  664. $last = dol_strlen($bin)-1;
  665. for($i=0; $i<=$last; $i++){ $x += $bin[$last-$i] * pow(2,$i); }
  666. $x = dechex($x);
  667. if($pad){ while(dol_strlen($x) < intval(dol_strlen($bin))/4){ $x = "0$x"; } }
  668. if($upper){ $x = strtoupper($x); }
  669. return $x;
  670. }
  671. /**
  672. * Convert an hexadecimal string into a binary string
  673. *
  674. * @param hexa Hexadecimal string to convert (example: 'FF')
  675. * @return string bin
  676. */
  677. function hexbin($hexa)
  678. {
  679. $bin='';
  680. $strLength = dol_strlen($hexa);
  681. for($i=0;$i<$strLength;$i++)
  682. {
  683. $bin.=str_pad(decbin(hexdec($hexa{$i})),4,'0',STR_PAD_LEFT);
  684. }
  685. return $bin;
  686. }
  687. /**
  688. * Retourne le numero de la semaine par rapport a une date
  689. *
  690. * @param time Date au format 'timestamp'
  691. * @return int Numero de semaine
  692. */
  693. function numero_semaine($time)
  694. {
  695. $stime = strftime('%Y-%m-%d',$time);
  696. if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+)\s?([0-9]+)?:?([0-9]+)?/i',$stime,$reg))
  697. {
  698. // Date est au format 'YYYY-MM-DD' ou 'YYYY-MM-DD HH:MM:SS'
  699. $annee = $reg[1];
  700. $mois = $reg[2];
  701. $jour = $reg[3];
  702. }
  703. /*
  704. * Norme ISO-8601:
  705. * - La semaine 1 de toute annee est celle qui contient le 4 janvier ou que la semaine 1 de toute annee est celle qui contient le 1er jeudi de janvier.
  706. * - La majorite des annees ont 52 semaines mais les annees qui commence un jeudi et les annees bissextiles commencant un mercredi en possede 53.
  707. * - Le 1er jour de la semaine est le Lundi
  708. */
  709. // Definition du Jeudi de la semaine
  710. if (date("w",mktime(12,0,0,$mois,$jour,$annee))==0) // Dimanche
  711. $jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)-3*24*60*60;
  712. else if (date("w",mktime(12,0,0,$mois,$jour,$annee))<4) // du Lundi au Mercredi
  713. $jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)+(4-date("w",mktime(12,0,0,$mois,$jour,$annee)))*24*60*60;
  714. else if (date("w",mktime(12,0,0,$mois,$jour,$annee))>4) // du Vendredi au Samedi
  715. $jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee)-(date("w",mktime(12,0,0,$mois,$jour,$annee))-4)*24*60*60;
  716. else // Jeudi
  717. $jeudiSemaine = mktime(12,0,0,$mois,$jour,$annee);
  718. // Definition du premier Jeudi de l'annee
  719. if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==0) // Dimanche
  720. {
  721. $premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+4*24*60*60;
  722. }
  723. else if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))<4) // du Lundi au Mercredi
  724. {
  725. $premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+(4-date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine))))*24*60*60;
  726. }
  727. else if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))>4) // du Vendredi au Samedi
  728. {
  729. $premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine))+(7-(date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))-4))*24*60*60;
  730. }
  731. else // Jeudi
  732. {
  733. $premierJeudiAnnee = mktime(12,0,0,1,1,date("Y",$jeudiSemaine));
  734. }
  735. // Definition du numero de semaine: nb de jours entre "premier Jeudi de l'annee" et "Jeudi de la semaine";
  736. $numeroSemaine = (
  737. (
  738. date("z",mktime(12,0,0,date("m",$jeudiSemaine),date("d",$jeudiSemaine),date("Y",$jeudiSemaine)))
  739. -
  740. date("z",mktime(12,0,0,date("m",$premierJeudiAnnee),date("d",$premierJeudiAnnee),date("Y",$premierJeudiAnnee)))
  741. ) / 7
  742. ) + 1;
  743. // Cas particulier de la semaine 53
  744. if ($numeroSemaine==53)
  745. {
  746. // Les annees qui commence un Jeudi et les annees bissextiles commencant un Mercredi en possede 53
  747. if (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==4 || (date("w",mktime(12,0,0,1,1,date("Y",$jeudiSemaine)))==3 && date("z",mktime(12,0,0,12,31,date("Y",$jeudiSemaine)))==365))
  748. {
  749. $numeroSemaine = 53;
  750. }
  751. else
  752. {
  753. $numeroSemaine = 1;
  754. }
  755. }
  756. //echo $jour."-".$mois."-".$annee." (".date("d-m-Y",$premierJeudiAnnee)." - ".date("d-m-Y",$jeudiSemaine).") -> ".$numeroSemaine."<BR>";
  757. return sprintf("%02d",$numeroSemaine);
  758. }
  759. /**
  760. * Convertit une masse d'une unite vers une autre unite
  761. *
  762. * @param weight float Masse a convertir
  763. * @param from_unit int Unite originale en puissance de 10
  764. * @param to_unit int Nouvelle unite en puissance de 10
  765. * @return float Masse convertie
  766. */
  767. function weight_convert($weight,&$from_unit,$to_unit)
  768. {
  769. /* Pour convertire 320 gr en Kg appeler
  770. * $f = -3
  771. * weigh_convert(320, $f, 0) retournera 0.32
  772. *
  773. */
  774. while ($from_unit <> $to_unit)
  775. {
  776. if ($from_unit > $to_unit)
  777. {
  778. $weight = $weight * 10;
  779. $from_unit = $from_unit - 1;
  780. $weight = weight_convert($weight,$from_unit, $to_unit);
  781. }
  782. if ($from_unit < $to_unit)
  783. {
  784. $weight = $weight / 10;
  785. $from_unit = $from_unit + 1;
  786. $weight = weight_convert($weight,$from_unit, $to_unit);
  787. }
  788. }
  789. return $weight;
  790. }
  791. /**
  792. * Save personnal parameter
  793. *
  794. * @param db Handler database
  795. * @param conf Object conf
  796. * @param user Object user
  797. * @param tab Tableau (cle=>valeur) des parametres a sauvegarder
  798. * @return int <0 if KO, >0 if OK
  799. */
  800. function dol_set_user_param($db, $conf, &$user, $tab)
  801. {
  802. // Verification parametres
  803. if (count($tab) < 1) return -1;
  804. $db->begin();
  805. // We remove old parameters for all keys in $tab
  806. $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_param";
  807. $sql.= " WHERE fk_user = ".$user->id;
  808. $sql.= " AND entity = ".$conf->entity;
  809. $sql.= " AND param in (";
  810. $i=0;
  811. foreach ($tab as $key => $value)
  812. {
  813. if ($i > 0) $sql.=',';
  814. $sql.="'".$key."'";
  815. $i++;
  816. }
  817. $sql.= ")";
  818. dol_syslog("functions2.lib::dol_set_user_param sql=".$sql, LOG_DEBUG);
  819. $resql=$db->query($sql);
  820. if (! $resql)
  821. {
  822. dol_print_error($db);
  823. $db->rollback();
  824. return -1;
  825. }
  826. foreach ($tab as $key => $value)
  827. {
  828. // Set new parameters
  829. if ($value && (! $url || in_array($key,array('sortfield','sortorder','begin','page'))))
  830. {
  831. $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_param(fk_user,entity,param,value)";
  832. $sql.= " VALUES (".$user->id.",".$conf->entity.",";
  833. $sql.= " '".$key."','".$db->escape($value)."');";
  834. dol_syslog("functions2.lib::dol_set_user_param sql=".$sql, LOG_DEBUG);
  835. $result=$db->query($sql);
  836. if (! $result)
  837. {
  838. dol_print_error($db);
  839. $db->rollback();
  840. return -1;
  841. }
  842. $user->page_param[$key] = $value;
  843. }
  844. }
  845. $db->commit();
  846. return 1;
  847. }
  848. /**
  849. * Returns formated reduction
  850. *
  851. * @param reduction Reduction percentage
  852. * @param langs Output language
  853. * @return string Formated reduction
  854. */
  855. function dol_print_reduction($reduction=0,$langs)
  856. {
  857. $string = '';
  858. if ($reduction == 100)
  859. {
  860. $string = $langs->trans("Offered");
  861. }
  862. else
  863. {
  864. $string = $reduction.'%';
  865. }
  866. return $string;
  867. }
  868. /**
  869. * Return OS version.
  870. * Note that PHP_OS returns only OS (not version) and OS PHP was built on, not
  871. * necessarly OS PHP runs on.
  872. *
  873. * @return string OS version
  874. */
  875. function version_os()
  876. {
  877. $osversion=php_uname();
  878. return $osversion;
  879. }
  880. /**
  881. * Return PHP version
  882. *
  883. * @return string PHP version
  884. */
  885. function version_php()
  886. {
  887. return phpversion();
  888. }
  889. /**
  890. * Return Dolibarr version
  891. *
  892. * @return string Dolibarr version
  893. */
  894. function version_dolibarr()
  895. {
  896. return DOL_VERSION;
  897. }
  898. /**
  899. * Return web server version
  900. *
  901. * @return string Web server version
  902. */
  903. function version_webserver()
  904. {
  905. return $_SERVER["SERVER_SOFTWARE"];
  906. }
  907. /**
  908. * Return list of activated modules usable for document generation
  909. *
  910. * @param $db Database handler
  911. * @param $type Type of models (company, invoice, ...)
  912. * @param $maxfilenamelength Max length of value to show
  913. * @return int or array 0 if no module is activated, or array(key=>label). For modules that need directory scan, key is completed with ":filename".
  914. */
  915. function getListOfModels($db,$type,$maxfilenamelength=0)
  916. {
  917. global $conf,$langs;
  918. $liste=array();
  919. $found=0;
  920. $dirtoscan='';
  921. $sql = "SELECT nom as id, nom as lib, libelle as label, description as description";
  922. $sql.= " FROM ".MAIN_DB_PREFIX."document_model";
  923. $sql.= " WHERE type = '".$type."'";
  924. $sql.= " AND entity = ".$conf->entity;
  925. $resql = $db->query($sql);
  926. if ($resql)
  927. {
  928. $num = $db->num_rows($resql);
  929. $i = 0;
  930. while ($i < $num)
  931. {
  932. $found=1;
  933. $obj = $db->fetch_object($resql);
  934. // If this generation module needs to scan a directory, then description field is filled
  935. // with the constant that contains list of directories to scan (COMPANY_ADDON_PDF_ODT_PATH, ...).
  936. if (! empty($obj->description)) // List of directories to scan is defined
  937. {
  938. include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
  939. $const=$obj->description;
  940. $dirtoscan.=($dirtoscan?',':'').preg_replace('/[\r\n]+/',',',trim($conf->global->$const));
  941. $listoffiles=array();
  942. // Now we add models found in directories scanned
  943. $listofdir=explode(',',$dirtoscan);
  944. foreach($listofdir as $key=>$tmpdir)
  945. {
  946. $tmpdir=trim($tmpdir);
  947. $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir);
  948. if (! $tmpdir) { unset($listofdir[$key]); continue; }
  949. if (is_dir($tmpdir))
  950. {
  951. $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt');
  952. if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles);
  953. }
  954. }
  955. if (count($listoffiles))
  956. {
  957. foreach($listoffiles as $record)
  958. {
  959. $max=($maxfilenamelength?$maxfilenamelength:28);
  960. $liste[$obj->id.':'.$record['fullname']]=dol_trunc($record['name'],$max,'middle');
  961. }
  962. }
  963. else
  964. {
  965. $liste[0]=$obj->label.': '.$langs->trans("None");
  966. }
  967. }
  968. else
  969. {
  970. $liste[$obj->id]=$obj->label?$obj->label:$obj->lib;
  971. }
  972. $i++;
  973. }
  974. }
  975. else
  976. {
  977. dol_print_error($db);
  978. return -1;
  979. }
  980. if ($found) return $liste;
  981. else return 0;
  982. }
  983. /**
  984. * This function evaluates a string that should be a valid IPv4
  985. *
  986. * @return It returns 0 if $ip is not a valid IPv4
  987. * It returns 1 if $ip is a valid IPv4 and is a public IP
  988. * It returns 2 if $ip is a valid IPv4 and is a private lan IP
  989. */
  990. function is_ip($ip)
  991. {
  992. if (!preg_match("/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/", $ip)) return 0;
  993. if (sprintf("%u",ip2long($ip)) == sprintf("%u",ip2long('255.255.255.255'))) return 0;
  994. if (sprintf("%u",ip2long('10.0.0.0')) <= sprintf("%u",ip2long($ip)) and sprintf("%u",ip2long($ip)) <= sprintf("%u",ip2long('10.255.255.255'))) return 2;
  995. if (sprintf("%u",ip2long('172.16.0.0')) <= sprintf("%u",ip2long($ip)) and sprintf("%u",ip2long($ip)) <= sprintf("%u",ip2long('172.31.255.255'))) return 2;
  996. if (sprintf("%u",ip2long('192.168.0.0')) <= sprintf("%u",ip2long($ip)) and sprintf("%u",ip2long($ip)) <= sprintf("%u",ip2long('192.168.255.255'))) return 2;
  997. if (sprintf("%u",ip2long('169.254.0.0')) <= sprintf("%u",ip2long($ip)) and sprintf("%u",ip2long($ip)) <= sprintf("%u",ip2long('169.254.255.255'))) return 2;
  998. return 1;
  999. }
  1000. /**
  1001. * Build a login from lastname, firstname
  1002. *
  1003. * @param lastname Lastname
  1004. * @param firstname Firstname
  1005. * @return string
  1006. */
  1007. function dol_buildlogin($lastname,$firstname)
  1008. {
  1009. $login=strtolower(dol_string_unaccent($firstname));
  1010. $login.=($login?'.':'');
  1011. $login.=strtolower(dol_string_unaccent($lastname));
  1012. $login=dol_string_nospecial($login,''); // For special names
  1013. return $login;
  1014. }
  1015. /**
  1016. * Return array to use for SoapClient constructor
  1017. *
  1018. * @return param
  1019. */
  1020. function getSoapParams()
  1021. {
  1022. global $conf;
  1023. $params=array();
  1024. $proxyuse =(empty($conf->global->MAIN_PROXY_USE)?false:true);
  1025. $proxyhost=(empty($conf->global->MAIN_PROXY_USE)?false:$conf->global->MAIN_PROXY_HOST);
  1026. $proxyport=(empty($conf->global->MAIN_PROXY_USE)?false:$conf->global->MAIN_PROXY_PORT);
  1027. $proxyuser=(empty($conf->global->MAIN_PROXY_USE)?false:$conf->global->MAIN_PROXY_USER);
  1028. $proxypass=(empty($conf->global->MAIN_PROXY_USE)?false:$conf->global->MAIN_PROXY_PASS);
  1029. $timeout =(empty($conf->global->MAIN_USE_CONNECT_TIMEOUT)?10:$conf->global->MAIN_USE_CONNECT_TIMEOUT); // Connection timeout
  1030. $response_timeout=(empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT)?30:$conf->global->MAIN_USE_RESPONSE_TIMEOUT); // Response timeout
  1031. //print extension_loaded('soap');
  1032. if ($proxyuse)
  1033. {
  1034. $params=array('connection_timeout'=>$timeout,
  1035. 'response_timeout'=>$response_timeout,
  1036. 'proxy_use' => 1,
  1037. 'proxy_host' => $proxyhost,
  1038. 'proxy_port' => $proxyport,
  1039. 'proxy_login' => $proxyuser,
  1040. 'proxy_password' => $proxypass,
  1041. 'trace' => 1
  1042. );
  1043. }
  1044. else
  1045. {
  1046. $params=array('connection_timeout'=>$timeout,
  1047. 'response_timeout'=>$response_timeout,
  1048. 'proxy_use' => 0,
  1049. 'proxy_host' => false,
  1050. 'proxy_port' => false,
  1051. 'proxy_login' => false,
  1052. 'proxy_password' => false,
  1053. 'trace' => 1
  1054. );
  1055. }
  1056. return $params;
  1057. }